Introduction

Apple Pay enables customers with iOS devices or Macs to pay using payment methods stored in their wallet-app.

Merchants need to display an Apple Pay button to eligible customers, who then get presented a payment sheet for easy review of the order and payment.

Merchants can configure the look and feel of both buttons and payment sheet, but should adhere to the Apple guidelines.

Overview

Applepay is currently not supported in all countries, please check with Applepay if it is available in your country/region.

All currencies that applepay supports are currently also supported by the PAYONE platform

supported Payment methods:

  • Visa
  • Mastercard
  • girocard (expected soon)

The token is a so called pseudo card PAN, a number that resembles a credit card number, so that 3rd party systems can use it, but doesn't entail the PCI DSS requirements for storing card data. To avoid the software on the server to come in contact with credit card data, the Client API is used for communication between the buyer's browser and PAYONE.

We strongly recommend using our card tokenization mechanic as outlined in Hosted-iFrame Mode - Short description. Not only will this significantly decrease your PCI DSS compliance efforts, using the tokenized pseudocardpan will also decrease the amount of card parameters you will have to handle.

Test Data

the test data that can be used is documented on the developer page of Apple Pay

Integrations

POST Request Pre- /Authorization
Account Parameters
request
required
Fixed Value: preauthorization
mid
required
your merchant ID, 5-digit numeric
aid
required
your subaccount ID, 5-digit numeric
portalId
required
your Portal ID, 7-digit numeric
key
required
your key value, alpha-numeric
PERSONAL DATA Parameters
firstname
optional
Format CHAR(1..50)

First name of customer; optional if company is used, i.e.: you may use

"company" or "lastname" or "firstname" plus "lastname"

lastname
required
Format CHAR(2..50)

Last name of customer; optional if company is used, i.e.: you may use

"company" or "lastname" or "firstname" plus "lastname"

company
optional
Format CHAR(2..50)

Company name, required for B2B transactions (if add_paydata[b2b] = “yes”)

street
optional
Format CHAR(1..50)

Street number and name (required: at least one character)

zip
optional
Format CHAR(2..50)
Permitted Symbols [0-9][A-Z][a-z][_.-/ ]

Postcode

city
optional
Format CHAR(2..50)

City of customer

country
required
Format List

Permitted values ISO 3166 2-letter-codes

Samples DE / GB/ US

Specifies country of address for the customer.

Some countries require additional information in parameter "state"
email
optional
Format CHAR(5..254)

Permitted Symbols RFC 5322

Special Remark email validation:

Max. length for email is 254 characters. Validation is set up in the following way:

Username = Max. 63 characters

Domain Name = Max. 63 characters
Domain Suffixes = Max. 4 suffixes with max. 124 characters 
Example: username[63]@domain_name[63].suffix[60].suffix[60].suffix[4]

"@" and "." is counted as a character as well; in case of a total of three suffixes, this would allow a total of 254 characters.

email-address of customer

birthday
optional
Format DATE(8), YYYYMMDD

Samples 20190101 / 19991231


Date of birth of customer

telephonenumber
optional

Telephone number

add_paydata PARAMETERS
add_paydata[paymentdata_token_version]
required
Format String

Sample EC_v1

add_paydata[paymentdata_token_data]
required
Sample rhHAQUrR118u[...]cwDw==
add_paydata[paymentdata_token_signature]
required
Format String

Sample MIAGCSqGSIb3DQEHAqCAMIACAQE[...]AAAAAAA==

add_paydata[paymentdata_token_ephemeral_publickey]
required

Sample MFkwEwYHKoZIzj0[...]Y2A==

add_paydata[paymentdata_token_publickey_hash]
required
Format String

Sample
ilecVF58bpB8qio[...]l6eirw2Y1v1KU

add_paydata[paymentdata_token_transaction_id]
required
Format String

Sample be2e745845b31dfac7778c6e29[...]b658cbcca971c0e0

Response Parameters

