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

@ivorypay/node-sdk

v1.0.0

Published

Official Node.js SDK for the IvoryPay Merchant API

Readme

IvoryPay Node.js SDK

Official Node.js SDK for the IvoryPay Merchant API. Accept crypto and fiat payments, send payouts, query rates, and verify webhooks — all with full TypeScript support.


Table of Contents


Installation

npm install @ivorypay/node-sdk
# or
yarn add @ivorypay/node-sdk

Quick Start

import { IvoryPay } from '@ivorypay/node-sdk';

const ivorypay = new IvoryPay({
  secretKey: process.env.IVORYPAY_SECRET_KEY,
});

// Accept a crypto payment
const { data } = await ivorypay.transactions.create({
  amount: 5000,
  baseFiat: 'NGN',
  token: 'USDT',
  channel: 'CRYPTO',
  network: 'BSC_MAINNET',
  reference: 'order_abc123',
  email: '[email protected]',
});

console.log(data.collectionDetails); // { network, address }
console.log(data.amountInCrypto);    // amount customer should send
console.log(data.expiresAt);         // session expiry

Configuration

const ivorypay = new IvoryPay({
  secretKey: 'sk_test_xxxxxxxxxxxx', // required
  baseUrl: 'https://api.ivorypay.io/api', // optional — override for local testing
});

| Option | Type | Required | Description | | ----------- | -------- | -------- | --------------------------------------------------------------- | | secretKey | string | Yes | Your secret API key from the IvoryPay dashboard | | baseUrl | string | No | Override the API base URL. Defaults to https://api.ivorypay.io/api |


Authentication

IvoryPay uses secret API keys for authentication. Your key is sent directly in the Authorization header — no Bearer prefix.

Authorization: sk_test_xxxxxxxxxxxx
  • Keys prefixed with sk_test_ point to the TEST (sandbox) environment
  • Keys prefixed with sk_live_ point to the LIVE (production) environment

Security: Never expose your secret key in frontend code, version control, or logs. Always load it from environment variables.


Modules

Transactions (Accept Payments)

Create payment requests and let customers pay with crypto or fiat.

ivorypay.transactions.create(input)

// CRYPTO payment
const { data } = await ivorypay.transactions.create({
  amount: 5000,          // amount in baseFiat
  baseFiat: 'NGN',       // NGN or USD
  token: 'USDT',         // crypto token to accept
  channel: 'CRYPTO',
  network: 'BSC_MAINNET',
  reference: 'order_001', // must be unique per transaction
  email: '[email protected]',
});

// data.collectionDetails => { network, address }
// Share this address with your customer so they can pay

// FIAT payment
const { data } = await ivorypay.transactions.create({
  amount: 5000,
  baseFiat: 'NGN',
  token: 'USDT',
  channel: 'FIAT',
  fiatCurrency: 'NGN',   // currency the customer pays in
  reference: 'order_002',
  email: '[email protected]',
});

// data.collectionDetails => { accountName, accountNumber, bankName }
// Show these bank details to your customer for payment

Input fields:

| Field | Type | Required | Description | | -------------- | -------- | ---------------- | ---------------------------------------------- | | amount | number | Yes | Amount in base fiat | | baseFiat | string | Yes | NGN or USD | | token | string | Yes | USDT or USDC | | channel | string | Yes | CRYPTO or FIAT | | reference | string | Yes | Unique transaction reference | | email | string | Yes | Customer email | | network | string | CRYPTO only | Blockchain network | | fiatCurrency | string | FIAT only | Fiat currency for the payment |


ivorypay.transactions.verify(reference)

Verify the status of any transaction. Useful for polling before webhooks arrive.

const { data } = await ivorypay.transactions.verify('order_001');

console.log(data.status); // PENDING | PROCESSING | CONFIRMING | SUCCESS | FAILED | EXPIRED | MISMATCH

Business Transactions

Verify and manage transactions using your secret key for additional settlement details.

ivorypay.businessTransactions.verify(reference)

const { data } = await ivorypay.businessTransactions.verify('order_001');

console.log(data.settledAmountInCrypto);
console.log(data.receivedAmountInCrypto);
console.log(data.completedAt);

ivorypay.businessTransactions.refresh(reference, fiatCurrency?)

Refresh an expired CRYPTO payment session, extending validity by 10 minutes.

const { data } = await ivorypay.businessTransactions.refresh('order_001', 'NGN');

Crypto Transfer

Send crypto directly to a wallet address.

ivorypay.cryptoTransfer.initiate(input)

const { data } = await ivorypay.cryptoTransfer.initiate({
  amount: 10,             // amount in crypto
  token: 'USDT',
  network: 'BSC_MAINNET',
  address: '0xRecipientWalletAddress',
  reference: 'payout_001', // must be unique
});

Input fields:

