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

valuepay-react-native

v2.0.0

Published

Official react-native package for the value payment solution provider service

Readme

valuepay-react-native

Official React Native SDK for the Valuepay Payment Gateway. Provides a secure, drop-in payment modal for accepting payments in your React Native application.

Table of Contents

Features

  • Secure WebView-based payment modal with HTTPS-only communication
  • Supports 6 payment channels: Card, USSD, Bank Transfer, Mobile Money, QR Code, OPay
  • 13 supported currencies across Africa and internationally
  • Full TypeScript support with strict type definitions
  • Built-in payment validation with detailed error reporting
  • Tree-shakeable ESM output
  • Compatible with iOS, Android, and Expo projects
  • Minimal dependencies

Requirements

| Dependency | Version | |---|---| | React Native | >= 0.73.0 | | React | >= 18.0.0 | | react-native-webview | >= 13.13.5 |

Installation

Install the package and its peer dependency:

# npm
npm install valuepay-react-native react-native-webview

# yarn
yarn add valuepay-react-native react-native-webview

iOS

Install CocoaPods dependencies after adding the package:

cd ios && pod install

Expo

If using Expo, install the compatible WebView package:

npx expo install react-native-webview

Quick Start

import { useState } from 'react';
import { Button, View, StyleSheet, Alert } from 'react-native';
import {
  ValuepayReactNative,
  validatePaymentProp,
  PaymentProp,
  ReturnObject,
} from 'valuepay-react-native';

const App = () => {
  const [isPaymentVisible, setPaymentVisible] = useState(false);

  const paymentDetails: PaymentProp = {
    publicKey: 'YOUR_PUBLIC_KEY', // from https://developer.valuepayng.com/
    transactionRef: 'TX_' + Date.now().toString(),
    amount: 5000, // amount in kobo (5000 kobo = 50 NGN)
    currency: 'NGN',
    customer: {
      email: '[email protected]',
    },
    onSuccess: (response: ReturnObject) => {
      console.log('Payment successful:', response);
      setPaymentVisible(false);
      // Verify payment on your backend using response.transaction_id
    },
  };

  const handlePay = () => {
    if (validatePaymentProp(paymentDetails)) {
      setPaymentVisible(true);
    } else {
      Alert.alert('Error', 'Invalid payment configuration');
    }
  };

  return (
    <View style={styles.container}>
      <Button title="Pay Now" onPress={handlePay} />
      {isPaymentVisible && (
        <ValuepayReactNative
          payment={paymentDetails}
          isVisible={isPaymentVisible}
        />
      )}
    </View>
  );
};

const styles = StyleSheet.create({
  container: { flex: 1, justifyContent: 'center', alignItems: 'center' },
});

export default App;

API Reference

ValuepayReactNative

The main payment modal component.

<ValuepayReactNative payment={paymentDetails} isVisible={isPaymentVisible} />

| Prop | Type | Required | Description | |---|---|---|---| | payment | PaymentProp | Yes | Payment configuration object | | isVisible | boolean | Yes | Controls modal visibility |

Note: Conditionally render the component ({isVisible && <ValuepayReactNative ... />}) for optimal performance. The component unmounts and cleans up when hidden.


PaymentProp

Configuration object for payment details. Passed to the payment prop of ValuepayReactNative.

Required Fields

| Field | Type | Description | |---|---|---| | publicKey | string | Your Valuepay public key from developer.valuepayng.com | | transactionRef | string | Unique transaction reference. Must be unique per payment attempt | | amount | number | Payment amount in the smallest currency unit (e.g. kobo for NGN). Must be greater than 0 | | customer | Customer | Customer information (see below) | | onSuccess | (response: ReturnObject) => void | Called when payment completes successfully |

Optional Fields

| Field | Type | Default | Description | |---|---|---|---| | currency | currencyTypes | 'NGN' | Payment currency. See Supported Currencies | | channels | PaymentChannel[] | All enabled | Payment methods to display. See Payment Channels | | type | string | 'default' | Checkout type | | redirectUrl | string | 'https://example.com' | URL the checkout page redirects to after payment | | callback | (response: ReturnObject) => void | - | Called on payment failure or unknown status | | onCancelled | (response: ReturnObject) => void | - | Called when the user cancels payment | | onAborted | (response: ReturnObject) => void | - | Called on payment error or abort | | onClosed | (response: ReturnObject) => void | - | Called when the payment modal is closed | | customisedCheckout | Customizations | - | Checkout branding options (see below) | | metaData | Record<string, unknown> | - | Custom key-value metadata attached to the transaction |

Customer Object

| Field | Type | Required | Description | |---|---|---|---| | email | string | Yes | Customer's email address | | fullName | string | No | Customer's full name | | phone | string | No | Customer's phone number (E.164 format recommended) |

Customizations Object

