Use the XPay React Native SDK to render embedded card, JazzCash, or EasyPaisa payment fields and confirm a PaymentIntent from a React Native application.
Before you begin
Create the PaymentIntent on the merchant backend. The application needs its pi_client_secret, together with the publishable key and account ID supplied for client integration.
Do not include the API HMAC secret in the React Native application. Current React Native packages no longer require hmacSecret in XPayProvider.
Install the current SDK
For React Native 0.76 and later, install the required WebView and the package for the selected environment.
WebView dependency:
npm install react-native-webview@^13.13.5Production package:
npm install @xstak/xpay-element-react-native@7.2.0Test package:
npm install @xstak/xpay-element-react-native-stage@6.3.0Use the production package and production credentials together. Use the test package only with XPay test credentials.
Compatibility with React Native versions below 0.76
Existing applications below React Native 0.76 use:
Use the current non-legacy packages for new applications.
Initialize the SDK
Import the production components:
import {
XPayProvider,
PaymentElement
} from "@xstak/xpay-element-react-native";For a test integration, import them from @xstak/xpay-element-react-native-stage instead.
Wrap the payment element with XPayProvider:
import React, { useState } from "react";
import { Button, Text, View } from "react-native";
import {
XPayProvider,
PaymentElement
} from "@xstak/xpay-element-react-native";
export function CardPayment({ paymentIntent }) {
const [canPay, setCanPay] = useState(false);
const [message, setMessage] = useState("");
async function pay() {
const customer = { name: "Ayesha Khan" };
const result = await PaymentElement.confirmPayment(
paymentIntent.pi_client_secret,
customer
);
setMessage(result.message);
}
return (
<XPayProvider
xpay={{
publishableKey: "{{publishable_key}}",
accountId: "{{account_id}}"
}}
>
<View>
<PaymentElement
onReady={(data) => {
setCanPay(data.complete);
}}
/>
<Button
title="Pay now"
disabled={!canPay}
onPress={pay}
/>
{message ? <Text>{message}</Text> : null}
</View>
</XPayProvider>
);
}Use onReady for form validation
onReady provides form-completion data. data.complete becomes true when all required payment fields contain valid input. Use it to enable a disabled payment button only when the customer can submit the form.
Do not interpret onReady as a final payment result. It describes client-side form validity before confirmation.
Confirm the selected payment method
Call confirmPayment() on the element that matches the customer's selected method:
const customer = { name: "Ayesha Khan" };
const { message, error } = await PaymentElement.confirmPayment(
paymentIntent.pi_client_secret,
customer
);The current React Native page also provides JazzCashPaymentElement and EasyPaisaPaymentElement. Their confirmation methods accept the PaymentIntent client secret and customer object in the same flow.
Use the SDK response to update the customer interface. Reconcile the final backend result through the verified payment webhook.
Handle errors
- Disable repeated submission while confirmation is in progress.
- Display a customer-safe message when
errorindicates failure. - Keep the customer in the application while required authentication is shown.
- Match the webhook
payment_intent_idto the merchant order before fulfillment.
Test the integration
Use the test package with the approved XPay test scenarios. EasyPaisa does not support the XPay test environment.