UNPKG

@cardql/react-native-tap

Version:

CardQL SDK for React Native tap-to-pay for secure in-person payments

380 lines (304 loc) 8.98 kB
# @cardql/react-native-tap CardQL SDK for React Native tap-to-pay for secure in-person payments. ## Features - **Payment Terminal Integration**: Built on certified payment infrastructure - **Multiple Reader Support**: Works with certified card readers - **Local Mobile Payments**: Tap-to-phone payments using device NFC (where supported) - **Real-time Processing**: Live payment status and transaction updates - **TypeScript Support**: Fully typed API with comprehensive type definitions - **Error Handling**: Detailed error reporting with user-friendly messages - **Offline Support**: Inherits offline capabilities from @cardql/react-native - **Receipt Generation**: Automatic receipt creation with transaction details ## Installation ```bash npm install @cardql/react-native-tap # or yarn add @cardql/react-native-tap ``` ### Peer Dependencies This package requires the following peer dependencies: ```bash npm install @cardql/react-native-tap react react-native ``` ## Quick Start ### 1. Setup Payment Terminal Provider First, wrap your app with the payment terminal provider and implement a token provider: ```tsx import React from "react"; import { PaymentTerminalProvider } from "@cardql/react-native-tap"; function App() { const fetchTokenProvider = async () => { // Fetch connection token from your backend const response = await fetch(`${API_URL}/connection_token`, { method: "POST", headers: { "Content-Type": "application/json", }, }); const { secret } = await response.json(); return secret; }; return ( <PaymentTerminalProvider logLevel="verbose" tokenProvider={fetchTokenProvider}> {/* Your app components */} </PaymentTerminalProvider> ); } ``` ### 2. Use the TapToPayReader Component ```tsx import React from "react"; import { TapToPayReader } from "@cardql/react-native-tap"; function PaymentScreen() { const fetchTokenProvider = async () => { // Your token provider implementation const response = await fetch(`${API_URL}/connection_token`, { method: "POST", }); const { secret } = await response.json(); return secret; }; const handleSuccess = (result) => { console.log("Payment successful:", result); // Handle successful payment }; const handleError = (error) => { console.error("Payment failed:", error); // Handle payment error }; return ( <TapToPayReader amount="10.00" currency="USD" merchantID="your-merchant-id" userID="user-123" tokenProvider={fetchTokenProvider} onSuccess={handleSuccess} onError={handleError} autoInit={true} autoDiscoverReaders={true} simulated={__DEV__} // Use simulated readers in development /> ); } ``` ### 3. Using the Hook Directly For more control, use the `useTapToPay` hook: ```tsx import React, { useEffect } from "react"; import { useTapToPay } from "@cardql/react-native-tap"; function CustomPaymentFlow() { const fetchTokenProvider = async () => { const response = await fetch(`${API_URL}/connection_token`, { method: "POST", }); const { secret } = await response.json(); return secret; }; const tapToPay = useTapToPay({ config: { merchantID: "your-merchant-id", currency: "USD", paymentConfig: { tokenProvider: fetchTokenProvider, logLevel: "info", simulated: __DEV__, }, }, readerConfig: { discoveryMethod: "localMobile", simulated: __DEV__, }, events: { onReaderDiscovered: (readers) => { console.log("Found readers:", readers.length); }, onReaderConnected: (reader) => { console.log("Connected to reader:", reader.id); }, onPaymentMethodCollected: (paymentMethod) => { console.log("Payment method collected:", paymentMethod.type); }, onSuccess: (result) => { console.log("Payment successful:", result); }, onError: (error) => { console.error("Payment error:", error); }, }, autoInit: true, autoDiscoverReaders: true, }); const handlePayment = async () => { try { const result = await tapToPay.processPayment({ amount: "25.00", currency: "USD", merchantID: "your-merchant-id", userID: "user-123", description: "Coffee and pastry", }); if (result.success) { console.log("Payment completed:", result.payment); } else { console.error("Payment failed:", result.error); } } catch (error) { console.error("Payment processing error:", error); } }; return ( <View> <Text> Status: {tapToPay.isInitialized ? "Ready" : "Initializing..."} </Text> <Text>Readers: {tapToPay.discoveredReaders.length}</Text> <Text>Connected: {tapToPay.connectedReader?.id || "None"}</Text> <Button title="Start Payment" onPress={handlePayment} disabled={!tapToPay.connectedReader || tapToPay.isCollectingPayment} /> </View> ); } ``` ## Reader Types ### Local Mobile (Tap-to-Phone) Use your device's built-in NFC for contactless payments: ```tsx const readerConfig = { discoveryMethod: "localMobile", simulated: false, }; ``` ### Bluetooth Readers Connect to certified Bluetooth card readers: ```tsx const readerConfig = { discoveryMethod: "bluetoothScan", simulated: false, }; ``` ### Internet Readers Connect to internet-connected payment terminal readers: ```tsx const readerConfig = { discoveryMethod: "internet", locationId: "your-location-id", }; ``` ## Configuration ### TapToPayConfig ```tsx interface TapToPayConfig { merchantID: string; currency?: string; timeout?: number; acceptedCardTypes?: CardType[]; paymentConfig: PaymentTerminalConfig; captureMethod?: "automatic" | "manual"; customBranding?: { primaryColor?: string; logo?: string; merchantName?: string; }; } ``` ### PaymentTerminalConfig ```tsx interface PaymentTerminalConfig { tokenProvider: () => Promise<string>; logLevel?: "verbose" | "info" | "warn" | "error"; simulated?: boolean; } ``` ### CardReaderConfig ```tsx interface CardReaderConfig { discoveryMethod: "bluetoothScan" | "localMobile" | "internet"; simulated?: boolean; locationId?: string; autoConnect?: boolean; enableTipping?: boolean; skipTipping?: boolean; } ``` ## Payment Flow 1. **Initialize**: Terminal SDK initializes with your token provider 2. **Discover**: Find available card readers (automatic or manual) 3. **Connect**: Connect to a specific reader 4. **Create Payment Intent**: Initialize payment with amount and currency 5. **Collect Payment Method**: Reader captures card information 6. **Confirm Payment**: Process the payment through the payment gateway 7. **Complete**: Payment is confirmed and receipt is generated ## Error Handling The SDK provides detailed error information: ```tsx interface TapToPayError { code: TapToPayErrorCode; message: string; details?: any; gatewayError?: any; userFriendlyMessage?: string; canRetry?: boolean; suggestedAction?: string; } ``` Common error codes: - `TERMINAL_NOT_SUPPORTED`: Device doesn't support payment terminal - `READER_CONNECTION_FAILED`: Could not connect to card reader - `PAYMENT_COLLECTION_FAILED`: Could not collect payment method - `PAYMENT_CONFIRMATION_FAILED`: Could not confirm payment - `TRANSACTION_DECLINED`: Payment was declined by issuer ## Events Listen to payment flow events: ```tsx const events = { onReaderDiscovered: (readers: Reader[]) => void; onReaderConnected: (reader: Reader) => void; onReaderDisconnected: (reason?: string) => void; onPaymentMethodCollected: (paymentMethod: PaymentMethod) => void; onPaymentIntentCreated: (paymentIntent: PaymentIntent) => void; onDisplayMessage: (message: string) => void; onError: (error: TapToPayError) => void; onSuccess: (result: TapPaymentResult) => void; onCancel: () => void; }; ``` ## Testing ### Simulated Mode Enable simulated mode for testing: ```tsx <TapToPayReader simulated={true} // ... other props /> ``` ### Test Cards In simulated mode, use these test card numbers: - Visa: `4242424242424242` - Mastercard: `5555555555554444` - American Express: `378282246310005` ## Requirements ### iOS - iOS 15.1 or later - NFC-capable device for local mobile payments - Xcode 13 or later ### Android - Android API level 26 (Android 8.0) or later - NFC-capable device for local mobile payments - compileSdkVersion 35 - targetSdkVersion 35 ## Security - All payment data is handled securely by the payment terminal - Card data never touches your application - PCI DSS compliant by design - End-to-end encryption for all transactions ## Support For support with payment terminal integration: - [CardQL Documentation](https://docs.cardql.com) ## License MIT License - see LICENSE file for details.