| Field | Type | Required | Description | |---|---|---|---| | title | string | No | Checkout page title | | description | string | No | Payment description shown to the customer | | logoLink | string | No | URL to your brand logo displayed on the checkout page |


ReturnObject

Response object passed to all callback handlers.

| Field | Type | Description | |---|---|---| | status | statusType | Payment status (see table below) | | tx_ref | string | Your transaction reference | | transaction_id | string? | Valuepay's unique transaction identifier | | message | string? | Human-readable status message |

Status Values

| Status | Description | Callback | |---|---|---| | 'successful' | Payment completed successfully | onSuccess | | 'completed' | Payment completed successfully | onSuccess | | 'success' | Payment completed successfully | onSuccess | | 'cancelled' | User cancelled the payment | onCancelled | | 'aborted' | Payment encountered an error | onAborted | | 'closed' | User closed the payment modal | onClosed | | 'unknown' | Unable to determine payment status | callback |


Validation

Two validation functions are available for checking payment configuration before initiating a transaction.

validatePaymentProp(payment: PaymentProp): boolean

Returns true if the payment configuration is valid. Use this for simple pass/fail checks.

import { validatePaymentProp } from 'valuepay-react-native';

if (validatePaymentProp(paymentDetails)) {
  setPaymentVisible(true);
}

validatePaymentPropDetailed(payment: PaymentProp): ValidationResult

Returns a detailed validation result with specific error messages. Use this when you need to display validation errors to the user or for debugging.

import { validatePaymentPropDetailed } from 'valuepay-react-native';

const result = validatePaymentPropDetailed(paymentDetails);
if (!result.valid) {
  console.log('Validation errors:', result.errors);
  // ['amount is required and must be a positive number', 'customer.email is required']
}

ValidationResult

| Field | Type | Description | |---|---|---| | valid | boolean | Whether the payment configuration is valid | | errors | string[] | List of validation error messages (empty if valid) |

Validation rules applied:

  • publicKey must be a non-empty string
  • transactionRef must be a non-empty string
  • amount must be a positive number
  • customer.email must be a valid email address
  • channels (if provided) must only contain valid payment channel values

Payment Channels

Restrict which payment methods are shown by passing a channels array. If omitted, all channels enabled on your merchant dashboard are displayed.

| Channel | Value | Description | |---|---|---| | Card | 'card' | Credit and debit card payments | | USSD | 'ussd' | USSD banking (Nigeria) | | Bank Transfer | 'transfer' | Direct bank transfer | | Mobile Money | 'mobile' | Mobile money providers | | QR Code | 'qrcode' | Scan-to-pay QR code | | OPay | 'opay' | OPay digital wallet |

// Only show card and bank transfer options
const paymentDetails: PaymentProp = {
  // ...
  channels: ['card', 'transfer'],
};

Supported Currencies

| Code | Currency | |---|---| | NGN | Nigerian Naira | | USD | United States Dollar | | EUR | Euro | | GBP | British Pound Sterling | | GHS | Ghanaian Cedi | | ZAR | South African Rand | | KES | Kenyan Shilling | | UGX | Ugandan Shilling | | TZS | Tanzanian Shilling | | RWF | Rwandan Franc | | MWK | Malawian Kwacha | | XAF | Central African CFA Franc | | XOF | West African CFA Franc |

Payment Flow

1. Configure PaymentProp with your public key and transaction details
                          |
2. Call validatePaymentProp() to verify configuration
                          |
3. Set isVisible to true to display the payment modal
                          |
4. User completes payment on the Valuepay checkout page (WebView)
                          |
5. SDK parses the payment response from the redirect URL
                          |
6. Appropriate callback fires (onSuccess / onCancelled / onAborted / onClosed / callback)
                          |
7. Your app dismisses the modal (set isVisible to false)
                          |
8. IMPORTANT: Verify the payment on your backend server
   using the transaction_id and tx_ref from the response

Backend verification is mandatory. Never rely solely on the client-side callback to confirm payment. Use the Valuepay Verify API with transaction_id and your secret key to confirm the payment status and amount on your server.

Advanced Usage

Detailed Validation

Display specific validation errors to help users correct their input:

import { validatePaymentPropDetailed } from 'valuepay-react-native';

const handlePay = () => {
  const { valid, errors } = validatePaymentPropDetailed(paymentDetails);

  if (!valid) {
    Alert.alert('Payment Error', errors.join('\n'));
    return;
  }

  setPaymentVisible(true);
};

Custom Metadata

Attach custom data to the transaction for order tracking, analytics, or reconciliation:

const paymentDetails: PaymentProp = {
  // ...required fields
  metaData: {
    orderId: 'ORD-12345',
    productName: 'Premium Subscription',
    customer_mac: 'unique-device-id',
    linkId: 'invoice-456', // required when type is not 'default'
  },
};

Customised Checkout

Brand the checkout page with your company details:

