Skip to main content
PaymentFlowManager is the top-level component that renders the complete TapRails payment experience. It handles all UI states, NFC operations, and API calls internally.

Import

import { PaymentFlowManager } from '@taprails/tap-to-pay';

Usage

{showFlow && (
  <PaymentFlowManager
    config={{
      type: 'merchant',         // or 'customer'
      onComplete: (data) => {}, // called on success
      onCancel: () => {},       // called when user cancels
      onError: (err) => {},     // called on error
    }}
    onMerchantCancel={() => setShowFlow(false)}
  />
)}

Props

config
PaymentFlowConfig
required
Configuration object that controls which flow to render and how to handle events.
onMerchantCancel
() => void
Called when the merchant cancels the flow. Used to unmount the component. Required when config.type === 'merchant'.
onCustomerCancel
() => void
Called when the customer cancels the flow. Required when config.type === 'customer'.

PaymentFlowConfig

interface PaymentFlowConfig {
  type: 'merchant' | 'customer';
  onComplete?: (data: MerchantFlowData | CustomerFlowData) => void;
  onCancel?: () => void;
  onError?: (error: Error) => void;
}
type
'merchant' | 'customer'
required
Determines which payment flow to render. 'merchant' shows the amount input + HCE waiting screen. 'customer' shows the tap instruction + processing screens.
onComplete
(data) => void
Called when the payment flow completes successfully. Receives MerchantFlowData or CustomerFlowData depending on the flow type.
onCancel
() => void
Called when the user explicitly cancels the flow.
onError
(error: Error) => void
Called when an unrecoverable error occurs. The component remains mounted with an error screen — call your cancel handler from here to unmount if needed.

Callback Data Types

MerchantFlowData (onComplete for merchant)

interface MerchantFlowData {
  amount?: string;
  merchantId?: string;
  paymentRequest?: PaymentRequest;
  txHash?: string;
  error?: Error;
}

CustomerFlowData (onComplete for customer)

interface CustomerFlowData {
  paymentRequest?: PaymentRequest;
  customerWallet?: string;
  processedPayment?: ProcessPaymentResponse;
  error?: Error;
}

Flow State Machines

Merchant

idle → creating → waiting → success

                  error

Customer

idle → scanning → confirming → processing → success
          ↓                          ↓
        error                      error

Examples

<PaymentFlowManager
  config={{
    type: 'merchant',
    onComplete: ({ paymentRequest }) => {
      analytics.track('payment_received', {
        paymentId: paymentRequest?.paymentId,
      });
      setShowFlow(false);
    },
    onCancel: () => setShowFlow(false),
    onError: (err) => {
      Sentry.captureException(err);
      setShowFlow(false);
    },
  }}
  onMerchantCancel={() => setShowFlow(false)}
/>
PaymentFlowManager renders as a full-screen overlay. Wrap it in a conditional render and toggle visibility via state, rather than using the visible prop pattern.