Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

@bishaldahal/react-native-khalti-checkout

bishaldahal2kMIT0.2.2TypeScript support: included

React Native/Expo SDK for Khalti Payment Gateway. Accept payments from Khalti, eBanking, mobile banking, and cards in Nepal.

react-native, expo, khalti, payment-gateway, nepal, mobile-payment, react-native, khalti, android, ios, checkout, native-module, example

readme

React Native Khalti Checkout

npm version npm downloads Platform TypeScript License: MIT PRs Welcome

React Native/Expo SDK for Khalti Payment Gateway

Accept payments from Khalti wallet, eBanking, mobile banking, and cards in your Expo applications.

🚀 Quick Start📖 Usage💡 Examples🐛 Issues

🚀 Quick Start

Here's how to get Khalti payments working in your Expo app:

1. Installation

npx expo install @bishaldahal/react-native-khalti-checkout

2. Build Development Client

⚠️ Important: This package requires native code and does not work with Expo Go.

# Create development build
eas build --profile development --platform android

# Or build locally
npx expo run:android

3. Basic Usage

import KhaltiPaymentSdk from "@bishaldahal/react-native-khalti-checkout";

const handlePayment = async () => {
  try {
    const result = await KhaltiPaymentSdk.startPayment({
      publicKey: "your_khalti_public_key",
      pidx: "payment_id_from_backend", // Get this from your server
      environment: "TEST", // Use "PROD" for production
    });
    console.log("Payment successful:", result);
  } catch (error) {
    console.error("Payment failed:", error);
  }
};

That's the basic setup. Jump to detailed setup or see complete example.

✨ Features

  • 🔧 Expo Compatible - Fully tested with Expo SDK 52 & 53 (may work with others)
  • 🚀 Easy Integration - Simple API with TypeScript support
  • 🔒 Secure & Reliable - Built-in validation & error handling
  • ⚡ Real-time Events - Listen to payment events instantly
  • 🌍 Multi-environment - TEST and PROD environments
  • 📱 Native Performance - Uses Khalti's official native SDKs
  • 💾 Memory Safe - Automatic cleanup of event listeners

📋 Prerequisites

Item Requirement Link
Platform Expo SDK 52+ / React Native 0.72+ Expo Docs
OS Support Android 5.0+ (API 21) & iOS 15.1+ -
Node.js Version 16 or higher Download
Khalti Account Merchant account with API keys Test | Prod
Development Expo Development Build Guide

Environment Variables

Variable Description Example Required
KHALTI_PUBLIC_KEY Public key from Khalti dashboard test_public_key_xxxxx
KHALTI_SECRET_KEY Secret key (backend only) test_secret_key_xxxxx ✅ (Backend)

Setup Guide

⚠️ Important: This SDK only works with Expo Development Builds (not Expo Go) and is fully tested with Expo SDK 52 & 53. Compatible with other versions but not guaranteed.

For New Projects

# Create new Expo project with latest SDK
npx create-expo-app@latest MyKhaltiApp --template blank-typescript
cd MyKhaltiApp

# Install Khalti SDK
npx expo install @bishaldahal/react-native-khalti-checkout

# Install development build dependencies
npx expo install expo-dev-client
npm install -g @expo/eas-cli

For Existing Projects

# Install Khalti SDK
npx expo install @bishaldahal/react-native-khalti-checkout

# Install development build dependencies
npx expo install expo-dev-client
npm install -g @expo/eas-cli

Configure Your Project

1. Update app.json/app.config.js:

{
  "expo": {
    "name": "Your App Name",
    "slug": "your-app-slug",
    "version": "1.0.0",
    "platforms": ["android", "ios"],
    "android": {
      "package": "com.yourcompany.yourapp",
      "versionCode": 1,
      "compileSdkVersion": 34,
      "targetSdkVersion": 34,
      "minSdkVersion": 21
    },
    "ios": {
      "bundleIdentifier": "com.yourcompany.yourapp"
    },
    "plugins": ["expo-dev-client"]
  }
}

2. Create development build:

# Setup EAS (first time only)
eas login
eas init

# Build for Android (recommended for testing)
eas build --profile development --platform android

# Install the APK on your device when build completes

3. Start development:

# Start development server
npx expo start --dev-client

# Open on your device with the custom development build

Usage

Complete Payment Implementation

Here's a more complete example with event listeners and error handling:

import React, { useEffect, useState } from "react";
import { View, Button, Alert, Text } from "react-native";
import KhaltiPaymentSdk from "@bishaldahal/react-native-khalti-checkout";

