# React Native App Integration

Accept NFC payments from your React Native app using [`@monei-js/monei-pay-react-native-sdk`](https://www.npmjs.com/package/@monei-js/monei-pay-react-native-sdk). Built as an Expo module — works with both Expo and bare React Native projects.

**Source:** [github.com/MONEI/monei-pay-react-native-sdk](https://github.com/MONEI/monei-pay-react-native-sdk)

Cross-platform

One API for both platforms. The SDK handles URL schemes on iOS and intents on Android automatically.

## How it works[​](#how-it-works "Direct link to How it works")

1. Your app calls `MoneiPay.acceptPayment(...)` with a token and amount
2. **iOS:** the SDK opens MONEI Pay via a Universal Link (no system prompt)
3. **Android:** the SDK launches CloudCommerce (default) or MONEI Pay via intent
4. The payment result resolves as a promise

iOS opens with no prompt

On iOS the SDK opens MONEI Pay via a Universal Link (`https://pay.monei.com/accept-payment`), so the app launches directly without an "Open in MONEI Pay?" confirmation. MONEI Pay installs that predate Universal Link support fall back automatically to the `monei-pay://` URL scheme. No change to your integration is required.

## Prerequisites[​](#prerequisites "Direct link to Prerequisites")

* [MONEI account](https://dashboard.monei.com/signup)
* React Native 0.73+ / Expo SDK 50+
* POS auth token from your backend (see [Getting Started](https://docs.monei.com/monei-pay/app-integration/getting-started/.md))
* **iOS:** MONEI Pay installed on the device
* **Android (Direct):** CloudCommerce installed
* **Android (Via MONEI Pay):** MONEI Pay installed

Development build required

This SDK includes native code — [development builds](https://docs.expo.dev/develop/development-builds/introduction/) only. Expo Go is not supported.

## Integration[​](#integration "Direct link to Integration")

### 1. Install the SDK[​](#1-install-the-sdk "Direct link to 1. Install the SDK")

```
npx expo install @monei-js/monei-pay-react-native-sdk
```

Or install directly from GitHub:

```
npx expo install @monei-js/monei-pay-react-native-sdk@github:MONEI/monei-pay-react-native-sdk
```

### 2. Platform Configuration[​](#2-platform-configuration "Direct link to 2. Platform Configuration")

#### iOS[​](#ios "Direct link to iOS")

Add to `app.json` (or `Info.plist` directly):

app.json

```
{

  "expo": {

    "scheme": "your-app",

    "ios": {

      "infoPlist": {

        "LSApplicationQueriesSchemes": ["monei-pay"]

      }

    }

  }

}
```

Wire the completion handler:

App.tsx

```
import {Linking} from 'react-native';

import * as MoneiPay from '@monei-js/monei-pay-react-native-sdk';

import {useEffect} from 'react';



export default function App() {

  useEffect(() => {

    const subscription = Linking.addEventListener('url', ({url}) => {

      MoneiPay.handleCompleteRedirect(url);

    });

    return () => subscription.remove();

  }, []);



  // ...

}
```

#### Android[​](#android "Direct link to Android")

No configuration needed. The SDK's `AndroidManifest.xml` includes the required `<queries>` entries, merged automatically by the build system.

### 3. Accept a Payment[​](#3-accept-a-payment "Direct link to 3. Accept a Payment")

```
import * as MoneiPay from '@monei-js/monei-pay-react-native-sdk';



async function acceptPayment() {

  try {

    const result = await MoneiPay.acceptPayment({

      token: 'eyJ...',

      amount: 1500,

      description: 'Order #123',

      customerName: 'John Doe',

      customerEmail: 'john@example.com',

      callbackUrl: 'https://merchant.com/webhook/monei',

      completeScheme: 'your-app', // iOS only

      mode: 'direct' // Android only: 'direct' (default) or 'via-monei-pay'

    });



    if (result.success) {

      console.log('Payment approved:', result.transactionId);

      console.log('Card:', result.cardBrand, result.maskedCardNumber);

    }

  } catch (error) {

    console.error('Payment error:', error.message);

  }

}
```

Trust model

`callbackUrl` is a **trusted, signed webhook** delivered server-to-server — use it to fulfill orders. `completeScheme` (and the resulting `complete_url`) is a **client-side redirect only** — it brings the user back to your app but is not signed. See [Result Delivery](https://docs.monei.com/monei-pay/app-integration/getting-started/.md#result-delivery).

### SDK Reference[​](#sdk-reference "Direct link to SDK Reference")

#### `acceptPayment(params)`[​](#acceptpaymentparams "Direct link to acceptpaymentparams")

| Parameter         | Type     | Required          | Description                                                                                                                                                                         |
| ----------------- | -------- | ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `token`           | `string` | Yes               | POS auth token (raw JWT, no "Bearer " prefix)                                                                                                                                       |
| `amount`          | `number` | Yes               | Payment amount in cents (e.g. `1500` = 15.00 EUR)                                                                                                                                   |
| `description`     | `string` | No                | Payment description                                                                                                                                                                 |
| `customerName`    | `string` | No                | Customer name                                                                                                                                                                       |
| `customerEmail`   | `string` | No                | Customer email                                                                                                                                                                      |
| `customerPhone`   | `string` | No                | Customer phone                                                                                                                                                                      |
| `callbackUrl`     | `string` | No                | Trusted signed webhook URL. Must be strict `https://`, max 2048 chars. See [Result Delivery](https://docs.monei.com/monei-pay/app-integration/getting-started/.md#result-delivery). |
| `orderId`         | `string` | No                | Your merchant order reference. Surfaced in the webhook callback for reconciliation. Max 2048 chars. If omitted, the SDK generates one.                                              |
| `transactionType` | `string` | No                | Optional transaction type: `'SALE'` (default), `'AUTH'`, `'REFUND'`, `'CAPTURE'`, `'CANCEL'`, `'PAYOUT'`, `'VERIF'`. Server-validated.                                              |
| `completeScheme`  | `string` | Yes (iOS only)    | Your app's registered URL scheme — used to redirect the user back after the payment completes                                                                                       |
| `mode`            | `string` | No (Android only) | `'direct'` (default) or `'via-monei-pay'`                                                                                                                                           |

#### `handleCompleteRedirect(url)`[​](#handlecompleteredirecturl "Direct link to handlecompleteredirecturl")

Handle the completion redirect URL from MONEI Pay (iOS only). Wire into your `Linking` handler.

Returns `boolean` — `true` if the URL was handled.

#### `cancelPendingPayment()`[​](#cancelpendingpayment "Direct link to cancelpendingpayment")

Cancel any pending payment. The promise rejects with `'CANCELLED'`.

#### `PaymentResult`[​](#paymentresult "Direct link to paymentresult")

| Property           | Type      | Description                            |
| ------------------ | --------- | -------------------------------------- |
| `transactionId`    | `string`  | MONEI transaction ID                   |
| `success`          | `boolean` | Whether the payment was approved       |
| `amount`           | `number`  | Payment amount in cents                |
| `cardBrand`        | `string`  | Card brand (e.g. `visa`, `mastercard`) |
| `maskedCardNumber` | `string`  | Masked card number (e.g. `****1234`)   |

#### Error Codes[​](#error-codes "Direct link to Error Codes")

| Code                     | Description                                                                        |
| ------------------------ | ---------------------------------------------------------------------------------- |
| `NOT_INSTALLED`          | MONEI Pay or CloudCommerce not installed                                           |
| `PAYMENT_IN_PROGRESS`    | Another payment is already active                                                  |
| `PAYMENT_FAILED`         | Payment declined or failed                                                         |
| `PAYMENT_TIMEOUT`        | No response in time (iOS)                                                          |
| `CANCELLED`              | User cancelled                                                                     |
| `INVALID_PARAMS`         | Invalid input parameters                                                           |
| `INVALID_CALLBACK_URL`   | `callbackUrl` is not strict https or exceeds 2048 chars                            |
| `INVALID_COMPLETE_URL`   | `complete_url` (from `completeScheme`) uses a blocked scheme or exceeds 2048 chars |
| `INVALID_TOKEN`          | Auth token invalid or malformed                                                    |
| `TOKEN_EXPIRED`          | Auth token has expired (>24h)                                                      |
| `NOT_AUTHENTICATED`      | No token and user is not signed into MONEI Pay                                     |
| `ACCOUNT_NOT_CONFIGURED` | MONEI Pay account is missing required POS configuration                            |
| `FAILED_TO_OPEN`         | Could not open MONEI Pay (iOS)                                                     |

## Example app[​](#example-app "Direct link to Example app")

The [`example/`](https://github.com/MONEI/monei-pay-react-native-sdk/tree/master/example) directory contains a merchant demo app. From that folder run `npm install`, then `npx expo run:ios` or `npx expo run:android`.

note

NFC is not available in simulators or emulators — use a physical device.
