Apple Pay API

 
Note

Apple Pay is currently a closed Beta feature.

Integrate with Apple directly to support Apple Pay as part of your WePay implementation. Support Apple Pay in your iOS app via Apple's PassKit or on the web in Safari via Apple Pay JS API.

Out Of Scope

Apple Pay with WePay does not currently support Nonprofits.

Register With Apple

You'll need to register as a developer and merchant with Apple before using our ApplePay solution. Note that these are currently all manual steps you'll go through, as opposed to automated flows.

PartnerAppleWePayCreate Apple developer account1Generate Merchant Identity Certificate (MIC)2Request Payment Processing Certificate (PPC)3Send Certificate Signing Request (CSR)4Generate PPC with CSR5Send PPC6PartnerAppleWePay

Create an Apple developer account and then follow Apple's documentation to create your platform's Apple Merchant ID, Payment Processing Certificate, and Merchant Identity Certificate.

Payment Processing Certificate

To generate your Payment Processing Certificate, you'll need to use the Certificate Signing Request that we sent you. You'll then send your Payment Processing Certificate to us.


Onboard Merchants To Apple Pay

Once your platform is registered with Apple, you can onboard your merchants to Apple Pay. In our API Apple Pay implementation, you'll need to register each merchant individually rather than leveraging Apple's Mass Enablement API.

Verify Checkout Domains

First, prepare the domain(s) where the Apple Pay button will be hosted for verification in accordance with Apple's documentation. If your platform utilizes a single domain where checkouts occur (e.g. your platform owns the checkout page), then you can simply verify that single domain.

If merchants on your platform maintain the code of their own domains where transactions occur, then you'll need to instruct merchants on this step.

Once the domain(s) has/have been prepared, you can move on to the registration step.

Register Merchants

This step registers the merchant and verifies the domain using Apples's register merchant API. Once registered, you'll be able to create Apple Pay transactions for that merchant.


Process Apple Pay Payments

Before processing Apple Pay transactions, decide whether you will retrieve card holder information from the Apple JS or from your own form on your checkout page.

To retrieve card holder information from the Apple JS, use Apple's PKContactField to require name, email address, and postal address in the payment sheet presented to the payer.

At a high level, an Apple Pay transaction will go through the following steps:

  1. You request an Apple Pay session token
  2. You complete Apple Pay session token validation
  3. Payer is presented the payment sheet
  4. Apple JS returns payment bundle to the transaction front end
  5. You pass the payment bundle from your front end to your server
  6. Your server makes the POST /payment_methods and POST /payment WePay API requests

Beyond the broad strokes, this flow is a bit more complex and those details are described in the sequence diagram below:

Partner front endApple JSPartner serverApple serverWePay serverRequest to render Apple Pay button1Pass Apple Pay session data to your server2Request an Apple Pay session token3Return session token4Complete session validation5Pass payment bundle details6POST /payment_methods7payment_method_id8POST /payments9payment_id10Payment success message11Partner front endApple JSPartner serverApple serverWePay server

Pass Apple Pay Payment Bundles

Once the session token has been created and validated, the Apple JS will present the payment sheet to the payer and return payment data to your front end. The response from the Apple JS is documented here, and may look something like this:

