Skip to main content
Available in🇮🇳 India
Use Razorpay Apple Pay to add Apple Pay to your React Native app. Razorpay handles payment processing while you build your own UI around the Apple Pay button.
SDK VersionThe Apple Pay feature is available in react-native-customui version 2.3.0 and later. Apple Pay runs on iOS only.

Prerequisites

iOS OnlyApple Pay is available on iOS only. On Android, canMakePayment always returns false, so hide the Apple Pay button there.

One-Time Setup (Before Code)

Complete this setup once before writing any integration code.
  1. Create Apple Pay Merchant ID: In the Apple Developer Portal, go to Identifiers → + → Merchant IDs. Use the format merchant.com.yourcompany.app and register.
  2. Share Merchant ID with Razorpay: Send your Merchant ID to your Razorpay point of contact. The team will share a CSR file with you.
  3. Generate Certificate on Apple: In the Apple Developer Portal, open your Merchant ID → Create Certificate under Apple Pay Payment Processing. Upload the .csr, then download the apple_pay.cer.
Watch Out!Certificates expire after 25 months. Set a reminder to renew before expiry.
  1. Share Certificate with Razorpay: Send the apple_pay.cer file back to your Razorpay point of contact for configuration.
  1. Open ios/YourApp.xcworkspace in Xcode.
  2. Select your app target → Signing & Capabilities.
  3. Click + Capability → Apple Pay.
  4. Tick the Merchant ID created above.
This generates a .entitlements file. Sample output:
Entitlements
The merchant identifier in this entitlement must be the same one you pass as apple_pay.merchant_identifier at runtime.

Integration Steps

Step 1: Install the SDK

Install the package from npm:
Terminal

Step 2: Add the Apple Pay Plugin Pod

The Apple Pay plugin is opt-in. Add it to your ios/Podfile, inside your app target:
Podfile
Then install the pods:
Terminal
RazorpayApplePay is not published to the CocoaPods trunk. It ships as a Swift Package binary target and GitHub release asset. Declaring it as a hard dependency would break pod install for every existing app using react-native-customui, so the package ships a podspec that you add explicitly.The SDK resolves the plugin at runtime. If the pod is absent, your app still builds and Apple Pay degrades cleanly: canMakePayment returns false and open() rejects with DEVICE_NOT_SUPPORTED.

Step 3: Check if the Customer Can Pay

Call this before showing your Apple Pay button. It checks whether the user can pay via Apple Pay with your merchant account.
JavaScript
canMakePayment returns a boolean. It is merchant-aware, not a device probe: it fetches the card networks enabled for your Razorpay account and resolves true only when Apple Pay is live for your account and the customer’s Wallet holds a card on an accepted network. It returns false on Android. Hide the Apple Pay button when it is false.

Step 4: Create an Order on Your Server

Create a Razorpay order via the Orders API on your backend and send the order_id to your app.
Request
The response returns an order_id such as order_CuEzONfnOI86Ab. Pass this to your app. To carry your own order reference through an Apple Pay payment, set receipt and notes on the order (as shown above). See Attaching Your Own Order Reference.
Watch Out!Never embed your API secret in the mobile app. Orders must be created by your own backend. A decompiled app bundle exposes any secret it contains, and with it your merchant account.

Step 5: Load the Payment Button

Apple’s Human Interface Guidelines require the use of PKPaymentButton (or a visually compliant variant). Custom buttons will lead to App Store rejection. React Native has no built-in Apple Pay button. Expose PKPaymentButton to JavaScript with a small native view module (a UIViewRepresentable-style wrapper using RCTViewManager), or use a community package that does the same. Whichever you use, it must render Apple’s PKPaymentButton and call your payment handler on tap. Button constraints:
  • Use PKPaymentButton, not a generic button with an Apple Pay icon.
  • Do not place text or icons inside it.
  • Respect Apple’s minimum height requirement.
  • Use the automatic style on iOS 14+ for automatic light and dark mode adaptation.
  • Disable the button while a payment is in flight (see Step 6).
