Web JS Integration
Integrate Apple Pay using the headless Razorpay JS SDK with amount and currency passed at initialisation, with full control over button rendering and payment flow.
The headless JS integration gives you full control over the Apple Pay button and payment flow. You initialise the Razorpay JS object with the amount and currency at start, then check eligibility and trigger the payment yourself. Know more about
.Integrating Apple Pay using the headless JS SDK offers you the following advantages:
- Full control: Render your own button or let Razorpay render one for you using
mount(). - Flexible initialisation: Pass amount and currency at init time when the cart total is known upfront.
- Device-aware eligibility: Use
canMakePayment()to check Apple Pay support before showing the button. - Event-driven results: Handle payment success, failure and errors through event listeners.
- No extra script for existing merchants: The SDK ships with the Custom Checkout script you already use.
Before starting the integration, ensure you have the following:
- A Razorpay account with Apple Pay enabled.
- An existing Razorpay Custom Checkout integration.
- International Payments enabled on your Razorpay account.
- Your API Key Id available. Know how to generate .
- An HTTPS-enabled domain (TLS 1.2 or higher). Apple Pay requires a secure context and will not function over HTTP.
- Server-side capability to create orders via the Razorpay Orders API.
- Apple Pay domain verification completed for your checkout domain.
Follow the steps given below.
Apple Pay needs you to host a file in your domain.
Watch Out!
- The file path must be exactly as specified (case-sensitive).
- File hosting is required on websites where Razorpay Checkout loads as an overlay/iframe. This includes:
- WooCommerce, Magento and other ecommerce platforms where Razorpay appears as an overlay. Any website where
checkout.razorpay.comiframe is embedded.
- WooCommerce, Magento and other ecommerce platforms where Razorpay appears as an overlay. Any website where
- No file hosting required on:
- Shopify, Mobile SDKs (Flutter, Native iOS, React Native) and Razorpay no-code solutions, such as and .
-
Download the
. -
Host the file on your server.
- Upload the file to this exact path on your website:
/.well-known/apple-developer-merchantid-domain-association- For example, if your domain is
https://www.yourstorename.com, the file must be accessible at:
https://www.yourstorename.com/.well-known/apple-developer-merchantid-domain-association -
Ensure correct configuration. When setting up Apple Pay domain verification, follow these requirements:
File Path and Response
- The verification file must be accessible at the exact path,
/.well-known/apple-developer-merchantid-domain-association. - The file must return a direct HTTP 200 status code and not a 301, 302 or any 3xx redirects.
- Apple does not support HTTP URL redirects for the domain association file.
Server Configuration
- The file must be served via HTTPS 1.1 protocol.
- The file must have Content-Type: text/plain in the header.
- The file must be externally accessible (not behind authentication).
- The file must not be password protected.
- The file must not be behind a proxy or redirect.
Network Access
- Ensure the file is not behind a firewall or access restrictions.
- If using a firewall, configure it to allow Apple's .
- The verification file must be accessible at the exact path,
-
After completing the above steps, please contact the
to enable Apple Pay.
Include the Razorpay Custom Checkout script in your page's <head> tag.
<head><script src="https://checkout.razorpay.com/v1/razorpay.js"></script></head>
Handy Tip
Load this script on every page where you intend to use the Apple Pay integration. Existing Custom Checkout merchants already load this script.
Pass the amount and currency when you initialise Razorpay. Use the on_payment_initiate_create_order callback to create the order on your server right before the payment sheet opens.
const razorpay = new Razorpay({key: 'rzp_test_XXXXXXXXXX',prefill: {contact: '+919876543210', // This is your customer's contact number.},amount: 1000,currency: 'EUR',on_payment_initiate_create_order: async () => {// Called right before the payment sheet opens.// Create the order on your server here, then:razorpay.set('order_id', orderIdFromYourServer);},});
Watch Out!
on_payment_initiate_create_order is where you create the Razorpay order. You must call razorpay.set('order_id', ...) inside it before it resolves — the payment cannot be authorised without an order id.
Register event listeners for payment success and failure.
razorpay.on('payment.success', (response) => {// response.paymentData.razorpay_payment_id// response.paymentData.razorpay_order_id// response.paymentData.razorpay_signature});razorpay.on('payment.failure', (response) => {// response.error -> { code, description, source, reason }});
Check whether the customer's device supports Apple Pay using canMakePayment(), then trigger the payment using one of the following options.
After a successful payment (the payment.success event fires), verify the payment signature on your server before fulfilling the order.
Send the following fields to your backend:
razorpay_payment_idrazorpay_order_idrazorpay_signature
Verify them using the standard
.Watch Out!
Never fulfil an order based solely on the client-side payment.success event. Signature verification ensures the payment was genuinely processed by Razorpay and has not been tampered with.
Every failure — from payment.failure events or a caught exception — carries the same shape:
{code: 'PAYMENT_CANCELLED' | 'PAYMENT_FAILED' | 'INTERNAL_ERROR',description: string, // safe to show to the customersource: 'customer' | 'merchant' | 'bank' | 'internal',reason: string, // machine-readable, for logging}
- Load
https://checkout.razorpay.com/v1/razorpay.js - Initialise
new Razorpay({ amount, currency, ... }) - Implement order creation inside
on_payment_initiate_create_order - Wire up
payment.success/payment.failurehandling - Test
canMakePayment()handling for devices/browsers where Apple Pay is not available - Verify the payment signature on your server before fulfilling the order
Is this integration guide useful?