ReactNative Payments

Accept Payments with Apple Pay and Android Pay using the Payment Request API.
Implementation of W3C Payment Request API(version 08 September 2022) for React
Native.
Currently not all the features described for the browsers are supported by this lib. Please feel free to open a PR.
See TODO
This library represents a significant improvement over the
fantastic react-native-payments library, with the following enhancements:
- Complete Rewrite: The library has undergone a comprehensive refactoring and is now fully written
in TypeScript.
- Native Type Support: We have introduced native types for both IOS and Android, ensuring full typing and detailed
documentation.
- Unified API: With the aim of simplifying usage, the library now offers a unified API for both IOS and Android. You will no
longer need code-dependent logic when utilizing the library, thanks to unified
interfaces/enums/types
.
- Enhanced Native Code: The IOS and JAVA native code has been thoroughly updated, refactored, and simplified. All deprecated
code has been removed, ensuring better performance and stability.
- Streamlined Gateway Support: While Stripe/Braintree built-in gateway support has been removed, we continue to support
custom gateways. The removal of built-in gateway support enables us to focus on providing better integration for custom
solutions, especially since Stripe and Braintree already have their dedicated libraries.
- ReactNative's New Architecture: The library now
supports Turbo Modules., ensuring compatibility
with ReactNative's latest architecture.
These enhancements ensure that the library is more efficient, maintainable, and future-proof, offering a seamless payment
integration experience for your applications.
Features
- Streamlined. Say goodbye to complicated checkout forms.
- Efficient. Accelerate checkouts for higher conversion rates.
- Forward-looking. Utilize a W3C Standards API endorsed by major companies such as Google, Firefox,
and more.
- Versatile. Share payment code seamlessly across iOS, Android, and web applications.
Installation
- Install package
@rnw-community/react-native-payments
using your package manager.
ApplePay setup
#import <RCTAppDelegate.h>
#import <UIKit/UIKit.h>
#import <PassKit/PassKit.h> // Add this import
@interface AppDelegate : RCTAppDelegate
AndroidPay setup
dependencies {
// The version of react-native is set by the React Native Gradle Plugin
implementation("com.facebook.react:react-android")
implementation 'com.google.android.gms:play-services-wallet:19.2.0'
Expo setup
To integrate with Expo custom builds, you need to add the payment plugin from the package into your app.config.js
:
- Update your
app.config.js
configuration:
export default {
expo: {
...
ios: {
...
infoPlist: {
merchant_id: [your_merchant_id],
},
entitlements: {
"com.apple.developer.in-app-payments": [your_merchant_id],
},
...
},
plugins: [
...
"@rnw-community/react-native-payments",
],
},
};
Usage
Detailed guide should be found at:
The PaymentRequest class is designed to facilitate the integration of payment processing into your React Native application.
It leverages TypeScript for robust typing and ensures seamless payment experiences across both iOS and Android platforms.
Below is a comprehensive guide on how to use the PaymentRequest class effectively:
1. Importing the class
import {PaymentRequest} from '@rnw-community/react-native-payments';
2. Creating an Instance
import { PaymentMethodNameEnum, SupportedNetworkEnum } from "@rnw-community/react-native-payments/src";
const methodData = [
{
supportedMethods: PaymentMethodNameEnum.ApplePay,
data: {
merchantIdentifier: 'merchant.com.your-app.namespace',
supportedNetworks: [SupportedNetworkEnum.Visa, SupportedNetworkEnum.Mastercard],
countryCode: 'US',
currencyCode: 'USD',
requestBillingAddress: true,
requestPayerEmail: true,
requestShipping: true
}
},
{
supportedMethods: PaymentMethodNameEnum.AndroidPay,
data: {
supportedNetworks: [SupportedNetworkEnum.Visa, SupportedNetworkEnum.Mastercard],
environment: EnvironmentEnum.Test,
countryCode: 'DE',
currencyCode: 'EUR',
requestBillingAddress: true,
requestPayerEmail: true,
requestShipping: true,
gatewayConfig: {
gateway: 'example',
gatewayMerchantId: 'exampleGatewayMerchantId',
},
}
}
];
const paymentDetails = {
};
const paymentRequest = new PaymentRequest(methodData, paymentDetails);
Note: The methodData
parameter is an array of PaymentMethodData
objects that represent
the supported payment methods in your application. Each PaymentMethodData
object should have a supportedMethods
property specifying the type of payment method (e.g., PaymentMethodNameEnum.AndroidPay
or PaymentMethodNameEnum.ApplePay
)
and a data property containing the corresponding platform-specific data.
2.1 Additional methodData.data options
Depending on the platform and payment method, you can provide additional data to the methodData.data
property:
environment
: This property represents the Android environment for the payment.
requestPayerName
: "An optional boolean field that, when present and set to true, indicates that the PaymentResponse
will include the name of the payer.
requestPayerPhone
: "An optional boolean field that, when present and set to true, indicates that the PaymentResponse
will include the phone of the payer.
requestBillingAddress
: An optional boolean field that, when present and set to true, indicates that the PaymentResponse
will
include the billing address of the payer.
requestPayerEmail
: An optional boolean field that, when present and set to true, indicates that the PaymentResponse
will
include the email address of the payer.
requestShipping
: An optional boolean field that, when present and set to true, indicates that the PaymentResponse
will
include the shipping address of the payer.
3. Checking Payment Capability
Before displaying the payment sheet to the user, you can check if the current device supports the payment methods specified:
const isPaymentPossible = await paymentRequest.canMakePayment();
This method returns a boolean value indicating whether the device supports the specified payment methods.
The PaymentRequest
class automatically handles platform-specific payment data based on the provided methodData.
4. Displaying the Payment Sheet
Once you have verified the device's capability, you can proceed to display the payment sheet for the user to complete the
transaction:
try {
const paymentResponse = await paymentRequest.show();
} catch (error) {
}
const paymentResponse = paymentRequest.show().then(...).catch(...);
The paymentRequest.show()
method returns a promise that resolves with a PaymentResponse
object representing the user's
payment response.
5. Processing the PaymentResponse
To send all the relevant payment information to the backend (BE) for further processing and validation, you need to extract
the required data from the PaymentResponseDetailsInterface
object.
The PaymentResponseDetailsInterface
provides various properties that encompass essential details about the payment,
including the payment method used, the payer's information, and transaction-related information.
const paymentResponse = paymentRequest.show().then((paymentResponse) => {
paymentResponse.androidPayToken;
paymentResponse.applePayToken;
paymentResponse.billingAddress;
paymentResponse.payerEmail;
paymentResponse.payerName;
paymentResponse.payerPhone;
paymentResponse.shippingAddress;
}).catch(...);
The PaymentResponseDetailsInterface
includes the following additional properties:
billingAddress
: This property represents user billing details PaymentResponseAddressInterface
and available if was requested in the PaymentRequest
.
shippingAddress
: This property represents user shipping details PaymentResponseAddressInterface
and available if was requested in the PaymentRequest
.
payerEmail
: This property represents user email and available if was requested in the PaymentRequest
.
payerPhone
: This property represents user phone and available if was requested in the PaymentRequest
.
androidPayToken
: This property represents PaymentToken
information returned by AndroidPay
, this should be sent to your payment provider.
applePayToken
: This property represents PaymentToken
information returned by ApplePay
, this should be sent to your payment provider.
6. Closing the Payment Sheet
Once the payment process is successfully completed, it's essential to close the payment sheet by calling the
PaymentResponse.complete()
method. This method takes a parameter from the PaymentComplete
enum to indicate the outcome of
the
payment and hide the payment sheet accordingly.
paymentResponse.complete(PaymentComplete.Success)
This will have no affect in the Android platform due to AndroidPay implementation.
7. Aborting the Payment
The PaymentRequset.abort()
method in the Payment Request API allows developers to programmatically cancel an ongoing
payment request or dismiss
the payment sheet when it is in an interactive state. This method is used to handle scenarios where the user decides to
cancel the
payment process or when specific conditions require the payment request to be aborted.
This will have no affect in the Android platform due to AndroidPay implementation.
Unit testing
Due to new TurboModules architecture in React Native, you can encounter issues with Jest tests. To fix this, you can mock
the TurboModuleRegistry to disable the Payment
module in Jest tests. Here is an example of how you can do this:
const turboModuleRegistry = jest.requireActual(
'react-native/Libraries/TurboModule/TurboModuleRegistry'
);
export function setupJestTurboModuleMock(): void {
jest.mock('react-native/Libraries/TurboModule/TurboModuleRegistry', () => {
return {
...turboModuleRegistry,
getEnforcing: (name: string) => {
if (name === 'Payment') {
return null;
}
return turboModuleRegistry.getEnforcing(name);
},
};
});
}
Example
You can find working example in the App
component of
the react-native-payments-example package.
TODO
Docs
Native
W3C spec:
Other
License
This library is licensed under The MIT License.