npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

applepay-rn

v0.0.6

Published

A React Native wrapper around Tap Payments’ Apple Pay iOS SDK, enabling seamless Apple Pay integration in React Native apps.

Readme

ApplePay-RN

A comprehensive React Native bridge to Apple Pay integration that brings native iOS Apple Pay functionality to React Native apps. Simplifies secure payment processing with Apple Pay, including native callback handling and seamless TypeScript support.

Overview

ApplePay-RN provides a complete React Native wrapper around the native Apple Pay iOS framework. It enables React Native developers to integrate Apple Pay payments into their applications with minimal effort while maintaining full access to native payment capabilities.

Key Features:

  • ✅ Native Apple Pay integration for React Native
  • ✅ TypeScript support with full type definitions
  • ✅ Comprehensive callback system for payment events
  • ✅ Flexible configuration options matching native API
  • ✅ Support for multiple payment scenarios (one-time, recurring, deferred)
  • ✅ Automatic native module linking (autolinking)
  • ✅ Example app demonstrating best practices

Requirements

  • React Native: 0.78+
  • iOS: 16.0+ (minimum deployment target)
  • Xcode: 14.0+
  • CocoaPods: For iOS dependency management
  • Node.js: 14.0+
  • Yarn/npm: For JavaScript package management

Installation

1. Install the Package

Using npm:

npm install applepay-rn

Using yarn:

yarn add applepay-rn

2. Install Pod Dependencies

Navigate to the iOS directory and install CocoaPods dependencies:

cd ios
pod install
cd ..

Quick Start

1. Import the Component

import { TapApplePay, type ApplePayConfiguration } from 'applepay-rn';

2. Create Configuration

Define your payment configuration:

const configuration: ApplePayConfiguration = {
  // REQUIRED
  publicKey: "pk_test_******",
  scope: "AppleToken",
  merchant: {
    id: "**********"
  },
  
  // OPTIONAL
  interface: {
    locale: "en",
    theme: "light",
    edges: "curved",
    type: "buy"
  },
  
  // REQUIRED
  customer: {
    name: [
      {
        lang: "en",
        first: "John",
        last: "Smith",
        middle: "David"
      }
    ],
    contact: {
      email: "[email protected]",
      phone: {
        countryCode: "+1",
        number: "5551234567"
      }
    }
  },
  
  // REQUIRED
  acceptance: {
    supportedBrands: ["visa", "masterCard"],
    supportedCards: ["credit", "debit"]
  },
  
  // REQUIRED
  transaction: {
    amount: "20.00",
    currency: "KWD"
  }
};

3. Use the Component

import React, { useCallback } from 'react';
import { View, StyleSheet } from 'react-native';
import { TapApplePay, type ApplePayConfiguration } from 'applepay-rn';

const App = () => {
  const handleReady = useCallback(() => {
    console.log('Apple Pay ready');
  }, []);

  const handleSuccess = useCallback((data: string) => {
    console.log('Payment successful:', data);
  }, []);

  const handleError = useCallback((error: string) => {
    console.log('Payment error:', error);
  }, []);

  const handleCancel = useCallback(() => {
    console.log('Payment canceled');
  }, []);

  return (
    <View style={styles.container}>
      <TapApplePay
        configuration={configuration}
        onReady={handleReady}
        onClick={() => console.log('Button clicked')}
        onSuccess={handleSuccess}
        onError={handleError}
        onCancel={handleCancel}
        onChargeCreated={(data) => console.log('Charge created:', data)}
        onOrderCreated={(data) => console.log('Order created:', data)}
        onMerchantValidation={(data) => console.log('Merchant validation:', data)}
        style={styles.applePayButton}
      />
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    paddingHorizontal: 16,
  },
  applePayButton: {
    height: 100,
  },
});

export default App;

Configuration Parameters

Core Configuration

| Parameter | Description | Required | Type | Example | |-----------|-------------|----------|------|---------| | publicKey | Your Tap public API key for authentication | ✅ | String | "pk_test_********" | | scope | Token scope type ('AppleToken' or 'TapToken') | ✅ | String | "AppleToken" | | merchant | Merchant account information with ID | ✅ | Object | { id: "********" } |

Transaction Configuration (REQUIRED)