Test on a Real DeviceRun on a physical iOS device. Transactions cannot complete on the simulator. Tap your Apple Pay button, authenticate with Face ID or Touch ID, then confirm the payment record appears in the Razorpay Dashboard.

Step 6: Trigger the Payment on User Tap

This call must be made in response to a user gesture (such as a button tap). Do not call it on mount or from a timer. Use the existing Razorpay.open(options) API with an Apple Pay payload.
JavaScript
Guard Against Double TapsApple Pay will not present a second payment sheet while one is pending. If open() is called twice, both calls fail with SHEET_PRESENTATION_FAILED. Disable the Apple Pay button as soon as it is tapped and re-enable it only after the promise settles.

Step 7: Handle the Payment Result

open() returns a promise. It resolves with the payment payload on success and rejects with an error object on failure or cancellation.
JavaScript
Success response (promise resolves with):
Response
Failure response (promise rejects with):
Response
metadata.payment_id is present only when a payment was created before the failure.

Step 8: Verify Payment Signature on Your Server

Always verify the signature on your server before fulfilling the order. A successful open() is not a fulfilled order. Send razorpay_payment_id, razorpay_order_id and razorpay_signature to your backend for HMAC verification.
Watch Out!Never fulfil an order based solely on the client-side result. Always verify the payment signature server-side.
See the signature verification guide for Node.js and other language samples.

Attaching Your Own Order Reference

notes passed in the Razorpay.open() options are not carried onto the payment for Apple Pay. If your system maps payments back to your own order ID, set the reference on the order instead. Set it at order creation (Step 4):
Order
Then read it back:
This Differs From Other Flows on the Same SDKOn UPI and standard card payments, notes passed at payment time do reach the payment object. On Apple Pay they do not. If you reuse payment-creation code across methods, this is the one field that will not behave the same way.
In this SDK’s Razorpay.open() options, notes must be a nested JSON object. Flat bracket keys such as "notes[orderId]" are not parsed as notes here.

Error Codes

Apple Pay uses the same Razorpay.open() promise, the same success and error events and the same error envelope as any other payment method in this SDK. If your app already handles card payments, your existing .then() and .catch() handle Apple Pay with no changes. On failure, read the error code as a string from err.error.code in the rejected promise. (The top-level err.code is a numeric 0 for failures and 1 for cancellation. This is the SDK-wide envelope, not something Apple Pay introduces.)

Currency and Card Networks

American Express is accepted for INR payments only. For any other currency the SDK removes American Express from the payment sheet automatically. You do not need to do anything.

Complete Working Example

JavaScript

Frequently Asked Questions

No. The Simulator has no Secure Element, so the Apple Pay token it produces is empty and the payment fails. Razorpay test mode does not process Apple Pay tokens. Test on a physical iOS device with a real card in Wallet, using your rzp_live_* key.
The SDK separates detection from payment. Use canMakePayment to decide whether to include the Apple Pay row at all. When the user selects that row, show the Apple Pay button. When they tap it, call Razorpay.open(options) with the Apple Pay payload.
  • Merchant ID alignment: Does the Merchant ID you passed in app.apple_pay.merchant_identifier match the one in your .entitlements and the one uploaded to the Razorpay Dashboard?
  • Certificate uploaded: Is the CSR-signed certificate for that Merchant ID present in the Razorpay Dashboard?
  • Network match: Are you testing with a card whose network is enabled for your Razorpay account?
  • Backend support: Is Apple Pay enabled for your account in the Razorpay Dashboard?
  • Real device: Are you running on a physical device, not the Simulator?
If all of these are correct, check err.error.description in the rejected promise for the specific failure reason from the backend.
canMakePayment checks your merchant account as well as the device. It returns false when Apple Pay is not enabled for your Razorpay account, when none of the cards in Wallet are on a network enabled for your account, when the RazorpayApplePay pod is not installed or on Android.