Copy
Copied
{
  "token":{
    "paymentData":{
      "data":"qkQHXlXvbf5SM8aI1VqrzTw6gOaYMSDstxtuvpu/EvarLxUcQpkngJvNF02TocNLv0Vxs5/cSsaEaUweJc99dUEG26VXfULIrTLULjE08XAx+PO1TuPl3pEon9EWqT3VuEkTZSqgctIYMx50cd3ZMELB0o/pBITDnRnJMeAVxQ194AFScE/2U83leFEg6tKRs8Qz9b2WtwgiScx1TdgbZKNZYcZSWLlfHdGzB8hdjzy2zLkBbUArbc43XGiaJxfyvnMYUx6jB9mCNeO67aILPj9Z0z3berJuSlnEWqEXttEM7dzsLchj//IlmxUCpeaYDLdigiLiCj+ZKfAsoXrg9rfxoihDYm0iYhrqU/JZOZsipfN5yGtfuQ9mUWBNFROy1MiatMSrJWsCOCokk+MSM2JUzTfC7ST1T1Yx5rrFX+ONecK73FuyOvleLqP3lrP0cfzE+rU7qNoHuuEOInoBntxAdxZwdH+BILcvfn5pX2TfQbF9FxZn993dzmwcf/4ozbD+7xEiHerDw38h8GbFJ47fjee519HrS4BdwVkYaUkAiLkkBgTDwqmSoQ==",
      "signature":"MIAGCSqGSIb3DQEHAqCAMIACAQExDzANBglghkgBZQMEAgEFADCABgkqhkiG9w0BBwEAAKCAMIID5DCCA4ugAwIBAgIIWdihvKr0480wCgYIKoZIzj0EAwIwejEuMCwGA1UEAwwlQXBwbGUgQXBwbGljYXRpb24gSW50ZWdyYXRpb24gQ0EgLSBHMzEmMCQGA1UECwwdQXBwbGUgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxEzARBgNVBAoMCkFwcGxlIEluYy4xCzAJBgNVBAYTAlVTMB4XDTIxMDQyMDE5MzcwMFoXDTI2MDQxOTE5MzY1OVowYjEoMCYGA1UEAwwfZWNjLXNtcC1icm9rZXItc2lnbl9VQzQtU0FOREJPWDEUMBIGA1UECwwLaU9TIFN5c3RlbXMxEzARBgNVBAoMCkFwcGxlIEluYy4xCzAJBgNVBAYTAlVTMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEgjD9q8Oc914gLFDZm0US5jfiqQHdbLPgsc1LUmeY+M9OvegaJajCHkwz3c6OKpbC9q+hkwNFxOh6RCbOlRsSlaOCAhEwggINMAwGA1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAUI/JJxE+T5O8n5sT2KGw/orv9LkswRQYIKwYBBQUHAQEEOTA3MDUGCCsGAQUFBzABhilodHRwOi8vb2NzcC5hcHBsZS5jb20vb2NzcDA0LWFwcGxlYWljYTMwMjCCAR0GA1UdIASCARQwggEQMIIBDAYJKoZIhvdjZAUBMIH+MIHDBggrBgEFBQcCAjCBtgyBs1JlbGlhbmNlIG9uIHRoaXMgY2VydGlmaWNhdGUgYnkgYW55IHBhcnR5IGFzc3VtZXMgYWNjZXB0YW5jZSBvZiB0aGUgdGhlbiBhcHBsaWNhYmxlIHN0YW5kYXJkIHRlcm1zIGFuZCBjb25kaXRpb25zIG9mIHVzZSwgY2VydGlmaWNhdGUgcG9saWN5IGFuZCBjZXJ0aWZpY2F0aW9uIHByYWN0aWNlIHN0YXRlbWVudHMuMDYGCCsGAQUFBwIBFipodHRwOi8vd3d3LmFwcGxlLmNvbS9jZXJ0aWZpY2F0ZWF1dGhvcml0eS8wNAYDVR0fBC0wKzApoCegJYYjaHR0cDovL2NybC5hcHBsZS5jb20vYXBwbGVhaWNhMy5jcmwwHQYDVR0OBBYEFAIkMAua7u1GMZekplopnkJxghxFMA4GA1UdDwEB/wQEAwIHgDAPBgkqhkiG92NkBh0EAgUAMAoGCCqGSM49BAMCA0cAMEQCIHShsyTbQklDDdMnTFB0xICNmh9IDjqFxcE2JWYyX7yjAiBpNpBTq/ULWlL59gBNxYqtbFCn1ghoN5DgpzrQHkrZgTCCAu4wggJ1oAMCAQICCEltL786mNqXMAoGCCqGSM49BAMCMGcxGzAZBgNVBAMMEkFwcGxlIFJvb3QgQ0EgLSBHMzEmMCQGA1UECwwdQXBwbGUgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxEzARBgNVBAoMCkFwcGxlIEluYy4xCzAJBgNVBAYTAlVTMB4XDTE0MDUwNjIzNDYzMFoXDTI5MDUwNjIzNDYzMFowejEuMCwGA1UEAwwlQXBwbGUgQXBwbGljYXRpb24gSW50ZWdyYXRpb24gQ0EgLSBHMzEmMCQGA1UECwwdQXBwbGUgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxEzARBgNVBAoMCkFwcGxlIEluYy4xCzAJBgNVBAYTAlVTMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE8BcRhBnXZIXVGl4lgQd26ICi7957rk3gjfxLk+EzVtVmWzWuItCXdg0iTnu6CP12F86Iy3a7ZnC+yOgphP9URaOB9zCB9DBGBggrBgEFBQcBAQQ6MDgwNgYIKwYBBQUHMAGGKmh0dHA6Ly9vY3NwLmFwcGxlLmNvbS9vY3NwMDQtYXBwbGVyb290Y2FnMzAdBgNVHQ4EFgQUI/JJxE+T5O8n5sT2KGw/orv9LkswDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBS7sN6hWDOImqSKmd6+veuv2sskqzA3BgNVHR8EMDAuMCygKqAohiZodHRwOi8vY3JsLmFwcGxlLmNvbS9hcHBsZXJvb3RjYWczLmNybDAOBgNVHQ8BAf8EBAMCAQYwEAYKKoZIhvdjZAYCDgQCBQAwCgYIKoZIzj0EAwIDZwAwZAIwOs9yg1EWmbGG+zXDVspiv/QX7dkPdU2ijr7xnIFeQreJ+Jj3m1mfmNVBDY+d6cL+AjAyLdVEIbCjBXdsXfM4O5Bn/Rd8LCFtlk/GcmmCEm9U+Hp9G5nLmwmJIWEGmQ8Jkh0AADGCAYwwggGIAgEBMIGGMHoxLjAsBgNVBAMMJUFwcGxlIEFwcGxpY2F0aW9uIEludGVncmF0aW9uIENBIC0gRzMxJjAkBgNVBAsMHUFwcGxlIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRMwEQYDVQQKDApBcHBsZSBJbmMuMQswCQYDVQQGEwJVUwIIWdihvKr0480wDQYJYIZIAWUDBAIBBQCggZUwGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMjExMjE0MjMxODQ3WjAqBgkqhkiG9w0BCTQxHTAbMA0GCWCGSAFlAwQCAQUAoQoGCCqGSM49BAMCMC8GCSqGSIb3DQEJBDEiBCCJVm75PqgyrPA5q7pDhDRLm4XWBDmWrr4Pohui1u3LBjAKBggqhkjOPQQDAgRHMEUCIA/6Ubv/Dvy2P1rKozaOQR2TDp2Vak84zsMhOZ6/q3ZqAiEAj84jV7iAQANzANB4n69FasSlDpiv0oo02NdGB945bqUAAAAAAAA=",
      "header":{
        "publicKeyHash":"D/WrmNFCL1pI16vV1TwI/loSNqYRlc4yvAxhDaDbtZo=",
        "ephemeralPublicKey":"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE9YdJq6t24JuFM2GIi2ht44lKMtdzqQ8xaXgnrhChkfqcqgAdrcYhkNvv8tI3XAUX/t3Rm8q/64lNt4LX1uExwg==",
        "transactionId":"d8b7b1b8244ec42a8858af8f0d103c958dd8ae03857bf3b413a51b88210eda69"
        },
      "version":"EC_v1"
      },
    "paymentMethod":{
      "displayName":"MasterCard 1471",
      "network":"MasterCard",
       "type":"debit"
      },
    "transactionIdentifier":"D8B7B1B8244EC42A8858AF8F0D103C958DD8AE03857BF3B413A51B88210EDA69"
  }
}