export default function PaymentScreen() {
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    // Set up event listeners
    const successSubscription = KhaltiPaymentSdk.onPaymentSuccess((payload) => {
      console.log("Payment successful:", payload);
      Alert.alert("Success", `Transaction ID: ${payload.txnId}`);
      setLoading(false);
    });

    const errorSubscription = KhaltiPaymentSdk.onPaymentError((payload) => {
      console.log("Payment failed:", payload);
      Alert.alert(
        "Payment Failed",
        payload.error_description || "Unknown error"
      );
      setLoading(false);
    });

    const cancelSubscription = KhaltiPaymentSdk.onPaymentCancel((payload) => {
      console.log("Payment cancelled:", payload);
      Alert.alert("Payment Cancelled", "You cancelled the payment");
      setLoading(false);
    });

    // Cleanup subscriptions
    return () => {
      successSubscription.remove();
      errorSubscription.remove();
      cancelSubscription.remove();
    };
  }, []);

  // WARNING: This should be done from your backend in production
  const createPaymentInBackend = async (amount: number) => {
    // In production, make this API call from your backend server
    const response = await fetch("YOUR_BACKEND_URL/create-khalti-payment", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        amount: amount,
        orderId: `order-${Date.now()}`, // Unique order ID from the backend
        customerInfo: {
          name: "John Doe",
          email: "john@example.com",
          phone: "9800000000",
        },
      }),
    });

    const data = await response.json();
    return data.pidx;
  };

  // Alternative: Frontend payment initiation (FOR DEMO/TESTING ONLY)
  const createPaymentFromFrontend = async (amount: number) => {
    try {
      const response = await fetch(
        "https://a.khalti.com/api/v2/epayment/initiate/",
        {
          method: "POST",
          headers: {
            Authorization: "key test_secret_key_your_secret_key_here", // NEVER do this in production
            "Content-Type": "application/json",
          },
          body: JSON.stringify({
            return_url: "https://example.com/payment/",
            website_url: "https://example.com/",
            amount: amount * 100, // Convert to paisa
            purchase_order_id: `order-${Date.now()}`,
            purchase_order_name: "Test Product",
            customer_info: {
              name: "John Doe",
              email: "john@example.com",
              phone: "9800000000",
            },
          }),
        }
      );

      const data = await response.json();
      if (!response.ok) {
        throw new Error(data.detail || "Payment initialization failed");
      }

      return data.pidx;
    } catch (error) {
      throw new Error(`Failed to create payment: ${error.message}`);
    }
  };

  const handlePayment = async () => {
    setLoading(true);
    try {
      // Option 1: Get pidx from your backend (RECOMMENDED)
      // const pidx = await createPaymentInBackend(100);

      // Option 2: Frontend initiation (DEMO ONLY - NOT for production)
      const pidx = await createPaymentFromFrontend(100);

      // Start payment with Khalti SDK
      await KhaltiPaymentSdk.startPayment({
        publicKey: "test_public_key_your_key_here",
        pidx: pidx,
        environment: "TEST", // Use "PROD" for production
      });
    } catch (error) {
      console.error("Payment error:", error);
      Alert.alert("Error", error.message);
      setLoading(false);
    }
  };

  return (
    <View
      style={{
        flex: 1,
        justifyContent: "center",
        alignItems: "center",
        padding: 20,
      }}
    >
      <Text style={{ fontSize: 18, marginBottom: 20 }}>
        Khalti Payment Demo
      </Text>

      <Button
        title={loading ? "Processing..." : "Pay NPR 100"}
        onPress={handlePayment}
        disabled={loading}
      />

      <Text
        style={{
          marginTop: 20,
          fontSize: 12,
          color: "gray",
          textAlign: "center",
        }}
      >
        Note: This demo includes frontend payment initiation for testing.{"\n"}
        In production, always create payments from your backend server.
      </Text>
    </View>
  );
}

Configuration Options

interface PaymentArgs {
  publicKey: string; // Your Khalti public key
  pidx: string; // Payment identifier from backend
  environment?: "TEST" | "PROD"; // Default: 'TEST'
}

Event Response Types

// Success response
interface PaymentSuccessPayload {
  pidx: string;
  txnId: string;
  amount: number;
  mobile: string;
  status: string;
  timestamp: number;
}

// Error response
interface PaymentErrorPayload {
  error_key: string;
  error_description: string;
  timestamp: number;
}

// Cancel response
interface PaymentCancelPayload {
  reason?: string;
  timestamp: number;
}

