Pay with Apple Pay

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.

Google Pay Button Integration

The Apple Pay session must be set up this way:

JavaScript
var session = new ApplePaySession(1, {
currencyCode: 'EUR',
countryCode: 'DE',
 
// https://developer.apple.com/documentation/apple_pay_on_the_web/applepaylineitem
total: {
label: 'Your Merchant Name',
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']
});

Step 1: Create a Smart Transaction

The API endpoint to create a Smart Transaction is POST https://connect.secucard.com/api/v2/Smart/Transactions.

Request
POST /api/v2/Smart/Transactions HTTP/1.1
Host: connect-testing.secupay-ag.de
Authorization: Bearer qb56tjj1bcvo9n2nj4u38k84lo
Content-Type: application/json
Accept: application/json
 
{
"is_demo": true,
"intent": "sale",
"contract": {
"id": "GCR_CNEUVF64H5S8R58R7PB4Q6CNJESBPJ"
},
"customer": {
"id": "PCU_38RG7MHRE2NJTPFMXRYQP3NKW6GVAZ"
},
"merchantRef": "K/01234",
  "transactionRef": "B/001234567",
   "basket": {
"products": [
{
"id": 1,
"articleNumber": 30037,
"ean": "4999012345678",
"desc": "Höhenverstellbarer Schreibtisch",
"quantity": 1,
"priceOne": 49800,
"tax": 19
},
{
"id": 2,
"item_type": "coupon",
"desc": "Coupon 20 €",
"quantity": 1,
"priceOne": 2000,
"tax": 19
},
{
"id": 3,
"item_type": "shipping",
"desc": "Versand Spedition",
"quantity": 1,
"priceOne": 3500,
"tax": 19
}
]
},
"basket_info": {
"sum": 51300,
"currency": "EUR"
},
  "payment_context": {
"auto_capture": false
}
}

This creates a Smart Transaction to pay a hotel reservation. The customer is preset with the previously created object, and the amount is €119.70.

Monetary amounts are expressed in the smallest currency unit (e. g. Euro Cent).

If everything is fine, the API responds with 200 OK:

Response
HTTP/1.1 200 OK
Content-Type: application/json
 
{
"object": "smart.transactions",
"id": "STX_33PXAW2YN2NJTPM5KPGMK7QF5PBVA2",
"merchant": {
"object": "general.merchants",
"id": "MRC_AZS7P6FTNTC6NK0QWFDBREW94ZY2O7",
"companyname": "Smart Checkout Testmerchant 8"
},
"provider_contract": {
"object": "general.contracts",
"id": "GCR_QP49BFHYYKVAQBFWGE5VBBUUJEQ2P8"
},
"contract": {
"object": "general.contracts",
"id": "GCR_CNEUVF64H5S8R58R7PB4Q6CNJESBPJ"
},
"customer": {
"object": "payment.customers",
"id": "PCU_38RG7MHRE2NJTPFMXRYQP3NKW6GVAZ",
"contact": {
"forename": "Max",
"surname": "Mustermann",
"name": "Max Mustermann",
"salutation": "Mr.",
"address": {
"street": "Max-Muster-Str.",
"street_number": "25a",
"additional_address_data": "Whg. 202",
"postal_code": "09555",
"city": "Musterstadt",
"country": "DE"
},
"email": "mmustermann@example.net",
"mobile": "+491775555555",
"phone": "+495555555555"
}
},
"transactions": [],
"created": "2020-03-27T10:55:23+01:00",
"status": "created",
"merchantRef": "K/01234",
  "transactionRef": "B/001234567",
  "intent": "sale",
"basket": {
"products": [
{
"id": 1,
"articleNumber": 30037,
"ean": "4999012345678",
"desc": "Höhenverstellbarer Schreibtisch",
"quantity": 1,
"priceOne": 49800,
"tax": 19
},
{
"id": 2,
"item_type": "coupon",
"desc": "Coupon 20 €",
"quantity": 1,
"priceOne": 2000,
"tax": 19
},
{
"id": 3,
"item_type": "shipping",
"desc": "Versand Spedition",
"quantity": 1,
"priceOne": 3500,
"tax": 19
}
]
},
"basket_info": {
"sum": 51300,
"currency": "EUR"
},
  "is_demo": true,
// ...
"payment_context": {
"auto_capture": false,
"payment_methods": null,
"merchant_initiated": false,
"accrual": false,
"creditcard_schemes": [
"mastercard",
"visa",
"american express"
]
},
// ...
}

As you see, the system behind the secuconnect API added many things. Most interesting for is the ID of the Smart Transaction, here STX_33PXAW2YN2NJTPM5KPGMK7QF5PBVA2. You need it for the subsequent API calls.

Step 2: Authorise the Payment

In order to authorise the Smart Transaction for Apple Pay payment, you need to call POST Smart/Transactions/STX_xxx/prepare/creditcard:

Request
POST /api/v2/Smart/Transactions/STX_33PXAW2YN2NJTPM5KPGMK7QF5PBVA2/prepare/creditcard HTTP/1.1
Host: connect-testing.secupay-ag.de
Authorization: Bearer qb56tjj1bcvo9n2nj4u38k84lo
Content-Type: application/json
Accept: application/json

{
    "container": {
        "type": "applepay",
        "private": {
            "version": "EC_v1",
            "data": "g7tzh9wOG0TkzmFdMHYvqwmQtAV9Zsr2tgIvDr92EXd8VtLL29WM2UN5rt4FtUJjusnnl8S5WOcxIjZdftzxYp7CuGEOf7cOmJotUPP5MeCyjn8d7CQA+8O9PDcobRC1R+DlgoFmW3+VffJlEo2b6XrGlv0Yw8ml6uUp8LB7RfKUwGRIeSL/yHmrWTmaCRV8llQrbsHOp40t1YQ5S0l6ynqX+NknsbZ6KbCSUbdzJzdMzKCXEZpzfLnDMQKwVFiBuL+UNje7uzrzQbduWnKmGiC+Mkdp4gul9n8dN/xxMAB6p641oCVenjDarqq/t9ae4I6uuk+6ZIF/Ng8OOB+9Ks9nfjf6w/2a4qMJXlX/SCxAiaAFSVUz+1QjmzX+1sf38qooCXD/cJbc9x8=",
            "signature": "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",
            "header": {
                "ephemeralPublicKey": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEcdKUayPwZ2cmGwV7TRiR9AOUs1581B8wPqWgwiJzUhaQ2cRn4hw4f93Mq+leog27OzF5nhZFxEAPKrMzW/mDyQ==",
                "publicKeyHash": "9a/AmJ2u6BtDOZxusyFItlLeBaLYFMtH/McHzhqVi5Y=",
                "transactionId": "6b5396203987ad350d91c3d2f8b7606384d070ef45443b2422a30598ca937327"
            }
        }
    },
    "customer": {
        "id": "PCU_3M55SQZR42NSPDS8GGF4N55EZCDCAZ"
    },
    "merchant": {
         "id": "MRC_WVHJQFQ4JNVYNG5B55TYK748ZCHQP8"
    }
}

These are the parameters:

Parameter

Type

Meaning

container

object

Payment container data

container/type

string

Always "applepay" for this payment method

container/private

object

Data taken from the paymentData object of the decrypted Apple Pay token

customer

object

Customer. Only needed if not set before.

customer/id

string

Customer ID (PCU_xxx)

merchant

object

Merchant. Only needed if not identified by the contract.

merchant/id

string

Merchant ID (MRC_xxx)

The Smart Transaction is authorised immediately.

Response (3-D Secure Not Required)
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.

Step 3: 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.

Request
POST /api/v2/Smart/Transactions/STX_33PXAW2YN2NJTPM5KPGMK7QF5PBVA2/start HTTP/1.1
Host: connect-testing.secupay-ag.de
Authorization: Bearer qb56tjj1bcvo9n2nj4u38k84lo
Accept: application/json

If everything is fine, the API responds with 200 OK:

Response
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.

Note: You also need to mark the actual delivery. This is needed to determine the due date of the payment.