const transaction = {
  // REQUIRED: Transaction amount as string
  amount: "20.00",
  
  // REQUIRED: ISO 4217 currency code (e.g., KWD, USD, AED)
  currency: "KWD",
  
  // OPTIONAL: Coupon code for discount
  couponCode: "SAVE10",
  
  // OPTIONAL: Shipping options for the transaction
  shipping: [
    {
      // REQUIRED: Shipping method label
      label: "Standard Shipping",
      // REQUIRED: Shipping description
      detail: "5–7 business days",
      // REQUIRED: Shipping cost
      amount: "1.00",
      // REQUIRED: Unique identifier
      identifier: "std"
    }
  ],
  
  // OPTIONAL: Line items breakdown
  items: [
    {
      // REQUIRED: Item type ('final' or 'pending')
      type: "final",
      // REQUIRED: Item label/description
      label: "Product Order",
      // REQUIRED: Item amount
      amount: "20.00",
      // REQUIRED: Payment timing ('immediate', 'recurring', 'deferred', 'automaticReload')
      paymentTiming: "immediate"
    }
  ]
};

Customer Configuration (REQUIRED)

const customer = {
  // OPTION 1: Use customer ID (if customer already exists in system)
  // id: "cust_123",
  
  // OPTION 2: Provide customer details
  name: [
    {
      // REQUIRED: Language code ('en', 'ar', 'fr')
      lang: "en",
      // REQUIRED: First name
      first: "John",
      // REQUIRED: Last name
      last: "Smith",
      // OPTIONAL: Middle name
      middle: "David"
    }
  ],
  
  // REQUIRED: At least email OR phone (or both)
  contact: {
    // OPTIONAL: Email address (required if phone not provided)
    email: "[email protected]",
    
    // OPTIONAL: Phone number (required if email not provided)
    phone: {
      // REQUIRED IF PHONE PROVIDED: Country code with + prefix
      countryCode: "+1",
      // REQUIRED IF PHONE PROVIDED: Phone number
      number: "5551234567"
    }
  }
};

Interface Configuration (OPTIONAL)

const interfaceConfig = {
  // OPTIONAL: Display language ('en' or 'ar', defaults to 'en')
  locale: "en",
  
  // OPTIONAL: Theme mode ('light', 'dark', or 'dynamic', defaults to 'light')
  theme: "light",
  
  // OPTIONAL: Button edges style ('curved' or 'flat', defaults to 'curved')
  edges: "curved",
  
  // OPTIONAL: Button type ('book', 'buy', 'check-out', 'pay', 'plain', 'subscribe')
  type: "buy"
};

Acceptance Configuration (REQUIRED)

const acceptance = {
  // REQUIRED: Supported card brands/networks
  // Options: 'amex', 'mada', 'masterCard', 'visa', 'chinaUnionPay', 'discover', 'electron', 'jcb', 'maestro'
  supportedBrands: ["visa", "masterCard"],
  
  // REQUIRED: Supported card types
  // Options: 'credit', 'debit'
  supportedCards: ["credit", "debit"],
  
  // OPTIONAL: Supported regions for payments
  // Options: 'LOCAL' (within country), 'REGIONAL' (regional area), 'GLOBAL' (worldwide)
  supportedRegions: ["LOCAL", "REGIONAL"],
  
  // OPTIONAL: Supported countries (ISO 3166-1 alpha-2 codes)
  supportedCountries: ["AE", "KW", "SA", "QA", "BH", "OM", "EG", "JO", "LB"]
};

Features Configuration (OPTIONAL)

const features = {
  // OPTIONAL: Allow coupon code entry (defaults to false)
  supportsCouponCode: true,
  
  // OPTIONAL: Shipping contact fields to collect from user
  // Options: "name" (customer name), "phone" (phone number), "email" (email address)
  // Can be empty array [] to not collect any fields
  shippingContactFields: ["name", "phone", "email"]
};

Component Props

TapApplePay Props

interface TapApplePayProps {
  // Payment configuration object (required)
  configuration: ApplePayConfiguration;
  
  // View style props (optional)
  style?: StyleProp<ViewStyle>;
  
  // Callback when Apple Pay view is ready
  onReady?: () => void;
  
  // Callback when user clicks the Apple Pay button
  onClick?: () => void;
  
  // Callback when payment succeeds
  onSuccess?: (data: string) => void;
  
  // Callback when charge is created
  onChargeCreated?: (data: string) => void;
  
  // Callback when order is created
  onOrderCreated?: (data: string) => void;
  
  // Callback when user cancels payment
  onCancel?: () => void;
  
  // Callback when payment fails
  onError?: (error: string) => void;
  
  // Callback for merchant validation
  onMerchantValidation?: (data: string) => void;
}

Callback Responses

onSuccess Response Example

