@tapayadot/accept-react-native
v1.3.2
Published
Accept SDK for React Native/Expo
Readme

React Native / Expo SDK for integrating Tapaya Accept payment processing into your app.
Installation
npm install @tapayadot/accept-react-nativeExpo plugin
Add the plugin to your app.json. The plugin automatically configures the native Android Maven repository and iOS Swift Package Manager dependency:
{
"expo": {
"plugins": ["@tapayadot/accept-react-native"]
}
}Then run:
npx expo prebuildPlugin options
The plugin accepts options to toggle optional native features. Pass them as the second element of the plugin entry in app.json:
| Option | Type | Default | Description |
|---|---|---|---|
| enableStripe | boolean | false | Android only. Bundle the optional com.tapaya:accept-stripe dependency. Enable this only if your merchant account uses Stripe-backed payment processing. |
{
"expo": {
"plugins": [
[
"@tapayadot/accept-react-native",
{ "enableStripe": true }
]
]
}
}When enableStripe is true, the plugin writes com.tapaya.accept.enableStripe=true into your app's android/gradle.properties during prebuild, which adds com.tapaya:accept-stripe to the Android build. iOS payment processing is bundled in the Swift Package and requires no flag.
Re-run prebuild after changing plugin options so the native projects pick up the change:
npx expo prebuild --cleanAndroid
The Android SDK is distributed via Maven Central, which is a default repository in every Android project — no additional repository configuration is required.
iOS
The iOS SDK is resolved via Swift Package Manager during prebuild / pod install. No additional configuration is required.
Requirements
- React Native 0.74+ / Expo SDK 51+
- iOS 26+
- Android API 30+
Usage
Setup
import Accept from '@tapayadot/accept-react-native';
// Initialize once at app launch
await Accept.initialize(/* demo: */ false);
// Authenticate with your merchant token
await Accept.authenticate('your-merchant-token');UI Theming
Customize colors and logos at initialization or any time after:
import Accept, { type AcceptThemeConfiguration } from '@tapayadot/accept-react-native';
import { assetToBase64 } from '@tapayadot/accept-react-native/utils';
const theme: AcceptThemeConfiguration = {
colors: {
accent: '#FF8400',
error: '#E6282B',
warning: '#FF8000',
success: '#228800',
brandGradientColors: { start: '#FF8400', end: '#9A94E9' },
},
images: {
brandLogo: await assetToBase64(require('./assets/brand-logo.png')),
toolbarLogo: await assetToBase64(require('./assets/toolbar-logo.png')),
solidLogo: await assetToBase64(require('./assets/solid-logo.png')),
},
};
// Pass at initialization
await Accept.initialize(false, theme);
// Or apply after initialization
await Accept.setTheme(theme);Omit colors or images to keep SDK defaults for that slot. Images must be PNG or JPEG — SVG is not supported.
assetToBase64requiresexpo-assetandexpo-file-system. Both are included in managed Expo projects. Bare React Native users must install them manually.
Request Location Permission
Required before processing card payments (Tap-to-Pay):
await Accept.requestLocationPermission();Card Payment (Tap-to-Pay)
import Accept, { CardPaymentIntent } from '@tapayadot/accept-react-native';
const intent: CardPaymentIntent = {
paymentIntentId: 'pi_xxx',
amount: 1500,
requestedCurrency: 'CZK', // ISO 4217 alpha-3
settlementCurrency: 'EUR',
};
const result = await Accept.payments.startCardPayment(
intent,
(status) => console.log('Status update:', status),
(message, exception) => console.error('Error:', message, exception),
);
switch (result.status) {
case 'approved':
console.log('Approved:', result.authorizationCode);
break;
case 'declined':
console.log('Declined:', result.reason);
break;
}Refund a Card Payment
const refund = await Accept.payments.refund({
paymentToken: 'pi_xxx', // source payment intent id (or server payment UUID)
reason: 'customerRequest', // 'customerRequest' | 'duplicate' | 'fraudulent' | 'expiredCharge'
});
console.log(refund.status); // 'success' | 'pending' | 'cancelled' | 'refunded' | 'failed' | 'actionNeeded'Cancel an Active Payment
// Dismisses any payment UI and cancels the in-flight transaction.
await Accept.payments.cancelActivePayment();SEPA Instant Credit Transfer
const result = await Accept.payments.startSepaPayment(
{
paymentIntentId: 'pi_xxx',
amount: 1000,
requestedCurrency: 'EUR',
settlementCurrency: 'EUR',
},
(status) => console.log('Status update:', status),
(message, exception) => console.error('Error:', message, exception),
);
if (result.status === 'verified') {
console.log('Received from:', result.receivedFromIban);
}Certis (Czech Instant Transfer)
const result = await Accept.payments.startCertisPayment(
{
paymentIntentId: 'pi_xxx',
amount: 10000,
requestedCurrency: 'CZK',
settlementCurrency: 'CZK',
},
(status) => console.log('Status update:', status),
(message, exception) => console.error('Error:', message, exception),
);Onboarding Status
// Aggregate status across all payment methods
const onboarding = await Accept.identity.getOnboardingStatus();
console.log(onboarding.isOnboarded);
onboarding.paymentMethods.forEach((m) =>
console.log(m.method, m.status), // e.g. 'CARD', 'ACTIVE'
);
// Single-method status
const cardStatus = await Accept.identity.getPaymentMethodStatus('CARD');
// 'NOT_STARTED' | 'PENDING' | 'ACTIVE' | 'ATTENTION_NEEDED' | 'ACTION_REQUIRED' | 'BLOCKED'KYB Onboarding
// Check if onboarding is needed before launching the KYB flow
await Accept.identity.presentKyb({
businessType: 'company',
legalName: 'Acme s.r.o.',
businessEmail: '[email protected]',
countryCode: 'CZ',
registrationNumber: '12345678',
vatNumber: 'CZ12345678',
addressLine1: 'Václavské náměstí 1',
city: 'Praha',
postalCode: '11000',
bankAccountIban: 'CZ...',
businessUrl: 'https://acme.com',
productDescription: 'SaaS platform',
supportPhone: '+420123456789',
});Session Management
// Check current SDK status
const status = await Accept.getStatus(); // 'IDLE' | 'INITIALIZED' | 'LOGGED_IN'
// Query the result of a previous payment
const result = await Accept.getPaymentStatus('pi_xxx');
// Log out
await Accept.logOut();Demo Mode
await Accept.demo.enable(); // simulate payments without real terminals
const isDemo = await Accept.demo.isEnabled();
await Accept.demo.disable();UI Behavior (Android only)
await Accept.setUiBehavior({
resultScreenDurationSeconds: 5,
showResultScreen: true,
nfcZone: {
indicator: 'BELOW', // 'DEFAULT' | 'ABOVE' | 'BELOW' | 'FRONT' | 'BEHIND'
position: { xBias: 0.5, yBias: 0.7 }, // omit to use terminal default
},
});Companion App
The Tapaya companion app is required for card payments. Supported on both iOS and Android:
const installed = await Accept.isCompanionAppInstalled();
if (!installed) {
// Prompt user to install via the store product sheet (App Store on iOS, Play Store on Android)
await Accept.presentCompanionAppSheet();
} else {
// Pair with the companion app (rejects if it is not installed or not ready)
await Accept.pairWithCompanionApp();
}API Reference
Top-level
| Method | Description |
|---|---|
| initialize(demo?, theme?) | Initialize the SDK. Pass true for sandbox mode. Optionally provide a UI theme. |
| setTheme(theme) | Apply a UI theme after initialization. |
| setUiBehavior(behavior) | Android only. Configure result screen + NFC zone. |
| authenticate(token) | Authenticate with a merchant JWT token. |
| getStatus() | Returns 'IDLE' \| 'INITIALIZED' \| 'LOGGED_IN'. |
| getPaymentStatus(paymentIntentId) | Retrieve the result of a previous payment. |
| logOut() | End the current merchant session. |
| requestLocationPermission() | Request location permission (required for card payments). |
| isCompanionAppInstalled() | Check if the Tapaya companion app is installed. |
| presentCompanionAppSheet() | Show the store product sheet for the companion app (App Store on iOS, Play Store on Android). |
| pairWithCompanionApp() | Pair with the installed companion app. |
Accept.payments
| Method | Description |
|---|---|
| startCardPayment(intent, onStatus, onError) | Start a card/Tap-to-Pay payment. |
| startSepaPayment(intent, onStatus, onError) | Start a SEPA Instant payment. |
| startCertisPayment(intent, onStatus, onError) | Start a Certis Instant payment. |
| refund(intent) | Refund a previously completed card payment (headless, no UI). |
| cancelActivePayment() | Dismiss in-flight payment UI and cancel the transaction. |
Accept.identity
| Method | Description |
|---|---|
| presentKyb(prefilling?) | Launch the KYB onboarding UI with optional prefill data. |
| getOnboardingStatus() | Returns aggregate merchant onboarding status across payment methods. |
| getPaymentMethodStatus(method) | Returns onboarding status for a single payment method. |
Accept.demo
| Method | Description |
|---|---|
| enable() | Enable demo mode — payments are simulated, no real terminal required. |
| disable() | Return to real terminal flows. |
| isEnabled() | Whether demo mode is currently enabled. |
Types
Currency and country fields are plain ISO strings:
- Currency — ISO 4217 alpha-3 (
'CZK','EUR','GBP', …) - Country — ISO 3166-1 alpha-2 (
'CZ','GB', …)
type CardPaymentIntent = {
paymentIntentId: string
amount: number // smallest currency unit (e.g. hellers)
requestedCurrency: string // ISO 4217 alpha-3
settlementCurrency?: string // defaults to requestedCurrency
}
type CardPaymentResult = {
status: 'pending' | 'approved' | 'declined' | 'refunded' | 'aborted'
last4?: string
brand?: string
authorizationCode?: string
terminalId?: string
companyName?: string
companyAddress1?: string
companyAddress2?: string
companyCity?: string
companyCountry?: string // ISO 3166-1 alpha-2
reason?: string
receiptUrl?: string
refundToken?: string // present when this card payment was refunded
}
type SepaPaymentIntent = { paymentIntentId: string; amount: number; requestedCurrency: string; settlementCurrency?: string }
type SepaPaymentResult = { status: 'pending' | 'verified' | 'aborted' | 'refunded' | 'declined'; postponed: boolean; receivedAt: string; receivedFromIban: string; receiptUrl?: string }
type CertisPaymentIntent = { paymentIntentId: string; amount: number; requestedCurrency: string; settlementCurrency?: string }
type CertisPaymentResult = { status: 'pending' | 'verified' | 'aborted' | 'refunded' | 'declined'; postponed: boolean; receivedAt: string; receivedFromIban: string; receiptUrl?: string }
type RefundReason = 'customerRequest' | 'duplicate' | 'fraudulent' | 'expiredCharge'
type TransactionStatus = 'pending' | 'success' | 'cancelled' | 'refunded' | 'failed' | 'actionNeeded'
type RefundIntent = {
paymentToken: string // source payment UUID or original paymentIntentId
refundToken?: string // idempotency token, pass same value on retry
reason: RefundReason
}
type RefundResult = {
refundToken?: string
status: TransactionStatus
refundReason: RefundReason
paymentMethod?: PaymentMethod
requestedAmount?: number
requestedCurrency?: string
settlementAmount?: number
settlementCurrency?: string
fxRate?: number
createdAt?: string // ISO 8601 UTC
processedAt?: string // ISO 8601 UTC
}
type PaymentMethod = 'CARD' | 'SEPA' | 'CERTIS' | 'CRYPTO'
type PaymentMethodStatus = 'NOT_STARTED' | 'PENDING' | 'ACTIVE' | 'ATTENTION_NEEDED' | 'ACTION_REQUIRED' | 'BLOCKED'
type AcceptPaymentMethodStatus = { method: PaymentMethod; status: PaymentMethodStatus }
type AcceptOnboardingStatus = { isOnboarded: boolean; paymentMethods: AcceptPaymentMethodStatus[] }
type GradientColors = { start: string; end: string }
type AcceptColorTheme = {
accent: string // #RRGGBB or #AARRGGBB
error: string
warning: string
success: string
brandGradientColors?: GradientColors
brandSubtleGradientColors?: GradientColors
}
type AcceptImageTheme = {
brandLogo: string // base64 PNG/JPEG
toolbarLogo: string
solidLogo: string
}
type AcceptThemeConfiguration = {
colors?: AcceptColorTheme
images?: AcceptImageTheme
}
// Android-only
type NfcIndicator = 'DEFAULT' | 'ABOVE' | 'BELOW' | 'FRONT' | 'BEHIND'
type NfcPosition = { xBias: number; yBias: number } // 0..1 normalized; omit position for terminal default
type NfcZone = { indicator: NfcIndicator; position?: NfcPosition }
type AcceptUiBehavior = {
resultScreenDurationSeconds?: number
showResultScreen?: boolean
nfcZone?: NfcZone
}
type KybPrefillData = {
businessType?: 'individual' | 'company' | 'nonProfit' | 'governmentEntity'
countryCode?: string // ISO 3166-1 alpha-2
registrationNumber?: string
vatNumber?: string
legalName?: string
addressLine1?: string
addressLine2?: string
city?: string
postalCode?: string
merchantCategoryCode?: number
businessEmail?: string
bankAccountIban?: string
businessUrl?: string
productDescription?: string
supportPhone?: string
}Documentation
Full documentation is available at docs.tapaya.com.
License
Licensed under the Apache License, Version 2.0.
