React Native

Overview

Bring secure Telr payments to your React Native app fast. Our plug-in launches the checkout flow, manages the payment steps behind the scenes, and returns a clear success or failure result, so your team ships quicker and supports less.

Requirements

  • React Native ≥ 0.71.0
  • iOS: 15.1+
  • Android minSdk 21+ (target/compile SDK 34 recommended)
  • Your backend must return two URLs taken directly from the createOrder API response:
    • tokenUrl — value of _links.auth.href
    • orderUrl — value of _links.self.href

Installation

Install the package in your React Native app:

npm install @telrsdk/rn-telr-sdk
# or
yarn add @telrsdk/rn-telr-sdk
# iOS only
cd ios && pod install

Autolinking will register the native modules on both platforms. For older projects, add the package manually via settings.gradle/Podfile.

Usage

import TelrSdk, {
  initialize,
  launchPayment,
  payWithCard,
  payWithApplePay,
  launchGooglePayPayment,
  launchSamsungPayPayment,
  payWithSavedCard,
  addCard,
  getSdkVersion,
} from '@telrsdk/rn-telr-sdk';

async function startTelrFlow() {
  await initialize({
    languageCode: 'en',
    // iOS-only:
    applePayMerchantId: 'merchant.com.yourcompany.yourapp',
    applePayButtonType: 'buy',        // optional
    applePayButtonStyle: 'automatic', // optional
    // Android-only:
    samsungPayServiceId: null,
    samsungPayMerchantId: null,
    googlePayGatewayMerchantId: null,
    googlePayMerchantId: null,
    debug: __DEV__,
  });

  const paymentResult = await launchPayment({
    tokenUrl: 'https://merchant.example.com/token',
    orderUrl: 'https://merchant.example.com/order',
  });

  if (paymentResult.status === 'SUCCESS') {
    console.log('Payment complete');
  } else if (paymentResult.status === 'PENDING') {
    console.log('Payment is pending, confirm final status from backend');
  } else if (paymentResult.status === 'CANCELLED') {
    console.log('Customer cancelled the payment sheet');
  } else {
    console.error('Payment failed', paymentResult.error);
  }
}

On iOS the module pulls in Telr's native TelrSDK CocoaPod. After installing the package, run cd ios && pod install so the Swift bridge can link against the native SDK.

Supported Payment Methods

The SDK supports the following payment methods (availability is controlled by your Telr account and order configuration):

  • Credit/Debit Cards — Visa, Mastercard, Amex, mada (with 3D Secure)
  • Apple Pay (iOS) — requires Merchant Identity setup (see below)
  • Google Pay (Android) — requires Google Pay merchant configuration (see below)
  • Samsung Pay (Android) — requires Samsung device and manifest setup (see below)
  • Click to Pay — no merchant setup required (see below)
  • Tabby — Buy Now Pay Later
  • Tamara — Buy Now Pay Later
  • STC Bank — direct bank payment

Custom Colors (Theming)

Theme the SDK's payment UI to match your brand by passing colors to initialize. Provide light and/or dark variants; each color is an optional hex string ("#RRGGBB" or "#AARRGGBB").

await initialize({
  colors: {
    light: {
      primary: '#0057FF',            // Pay button, selected tick, links
      background: '#FFFFFF',         // payment sheet / surface background
      textLabel: '#101828',         // primary text
      border: '#E4E7EC',            // field/card outlines, dividers
      buttonText: '#FFFFFF',        // text on the Pay button
      textFieldText: '#101828',     // text the user types into inputs
      textFieldBackground: '#F2F4F7', // input field fill
    },
    dark: {
      primary: '#4C8DFF',
      background: '#101828',
      textLabel: '#F2F4F7',
      border: '#344054',
      buttonText: '#FFFFFF',
      textFieldText: '#F2F4F7',
      textFieldBackground: '#1D2939',
    },
  },
});

Colors resolve per token: init colors → store colors from the Telr portal → SDK default. Any token left unset falls through to the next source. Two secondary tones are derived automatically (no separate keys): muted text is textLabel at reduced opacity, and placeholder/hint text is textFieldText at reduced opacity. Provide both light and dark for full control — store colors are applied per-mode and do not cross-fill between modes.

Dedicated wallet methods (your own button)

To show your own wallet button instead of the SDK's payment screen, call the dedicated method from your button's press handler. The SDK owns the whole wallet session and returns only the final result — with orderRef and transactionRef populated for server-side verification. No SDK payment UI is shown.

import { Platform } from 'react-native';

// iOS — from your own Apple Pay button:
const res = await payWithApplePay({ tokenUrl, orderUrl });

// Android — from your own Google Pay / Samsung Pay button:
const res = await launchGooglePayPayment({ tokenUrl, orderUrl });
const res2 = await launchSamsungPayPayment({ tokenUrl, orderUrl });

if (res.status === 'SUCCESS') {
  // res.orderRef, res.transactionRef
}

Each method is platform-specific: calling the iOS method on Android (or vice-versa) resolves to a failure with error.code === 'unsupported_platform', so gate the button on Platform.OS. These require the same wallet configuration as the in-sheet flow (Apple Pay Merchant ID; Google Pay gateway/merchant IDs; Samsung Pay Service ID + manifest meta-data).

@telrsdk/rn-telr-sdk

Lightweight React Native module that exposes Telr platform information via the legacy native modules bridge. This package is meant as a starting point for wiring native capabilities into JavaScript.

Requirements

  • React Native >= 0.71.0
  • iOS 15.1+
  • Android minSdk 21+ (target/compile SDK 34 recommended)

Installation

npm install @telrsdk/rn-telr-sdk
# or
yarn add @telrsdk/rn-telr-sdk
# iOS only
cd ios && pod install

Autolinking will register the native modules on both platforms. For older projects, add the package manually via settings.gradle/Podfile.

Usage

import TelrSdk, {
  initialize,
  launchPayment,
  payWithCard,
  payWithApplePay,
  launchGooglePayPayment,
  launchSamsungPayPayment,
  payWithSavedCard,
  addCard,
  getSdkVersion,
} from '@telrsdk/rn-telr-sdk';

async function startTelrFlow() {
  await initialize({
    languageCode: 'en',
    // iOS-only:
    applePayMerchantId: 'merchant.com.yourcompany.yourapp',
    applePayButtonType: 'buy',        // optional
    applePayButtonStyle: 'automatic', // optional
    // Android-only:
    samsungPayServiceId: null,
    samsungPayMerchantId: null,
    googlePayGatewayMerchantId: null,
    googlePayMerchantId: null,
    debug: __DEV__,
  });

  const paymentResult = await launchPayment({
    tokenUrl: 'https://merchant.example.com/token',
    orderUrl: 'https://merchant.example.com/order',
  });

  if (paymentResult.status === 'SUCCESS') {
    console.log('Payment complete');
  } else if (paymentResult.status === 'PENDING') {
    console.log('Payment is pending, confirm final status from backend');
  } else if (paymentResult.status === 'CANCELLED') {
    console.log('Customer cancelled the payment sheet');
  } else {
    console.error('Payment failed', paymentResult.error);
  }
}

On iOS the module pulls in Telr's native TelrSDK CocoaPod. After installing the package, run cd ios && pod install so the Swift bridge can link against the native SDK.

Supported Payment Methods

The SDK supports the following payment methods (availability is controlled by your Telr account and order configuration):

  • Credit/Debit Cards — Visa, Mastercard, Amex, mada (with 3D Secure)
  • Apple Pay (iOS) — requires Merchant Identity setup (see below)
  • Google Pay (Android) — requires Google Pay merchant configuration (see below)
  • Samsung Pay (Android) — requires Samsung device and manifest setup (see below)
  • Click to Pay — no merchant setup required (see below)
  • Tabby — Buy Now Pay Later
  • Tamara — Buy Now Pay Later
  • STC Bank — direct bank payment

Custom Colors (Theming)

Theme the SDK's payment UI to match your brand by passing colors to initialize. Provide light and/or dark variants; each color is an optional hex string ("#RRGGBB" or "#AARRGGBB").

await initialize({
  colors: {
    light: {
      primary: '#0057FF',            // Pay button, selected tick, links
      background: '#FFFFFF',         // payment sheet / surface background
      textLabel: '#101828',         // primary text
      border: '#E4E7EC',            // field/card outlines, dividers
      buttonText: '#FFFFFF',        // text on the Pay button
      textFieldText: '#101828',     // text the user types into inputs
      textFieldBackground: '#F2F4F7', // input field fill
    },
    dark: {
      primary: '#4C8DFF',
      background: '#101828',
      textLabel: '#F2F4F7',
      border: '#344054',
      buttonText: '#FFFFFF',
      textFieldText: '#F2F4F7',
      textFieldBackground: '#1D2939',
    },
  },
});

Colors resolve per token: init colors → store colors from the Telr portal → SDK default. Any token left unset falls through to the next source. Two secondary tones are derived automatically (no separate keys): muted text is textLabel at reduced opacity, and placeholder/hint text is textFieldText at reduced opacity. Provide both light and dark for full control — store colors are applied per-mode and do not cross-fill between modes.