Testing

Test Credentials

For testing in the sandbox environment, use these:

Field Value Notes
Khalti ID 9800000000 to 9800000005 Any of these test numbers
MPIN 1111 4-digit PIN
OTP 987654 6-digit verification code

Common Issues & Solutions

"Module not found" error

You need to rebuild your development client after installing the package:

# Clear cache and rebuild
npx expo start --clear
eas build --profile development --platform android --clear-cache

Payment not starting

Check these common issues:

  • Verify your public key is correct
  • Make sure the PIDX is valid and from your backend
  • Check your network connection
  • Validate the environment setting (TEST vs PROD)

Security Best Practices

✅ Do This

  • Use public keys only in mobile apps
  • Create payments from your backend server
  • Verify payments server-side
  • Use HTTPS for all API communications
  • Validate payment status in your backend

❌ Don't Do This

  • Never put secret keys in mobile apps
  • Don't rely only on client-side payment verification
  • Don't store sensitive payment data locally

📱 Platform Support

Platform Status SDK Version Notes
Android Fully Supported API 21+ Works best for testing
iOS Fully Supported iOS 15.1+ Full native SDK integration

Compatibility Matrix

Expo SDK React Native Node.js Status
52-53 0.72+ 16+ Fully Tested
49-51 0.70-0.71 16+ ⚠️ May work
< 49 < 0.70 < 16 ❌ Not supported

📖 API Reference

Core Methods

Method Parameters Returns Description
startPayment(args) PaymentArgs Promise<PaymentSuccessPayload> Initiates payment process
onPaymentSuccess(callback) Function Subscription Listen for successful payments
onPaymentError(callback) Function Subscription Listen for payment errors
onPaymentCancel(callback) Function Subscription Listen for payment cancellations
closePayment() None Promise<void> Closes current payment session

Utility Methods

// Clean up all event listeners
KhaltiPaymentSdk.removeAllListeners();

// Check if SDK is ready
const isReady = KhaltiPaymentSdk.isReady();

Example App

Check out the example application for a complete implementation with:

  • 🔧 Complete configuration setup
  • 💳 Payment flow implementation
  • 🚨 Error handling patterns
  • 🎨 UI integration examples

Run the Example

git clone https://github.com/bishaldahal/react-native-khalti-checkout.git
cd react-native-khalti-checkout/example
npm install
npx expo run:android

🤝 Contributing

We welcome contributions!

How to contribute

# Fork and clone the repository
git clone https://github.com/your-username/react-native-khalti-checkout.git
cd react-native-khalti-checkout
npm install

# Run example app
cd example && npm install && npx expo run:android

Guidelines

  • Follow existing code style
  • Add tests for new features
  • Update documentation when needed
  • Test on real devices when possible

See Contributing Guide for more details.

📞 Support

Need help? Here are your options:

Resource Description Link
📚 Documentation Official Khalti docs docs.khalti.com
🐛 Bug Reports Report issues GitHub Issues
💬 Discussions Community support GitHub Discussions
Email Direct support support@khalti.com

If you find this helpful, consider giving it a star on GitHub!

License

This project is licensed under the MIT License - see the LICENSE file for details.

📋 Third-Party Notices

This package uses the official Khalti Android SDK. See THIRD_PARTY_NOTICES.md for full license information.


🇳🇵 Made with ❤️ for the Nepalese Developer Community

Found this helpful? Give it a ⭐ on GitHub!

GitHub stars GitHub forks

Happy Coding! 🚀

changelog

Changelog

All notable changes to this project will be documented in this file. See standard-version for commit guidelines.

0.2.2 (2025-09-08)

0.2.1 (2025-09-05)

Features

  • example: add icons for example app (09026cc)

Bug Fixes

  • update package name in package.json and package-lock.json for consistency (60fe1ab)

0.2.0 (2025-09-02)

Bug Fixes

  • remove expo-modules-core dependency and update event subscription types (02e1e6d)

0.2.0-beta.5 (2025-07-28)

Features

  • iOS: implement iOS support for Khalti Payment SDK (78b03e9)

0.2.0-beta.4 (2025-07-10)

0.2.0-beta.3 (2025-07-10)

0.2.0-beta.2 (2025-07-10)

0.2.0-beta.1 (2025-07-09)

0.2.0-beta.0 (2025-07-09)

Features

  • implement async functions for closePayment and getPaymentConfig in KhaltiPaymentSdkModule (2469577)

Bug Fixes

  • standardize quotation marks in code examples and improve README clarity (b8385db)

