Native Apple Pay Integration Guide
Native Apple Pay integration. Enable seamless Apple Pay checkout directly on your website or application. Your frontend manages the user interface and Apple Pay interaction, while Mercuryo handles payment processing on the backend.
What You Can Build
✅ Native Apple Pay checkout – Process payments directly on your site without redirecting users to the Mercuryo widget
✅ Seamless user experience – Users complete the entire payment flow without leaving your application
✅ Headless integration – Full control over the UI while Mercuryo handles payment processing
✅ Built-in compliance – KYC/AML handled, with automatic fallback to full widget when needed
✅ Secure processing – Two-certificate model ensures maximum security and clear separation of responsibilities
Contact your integration manager for more details, or email us at sales@mercuryo.io.
Country Restrictions
-
For users from the United States (US) or United Kingdom (GB): Native Apple Pay is currently not working.
-
For payments with bank cards issued in the United States (US) or United Kingdom (GB): Payments will not be processed at this time, regardless of the user's location.
Mercuryo will enforce this on our backend, but we recommend you also apply this logic on your frontend to improve the user experience.
Transaction Limits for Non-KYC Users
For users who have not completed the KYC (Know Your Customer) procedure, there is a cumulative transaction limit. The total turnover for a user, calculated across all their transactions and converted to EUR, cannot exceed €700. If a new transaction causes the user to exceed this limit, it will be rejected. This is one of the primary scenarios that may trigger an error requiring the user to be redirected to the full Mercuryo widget to complete KYC.
Integration Flow Overview
The integration is based on a "headless" model where your application manages the user interface and initial interaction with Apple, and Mercuryo's backend manages the payment execution.
The process consists of three main stages:
- Client-Side (Partner's Frontend): The user initiates the payment, and your frontend application communicates with the Apple Pay SDK.
- Server-Side (Partner's Backend): Your backend validates the merchant session with Apple using your own
Merchant Identity Certificate. - Processing (Mercuryo's Backend): Your application sends the encrypted payment data to Mercuryo, where we decrypt it using your
Payment Processing Certificateand process the transaction.
Sequence Diagram
This diagram provides a detailed, step-by-step visualization of the entire flow.
Onboarding: Certificate Setup
Before you can begin the integration, you must configure two types of Apple Pay certificates. This integration relies on a two-certificate model to ensure maximum security and clear separation of responsibilities.
1. Merchant Identity Certificate
- Purpose: To authenticate your server with Apple's servers when validating a merchant session. This certificate is used to establish a secure TLS connection for the session validation request.
- Responsibility: Yours.
- Action: You must generate this certificate in your Apple Developer account and securely store it along with its private key on your backend infrastructure. You will use it to handle the
onmerchantvalidationstep. Mercuryo never sees this certificate or its key. - Official Documentation: For details, see Apple's documentation on Creating a Merchant Identity Certificate.
2. Payment Processing Certificate
- Purpose: To allow Mercuryo to decrypt the final payment token. Apple uses the public key of this certificate to encrypt the payment data.
- Responsibility: Ours to initiate, Yours to generate, Ours to use.
- Action: During the onboarding process, we (Mercuryo) will provide you with a Certificate Signing Request (CSR). You must upload this CSR to your Apple Developer account to generate the final Payment Processing Certificate (
.cerfile). You then need to securely provide the downloaded.cerfile back to us. We will use this certificate, paired with our private key, to process payments on your behalf. - Official Documentation: This certificate is associated with your Merchant ID and is used for encrypting payment data. See Apple's guide on configuring Apple Pay.
Step 1: Getting a Quote
Before initiating the Apple Pay payment sheet, your application must first get a transaction quote from Mercuryo. This step provides your user with the exact exchange rate and provides your application with a buy_token required to execute the payment.
You must call the standard /widget/buy/rate endpoint. To specify that this is a Native Apple Pay transaction, you must include the payment_method=apple parameter.
API Endpoint: GET /widget/buy/rate
| Parameter | Required For Native Flow Determination | Description |
|---|---|---|
widget_id |
Yes | Your unique identifier provided by Mercuryo. |
from |
Yes | Source currency code (e.g., USD). |
to |
Yes | Target currency code (e.g., BTC). |
amount |
Yes | The amount in the from currency. |
payment_method |
Yes | Must be apple for this flow. |
is_total |
Yes | A boolean that determines how to interpret the amount. While optional in the generic API, it is required for this flow to ensure correct calculations. Defaults to true. |
network |
Yes | While optional in the generic API, the blockchain network is required for this flow to determine availability and correct fees. |
address |
Yes | While optional in the generic API, the destination wallet address is required for this flow for risk assessment. |
country / ip_address |
Yes | At least one of these fields is required to perform geo-restriction checks. ip_address is the preferred method. |
Success Response
The response will contain the current rate, fee breakdown, and the buy_token. Crucially, it will also include a new boolean flag, is_native_available.
{
"status": 200,
"data": {
"buy_token": "abc123def456...",
"currency": "BTC",
"amount": "0.00234398",
"fiat_amount": "300.00",
"fiat_currency": "USD",
...
"is_native_available": true
}
}
Note: Your frontend should check for
is_native_available: true. If this flag is present andtrue, you can proceed with showing the native Apple Pay button. If it isfalseor absent, you should fall back to a different flow (e.g., redirecting the user to the full Mercuryo widget).You must store the
buy_tokenas it is a required field for the finalPOST /sdk-partner/native-mobile-pay/mobile-paycall.
Step 2: Partner-Side Implementation
Terms of Service
Since the payment is processed entirely on your side without redirecting users to the Mercuryo widget, you MUST obtain user consent to Mercuryo's Terms of Service before processing the payment. This is a mandatory compliance requirement.
You must display a link to Mercuryo's Terms of Service either before initiating Apple Pay or on the Apple Pay screen.
Payment Processing Disclosure
According to Apple's requirements, you MUST clearly indicate that the payment is processed through Mercuryo. This must be visible to the user on the Apple Pay payment sheet.
Example: "Pay Mercuryo (via [Your Company Name])"
PaymentRequest Initialization
Your frontend is responsible for creating and displaying the Apple Pay payment request. The modern and recommended way to integrate Apple Pay on the Web is by using the W3C standard Payment Request API.
When the user clicks the "Pay with Apple Pay" button, your frontend must create an ApplePayPaymentRequest or PaymentRequest. It is crucial that this request asks for all the necessary user information that Mercuryo requires for processing.
Official Documentation:
You must verify that your PaymentRequest includes the following parameters with the specified values:
1. merchantCapabilities
Reference: ApplePayMerchantCapability
You MUST include:
"supports3DS""supportsCredit""supportsDebit"
2. supportedNetworks
References:
You MUST include:
"masterCard""visa"
3. countryCode
Reference: countryCode
You MUST set:
"LT"
4. label (in total object)
Reference: ApplePayLineItem.label
This is the code, but essentially it refers to the label field of the total object.
According to Apple's requirements, you MUST clearly indicate that the payment is processed through Mercuryo. This must be visible to the user on the Apple Pay payment sheet.
Example: "Pay Mercuryo (via [Your Company Name])"
5. Contact Information & Billing Address
Reference: requiredBillingContactFields
You MUST request the following information from the payer via requiredBillingContactFields:
- Payer Name
- Payer Email
- Billing Address
Important: The values retrieved from these fields (Email, Name, Billing Address) MUST be passed to Mercuryo in the subsequent payment processing request.
Example PaymentRequest Configuration:
const paymentRequest = {
// ... your countryCode, currencyCode, total, etc.
"requiredBillingContactFields": [
"postalAddress",
"name",
"email"
],
// Note: If using W3C Payment Request API, use options:
// requestPayerName: true,
// requestPayerEmail: true,
// requestBillingAddress: true
// requestShipping: false
// ... other Apple Pay configuration
};
Your frontend will then handle the onmerchantvalidation event by calling your backend to get a valid merchantSession. After the user authorizes the payment, your frontend will receive the encrypted paymentToken.
Backend: Validating the Merchant Session
Your backend must expose an endpoint that your frontend can call during the onmerchantvalidation event. This endpoint is responsible for:
- Receiving the
validationURLfrom your frontend. - Making a
POSTrequest to that URL using yourMerchant Identity Certificateto authenticate with Apple's servers. - Returning the resulting
merchantSessionobject to your frontend.
Step 3: Calling the Mercuryo API
Once your frontend has the encrypted paymentToken, it sends this token along with other transaction details to Mercuryo's dedicated native processing endpoint. The paymentToken must be encoded in base64 format before sending.
Request Authentication
All API requests sent from your backend to Mercuryo's API must be authenticated. This is done using two HTTP headers: sdk-partner-token for identification and x-signature for verifying the request integrity.
HTTP Headers
| Header | Description |
|---|---|
sdk-partner-token |
Your unique partner authentication token, provided by your account manager. |
x-signature |
The HMAC-SHA256 signature of the raw request body. See the next section for how to generate this value. |
How to Generate the Signature (x-signature)
The signature ensures that the request body has not been tampered with.
- Get Your Sign Key: This is your unique Sign Key, which you can find in your partner dashboard. Keep this key confidential.
- Prepare the Request Body: Your request body must be a valid JSON object.
- Construct the Message to Sign: The signature is generated from the raw JSON request body string. Important: The JSON string must not contain any extra whitespace or formatting. It should be a compact, one-line string.
- Compute the Signature: Use the HMAC-SHA256 algorithm to compute the signature. The
messageis the raw JSON request body, and thekeyis your Sign Key. The output should be a hex-encoded string. - Add the Signature to the Header: Include the generated signature in the
x-signatureHTTP header with every request.
API Endpoint: POST /sdk-partner/native-mobile-pay/mobile-pay
- Authentication: The request must be authenticated using your partner
sdk-partner-token, sent as an HTTP header. - Content-Type:
application/json
Request Body
| Field | Type | Description |
|---|---|---|
pay_token |
string |
Required. The base64 encrypted paymentToken received from the Apple Pay SDK. |
buy_token |
string |
Required. The unique quote identifier received from Mercuryo's GET /widget/buy/rate endpoint. |
email |
string |
Required. The user's email address, obtained from the Apple Pay payment sheet. |
first_name |
string |
Required. The user's first name. |
last_name |
string |
Required. The user's last name. |
billing_address |
object |
Required. The user's billing address object, as provided by Apple Pay. The object must match the structure of Apple's ApplePayPaymentContact object. See example below. |
address |
string |
Required. The destination cryptocurrency wallet address for the user. |
ip |
string |
Required. The user's IP address. |
merchant_transaction_id |
string |
Optional. Your internal identifier for the transaction. |
Example billing_address object:
"billing_address": {
"country_code": "US",
"street_line_1": "Asden Ct",
"street_line_2": "123",
"state_code": "OH",
"city": "Reynoldsburg",
"zip_code": "43068"
}
Success Response
Mercuryo's endpoint will synchronously return the initial status of the transaction in a nested data object.
{
"status": 200,
"data": {
"id": "28a3c125a28075453",
"status": "pending"
}
}
The status field inside the data object (e.g., "pending") indicates that the transaction has been accepted and is being processed. The final status will be sent via the server-to-server callback.
Handling Errors and Fallback to Widget
While the API can return standard HTTP error codes for general issues (e.g., 400 Bad Request for invalid parameters), the most critical response to handle is the one that triggers a fallback flow.
A key feature of this integration is the ability to seamlessly transition the user from a native Apple Pay flow to the full Mercuryo widget if additional user action is required. This ensures that transactions are not lost in cases where simple native payment is insufficient (e.g., the user needs to complete KYC).
Triggering the Fallback
The fallback mechanism is triggered when the /sdk-partner/native-mobile-pay/mobile-pay endpoint responds with a specific error code indicating that the transaction cannot be completed natively. This response indicates that while the request is valid, it cannot be processed without further user interaction. A detailed list of error codes will be provided later.
Example Error Responses:
Error response (transaction blocked):
{
"status": 403,
"code": 403006,
"message": "Transaction blocked."
}
Error response (transaction failed):
{
"status": 200,
"data": {
"id": "28a3c125a28075453",
"status": "order_failed"
}
}
Partner Frontend Implementation
Your frontend application should be designed to handle this fallback response:
- Check the response for the specific error code that signals a fallback is needed.
- Redirect the user's browser to the widget URL.
The user will land on the Mercuryo widget with all their transaction data pre-filled, where they can complete the required steps (e.g., upload documents for KYC) and finalize their purchase.
Step 4: Receiving the Final Status (Callback)
Because the final processing of the transaction is asynchronous, Mercuryo will notify your backend of the final transaction status using our standard server-to-server webhook. You must provide a secure callback URL to your Mercuryo integration manager during onboarding.
Callback Verification
To ensure the security and authenticity of the callback, each request will contain an x-signature HTTP header. You must verify this signature by calculating an HMAC-SHA256 hash of the raw JSON payload using your widget's Sign key (available in your Mercuryo dashboard) and comparing it to the value of the header.
Callback Payload
The callback payload is a standard CallbackNotification object, as described in our main API reference. For a Native Apple Pay transaction, the data object within the payload will have the following key identifiers:
"type": "buy""payment_method": "mobile_pay""method_code": "apple"
The status field within the data object will reflect the final state of the transaction, such as paid, order_failed, or cancelled.
Please refer to the /callback section in our main swagger-widget-integration.yaml documentation for the complete schema of the callback body and all possible transaction statuses.