Socket
Book a DemoInstallSign in
Socket

@cardql/react-native-tap

Package Overview
Dependencies
Maintainers
1
Versions
2
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@cardql/react-native-tap

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

1.0.1
latest
Source
npmnpm
Version published
Weekly downloads
5
25%
Maintainers
1
Weekly downloads
 
Created
Source

@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

npm install @cardql/react-native-tap
# or
yarn add @cardql/react-native-tap

Peer Dependencies

This package requires the following peer dependencies:

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:

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

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:

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:

const readerConfig = {
  discoveryMethod: "localMobile",
  simulated: false,
};

Bluetooth Readers

Connect to certified Bluetooth card readers:

const readerConfig = {
  discoveryMethod: "bluetoothScan",
  simulated: false,
};

Internet Readers

Connect to internet-connected payment terminal readers:

const readerConfig = {
  discoveryMethod: "internet",
  locationId: "your-location-id",
};

Configuration

TapToPayConfig

interface TapToPayConfig {
  merchantID: string;
  currency?: string;
  timeout?: number;
  acceptedCardTypes?: CardType[];
  paymentConfig: PaymentTerminalConfig;
  captureMethod?: "automatic" | "manual";
  customBranding?: {
    primaryColor?: string;
    logo?: string;
    merchantName?: string;
  };
}

PaymentTerminalConfig

interface PaymentTerminalConfig {
  tokenProvider: () => Promise<string>;
  logLevel?: "verbose" | "info" | "warn" | "error";
  simulated?: boolean;
}

CardReaderConfig

interface CardReaderConfig {
  discoveryMethod: "bluetoothScan" | "localMobile" | "internet";
  simulated?: boolean;
  locationId?: string;
  autoConnect?: boolean;
  enableTipping?: boolean;
  skipTipping?: boolean;
}

Payment Flow

  • Initialize: Terminal SDK initializes with your token provider
  • Discover: Find available card readers (automatic or manual)
  • Connect: Connect to a specific reader
  • Create Payment Intent: Initialize payment with amount and currency
  • Collect Payment Method: Reader captures card information
  • Confirm Payment: Process the payment through the payment gateway
  • Complete: Payment is confirmed and receipt is generated

Error Handling

The SDK provides detailed error information:

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:

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:

<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

License

MIT License - see LICENSE file for details.

Keywords

cardql

FAQs

Package last updated on 25 Jun 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

About

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.

  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc

U.S. Patent No. 12,346,443 & 12,314,394. Other pending.