Apple Pay on the Web 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.
UI Text Box |
---|
|
Please make sure you only make payment methods available for Apple Pay which are part of your contract with us. |
clearingtype | wallettype |
---|
wlt | APL |
These Requests and Usecases are applicable:
Merchant View
draw.io Diagram |
---|
border | true |
---|
| |
---|
diagramName | Apple Pay |
---|
simpleViewer | false |
---|
width | 400 |
---|
links | auto |
---|
tbstyle | top |
---|
lbox | true |
---|
diagramWidth | 1781 |
---|
revision | 3 |
---|
|
Merchants who want to offer Apple Pay must take these preparatory steps:
UI Steps |
---|
Code Block |
---|
|
language | js |
---|
|
Certificate Management
Apple Pay on Your Website
UI Step |
---|
Then, please make sure to follow the guidelines for Server Setup. |
UI Step |
---|
Create Merchant Identifier and Merchant Identity CertificateApple uses certificates for two steps in the payment process: - The Merchant Identity Certificate is used to authenticate your server when starting an Apple Pay session
- 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. UI Text Box |
---|
| You don't need a Mac to generate a CSR for a Merchant ID Certificate. Here's how to do it with openssl: Code Block |
---|
openssl genrsa -out private.key 2048 |
This generates a private.key file in your current folder. Keep this safe! Code Block |
---|
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: Code Block |
---|
openssl x509 -inform der -in merchant_id.cer -outform pem -out merchant_id.pem |
|
Image Added
|
UI Step |
---|
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. Image Added
Image Added
Image Added
When done, you should have an active Apple Pay Certificate: Image Added
|
|
Like other payment buttons, Apple Pay aims to skip the usual checkout steps and presents a complete payment sheet to the customer.
Image Added
source: Apple
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
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:
Code Block |
---|
|
{
"countryCode": "DE",
"currencyCode": "EUR",
"merchantCapabilities": [
"supports3DS" // mandatory
],
"supportedNetworks": [
"visa",
"masterCard",
"girocard"
],
"total": {
"label": "Demo (Card is not charged)",
"type": "final",
"amount": "1.99"
}
} |
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:
Code Block |
---|
|
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.
Code Block |
---|
|
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))
} |
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:
Code Block |
---|
language | js |
---|
title | Apple Pay Object |
---|
collapse | true |
---|
|
{
"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"
}
} |
API Requests
Overview of Special Parameters
A successful Apple Pay Session will return a payment object with all info on the session. Many contents of this object can be mapped to existing Server API parameters.
Section |
---|
Column |
---|
Code Block |
---|
language | js |
---|
title | Apple Pay Object |
---|
| "billingContact":{
"addressLines":[
"1 Street",
""
],
"administrativeArea":"",
"country":"United Kingdom",
"countryCode":"GB",
"familyName":"Appleseed",
"givenName":"John",
"locality":"London",
"postalCode":"AB12 3CD",
"subAdministrativeArea":"",
"subLocality":""
}, |
|
Column |
---|
Awesome Icon |
---|
size | 36pt |
---|
icon | fa-arrow-right |
---|
|
|
Column |
---|
UI Tab |
---|
| Code Block |
---|
"billingContact":{
"addressLines":[
"1 Street",
""
],
"administrativeArea":"",
"country":"United Kingdom",
"countryCode":"GB",
"familyName":"Appleseed",
"givenName":"John",
"locality":"London",
"postalCode":"AB12 3CD",
"subAdministrativeArea":"",
"subLocality":""
}, |
UI Tab |
---|
title |
Code Block |
---|
language | js |
---|
title | PAYONE Server API |
---|
| country=GB
lastname=Appleseed
firstname=John
street=1 Street
city=London
zip=AB12 3CD |
|
---|
|
UI Tabs |
---|
| Parameters | Code Block |
---|
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.)
|
API Parameter | Required | Comments |
---|
clearingtype | + |
Section |
---|
Layout box |
---|
cssClass | payonePermittedSymbols |
---|
floating | left |
---|
| Fixed Value |
Layout box |
---|
cssClass | payonePermittedSymbolsValue |
---|
floating | left |
---|
| wlt |
|
|
wallettype | + |
Section |
---|
Layout box |
---|
cssClass | payonePermittedSymbols |
---|
floating | left |
---|
| Fixed Value |
Layout box |
---|
cssClass | payonePermittedSymbolsValue |
---|
floating | left |
---|
| aplAPL |
|
|
|
cardtype | + Includepayoneparameter |
---|
| Name | cardtypecan be obtained from the unencrypted part of the payment token Section |
---|
Layout box |
---|
cssClass | payonePermittedSymbols |
---|
floating | left |
---|
| Allowed Values |
Layout box |
---|
cssClass | payonePermittedSymbolsValue |
---|
floating | left |
---|
| V M G |
|
|
---|
|
add_paydata[paymentdata_token_version] | + |
Section |
---|
Layout box |
---|
cssClass | payonePermittedSymbols |
---|
floating | left |
---|
| Sample |
Layout box |
---|
cssClass | payonePermittedSymbolsValue |
---|
floating | left |
---|
| EC_v1
|
|
Section |
---|
Layout box |
---|
cssClass | payonePermittedSymbols |
---|
floating | left |
---|
| Format |
Layout box |
---|
cssClass | payonePermittedSymbolsValue |
---|
floating | left |
---|
| String |
|
|
add_paydata[paymentdata_token_data] | + |
Section |
---|
Layout box |
---|
cssClass | payonePermittedSymbols |
---|
floating | left |
---|
| Sample |
Layout box |
---|
cssClass | payonePermittedSymbolsValue |
---|
floating | left |
---|
| rhHAQUrR118u[...]cwDw==
|
|
Section |
---|
Layout box |
---|
cssClass | payonePermittedSymbols |
---|
floating | left |
---|
| Format |
Layout box |
---|
cssClass | payonePermittedSymbolsValue |
---|
floating | left |
---|
| String |
|
|
add_paydata[paymentdata_token_signature] | + |
Section |
---|
Layout box |
---|
cssClass | payonePermittedSymbols |
---|
floating | left |
---|
| Sample |
Layout box |
---|
cssClass | payonePermittedSymbolsValue |
---|
floating | left |
---|
| MIAGCSqGSIb3DQEHAqCAMIACAQE [...]AAAAAAAAAAAAAAA==
|
|
Section |
---|
Layout box |
---|
cssClass | payonePermittedSymbols |
---|
floating | left |
---|
| Format |
Layout box |
---|
cssClass | payonePermittedSymbolsValue |
---|
floating | left |
---|
| String |
|
|
add_paydata[paymentdata_token_ephemeral_publickey] | + |
Section |
---|
Layout box |
---|
cssClass | payonePermittedSymbols |
---|
floating | left |
---|
| Sample |
Layout box |
---|
cssClass | payonePermittedSymbolsValue |
---|
floating | left |
---|
| MFkwEwYHKoZIzj0 [...]Y2A==
|
|
Section |
---|
Layout box |
---|
cssClass | payonePermittedSymbols |
---|
floating | left |
---|
| Format |
Layout box |
---|
cssClass | payonePermittedSymbolsValue |
---|
floating | left |
---|
| String |
|
|
add_paydata[paymentdata_token_publickey_hash] | + |
Section |
---|
Layout box |
---|
cssClass | payonePermittedSymbols |
---|
floating | left |
---|
| Sample |
Layout box |
---|
cssClass | payonePermittedSymbolsValue |
---|
floating | left |
---|
| ilecVF58bpB8qio[...]l6eirw2Y1v1KUCsdVgQ=
|
|
Section |
---|
Layout box |
---|
cssClass | payonePermittedSymbols |
---|
floating | left |
---|
| Format |
Layout box |
---|
cssClass | payonePermittedSymbolsValue |
---|
floating | left |
---|
| String |
|
|
add_paydata[paymentdata_token_transaction_id] | + |
Section |
---|
Layout box |
---|
cssClass | payonePermittedSymbols |
---|
floating | left |
---|
| Sample |
Layout box |
---|
cssClass | payonePermittedSymbolsValue |
---|
floating | left |
---|
| be2e745845b31dfac7778c6e29[...]b658cbcca971c0e0
|
|
Section |
---|
Layout box |
---|
cssClass | payonePermittedSymbols |
---|
floating | left |
---|
| Format |
Layout box |
---|
cssClass | payonePermittedSymbolsValue |
---|
floating | left |
---|
| String |
|
|
|
|
|
UI Tabs |
---|
UI Tab |
---|
|
Code Block |
---|
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 |
|
UI Tab |
---|
|
Code Block |
---|
status=APPROVED
txid=123456789
userid=987654321 |
|
|
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 |