0.1.0 (2025-07-09)

Features

  • Add comprehensive integration examples and configuration for Khalti Payment SDK (392cb80)
  • Add configuration files and update package dependencies for Khalti Payment SDK example (f395931)
  • Add linting script to package.json for improved code quality (edfae89)
  • Add MIT License to Khalti Payment SDK (4a603a4)
  • Add payment identifier to PaymentCancelPayload for improved cancellation tracking (0e12256)
  • Add Prettier configuration file for consistent code formatting (d966c07)
  • Add README for Khalti Payment SDK (c90d0b8)
  • Add THIRD_PARTY_NOTICES.md for Khalti Checkout SDK licensing information (fb2ee8d)
  • Enhance Khalti Payment SDK example with constants and utility functions (e4c44b7)
  • Enhance Khalti Payment SDK with improved validation, error handling, and new utility functions (9b5ef20)
  • Enhance KhaltiPaymentSdkModule with improved error handling and configuration management (0db9e65)
  • Enhance payment cancellation handling with console warning and optional subscription cleanup (69f69d8)
  • Implement centralized logging with AppLogger for payment SDK operations (8bc2e5c)
  • Implement comprehensive payment integration with Khalti SDK, including dynamic configuration and improved user interface (8e766ef)
  • Initialize Khalti Payment SDK for React Native (f718aec)
  • Refactor Khalti Payment SDK with constants, exception handling, and utility functions (6cba710)
  • Refactor payment status messages and reset form values for improved clarity (760bc2c)
  • Remove exclusions for support libraries and add AndroidX dependencies in build.gradle(added initially for compatibility) (71fcf49)
  • Remove IMPLEMENTATION_SUMMARY.md and INTEGRATION_GUIDE.md files (de7b643)
  • Rename package from khaltipaymentsdk to khalticheckout across the project (a139315)
  • Simplify payment cancellation message format (3f8d4c4)
  • Update .gitignore, add CHANGELOG and CONTRIBUTING files, and modify package.json for better project documentation (8e90277)
  • Update Khalti Payment SDK to use new API and improve payment handling (3a39fdb)
  • Update package.json with new version, comprehensive description, and improved metadata (edb8819)
  • Update payment handling to use nullable properties and replace constants with OnMessageEvent references (1e70f96)
  • Update README to reflect package name change and enhance example app documentation (f28eaca)
  • use default expo provided config with some changes (2a92331)
  • v0.1.0: Update package name, version, description, urls and keywords for correct project reference (424ee75)
  • With all payment methods: Implement Khalti Payment SDK with payment handling and event support (9105900)

Bug Fixes

  • Comment out unused KhaltiErrorCode import and remove getVersion method (49bc3be)
  • Update author name in module documentation for KhaltiPaymentSdkModule (ade1d63)
  • update build and test scripts for CI/CD compatibility (1342084)
  • Update Khalti initialization parameters for improved clarity and type safety (712f9b8)

Documentation

  • Revise README.md for improved clarity, features, and installation instructions (c3d4810)

Code Refactoring

  • Clean up code formatting and improve readability in App and constants files (bbaf669)
  • Clean up code formatting and improve validation error messages in payment argument validation (0eaa505)
  • Remove unused web and native view components from Khalti Payment SDK (a904822)

[0.1.0] - 2025-01-09

Added

  • Initial release of React Native/Expo SDK for Khalti Payment Gateway
  • Android support with Khalti's native Android SDK
  • Basic payment functionality with startPayment, closePayment, and getPaymentConfig methods
  • Event-driven architecture with success, error, and cancel events
  • TypeScript support with comprehensive type definitions
  • Input validation and sanitization utilities
  • Environment support (TEST and PROD)
  • Comprehensive error handling with specific error codes
  • Development debugging tools with conditional logging
  • Example application demonstrating integration patterns
  • Detailed documentation and integration guides

Security

  • Secure handling of API keys with environment-based validation
  • Built-in protection against key misuse (test keys in prod, etc.)
  • No storage of sensitive payment data

Dependencies

  • expo-modules-core ^2.4.2
  • Khalti checkout-android SDK integration

Platform Support

  • ✅ Android (API 21+)
  • 🚧 iOS (coming soon)
  • 🚧 Web (planned)

Release Notes Format

Added

For new features.

Changed

For changes in existing functionality.

Deprecated

For soon-to-be removed features.

Removed

For now removed features.

Fixed

For any bug fixes.

Security

In case of vulnerabilities.