| Field | Type | Required | Description | | ----------- | -------- | -------- | ----------------------------- | | amount | number | Yes | Amount in crypto | | token | string | Yes | Token to send | | network | string | Yes | Blockchain network | | address | string | Yes | Recipient wallet address | | reference | string | Yes | Unique payout reference |


ivorypay.cryptoTransfer.getNetworks(token)

const { data } = await ivorypay.cryptoTransfer.getNetworks('USDT');
// data => ['BSC_MAINNET', 'POLYGON', ...]

ivorypay.cryptoTransfer.getSupportedTokens()

const { data } = await ivorypay.cryptoTransfer.getSupportedTokens();

Fiat Transfer

Send fiat to a bank account or mobile money wallet.

ivorypay.fiatTransfer.resolveAccount(input)

Always resolve the account first to verify the recipient before sending funds.

const { data } = await ivorypay.fiatTransfer.resolveAccount({
  accountNumber: '0123456789',
  bankCode: '058',
  currency: 'NGN',
});

console.log(data.accountName); // verify this with your customer

ivorypay.fiatTransfer.initiate(input)

const { data } = await ivorypay.fiatTransfer.initiate({
  amount: 50,             // amount in crypto (debited from wallet)
  token: 'USDT',
  fiatCurrency: 'NGN',   // currency recipient receives
  payoutMethod: 'BANK_TRANSFER',
  accountNumber: '0123456789',
  bankCode: '058',
  reference: 'payout_002',
});

Input fields:

| Field | Type | Required | Description | | --------------- | -------- | -------- | ---------------------------------------- | | amount | number | Yes | Amount in crypto to debit | | token | string | Yes | USDT or USDC | | fiatCurrency | string | Yes | Fiat currency the recipient receives | | payoutMethod | string | Yes | BANK_TRANSFER or MOBILE_MONEY | | accountNumber | string | Yes | Recipient account number | | bankCode | string | Yes | Bank code from getBanks() | | reference | string | Yes | Unique payout reference |


ivorypay.fiatTransfer.getBanks()

const { data } = await ivorypay.fiatTransfer.getBanks();
// data => [{ id, name, code, country, currency }, ...]

Rates

Fetch conversion rates and fee estimates before initiating a transfer. Use these to show your users the exact amounts they will send and receive.

ivorypay.rates.fiatTransfer(input)

const { data } = await ivorypay.rates.fiatTransfer({
  amount: 100,
  token: 'USDT',
  fiatCurrency: 'NGN',
});

console.log(data.rate);               // current exchange rate
console.log(data.platformFeeInFiat);  // IvoryPay fee in fiat
console.log(data.amountInFiatLessFee); // recipient receives this

ivorypay.rates.cryptoTransfer(input)

const { data } = await ivorypay.rates.cryptoTransfer({
  amount: 10,
  token: 'USDT',
  network: 'BSC_MAINNET',
});

console.log(data.gasFeeInCrypto);
console.log(data.platformFeeInCrypto);

ivorypay.rates.fiatCollection(input)

const { data } = await ivorypay.rates.fiatCollection({
  amount: 5000,
  token: 'USDT',
  fiatCurrency: 'NGN',
});

ivorypay.rates.cryptoCollection(input)

const { data } = await ivorypay.rates.cryptoCollection({
  amount: 5000,
  token: 'USDT',
  fiatCurrency: 'NGN',
});

Blockchain Accounts

Create permanent, dedicated blockchain deposit addresses for your customers. Any deposit to these addresses automatically credits your business wallet.

ivorypay.blockchainAccounts.create(input)

const { data } = await ivorypay.blockchainAccounts.create({
  firstName: 'Jane',
  lastName: 'Doe',
  email: '[email protected]',
  blockchain: 'BSC_MAINNET',  // BSC_TESTNET for TEST keys
  token: 'USDT',
  phoneNumber: '+2348012345678', // optional
});

console.log(data.address);      // permanent deposit address
console.log(data.customerId);   // your reference to this customer

Idempotent: Calling this with the same email + blockchain + token returns the existing address rather than creating a new one.

Input fields:

| Field | Type | Required | Description | | ------------- | -------- | -------- | ------------------------------------- | | firstName | string | Yes | Customer first name | | lastName | string | Yes | Customer last name | | email | string | Yes | Customer email (unique identifier) | | blockchain | string | Yes | BSC_MAINNET or POLYGON | | token | string | Yes | USDT or USDC | | phoneNumber | string | No | Customer phone number |


Tokens

ivorypay.tokens.getSupportedTokens()

Get all tokens and networks currently enabled for your business.

const { data } = await ivorypay.tokens.getSupportedTokens();

ivorypay.tokens.getNetworks(token)

const { data } = await ivorypay.tokens.getNetworks('USDT');

Webhooks

IvoryPay sends webhook notifications to your registered URL when transaction events occur.

ivorypay.webhooks.verifySignature(rawBody, signature, secret)

Always verify the webhook signature before processing any event.

Important: Use the raw request body (before any JSON parsing) for verification. With Express, use express.raw() on your webhook route.