Permitted Values

APPROVED
ERROR
Response Parameter (Approved)
Format NUMERIC(9..12)

The txid specifies the payment process within the PAYONE platform

 userid
Format NUMERIC(9..12)

PAYONE User ID, defined by PAYONE

Response Parameter (Error)
Format NUMERIC(1..6)

In case of error the PAYONE Platform returns an error code for your internal usage.

Format CHAR(1..1024)

In case of error the PAYONE Platform returns an error message for your internal usage.

Format CHAR(1..1024)

The customermessage is returned to your system in order to be displayed to the customer.

(Language selection is based on the end customer's language, parameter "language")

Host: api.pay1.de
    Content-Type: application/x-www-form-urlencoded
    
Payload

add_paydata[paymentdata_token_data]=FpFyA6zSGkZC[...]xi8xeXCNbpGBpvlNXfcang==
add_paydata[paymentdata_token_ephemeral_publickey]=MFkwEwYHKoZIzj0CA[...]iXv34cYJ4lxZsjVgnsE0i6RX+mg==
add_paydata[paymentdata_token_publickey_hash]=tWOdQ0ARSRiQNsrS4[...]7X6KBxLLAa8=
add_paydata[paymentdata_token_signature]=MIAGCSqGSIb3DQEHAq[...]s9oHcqWMnolhsgAAAAAAAA
add_paydata[paymentdata_token_transaction_id]=12d7[...]d4eebc2e54109386
add_paydata[paymentdata_token_version]=EC_v1
aid=12345
amount=1000
api_version=3.11
cardtype=V
clearingtype=wlt
country=DE
currency=EUR
encoding=UTF-8
firstname=Demo
key=your key as md5
lastname=Dude
mid=12345
mode=test
portalid=123456
reference=your unique reference
request=preauthorization
wallettype=APL
RESPONSE

status=APPROVED
txid=123456789
userid=987654321
POST Request Capture

The capture request is used to finalize a preauthorized transaction.

If you use preauth/Capture with installment transactions, the capture request has to be sent right after the preauthorization

Account Parameters
request
required
Fixed Value: creditcardcheck
mid
required
your merchant ID, 5-digit numeric
aid
required
your subaccount ID, 5-digit numeric
portalId
required
your Portal ID, 7-digit numeric
key
required
your key value, alpha-numeric
common Parameters
txid
required
Format NUMERIC(9..12)

The txid specifies the payment process within the PAYONE platform

clearingtype
optional
Fixed Value wlt
wallettype
optional
Fixed Value: APL

APL: Apple Pay

capturemode
required
Format LIST
Value Comment
completed

Set with last capture; i.e.: Delivery completed.
No further capture is allowed.

notcompleted

Set with partial deliveries (last delivery with "completed")
Another capture is expected to complete the transaction.

Specifies whether this capture is the last one or whether there will be another one in future.

sequencenumber
optional
Format NUMERIC(1..3)
Permitted values 0..127

Sequence number for this transaction within the payment process (1..n), e.g. PreAuthorization: 0, 1. Capture: 1, 2. Capture: 2

Required for multi partial capture (starting with the 2nd capture)

amount
required
Format NUMERIC(1..10)
Permitted values max. +/- 19 999 999 99

Specifies the total gross amount of a payment transaction.

Value is given in smallest currency unit, e.g. Cent of Euro

The amount must be less than or equal to the amount of the corresponding booking.

currency
required
Fixed Value EUR
narrative_text
optional
Format CHAR(1..81)

Dynamic text element on account statements
(3 lines with 27 characters each) and credit card statements.

Response Parameters
Permitted Values
APPROVED
ERROR
Response Parameter (approved)
Format NUMERIC(9..12)

The txid specifies the payment process within the PAYONE platform

settleaccount
Format LIST
Value Comment
yes

Settlement of outstanding balances is carried out.

no

Do not carry out settlement of outstanding balances, book request only.

auto

The system decides - depending on type of payment and balance - if a settlement of balances can be carried out or not. (default)

Carry out settlement of outstanding balances. The request is booked and the resulting balance is settled by means of a collection, e.g. a refund.

Response parameters (error)
Format NUMERIC(1..6)

In case of error the PAYONE Platform returns an error code for your internal usage.

Format CHAR(1..1024)

In case of error the PAYONE Platform returns an error message for your internal usage.

customermessage
Format CHAR(1..1024)

The customermessage is returned to your system in order to be displayed to the customer.

(Language selection is based on the end customer's language, parameter "language")

Host: api.pay1.de
Content-Type: application/x-www-form-urlencoded


POST Request Debit
Account Parameters
request
required
Fixed Value: creditcardcheck
mid
required
your merchant ID, 5-digit numeric
aid
required
your subaccount ID, 5-digit numeric
portalId
required
your Portal ID, 7-digit numeric
key
required
your key value, alpha-numeric
common Parameters
txid
required
Format NUMERIC(9..12)

The txid specifies the payment process within the PAYONE platform

sequencenumber
required
Format NUMERIC(1..3)

Permitted values 0..127

Sequence number for this transaction within the payment process (1..n), e.g. PreAuthorization: 0, 1. Capture: 1, 2. Capture: 2

Required for multi partial capture (starting with the 2nd capture)

amount
required
Format NUMERIC(1..10)

Permitted values max. +/- 19 999 999 99

Specifies the total gross amount of a payment transaction.

Value is given in smallest currency unit, e.g. Cent of Euro; Pence of Pound sterling; Öre of Swedish krona.

The amount must be less than or equal to the amount of the corresponding booking.

currency
required
Fixed Value EUR
settleaccount
optional
Format LIST
Value Comment
yes

Settlement of outstanding balances is carried out.

no

Do not carry out settlement of outstanding balances, book request only.

auto

The system decides - depending on type of payment and balance - if a settlement of balances can be carried out or not. (default)

Carry out settlement of outstanding balances. The request is booked and the resulting balance is settled by means of a collection, e.g. a refund.

Response Parameters
Permitted Values
APPROVED
ERROR
Response Parameter (approved)
txid
Format NUMERIC(9..12)

The txid specifies the payment process within the PAYONE platform

settleaccount
Format LIST 
Value Comment
yes

Settlement of outstanding balances is carried out.

no

Do not carry out settlement of outstanding balances, book request only.

Provides information about whether a settlement of balances has been carried out.

Response Parameter (error)
errorcode
Format NUMERIC(1..6)

In case of error the PAYONE Platform returns an error code for your internal usage.

errormessage
Format CHAR(1..1024)

In case of error the PAYONE Platform returns an error message for your internal usage.

customermessage
Format CHAR(1..1024)

The customermessage is returned to your system in order to be displayed to the customer.

(Language selection is based on the end customer's language, parameter "language")

Host: api.pay1.de
Content-Type: application/x-www-form-urlencoded


Please make sure you only make payment methods available for Apple Pay which are part of your contract with us.

Sequence Diagram

Prerequisites

Onboarding

Merchants who want to offer Apple Pay must take these preparatory steps:

1
Apple Developer Account

First, please make sure your organization is enrolled in the Apple Developer Program.

2
Server Setup

Then, please make sure to follow the guidelines for Server Setup.

3
Create Merchant Identifier and Merchant Identity Certificate

Apple uses certificates for two steps in the payment process:

  1. The Merchant Identity Certificate is used to authenticate your server when starting an Apple Pay session
  2. The Payment Processing Certififcate is used to decrypt the payment object of a successful Apple Pay session

To create the Merchant ID and Merchant Identity Certificate, please follow the instructions on this Apple site.

You don't need a Mac to generate a CSR for a Merchant ID Certificate. Here's how to do it with openssl:  You don't need a Mac to generate a CSR for a Merchant ID Certificate. Here's how to do it with openssl: 

openssl genrsa -out private.key 2048

This generates a private.key file in your current folder. Keep this safe!

openssl req -new -sha256 -key private.key -nodes -out request.csr

you will be asked some basic questions about your organization. After this, a request.csr file is generated. You can then use this file to generate your Merchant Identification Certificate at Apple.

If you want to convert the merchant_id.cer file into the more widely used .pem format, you can use this command:

openssl x509 -inform der -in merchant_id.cer -outform pem -out merchant_id.pem

4
Create Payment Processing Certificate

For the PAYONE Platform to be able to decrypt your Apple Pay objects, we need a Payment Processing Certificate. For this, you first need to create a "Certificate Signing Request" in your PAYONE Merchant Interface. This CSR can then be uploaded to Apple at https://developer.apple.com/account/resources/certificates/add, resulting in a Certificate in the .cer format. This file should then be uploaded to our Merchant Interface again.

When done, you should have an active Apple Pay Certificate:

Apple Pay on Your Website

How Apple Pay Works

Like other payment buttons, Apple Pay aims to skip the usual checkout steps and presents a complete payment sheet to the customer.

source: Apple

Initiating The Payment Session

Apple Pay on the Web

Apple Pay on the Web uses JS-APIs built into Safari on Mac and mobile. For additional security, all Apple Pay sessions have to be initiated using the Merchant Identification Certificate. Additionally, your domains have to be whitelisted in the Apple Dev Portal.

For info on how to display the buttons and initiating the payment session, please refer to the Apple documentation: https://developer.apple.com/documentation/apple_pay_on_the_web/displaying_apple_pay_buttons and https://developer.apple.com/documentation/apple_pay_on_the_web/apple_pay_js_api/creating_an_apple_pay_session

Head to https://applepaydemo.apple.com/ for a nice overview and some demo code.

Please make sure to correctly configure your payment request for your merchant account capabilities. For example, a basic request for a merchant who can use Mastercard, Visa and girocard in live mode could look like this:

{
  "countryCode": "DE",
  "currencyCode": "EUR",
  "merchantCapabilities": [
    "supports3DS" // mandatory
  ],
  "supportedNetworks": [
    "visa",
    "masterCard",
        "girocard"
  ],
  "total": {
    "label": "Demo (Card is not charged)",
    "type": "final",
    "amount": "1.99"
  }
}

Handling of Co-Badged Cards

Since iOS15.4 the Apple Pay APIs will start to respect the order in which the supportedNetworks array is listed. When both networks of a co-badged card are supported by the merchant, and the customer’s default card is a co-badged card, the pre-selected network on that card will be selected based on the order in which the networks are listed. Merchant preference only affects the user’s default card (if it’s a co-badged card), merchants cannot change which card is set as the default.

For Mastercard co-badged Girocards, you could then specify the pre-selected network like this:

optional parameters


"supportedNetworks": [
    "girocard",
    "masterCard",
    "visa"
  ],
optional parameters


"supportedNetworks": [
    "masterCard",
    "girocard",
    "visa"
  ],

Apple Pay In-App

In-App Payments use the Apple PassKit API. For info on how to accept Apple Pay payments in your app, refer to the Apple documentation: https://developer.apple.com/documentation/passkit/apple_pay/offering_apple_pay_in_your_app

As in Apple Pay on the web, you should configure your app to accept only the card schemes that your merchant account supports:

static let supportedNetworks: [PKPaymentNetwork] = [
    .masterCard,
    .visa,
        .girocard
]

This code snippet from the Apple documentation shows how you can send the resulting payment data to your backend.

func paymentAuthorizationController(_ controller: PKPaymentAuthorizationController, didAuthorizePayment payment: PKPayment, handler completion: @escaping (PKPaymentAuthorizationResult) -> Void) {

    // Perform some very basic validation on the provided contact information
    var errors = [Error]()
    var status = PKPaymentAuthorizationStatus.success
    if payment.shippingContact?.postalAddress?.isoCountryCode != "US" {
        let pickupError = PKPaymentRequest.paymentShippingAddressUnserviceableError(withLocalizedDescription: "Sample App only picks up in the United States")
        let countryError = PKPaymentRequest.paymentShippingAddressInvalidError(withKey: CNPostalAddressCountryKey, localizedDescription: "Invalid country")
        errors.append(pickupError)
        errors.append(countryError)
        status = .failure
    } else {
        // Here you would send the payment token to your server or payment provider to process
        // Once processed, return an appropriate status in the completion handler (success, failure, etc)

                // PAYONE suggests sending the data to your backend first and requesting the PAYONE Server API from there
         }

    self.paymentStatus = status
    completion(PKPaymentAuthorizationResult(status: status, errors: errors))
}

Forwarding the Data to the Payone API

After the customer has completed the payment sheet and authenticated themselves by biometric means (TouchID, FaceID), you'll receive an Apple Pay Object like this:

Apple Pay Object
{
   "token":{
      "paymentData":{
         "version":"EC_v1",
         "data":"3+f4oOTwPa6f1UZ6tG...CE=",
         "signature":"MIAGCSqGSIb3DQ...AAAA==",
         "header":{
            "ephemeralPublicKey":"MFkwEK...Md==",
            "publicKeyHash":"l0CnXdMv...D1I=",
            "transactionId":"32b...4f3"
         }
      },
      "paymentMethod":{
         "displayName":"Visa 1234",
         "network":"Visa",
         "type":"debit"
      },
      "transactionIdentifier":"32b...4f3"
   },
   "billingContact":{
      "addressLines":[
         "1 Street",
         ""
      ],
      "administrativeArea":"",
      "country":"United Kingdom",
      "countryCode":"GB",
      "familyName":"Appleseed",
      "givenName":"John",
      "locality":"London",
      "postalCode":"AB12 3CD",
      "subAdministrativeArea":"",
      "subLocality":""
   },
   "shippingContact":{
      "addressLines":[
         "1 Street",
         ""
      ],
      "administrativeArea":"",
      "country":"United Kingdom",
      "countryCode":"GB",
      "familyName":"Appleseed",
      "givenName":"John",
      "locality":"London",
      "postalCode":"AB12 3CD",
      "subAdministrativeArea":"",
      "subLocality":"",
      "phoneNumber":"01234 567890",
      "emailAddress":"john.appleseed@apple.com"
   }
}

Many contents of this object can be mapped to existing Server API parameters.

Apple Pay Object
"billingContact":{
      "addressLines":[
         "1 Street",
         ""
      ],
      "administrativeArea":"",
      "country":"United Kingdom",
      "countryCode":"GB",
      "familyName":"Appleseed",
      "givenName":"John",
      "locality":"London",
      "postalCode":"AB12 3CD",
      "subAdministrativeArea":"",
      "subLocality":""
   },
PAYONE Server API
country=GB
        lastname=Appleseed
        firstname=John
        street=1 Street
        city=London
        zip=AB12 3CD

However, the actual payment part of the object is encrypted and has to be sent to the PAYONE API in special parameters.

(Please be aware, that the token created by Apple has a limited lifespan of 5 minutes. For mode=live PAYONE is obliged to reject expired tokens.) 

Apple Pay Specific Error Messages

Error Description Suggested Activity
2700

Request amount differs from apple pay token amount.

Make sure to use the same amount as in your Apple Pay payment sheet

2701

Request currency differs from apple pay token amount.

Make sure to use the same currency as in your Apple Pay payment sheet

2702

Failed to decrypt apple pay token

Check whether your Payment Processing Certificate is valid and uploaded to our merchant backend

2703

Certificate service declined request because of validation errors.

2704

Required parameter in apple pay token is missing or empty

Check if all required parameters for the Apple Pay token are set