React Native SDK for integrating with OpenPaymentPlatform via your own backend.
This SDK focuses on two practical things:
- provides typed models to build a checkout/session request,
- renders the hosted checkout in
react-native-webviewand delivers redirect callbacks (success/cancel/error).
Important: the library does not call OpenPaymentPlatform directly. It sends requests to your API (backendUrl), and your backend performs the OpenPaymentPlatform integration/proxying.
- Requirements
- Installation
- Quick start
- Checkout UI (WebView)
- 3DS App-to-App Redirects
- API: OpenPaymentPlatform
- Backend API (what you must implement)
- Errors
- Security notes
- Troubleshooting
- A React Native app (iOS/Android).
react-native-webview(peer dependency, because checkout is shown in a WebView).- A working backend that exposes endpoints for: session creation, status check, refund, and void.
Compatibility note: the example/ app is built for Expo SDK 54 / React Native 0.81, but the SDK can also be used in “bare” React Native projects.
npm install github:openpaymentplatform-net/react_native_openpaymentplatformIn the app that consumes the SDK, install peer dependencies:
npm i react-native-webviewIf you use Expo, prefer:
expo install react-native-webviewOn iOS (bare projects), you’ll typically need to install pods:
cd ios && pod installNote: crypto-js is installed automatically as a dependency of this SDK.
Initialize the singleton once at app startup using OpenPaymentPlatform.instance:
import { OpenPaymentPlatform } from '@openpaymentplatform/react-native-openpaymentplatform';
OpenPaymentPlatform.instance.initialize({
backendUrl: 'https://your-backend.example',
merchantKey: 'YOUR_MERCHANT_KEY',
password: 'YOUR_PASSWORD',
});import {
OpenPaymentPlatformRequest,
OpenPaymentPlatformOperation,
OpenPaymentPlatformOrder,
} from '@openpaymentplatform/react-native-openpaymentplatform';
const request = new OpenPaymentPlatformRequest({
operation: OpenPaymentPlatformOperation.purchase,
successUrl: 'https://your-app.example/payment/success',
cancelUrl: 'https://your-app.example/payment/cancel',
errorUrl: 'https://your-app.example/payment/error',
order: new OpenPaymentPlatformOrder({
number: 'ORDER-123',
amount: '10.00',
currency: 'USD',
description: 'Order #123',
}),
});The redirect URLs can be HTTPS routes or app/deep-link routes — the SDK only needs them to recognize success/cancel/error redirects.
import React, { useMemo } from 'react';
import { OpenPaymentPlatformCheckout, CheckoutController } from '@openpaymentplatform/react-native-openpaymentplatform';
export function CheckoutScreen() {
const controller = useMemo(
() =>
new CheckoutController({
paymentRequest: request,
onSuccessRedirect: (url) => {
console.log('Success redirect:', url);
},
onCancelRedirect: (url) => {
console.log('Cancel redirect:', url);
},
onErrorRedirect: (url) => {
console.log('Error redirect:', url);
},
onError: (e) => {
console.error('Checkout error:', e);
},
}),
[],
);
return <OpenPaymentPlatformCheckout controller={controller} />;
}OpenPaymentPlatformCheckout does the following:
- on mount, calls
OpenPaymentPlatform.instance.fetchPaymentUrl(paymentRequest), - opens the returned URL in
react-native-webview, - listens to navigation and calls the callbacks from
CheckoutController.
The SDK reads successUrl, errorUrl, cancelUrl from OpenPaymentPlatformRequest and checks every navigation with a simple url.includes(...).
Tip: keep these URLs reasonably unique (e.g. /payment/success) to avoid accidental matches.
Some 3DS flows redirect from WebView to a banking app using a custom scheme (non-HTTP URL), for example bankapp://....
Flow:
- WebView gets an external-scheme URL.
- SDK calls
onRedirectCallback(url)and blocks this navigation in WebView. - Your app opens that URL via
Linking.openURL(url). - Banking app returns back to your app via deep link.
- In your deep-link listener, call
controller.handleExternalRedirect(incomingUrl).
If incomingUrl is success/error/cancel, the matching callback is called. If it is HTTP(S), the SDK forwards it internally and checkout WebView continues the flow.
import React, { useEffect, useMemo } from 'react';
import { Linking } from 'react-native';
import {
CheckoutController,
OpenPaymentPlatformCheckout,
} from '@openpaymentplatform/react-native-openpaymentplatform';
export function CheckoutScreen() {
const controller = useMemo(
() =>
new CheckoutController({
paymentRequest: request,
onRedirectCallback: async (url) => {
if (!/^https?:\/\//i.test(url)) {
await Linking.openURL(url);
}
},
}),
[],
);
useEffect(() => {
const sub = Linking.addEventListener('url', ({ url }) => {
controller.handleExternalRedirect(url);
});
return () => sub.remove();
}, [controller]);
return <OpenPaymentPlatformCheckout controller={controller} />;
}OpenPaymentPlatform is a facade for backend requests. It stores configuration and uses it for all API calls.
OpenPaymentPlatform.instance.initialize({ backendUrl, merchantKey, password });This must be called before any methods below.
const url = await OpenPaymentPlatform.instance.fetchPaymentUrl(request);Creates a session on your backend and returns redirect_url which is then loaded in the WebView.
const status = await OpenPaymentPlatform.instance.checkStatus({ paymentId: '123' });
// or
const status2 = await OpenPaymentPlatform.instance.checkStatus({ orderId: 'ORDER-123' });const result = await OpenPaymentPlatform.instance.refundPayment({ paymentId: '123', amount: '10.00' });const result = await OpenPaymentPlatform.instance.voidPayment({ paymentId: '123' });The SDK expects your backendUrl to accept POST requests at:
POST /api/v1/session→ must return JSON withredirect_urlPOST /api/v1/payment/statusPOST /api/v1/payment/refundPOST /api/v1/payment/void
Payload is created from the SDK models using snake_case. The SDK also sends:
merchant_keyhash(signature)
Minimal response example for /api/v1/session:
{ "redirect_url": "https://hosted-checkout.example/..." }All errors delivered to controller.onError extend PaymentException.
Common types:
PaymentBackendException— backend returned a non-200response or an unexpected payload.PaymentInitializationException— network/parse/other unexpected errors.PaymentWebViewException— WebView load/navigation error.PaymentCallbackException— one of your callbacks threw (SDK catches it so the UI flow doesn’t crash).
- The SDK uses
passwordto generate request signatures (hash). That means the secret exists in the mobile app. - If that’s not acceptable for your architecture, move signing to your backend and avoid shipping the secret to the client.
- In any case: do not log
passwordand avoid storing it in plain text.
- iOS (bare): after installing
react-native-webview, runcd ios && pod install. - Blank WebView screen: verify that
/api/v1/sessionreturns a validredirect_url. - Callbacks don’t fire: ensure
successUrl/errorUrl/cancelUrlare unique enough (matching usesincludes). - Initialization errors: make sure
OpenPaymentPlatform.instance.initialize(...)runs before renderingOpenPaymentPlatformCheckout.
To report a specific issue or feature request, open a new issue.
Or write a direct letter to admin@openpaymentplatform.net.
MIT License. See the LICENSE file for more details.
Website: https://openpaymentplatform.net
Phone: +31-638-7642-70
Email: admin@openpaymentplatform.net
Address: OpenPaymentPlatform BV, Kingsfordweg 151, 1043 GR Amsterdam, The Netherlands
© 2014 - 2020 OpenPaymentPlatform. All rights reserved.
