Prerequisites
As a prerequisite, you should understand:
Process Details
You need to register a merchant ID using an Apple developer account. Additionally you need to assign a key pair to this merchant ID, and sign its accompanying certificate signing request (CSR) there. The key pair and CSR is received from us. With merchant ID and key pair you can integrate an Apple Pay button into your checkout solution.
The payment process itself works similar to other payment methods. When one operates the Apple Pay button, the payment instrument is chosen and the necessary security checks are performed. The Apple API returns a security token, that must be handed over to authorise the payment against the secuconnect API.
The secuconnect API methods to authorise and capture the payment are the same like for credit card payment, except there are no callback URLs for there is no second interactive 3-D Secure check, and there is a special Payment Container for Apple Pay. This Payment Container has a very short lifetime and cannot be reused.
Domain Validation and Registration
If Apple Pay is only to be integrated into a website (or if it is a web app), then no Apple Developer account is required.
The integration in native apps has not been tested yet; issues may occur due to the different Apple Team IDs. A hybrid app (like React Native or Flutter) should not be a problem.
Domain Validation File
The domain where the Apple Pay button is displayed must first be validated with Apple. The shop must offer a file /.well-known/apple-developer-merchantid-domain-association
having exactly the following content:
7B227073704964223A2234413632343942424633384330353830314536383844343938364139333933423032354642303544423944393638323244413732303633363731453836444133222C2276657273696F6E223A312C22637265617465644F6E223A313638393832353536323630392C227369676E6174757265223A223330383030363039326138363438383666373064303130373032613038303330383030323031303133313064333030623036303936303836343830313635303330343032303133303830303630393261383634383836663730643031303730313030303061303830333038323033653333303832303338386130303330323031303230323038346333303431343935313964353433363330306130363038326138363438636533643034303330323330376133313265333032633036303335353034303330633235343137303730366336353230343137303730366336393633363137343639366636653230343936653734363536373732363137343639366636653230343334313230326432303437333333313236333032343036303335353034306230633164343137303730366336353230343336353732373436393636363936333631373436393666366532303431373537343638366637323639373437393331313333303131303630333535303430613063306134313730373036633635323034393665363332653331306233303039303630333535303430363133303235353533333031653137306433313339333033353331333833303331333333323335333735613137306433323334333033353331333633303331333333323335333735613330356633313235333032333036303335353034303330633163363536333633326437333664373032643632373236663662363537323264373336393637366535663535343333343264353035323466343433313134333031323036303335353034306230633062363934663533323035333739373337343635366437333331313333303131303630333535303430613063306134313730373036633635323034393665363332653331306233303039303630333535303430363133303235353533333035393330313330363037326138363438636533643032303130363038326138363438636533643033303130373033343230303034633231353737656465626436633762323231386636386464373039306131323138646337623062643666326332383364383436303935643934616634613534313162383334323065643831316633343037653833333331663163353463336637656233323230643662616435643465666634393238393839336537633066313361333832303231313330383230323064333030633036303335353164313330313031666630343032333030303330316630363033353531643233303431383330313638303134323366323439633434663933653465663237653663346636323836633366613262626664326534623330343530363038326230363031303530353037303130313034333933303337333033353036303832623036303130353035303733303031383632393638373437343730336132663266366636333733373032653631373037303663363532653633366636643266366636333733373033303334326436313730373036633635363136393633363133333330333233303832303131643036303335353164323030343832303131343330383230313130333038323031306330363039326138363438383666373633363430353031333038316665333038316333303630383262303630313035303530373032303233303831623630633831623335323635366336393631366536333635323036663665323037343638363937333230363336353732373436393636363936333631373436353230363237393230363136653739323037303631373237343739323036313733373337353664363537333230363136333633363537303734363136653633363532303666363632303734363836353230373436383635366532303631373037303663363936333631363236633635323037333734363136653634363137323634323037343635373236643733323036313665363432303633366636653634363937343639366636653733323036663636323037353733363532633230363336353732373436393636363936333631373436353230373036663663363936333739323036313665363432303633363537323734363936363639363336313734363936663665323037303732363136333734363936333635323037333734363137343635366436353665373437333265333033363036303832623036303130353035303730323031313632613638373437343730336132663266373737373737326536313730373036633635326536333666366432663633363537323734363936363639363336313734363536313735373436383666373236393734373932663330333430363033353531643166303432643330326233303239613032376130323538363233363837343734373033613266326636333732366332653631373037303663363532653633366636643266363137303730366336353631363936333631333332653633373236633330316430363033353531643065303431363034313439343537646236666435373438313836383938393736326637653537383530376537396235383234333030653036303335353164306630313031666630343034303330323037383033303066303630393261383634383836663736333634303631643034303230353030333030613036303832613836343863653364303430333032303334393030333034363032323130306265303935373166653731653165373335623535653561666163623463373266656234343566333031383532323263373235313030326236316562643666353530323231303064313862333530613564643664643665623137343630333562313165623263653837636661336536616636636264383338303839306463383263646461613633333038323032656533303832303237356130303330323031303230323038343936643266626633613938646139373330306130363038326138363438636533643034303330323330363733313162333031393036303335353034303330633132343137303730366336353230353236663666373432303433343132303264323034373333333132363330323430363033353530343062306331643431373037303663363532303433363537323734363936363639363336313734363936663665323034313735373436383666373236393734373933313133333031313036303335353034306130633061343137303730366336353230343936653633326533313062333030393036303335353034303631333032353535333330316531373064333133343330333533303336333233333334333633333330356131373064333233393330333533303336333233333334333633333330356133303761333132653330326330363033353530343033306332353431373037303663363532303431373037303663363936333631373436393666366532303439366537343635363737323631373436393666366532303433343132303264323034373333333132363330323430363033353530343062306331643431373037303663363532303433363537323734363936363639363336313734363936663665323034313735373436383666373236393734373933313133333031313036303335353034306130633061343137303730366336353230343936653633326533313062333030393036303335353034303631333032353535333330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030346630313731313834313964373634383564353161356532353831303737366538383061326566646537626165346465303864666334623933653133333536643536363562333561653232643039373736306432323465376262613038666437363137636538386362373662623636373062656338653832393834666635343435613338316637333038316634333034363036303832623036303130353035303730313031303433613330333833303336303630383262303630313035303530373330303138363261363837343734373033613266326636663633373337303265363137303730366336353265363336663664326636663633373337303330333432643631373037303663363537323666366637343633363136373333333031643036303335353164306530343136303431343233663234396334346639336534656632376536633466363238366333666132626266643265346233303066303630333535316431333031303166663034303533303033303130316666333031663036303335353164323330343138333031363830313462626230646561313538333338383961613438613939646562656264656261666461636232346162333033373036303335353164316630343330333032653330326361303261613032383836323636383734373437303361326632663633373236633265363137303730366336353265363336663664326636313730373036633635373236663666373436333631363733333265363337323663333030653036303335353164306630313031666630343034303330323031303633303130303630613261383634383836663736333634303630323065303430323035303033303061303630383261383634386365336430343033303230333637303033303634303233303361636637323833353131363939623138366662333563333536636136326266663431376564643930663735346461323865626566313963383135653432623738396638393866373962353939663938643534313064386639646539633266653032333033323264643534343231623061333035373736633564663333383362393036376664313737633263323136643936346663363732363938323132366635346638376137643162393963623962303938393231363130363939306630393932316430303030333138323031383833303832303138343032303130313330383138363330376133313265333032633036303335353034303330633235343137303730366336353230343137303730366336393633363137343639366636653230343936653734363536373732363137343639366636653230343334313230326432303437333333313236333032343036303335353034306230633164343137303730366336353230343336353732373436393636363936333631373436393666366532303431373537343638366637323639373437393331313333303131303630333535303430613063306134313730373036633635323034393665363332653331306233303039303630333535303430363133303235353533303230383463333034313439353139643534333633303062303630393630383634383031363530333034303230316130383139333330313830363039326138363438383666373064303130393033333130623036303932613836343838366637306430313037303133303163303630393261383634383836663730643031303930353331306631373064333233333330333733323330333033333335333933323332356133303238303630393261383634383836663730643031303933343331316233303139333030623036303936303836343830313635303330343032303161313061303630383261383634386365336430343033303233303266303630393261383634383836663730643031303930343331323230343230653065366539313863363161363938666630656134386538316564616631366435653863363432346363363033396633646139613635623638343132343463303330306130363038326138363438636533643034303330323034343733303435303232313030633434386336393963353735613261633836373763633437386461666463626261363761313032623038623339663536343138633164363162616665633831313032323034656436366532613931333137626464616239636535646665663937633035653236316534333231333331656430303039613934666336376338326339316330303030303030303030303030227D
It must be accessible at a URL like https://shop.example.com/.well-known/apple-developer-merchantid-domain-association
.
Domain Registration
Now you can register your domain with the Apple Pay Merchant ID of secupay ("merchant.com.secupay.finaro
"). You must register the fully qualified domain name (FQDN) like www.example.com
(in contrast to just example.com
).
Our secuconnect API offers the endpoint /apple-pay/register-merchant-domain
for domain registration:
POST /apple-pay/register-merchant-domain HTTP/1.1
Host: connect.secucard.com
Authorization: Bearer qb56tjj1bcvo9n2nj4u38k84lo
Content-Type: application/json
Accept: application/json
{
"domainNames"
: [
"shop.example.com"
],
"encryptTo"
:
"merchant.com.secupay.finaro"
,
"partnerMerchantName"
:
"Musterfirma GmbH"
}
(Please note the base path is not /api/v2 here.)
The parameters have a direct equivalent to Apple Pay, see https://developer.apple.com/documentation/applepaywebmerchantregistrationapi/registermerchantrequest .
The parameter partnerInternalMerchantIdentifier
is generated by us and does not have to be transmitted. You can register up to 99 domains per call. The first domain in the list determines the partnerInternalMerchantIdentifier
.
If everything is fine, the API responds with 200 OK and an object like this:
HTTP/1.1 200 OK
Content-Type: application/json
{
"domainNames"
: [
"shop.example.com"
],
"encryptTo"
:
"merchant.com.secupay.finaro"
,
"partnerMerchantName"
:
"Musterfirma GmbH"
,
"partnerInternalMerchantIdentifier"
:
"merchant.com.secupay.finaro.com.example.shop"
}
The value of the partnerInternalMerchantIdentifier
must be stored and used as merchantIdentifier
of the Apple Pay Button.
Button Parameters
The other parameters can be requested from the secuconnect API:
POST /api/v2/General/Contracts/GCR_UWOTSTRSQFMGV5PK5LF65LNNL0H84G/IframeOptions HTTP/1.1
Host: connect-testing.secuconnect.com
Authorization: Bearer qb56tjj1bcvo9n2nj4u38k84lo
Accept: application/json
If everything is fine, the API responds with 200 OK and an object like this:
HTTP/1.1 200 OK
Content-Type: application/json
{
// ...
"payment_config"
: {
// ...
"Applepay"
: {
"label"
:
"Musterfirma GmbH"
,
"supported_networks"
: [
"masterCard"
,
"visa"
],
"merchant_capabilities"
: [
"supports3DS"
]
}
}
}
The returned parameters inside payment_config.Applepay
are used as-is to create the button.
Apple Pay Button Integration
The Apple Pay button must be set up this way:
//
https://developer.apple.com/documentation/apple_pay_on_the_web/displaying_apple_pay_buttons_using_javascript
<
script
src
=
"https://applepay.cdn-apple.com/jsapi/v1.1.0/apple-pay-sdk.js"
></
script
>
..
<
apple
-pay-button
buttonstyle
=
"black"
type
=
"buy"
locale
=
"de-DE"
></
apple
-pay-button>
The Apple Pay session must be set up this way:
// Creating an Apple Pay Session
// https://developer.apple.com/documentation/apple_pay_on_the_web/apple_pay_js_api/creating_an_apple_pay_session
// https://developer.apple.com/documentation/apple_pay_on_the_web/applepaypaymentrequest
var
session =
new
ApplePaySession(1, {
currencyCode:
'EUR'
,
countryCode:
'DE'
,
// https://developer.apple.com/documentation/apple_pay_on_the_web/applepaylineitem
total: {
label:
'Musterfirma GmbH'
,
amount:
'10.00'
,
type:
'final'
},
// https://developer.apple.com/documentation/apple_pay_on_the_web/applepayrequest/2951831-supportednetworks
supportedNetworks: [
'masterCard'
,
'visa'
],
// https://developer.apple.com/documentation/apple_pay_on_the_web/applepaymerchantcapability
merchantCapabilities: [
'supports3DS'
]
});
// Providing Merchant Validation
// https://developer.apple.com/documentation/apple_pay_on_the_web/apple_pay_js_api/providing_merchant_validation
// https://applepaydemo.apple.com/#merchantValidation
session.onvalidatemerchant = (event: any) => {
// Call your own server to request a new merchant session.
// You server will then call POST https://connect.secucard.com/apple-pay/create-payment-session with the same data.
// (Because of CORS this endpoint can not be called from the browser directly.)
fetch(
'/backend/apple-pay/init'
, {
method:
'POST'
,
body: JSON.stringify({
"merchantIdentifier"
:
"merchant.com.secupay.finaro.com.example.shop"
,
"displayName"
:
"TEST SHOP"
,
"initiative"
:
"web"
,
"initiativeContext"
:
"shop.example.com"
// Must be equal to the "domainNames" value in the "Domain Registration" section.
})
})
.then(res => res.json())
// Parse response as JSON.
.then(merchantSession => {
session.completeMerchantValidation(merchantSession);
})
.
catch
(err => {
console.error(
"Error fetching merchant session"
, err);
});
};
// Sending container data to the backend, which will then do the "Authorise the Payment" step.
session.onpaymentauthorized = (event: any) => {
let form = event.payment.token.paymentData;
fetch(
'/backend/apple-pay/authorise'
, {
method:
'POST'
,
body: {
id:
"STX_33PXAW2YN2NJTPM5KPGMK7QF5PBVA2"
,
container: {
type:
"applepay"
,
private: form
}
}
})
.then(res => res.json())
// Parse response as JSON.
.then(merchantSession => {
session.completePayment(session.STATUS_SUCCESS);
})
.
catch
(err => {
console.error(
"Error fetching merchant session"
, err);
});
}
session.oncancel = (event) => {
}
session.begin();
Authorise the Payment
In order to authorise the Smart Transaction for Apple Pay payment, you need to call POST Smart/Transactions/STX_.../prepare/creditcard
:
POST /api/v2/Smart/Transactions/STX_33PXAW2YN2NJTPM5KPGMK7QF5PBVA2/prepare/creditcard HTTP/1.1
Host: connect-testing.secuconnect.com
Authorization: Bearer qb56tjj1bcvo9n2nj4u38k84lo
Content-Type: application/json
Accept: application/json
{
"customer"
: {
"contact"
: {
"forename"
:
"Mike"
,
"surname"
:
"Mustermann"
,
"name"
:
"Mike Mustermann"
,
"address"
: {
"street"
:
"Musterstr."
,
"street_number"
:
"42"
,
"additional_address_data"
:
"App. 97"
,
"postal_code"
:
"09999"
,
"city"
:
"Dorianburgh"
,
"country"
:
"DE"
},
"email"
:
"Eunice.Spencer89@example.net"
,
"mobile"
:
"+491775555555"
,
"phone"
:
"+495555555555"
,
"dob"
:
"1965-12-31T00:00:00+01:00"
}
},
"container"
: {
"type"
:
"applepay"
,
"private"
: {
"version"
:
"EC_v1"
,
"data"
:
"g7tzh9wOG0TkzmFdMHYvqwmQtAV9Zsr2tgIvDr92EXd8VtLL29WM2UN5rt4FtUJjusnnl8S5WOcxIjZdftzxYp7CuGEOf7cOmJotUPP5MeCyjn8d7CQA+8O9PDcobRC1R+DlgoFmW3+VffJlEo2b6XrGlv0Yw8ml6uUp8...c9x8="
,
"signature"
:
"MIAGCSqGSIb3DQEHAqCAMIACAQExDzANBglghkgBZQMEAgEFADCABgkqhkiG9w0BBwEAAKCAMIID4zCCA4igAwIBAgIITDBBSVGdVDYwCgYIKoZIzj0EAwIwejEuMCwGA1UEAwwlQXBwbG.../Kft6VcCWj/aRqxEAAAAAAAA"
,
"header"
: {
"ephemeralPublicKey"
:
"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEcdKUayPwZ2cmGwV7TRiR9AOUs1581B8wPqWgwiJzUhaQ2cRn4hw4f93Mq+leog27OzF5nhZFxEAPKrMzW/mDyQ=="
,
"publicKeyHash"
:
"9a/AmJ2u6BtDOZxusyFItlLeBaLYFMtH/McHzhqVi5Y="
,
"transactionId"
:
"6b5396203987ad350d91c3d2f8b7606384d070ef45443b2422a30598ca937327"
}
}
}
}
These are the parameters:
Parameter | Type | Meaning |
---|---|---|
|
| Payment container data |
|
| Always |
|
| Data taken from the |
|
| Customer. Only needed if not set before. |
|
| Customer ID ( |
The Smart Transaction is authorised immediately.
HTTP/1.1 200 OK
Content-Type: application/json
...
{
"object"
:
"smart.transactions"
,
"id"
:
"STX_33PXAW2YN2NJTPM5KPGMK7QF5PBVA2"
,
// ...
"customer"
: {
"object"
:
"payment.customers"
,
"id"
:
"PCU_3M55SQZR42NSPDS8GGF4N55EZCDCAZ"
,
"contact"
: {
"forename"
:
"Mike"
,
"surname"
:
"Mustermann"
,
"name"
:
"Mike Mustermann"
,
"address"
: {
"street"
:
"Musterstr."
,
"street_number"
:
"42"
,
"additional_address_data"
:
"App. 97"
,
"postal_code"
:
"09999"
,
"city"
:
"Dorianburgh"
,
"country"
:
"DE"
},
"email"
:
"Eunice.Spencer89@example.net"
,
"mobile"
:
"+491775555555"
,
"phone"
:
"+495555555555"
,
"dob"
:
"1965-12-31T00:00:00+01:00"
}
},
"container"
: {
"object"
:
"payment.containers"
,
"id"
:
"PCT_SF9XGHPVC2NSQX03V86EREAMMET7AZ"
},
// ... // ...
"transactions"
: [{
"object"
:
"payment.transactions"
,
"id"
:
"PCI_4YN04HZ4Z705GMRSJ5EW4J4X0ZDPNW"
}],
"created"
:
"2020-10-29T14:13:41+01:00"
,
"updated"
:
"2020-10-29T14:13:50+01:00"
,
"status"
:
"approved"
,
// ...
"payment_method"
:
"creditcard"
,
"trans_id"
:
"30093721"
,
// ...
}
Status approved
means the payment is authorised and you should be able to capture it. Status failed
means you must repeat the payment process. You must also repeat the payment process when you update the Smart Transaction. It is then set back to created
.
If the option auto_capture
is true
, it would already capture the Smart Transaction. Status ok
, received
or collection
means you can deliver. Status pending
means you have to wait for one of these statusses. Status failed
means the payment failed, and you must repeat the payment process.
Capture the Payment
The way to capture an authorised payment is the same for all payment methods. If you have already studied this for invoice or direct debit payment, you will not find any new details.
In order to start the authorized Smart Transaction, you only need to call POST Smart/Transactions/STX_xxx/start
.
POST /api/v2/Smart/Transactions/STX_33PXAW2YN2NJTPM5KPGMK7QF5PBVA2/start HTTP/1.1
Host: connect-testing.secuconnect.com
Authorization: Bearer qb56tjj1bcvo9n2nj4u38k84lo
Accept: application/json
If everything is fine, the API responds with 200 OK
:
HTTP/1.1 200 OK
Content-Type: application/json
{
"object"
:
"smart.transactions"
,
"id"
:
"STX_33PXAW2YN2NJTPM5KPGMK7QF5PBVA2"
,
// ...
"transactions"
: [
{
"object"
:
"payment.transactions"
,
"id"
:
"PCI_FDBREW9ZS7P6FTN4ZY2ATC6NK0QWO7"
}
],
"created"
:
"2020-03-27T10:55:23+01:00"
,
"updated"
:
"2020-03-27T10:56:41+01:00"
,
"status"
:
"ok"
,
// ...
}
Status ok
, received
or collection
means you can deliver. Status pending
means you have to wait for one of these statusses. Status failed
means the payment failed, and you must repeat the payment process.
In case of invoice payment you need to mark the actual delivery. This is to know the payment has become due, and to calculate the due date.
See Also
Further information:
- Customer Details per Payment Method
- Obtain the Available Payment Methods
- Push Notifications for Payments
Other payment methods: