Skip to main content

Apple Pay

Apple Pay lets you charge the cards the buyer keeps in Wallet, from an iPhone, iPad, or Mac. There are two ways to accept it:

  • ONVO Checkout: turn Apple Pay on in the Dashboard and the button appears in your Checkout, with no code.
  • Your own site: register your domain, show the button with ONVO.js, and charge with payment intents.

Apple Pay accepts Visa, Mastercard, and American Express cards, for Costa Rica accounts, in CRC and USD.

StepReferencePayloads
Register a domainPOST /v1/payment-method-domainsRequest · Response
List domainsGET /v1/payment-method-domainsParameters · Response
Retrieve a domainGET /v1/payment-method-domains/{id}Response
Enable or disable a domainPOST /v1/payment-method-domains/{id}Request · Response
Validate a domain againPOST /v1/payment-method-domains/{id}/validateResponse
Check availabilityGET /v1/apple-pay/availabilityParameters · Response
Create the intentPOST /v1/payment-intentsRequest · Response
Confirm the intentPOST /v1/payment-intents/{id}/confirmRequest · Response

Before you start​

  • Turn on Apple Pay in the Dashboard, under Settings → Payment methods. It requires card payments to be on, and the switch applies per mode: test and live are enabled separately.
  • Your account must be activated. ONVO registers the merchant with Apple only after activation, in test mode too.
  • By turning Apple Pay on or registering a domain you accept the Apple Pay web merchant terms.
  • The button only appears on Apple devices with a card in Wallet. It works in Safari and in Chrome; what decides is the device and the card, not the browser.

ONVO Checkout (no code)​

If you charge with Checkout, turning Apple Pay on in the Dashboard is enough. ONVO automatically registers the merchant with Apple — it takes a few seconds and the status is visible on the same screen — and the button appears in your Checkout for compatible Apple devices. You need nothing else from this guide.

Apple Pay on your own site​

Four steps: publish the domain association file, register the domain, show the button with ONVO.js, and charge from your server with a payment intent.

1. Publish the association file​

Download ONVO's domain association file:

https://checkout.onvopay.com/.well-known/apple-developer-merchantid-domain-association

It is the same file for every ONVO merchant. Serve it unchanged on every domain that shows the button, at the same path and without a file extension:

https://shop.example.com/.well-known/apple-developer-merchantid-domain-association
  • The URL must answer 200 directly, without redirects, from a public HTTPS address.
  • Each subdomain that shows the button is registered separately: example.com, www.example.com, and shop.example.com are three domains.

2. Register the domain​

From your server, with your secret key:

curl https://api.onvopay.com/v1/payment-method-domains \
-X POST \
-H "Authorization: Bearer $ONVO_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{
"domainName": "shop.example.com"
}'

ONVO checks the file on the spot — typically one or two seconds — and registers the domain for Apple Pay:

{
"id": "cm1pmd8k2x0001a8f3h2k9q7z",
"domainName": "shop.example.com",
"enabled": true,
"mode": "live",
"applePay": { "status": "active" },
"createdAt": "2026-09-27T18:04:11.201Z",
"updatedAt": "2026-09-27T18:04:11.201Z"
}

If the file is missing or different, the domain is still created but stays inactive, and applePay.statusDetails.errorMessage explains why. Fix the file and retry with POST /v1/payment-method-domains/{id}/validate; it allows one attempt per domain per minute.

To manage your domains:

A domain registered with a live key also works in test mode. Registering a domain that already exists returns the existing domain.

3. Show the button with ONVO.js​

In the browser, with your publishable key, include Apple's Apple Pay SDK and ONVO.js:

<script src="https://applepay.cdn-apple.com/jsapi/1.latest/apple-pay-sdk.js"></script>
<script src="https://js.onvopay.com/v1/"></script>

<apple-pay-button id="apple-pay" buttonstyle="black" type="buy" locale="en-US" style="display: none"></apple-pay-button>

<script>
const onvo = ONVO("onvo_live_publishable_key_...");

const applePay = onvo.applePay({
countryCode: "CR",
currencyCode: "CRC",
total: { label: "My store", amount: "5000.00" },
});

const button = document.getElementById("apple-pay");

applePay.isAvailable().then((available) => {
if (available) button.style.display = "inline-block";
});