Dedicated wallet methods (your own button)

To show your own wallet button instead of the SDK's payment screen, call the dedicated method from your button's press handler. The SDK owns the whole wallet session and returns only the final result — with orderRef and transactionRef populated for server-side verification. No SDK payment UI is shown.

import { Platform } from 'react-native';

// iOS — from your own Apple Pay button:
const res = await payWithApplePay({ tokenUrl, orderUrl });

// Android — from your own Google Pay / Samsung Pay button:
const res = await launchGooglePayPayment({ tokenUrl, orderUrl });
const res2 = await launchSamsungPayPayment({ tokenUrl, orderUrl });

if (res.status === 'SUCCESS') {
  // res.orderRef, res.transactionRef
}

Each method is platform-specific: calling the iOS method on Android (or vice-versa) resolves to a failure with error.code === 'unsupported_platform', so gate the button on Platform.OS. These require the same wallet configuration as the in-sheet flow (Apple Pay Merchant ID; Google Pay gateway/merchant IDs; Samsung Pay Service ID + manifest meta-data).

Apple Pay (iOS)

  1. Apple Developer Portal: Enable Apple Pay for your App ID and create a Merchant Identity Certificate under Certificates, Identifiers & Profiles > Identifiers > Merchant IDs.
  2. Xcode: Open your .xcworkspace, add the Apple Pay capability to your target, and select your Merchant ID.
  3. SDK init: Pass your Merchant Identifier:
await initialize({
  applePayMerchantId: 'merchant.com.yourcompany.yourapp',
});

The SDK shows Apple Pay automatically when the device supports it and the user has cards in Wallet.

Samsung Pay (Android)

  1. Samsung Developers Portal: Register as a Samsung Pay partner at the Samsung Pay Developers portal and obtain a Service ID. Samsung registers the Service ID against your app's package name and signing certificate SHA-256 — debug and release builds have different SHAs, so register both (or use separate sandbox / production Service IDs).
  2. AndroidManifest.xml: Add under the <application> tag in android/app/src/main/AndroidManifest.xml:
<meta-data android:name="spay_sdk_api_level" android:value="2.22" />
<meta-data android:name="debug_mode" android:value="N" />
  • Use spay_sdk_api_level="2.22" exactly — this matches the Samsung Pay SDK bundled inside the Telr SDK. If a future Telr SDK release upgrades it, this value will be updated here.
  • debug_mode must be N in production. Set to Y only in development builds — shipping Y to production causes Samsung Pay to behave unpredictably.
  1. SDK init: Pass your Service ID:
await initialize({
  samsungPayServiceId: '<YOUR_SERVICE_ID>',
});

Samsung Pay only appears on Samsung devices with Samsung Wallet installed and provisioned, in supported regions.

Common reasons Samsung Pay does not appear

  1. App not registered with Samsung against your package name + signing SHA-256 — the most common cause. Debug and release builds have different SHAs. Use a sandbox Service ID with the debug-keystore SHA and a production Service ID with the release-keystore SHA, or register both SHAs against one Service ID.
  2. Device is not Samsung, or Samsung Wallet has no provisioned card — the SDK reports SPAY_NOT_READY and hides the option.
  3. Backend did not return order._links.samsungPay.href — confirm with your Telr account manager that Samsung Pay is enabled for your merchant account.
  4. Country / region not supported — Samsung Pay is region-locked. The device must be in a supported country.
  5. Manifest meta-data missing or wrong versionspay_sdk_api_level must match the value documented above. Filter logcat for SamsungPayRequirements to see validation warnings emitted by the SDK.

Google Pay (Android)

  1. Configure Google Pay for your Telr merchant account so the backend order includes order._links.googlePay.href.
  2. Pass your Android Google Pay settings during initialization:
await initialize({
  googlePayGatewayMerchantId: '<YOUR_GATEWAY_MERCHANT_ID>',
  googlePayMerchantId: '<YOUR_GOOGLE_MERCHANT_ID>',
});

Google Pay only appears when the backend enables it and Google Wallet is available and ready on the device.

Click to Pay

Click to Pay appears when your order enables allowedPaymentMethods.type = CLICK_TO_PAY (or order._links.clicktopay.href is present).

  • No SDK configuration or merchant registration required. dpaId, acquirer config, and locale come from the order response — Telr's backend owns the network registration.
  • The SDK handles consumer recognition, email entry, OTP authentication, saved-card listing, manual card entry, the network DCF challenge UI, and 3DS internally.
  • Recognition tokens are persisted on-device per dpaId so returning users skip the email/OTP step on the next session.

API