Pass this data to your own server and then Base64 encode the token object. Use the encoded result in a POST /payment_methods WePay API request like so:

tokenized card holder dataraw card holder data
Copy
Copied
{
  "type": "apple_pay",
  "apple_pay": {
    "payment_method_data": "{encoded-apple-token}",
    "card_holder": "{token.paymentMethod-from-Apple-JS}"
  }
}
Copy
Copied
{
  "type": "apple_pay",
  "apple_pay": {
    "payment_method_data": "{encoded-apple-token}",
    "card_holder": {
      "holder_name": "{collect-full-name-in-your-ui}",
      "address": {
        "postal_code": "{collect-in-your-ui}",
        "country": "{collect-in-your-ui}"
      }
    }
  }
}
On a successful request, we will return a UUID on the id parameter. Use this value to send a POST /payments WePay API request as normal:
Copy
Copied
{
  "account_id": "abc123",
  "amount": 1000,
  "currency": "USD",
  "order_id": "ordr-3cd20b3c-4008-400b-b708-2b844ce7be84",
  "fee_amount": 30,
  "custom_data": {
    "my_key": "invoice #54321"
   },   
  "payment_method":{
    "type": "payment_method_id",
    "payment_method_id": "{id-from-payment-methods-response}"
  },
  "initiated_by": "customer",
  "reference_id": "dfeb052b-ae8c-4a69-b909-8d9ecdd7c742"
}

Manage Certificates

Remember that Apple Pay certificates will expire and as such, you'll need to maintain certificates on an ongoing basis.