import express from 'express';
import { IvoryPay, WebhookPayload } from '@ivorypay/node-sdk';

const ivorypay = new IvoryPay({ secretKey: process.env.IVORYPAY_SECRET_KEY });

app.post(
  '/webhooks/ivorypay',
  express.raw({ type: 'application/json' }),
  (req, res) => {
    const rawBody = req.body.toString();
    const signature = req.headers['x-ivorypay-signature'] as string;

    const isValid = ivorypay.webhooks.verifySignature(
      rawBody,
      signature,
      process.env.IVORYPAY_WEBHOOK_SECRET,
    );

    if (!isValid) {
      return res.status(401).json({ message: 'Invalid signature' });
    }

    const payload = ivorypay.webhooks.parse(rawBody);

    switch (payload.event) {
      case 'cryptoCollection.success':
        // fulfill the order
        await fulfillOrder(payload.data.reference);
        break;
      case 'fiatCollection.success':
        await fulfillOrder(payload.data.reference);
        break;
      case 'cryptoPayout.success':
        // mark payout as completed
        break;
      case 'fiatPayout.failed':
        // handle failed payout
        break;
    }

    res.sendStatus(200); // always return 200 to acknowledge receipt
  },
);

Supported webhook events:

| Event | Description | | ------------------------------- | ----------------------------------------- | | cryptoCollection.success | Crypto payment received successfully | | cryptoCollection.failed | Crypto payment failed | | cryptoCollection.mismatch | Wrong amount received | | fiatCollection.success | Fiat payment received successfully | | fiatCollection.failed | Fiat payment failed | | cryptoPayout.success | Crypto transfer completed | | cryptoPayout.failed | Crypto transfer failed | | fiatPayout.success | Fiat transfer completed | | fiatPayout.failed | Fiat transfer failed | | cryptoSettlement.success | Crypto settlement completed | | fiatSettlement.success | Fiat settlement completed | | swap.success | Swap completed | | swap.failed | Swap failed | | cryptoCollectionRefund.success| Crypto collection refund sent | | fiatCollectionRefund.success | Fiat collection refund sent | | permanentWalletDeposit.success| Deposit to blockchain address received |


Error Handling

All SDK methods throw an IvoryPayError on failure. Always wrap your calls in try/catch.

import { IvoryPay, IvoryPayError } from '@ivorypay/node-sdk';

try {
  const { data } = await ivorypay.transactions.create({ ... });
} catch (error) {
  if (error instanceof IvoryPayError) {
    console.error(error.message);     // human-readable message
    console.error(error.statusCode);  // HTTP status code
    console.error(error.raw);         // full raw API response
  }
}

Common error status codes:

| Status | Meaning | | ------ | --------------------------------------------------- | | 400 | Bad request — check your input fields | | 401 | Unauthorized — invalid or missing API key | | 404 | Resource not found | | 422 | Unprocessable — e.g. duplicate reference | | 500 | Server error — retry with exponential backoff |


TypeScript Support

The SDK is written entirely in TypeScript and ships with full type declarations. All inputs and responses are typed.

import type {
  CreateTransactionInput,
  CreateTransactionResponse,
  InitiateFiatTransferInput,
  WebhookPayload,
  WebhookEvent,
  SupportedToken,
  SupportedNetwork,
  SupportedFiatCurrency,
  TransactionStatus,
  IvoryPayResponse,
} from '@ivorypay/node-sdk';

Supported Values

Tokens

| Value | Description | | ------ | --------------------- | | USDT | Tether USD | | USDC | USD Coin | | BTC | Bitcoin | | ETH | Ethereum | | SOL | Solana |

Networks

| Value | Description | | ------------- | ----------------------- | | BSC_MAINNET | BNB Smart Chain | | BSC_TESTNET | BNB Smart Chain Testnet | | POLYGON | Polygon (MATIC) | | ETH | Ethereum | | TRON | Tron | | SOLANA | Solana | | BITCOIN | Bitcoin |

Fiat Currencies

| Value | Description | | ----- | --------------- | | NGN | Nigerian Naira | | KES | Kenyan Shilling | | GHS | Ghanaian Cedi | | ZAR | South African Rand | | USD | US Dollar |

Transaction Statuses

| Value | Description | | ------------ | --------------------------------------------- | | PENDING | Awaiting payment from customer | | PROCESSING | Payment detected, being confirmed | | CONFIRMING | Awaiting blockchain confirmations | | SUCCESS | Payment confirmed and settled | | FAILED | Payment failed | | EXPIRED | Session expired before payment was received | | MISMATCH | Wrong amount was sent by the customer |


Environments

| Environment | Key Prefix | Description | | ----------- | ----------- | -------------------------------------- | | TEST | sk_test_ | Sandbox — no real funds move | | LIVE | sk_live_ | Production — real transactions |

Always build and test with sk_test_ keys. Switch to sk_live_ only when you are ready to go live.


License

MIT