const paymentDetails: PaymentProp = {
  // ...required fields
  customisedCheckout: {
    title: 'Acme Store',
    description: 'Payment for Order #12345',
    logoLink: 'https://yourdomain.com/logo.png',
  },
};

Full Example with All Callbacks

import { useState } from 'react';
import { Button, View, StyleSheet, Alert } from 'react-native';
import {
  ValuepayReactNative,
  validatePaymentPropDetailed,
  PaymentProp,
  ReturnObject,
} from 'valuepay-react-native';

const PaymentScreen = () => {
  const [isPaymentVisible, setPaymentVisible] = useState(false);

  const paymentDetails: PaymentProp = {
    publicKey: 'YOUR_PUBLIC_KEY',
    transactionRef: 'TX_' + Date.now().toString(),
    amount: 10000, // 100 NGN in kobo
    currency: 'NGN',
    channels: ['card', 'transfer', 'ussd'],
    redirectUrl: 'https://yourdomain.com/payment/callback',
    customer: {
      email: '[email protected]',
      fullName: 'Jane Doe',
      phone: '+2341234567890',
    },
    customisedCheckout: {
      title: 'My Store',
      description: 'Order #12345',
      logoLink: 'https://yourdomain.com/logo.png',
    },
    metaData: {
      orderId: '12345',
    },
    onSuccess: (response: ReturnObject) => {
      setPaymentVisible(false);
      Alert.alert('Success', 'Payment completed!');
      // Send response.transaction_id to your backend for verification
    },
    callback: (response: ReturnObject) => {
      setPaymentVisible(false);
      Alert.alert('Failed', response.message || 'Payment failed');
    },
    onCancelled: (response: ReturnObject) => {
      setPaymentVisible(false);
      Alert.alert('Cancelled', 'You cancelled the payment');
    },
    onAborted: (response: ReturnObject) => {
      setPaymentVisible(false);
      Alert.alert('Error', response.message || 'Payment was aborted');
    },
    onClosed: (response: ReturnObject) => {
      setPaymentVisible(false);
      // User closed modal without completing payment
    },
  };

  const handlePay = () => {
    const { valid, errors } = validatePaymentPropDetailed(paymentDetails);
    if (valid) {
      setPaymentVisible(true);
    } else {
      Alert.alert('Validation Error', errors.join('\n'));
    }
  };

  return (
    <View style={styles.container}>
      <Button title="Pay 100 NGN" onPress={handlePay} />
      {isPaymentVisible && (
        <ValuepayReactNative
          payment={paymentDetails}
          isVisible={isPaymentVisible}
        />
      )}
    </View>
  );
};

const styles = StyleSheet.create({
  container: { flex: 1, justifyContent: 'center', alignItems: 'center' },
});

export default PaymentScreen;

Migration from v1.0.x

v1.1.x is backward compatible with v1.0.x. The following changes are additive and require no code modifications:

What changed

  • Callbacks are now optional (except onSuccess). Previously all 5 callbacks (onSuccess, callback, onCancelled, onAborted, onClosed) were required. Now only onSuccess is required. Existing code passing all callbacks continues to work.
  • channels is now typed as PaymentChannel[] instead of string[]. Valid string values are unchanged, but TypeScript will now catch typos at compile time.
  • metaData is now typed as Record<string, unknown> instead of object for better type safety.
  • Currency type 'US' corrected to 'USD'. If you were using 'US', update to 'USD'.
  • New validatePaymentPropDetailed() function for detailed error reporting alongside the existing validatePaymentProp().
  • New exported types: ValidationResult, PaymentChannel, currencyTypes.
  • Validation now checks publicKey, amount > 0, and email format in addition to the existing checks.
  • Production logging removed. Console output is now gated behind __DEV__ and will not appear in release builds.
  • WebView debugging disabled in production. Chrome DevTools attachment is now restricted to development builds only.

Breaking changes

  • If you were using the currency code 'US', change it to 'USD'.

Security

This SDK is designed with payment security in mind:

  • HTTPS only — All communication with Valuepay servers uses HTTPS. Mixed content is blocked.
  • No secrets in client code — Only your public key is used client-side. Payment verification must happen on your backend with your secret key.
  • WebView debugging disabled in production — Chrome DevTools cannot attach to the payment WebView in release builds.
  • No production logging — Payment URLs and navigation data are not logged in production builds.
  • Server-side verification required — Always verify payments on your backend. See the Valuepay API documentation for verification endpoints.

Exports

All public exports from the package:

import {
  // Component
  ValuepayReactNative,

  // Validation
  validatePaymentProp,
  validatePaymentPropDetailed,

  // Types
  PaymentProp,
  ReturnObject,
  ValidationResult,
  PaymentChannel,
  currencyTypes,
} from 'valuepay-react-native';

Contributing

See the contributing guide to learn how to contribute to the repository and the development workflow.

Support

License

MIT


Made with create-react-native-library