button.addEventListener("click", () => {
// begin() must be called synchronously inside the click: Apple Pay requires it.
applePay.begin({
async onPaymentMethod({ paymentMethodId, complete }) {
const response = await fetch("/checkout/pay", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ paymentMethodId }),
});
const intent = await response.json();
complete(intent.status === "succeeded" ? "success" : "failure");
},
onCancel: () => {},
onError: (error) => console.error(error),
});
});
</script>
  • isAvailable() answers true only when the device is compatible and the domain is active for your account. If it returns false on a compatible device, query GET /v1/apple-pay/availability with your publishable key to see the reason (not_enabled, domain_not_registered, domain_inactive, or domain_disabled).
  • ONVO.js handles the merchant validation with Apple and creates the payment method; your onPaymentMethod callback receives the paymentMethodId ready to confirm.
  • Apple's SDK is not optional. Beyond the button, it defines window.ApplePaySession, the API ONVO.js uses to open the payment sheet. Safari ships it natively, other browsers do not: without that script, isAvailable() answers false in Chrome and the button never appears.

4. Charge from your server​

Create the payment intent with your secret key. The amount goes in the currency's minor unit: 500000 represents ₡5,000.00 and must match the payment sheet total (total.amount: "5000.00" in the example above).

curl https://api.onvopay.com/v1/payment-intents \
-X POST \
-H "Authorization: Bearer $ONVO_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{
"amount": 500000,
"currency": "CRC",
"description": "Order #1001"
}'

Confirm the intent with the paymentMethodId your endpoint received:

curl https://api.onvopay.com/v1/payment-intents/$PAYMENT_INTENT_ID/confirm \
-X POST \
-H "Authorization: Bearer $ONVO_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{
"paymentMethodId": "cl502zv0d0127ebdp3zt27651"
}'

If status is succeeded, the payment is approved: call complete('success') to close the Apple Pay sheet. If the confirmation fails, the intent returns to requires_payment_method with the details in lastPaymentError: call complete('failure') and, if the buyer wants to retry, open a new sheet.

Identify an Apple Pay payment​

The payment intent reports that the charge came from Apple Pay in paymentMethod.card.wallet. Use it for your receipts, your reconciliation, or your internal dashboard:

{
"paymentMethod": {
"type": "card",
"card": {
"brand": "Visa",
"last4": "3599",
"wallet": { "type": "apple_pay" }
}
}
}

The last4 belongs to the device's card, not to the buyer's physical card: Apple issues a different device account number for each device. The brand is the real one. When the payment did not come from a wallet, wallet is null.

Important​

Single-use credential

The Apple Pay credential works for a single charge and expires a few minutes after the buyer's approval. Confirm the intent immediately and do not store the paymentMethodId for later. If the confirmation fails, a retry requires opening a new payment sheet. Apple Pay is not supported for recurring charges for now.

Common errors and their cause:

CodeCause
apple_pay.not_enabledApple Pay is not turned on in the Dashboard for the account in that mode.
apple_pay.account_not_activatedThe account is not activated yet.
apple_pay.domain_not_verifiedThe page opening Apple Pay is not on an active, enabled domain of the account.
apple_pay.domain_validate_cooldownWait a minute before validating the same domain again.
apple_pay.token_replayedThat Apple Pay credential was already used; open a new sheet.
apple_pay.merchant_session_failedApple did not accept the merchant session. Retry; if it persists, contact support.
apple_pay_unsupported_networkThe card belongs to a network ONVO does not accept through Apple Pay. The accepted ones are Visa, Mastercard, and American Express.

Apple Pay domains in the Dashboard​

You can also manage domains without code from the Dashboard. Go to Settings → Payment methods and, on the Apple Pay row, select Manage domains to open the Apple Pay domains screen. From there you can see your domains with their status, download the association file, register a new domain, retry validation, and disable a domain. The screen is available when Apple Pay is enabled for your account.

Testing​

In test mode, with onvo_test_ keys, charges are simulated and no money moves, but the payment sheet, the domain registration, and the full flow are real. Test with a real Apple device and any card saved in Wallet: Apple's sandbox cards do not apply on the ONVO platform.

For local development, the domain must be served over HTTPS from a public address — for example, a tunnel — and registered the same way as in production. localhost cannot be registered.