Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/stripe/stripe-terminal-react-native/llms.txt

Use this file to discover all available pages before exploring further.

This guide walks through the complete payment collection flow: creating a PaymentIntent, collecting a payment method from the reader, confirming the payment, and handling errors.

Payment flow overview

1

Create a PaymentIntent

Create a PaymentIntent on your server or directly via the SDK and retrieve it in your app.
2

Collect a payment method

Call collectPaymentMethod to prompt the reader to accept a card or NFC payment.
3

Confirm the payment

Call confirmPaymentIntent (or use processPaymentIntent to combine both steps).
4

Handle the result

Check for errors and update your UI based on the final PaymentIntent status.

Create a PaymentIntent

You can create a PaymentIntent on your server and retrieve it by client secret, or create one directly from the SDK.
Create the PaymentIntent on your backend, then retrieve it in your app using the client secret.
const { retrievePaymentIntent } = useStripeTerminal();

// Fetch the client secret from your server
const response = await fetch('https://your-server.com/create-payment-intent', {
  method: 'POST',
  body: JSON.stringify({ amount: 1000, currency: 'usd' }),
});
const { clientSecret } = await response.json();

const { paymentIntent, error } = await retrievePaymentIntent(clientSecret);

if (error) {
  console.error('Failed to retrieve PaymentIntent:', error.message);
  return;
}

Collect a payment method

Pass the retrieved PaymentIntent to collectPaymentMethod. The reader will wait for a card tap, dip, or swipe.
import type { CollectPaymentMethodParams } from '@stripe/stripe-terminal-react-native';

const { collectPaymentMethod } = useStripeTerminal();

const { paymentIntent: collectedIntent, error } = await collectPaymentMethod({
  paymentIntent,
  skipTipping: false,
  tipEligibleAmount: 1000, // amount eligible for tipping, in cents
  customerCancellation: 'enableIfAvailable',
} satisfies CollectPaymentMethodParams);

if (error) {
  console.error('Collection failed:', error.message);
  return;
}

Tipping

Use skipTipping to bypass the tipping screen entirely, or tipEligibleAmount to specify which portion of the total is tip-eligible.
// Disable tipping
await collectPaymentMethod({ paymentIntent, skipTipping: true });

// Tip-eligible amount differs from the total (e.g., excluding tax)
await collectPaymentMethod({
  paymentIntent,
  skipTipping: false,
  tipEligibleAmount: 800, // $8.00 of a $10.00 total is eligible
});

Dynamic currency conversion

await collectPaymentMethod({
  paymentIntent,
  requestDynamicCurrencyConversion: true,
});

Surcharge notice

Display a surcharge notice on the reader screen before the customer presents their card.
await collectPaymentMethod({
  paymentIntent,
  surchargeNotice: 'A 2% surcharge applies to credit card transactions.',
});

MOTO (mail-order / telephone-order)

For card-not-present transactions, configure motoConfiguration to skip the CVC prompt.
await collectPaymentMethod({
  paymentIntent,
  motoConfiguration: {
    skipCvc: true,
  },
});

Customer cancellation

Control whether the customer can cancel on the reader.
await collectPaymentMethod({
  paymentIntent,
  customerCancellation: 'disableIfAvailable', // 'enableIfAvailable' | 'disableIfAvailable' | 'unspecified'
});

Confirm the payment

Two-step: collect then confirm

import type { ConfirmPaymentMethodParams } from '@stripe/stripe-terminal-react-native';

const { confirmPaymentIntent } = useStripeTerminal();

const { paymentIntent: confirmedIntent, error } = await confirmPaymentIntent({
  paymentIntent: collectedIntent,
} satisfies ConfirmPaymentMethodParams);

if (error) {
  console.error('Confirmation failed:', error.message);
  return;
}

console.log('Payment succeeded, status:', confirmedIntent.status);
// PaymentIntent.Status: 'succeeded' | 'requiresCapture' | 'requiresAction' | ...

Apply a surcharge on confirmation

import type { Surcharge } from '@stripe/stripe-terminal-react-native';

await confirmPaymentIntent({
  paymentIntent: collectedIntent,
  surcharge: {
    amount: 50, // surcharge amount in cents
    consent: {
      notice: 'A $0.50 surcharge has been applied.',
      collection: 'enabled', // 'enabled' | 'disabled'
    },
  } satisfies Surcharge,
});

One-step: processPaymentIntent

processPaymentIntent combines collectPaymentMethod and confirmPaymentIntent into a single call.
import type { ProcessPaymentIntentParams } from '@stripe/stripe-terminal-react-native';

const { processPaymentIntent } = useStripeTerminal();

const { paymentIntent: processedIntent, error } = await processPaymentIntent({
  paymentIntent,
  skipTipping: false,
  tipEligibleAmount: 1000,
  customerCancellation: 'enableIfAvailable',
  requestDynamicCurrencyConversion: false,
  surchargeNotice: 'A surcharge may apply.',
  surcharge: {
    amount: 50,
  },
} satisfies ProcessPaymentIntentParams);

Cancel a payment

If the customer leaves or you need to abort, cancel the PaymentIntent.
const { cancelPaymentIntent, cancelCollectPaymentMethod } = useStripeTerminal();

// Cancel an in-progress collectPaymentMethod call
await cancelCollectPaymentMethod();

// Cancel the PaymentIntent itself
const { paymentIntent: canceledIntent, error } = await cancelPaymentIntent({
  paymentIntent,
});

Manual capture

Create the PaymentIntent with captureMethod: 'manual' to authorize without capturing. Capture separately from your server.
const { paymentIntent } = await createPaymentIntent({
  amount: 1000,
  currency: 'usd',
  captureMethod: 'manual',
});

// After confirmPaymentIntent succeeds, the status will be 'requiresCapture'
// Capture from your server: stripe.paymentIntents.capture(paymentIntent.id)

Track payment status

Call getPaymentStatus to read the current payment status synchronously, or use the onDidChangePaymentStatus callback for reactive updates.
const { getPaymentStatus } = useStripeTerminal({
  onDidChangePaymentStatus: (status) => {
    // 'notReady' | 'ready' | 'processing' | 'waitingForInput'
    console.log('Payment status:', status);
  },
});

const currentStatus = await getPaymentStatus();