{
  "id": "tok_4WUP3423199C4Vp18rY9y554",
  "created": 1697656174554,
  "object": "token",
  "type": "CARD",
  "card": {
    "id": "card_U8Wb34231992m7q185g9i558",
    "brand": "VISA",
    "last_four": "4242",
    "exp_month": 2,
    "exp_year": 44
  }
}

onError Response Example

{
  "error": "Payment processing failed"
}

Advanced Usage

Recurring Payments

For subscription or recurring payment scenarios:

const recurringConfig = {
  transaction: {
    items: [
      {
        type: "final",
        label: "Monthly Subscription",
        amount: "9.99",
        paymentTiming: "recurring",
        scheduledPayment: {
          recurringStartDate: new Date().toISOString(),
          recurringIntervalUnit: "month",
          recurringIntervalCount: 1
        }
      }
    ]
  }
};

Deferred Payments

For payments scheduled for a future date:

const deferredConfig = {
  transaction: {
    items: [
      {
        type: "final",
        label: "Product Order",
        amount: "20.00",
        paymentTiming: "deferred",
        scheduledPayment: {
          deferredPaymentDate: new Date(Date.now() + 86400000).toISOString()
        }
      }
    ]
  }
};

Multiple Shipping Options

const shippingConfig = {
  transaction: {
    shipping: [
      {
        label: "Standard",
        detail: "5–7 days",
        amount: "1.00",
        identifier: "std"
      },
      {
        label: "Express",
        detail: "2–3 days",
        amount: "5.00",
        identifier: "exp"
      }
    ]
  }
};

Error Handling

Always implement error handling in your callbacks:

const handleError = (errorData: string) => {
  try {
    const error = JSON.parse(errorData);
    if (error.error) {
      const { code, message } = error.error;
      console.error(`Error ${code}: ${message}`);
      // Handle error appropriately
    }
  } catch (e) {
    console.error('Failed to parse error:', errorData);
  }
};

Example Application

A complete example application is included in the example folder demonstrating:

  • Basic Apple Pay integration with configuration management
  • Multiple screens: MainScreen (overview), SimpleScreen (minimal example), SettingsScreen (dynamic configuration)
  • Real-time event logging and console output
  • Multiple payment scenarios (one-time, recurring, shipping options)
  • Error handling and success callbacks
  • Standalone example component (StandaloneSimpleExample) for quick copy-paste integration

Running the Example App

Navigate to the example directory and run:

yarn 
yarn example ios

Example Screens

  1. MainScreen - Main navigation and quick test
  2. SimpleScreen - Minimal implementation example
  3. SettingsScreen - Dynamic configuration editor
  4. StandaloneSimpleExample - Fully self-contained component (copy-paste ready)

Native Dependency

This library wraps the native ApplePay-iOS module. The native bridge handles:

  • Native Apple Pay sheet presentation
  • Payment processing
  • Merchant validation
  • Native callback bridging to React Native

For detailed native implementation, see: ApplePay-iOS

Security Considerations

Best Practices:

  • Never expose your secret keys in your app (only use public keys)
  • Always validate payment responses on your backend
  • Use HTTPS for all communication
  • Never log sensitive payment data
  • Keep dependencies updated for security patches
  • Use TypeScript for type-safe payment configurations

Troubleshooting

Apple Pay not appearing

  • Ensure you're testing on a physical iOS device with Apple Pay configured
  • Verify your merchant identifier is correct
  • Check that your app signing certificate is properly configured
  • Ensure Apple Pay is enabled in Xcode capabilities

Payment failures

  • Verify your Tap API keys are correct
  • Check that your public key corresponds to your merchant account
  • Ensure the device has Apple Pay set up
  • Verify the transaction amount is valid

Configuration errors

  • Validate all required fields are present in the configuration object
  • Check for typos in parameter keys (they are case-sensitive)
  • Ensure currency codes are valid ISO 4217 codes
  • Use TypeScript to catch configuration errors at compile time

Build issues

  • Run pod install in the ios directory after adding the package
  • Clear build cache: cd ios && rm -rf Pods && pod install
  • For autolinking issues, verify your React Native version is 0.60+

Support & Documentation

License

MIT License - See LICENSE file for details

Contributing

We welcome contributions! Please feel free to submit pull requests with bug fixes, feature additions, or documentation improvements.

Version History

0.0.3

  • Initial release
  • React Native bridge to Apple Pay iOS
  • TypeScript support
  • Comprehensive callback system
  • Example app

Built with ❤️ by Tap Payments