Methods

  • initialize(options?)Promise<TelrInitResult>
    Initializes the SDK with language, debug, and platform-specific options. Pass colors (a TelrColorConfig) to theme the SDK's payment UI — see Custom Colors (Theming).
  • launchPayment(request)Promise<TelrPaymentResult>
    Presents the full Telr payment UI (all payment methods).
  • payWithCard(request)Promise<TelrPaymentResult>
    Presents a card-only payment form. Use this when building a custom merchant checkout page. If the order supports saving cards, the form shows a "Save my card details" checkbox; when the user opts in, the result's savedCard is populated — persist it to reuse later via payWithSavedCard.
  • payWithApplePay(request)Promise<TelrPaymentResult> (iOS only)
    Runs Apple Pay with no SDK UI, for a merchant-owned Apple Pay button. Returns the final result only (orderRef/transactionRef populated on success). On Android it resolves to a failure with error.code === 'unsupported_platform'.
  • launchGooglePayPayment(request)Promise<TelrPaymentResult> (Android only)
    Runs Google Pay with no SDK UI, for a merchant-owned Google Pay button. On iOS it resolves to a failure with error.code === 'unsupported_platform'.
  • launchSamsungPayPayment(request)Promise<TelrPaymentResult> (Android only)
    Runs Samsung Pay with no SDK UI, for a merchant-owned Samsung Pay button. On iOS it resolves to a failure with error.code === 'unsupported_platform'.
  • payWithSavedCard(request)Promise<TelrPaymentResult>
    Pays using a previously saved card. Pass a TelrSavedCard obtained from a prior addCard (or a payWithCard where the user opted to save).
  • addCard(request)Promise<TelrAddCardResult>
    Presents a form to save a card without charging. Returns saved card tokens that can be stored on your backend and used with payWithSavedCard.
  • getSdkVersion()Promise<string>
    Returns the underlying native SDK version string.

Types

type TelrPaymentStatus = 'SUCCESS' | 'FAILURE' | 'CANCELLED' | 'PENDING';

type TelrPaymentRequest = {
  tokenUrl: string;
  orderUrl: string;
};

type TelrSavedCard = {
  token: string;
  maskedCard: string;
  expiry: string;
  scheme: string;
  maskedName?: string | null;
};

type TelrSavedCardPaymentRequest = TelrPaymentRequest & {
  savedCard: TelrSavedCard;
};

type TelrPaymentResult = {
  status: TelrPaymentStatus;
  message: string;
  error?: { code?: string | null; message?: string | null } | null;
  orderRef?: string | null;        // Telr order reference (on success)
  transactionRef?: string | null;  // transaction/payment reference (on success)
  savedCard?: TelrSavedCard | null; // set when the user opts to save during payWithCard
};

type TelrAddCardResult = TelrPaymentResult & {
  ref?: string | null;
  maskedName?: string | null;
  savedCards?: TelrSavedCard[] | null;
};

type TelrColors = {
  primary?: string | null;             // Pay button, selected tick, links
  background?: string | null;          // payment sheet background
  textLabel?: string | null;           // primary text
  border?: string | null;              // field/card outlines, dividers
  buttonText?: string | null;          // text on the Pay button
  textFieldText?: string | null;       // text typed into inputs (also derives placeholder/hint)
  textFieldBackground?: string | null; // input field fill
};

type TelrColorConfig = {
  light?: TelrColors | null;
  dark?: TelrColors | null;
};

Merchant checkout page example

Build a custom checkout page using the individual payment methods:

// 1. Save a card
const addCardResult = await addCard({ tokenUrl, orderUrl });
if (addCardResult.status === 'SUCCESS') {
  // Store addCardResult.savedCards on your backend
}

// 2. Pay with a saved card
const result = await payWithSavedCard({ tokenUrl, orderUrl, savedCard });

// 3. Pay with a new card (card-only form)
const result = await payWithCard({ tokenUrl, orderUrl });

Development

npm run typecheck
npm run build

The TypeScript sources live under src/ and compile into lib/. Android and iOS legacy native module sources live under android/ and ios/.

Troubleshooting

  • iOS: CocoaPods cannot find TelrSDK — run pod repo update then pod install again. The pod is published from github.com/Telr-PG/telr-sdk-ios.
  • iOS: build fails due to iOS version — set platform :ios, '15.1' or newer in your Podfile.
  • Android: minSdk/targetSdk mismatch — use min 21 / target 34 / compile 34.
  • Android: E002 "Unable to register for Activity Result" — call initialize(...) early in your app lifecycle, before launching payment.
  • Network/HTTP errors — verify backend tokenUrl / orderUrl are reachable from the device.