BDPayments

A unified payment gateway package for Node.js. One API for Stripe, SSLCommerz, bKash, and Nagad.

Node 18+ TypeScript Zero Config 4 Gateways MIT License

Designed for developers who need to integrate multiple payment providers without writing gateway-specific code. Call charge(), execute(), refund(), or retrieve() — and let BDPayments route to the right adapter internally.

Installation

Install the core package:

npm install bdpayments

Then install only the gateway SDKs you actually use:

# For Stripe (requires its SDK)
npm install stripe

# SSLCommerz, bKash, Nagad
# → No extra SDK needed (uses REST API via fetch)

Configuration

BDPayments supports a three-tier credential system. Use whichever method fits your app — or combine them. Highest priority wins.

1

Per-Call Overrides Highest Priority

Pass credentials directly in any function call. Useful for multi-tenant apps where different merchants have different keys.

2

Global configure() Recommended

Call once at app startup to set credentials for all gateways you use.

3

Environment Variables Zero Config

Set env vars and the package reads them automatically — no code needed.

Global Configure Example

import { configure } from 'bdpayments';

configure({
  stripe: {
    apiKey: process.env.STRIPE_API_KEY,
  },
  bkash: {
    appKey: process.env.BKASH_APP_KEY,
    appSecret: process.env.BKASH_APP_SECRET,
    username: process.env.BKASH_USERNAME,
    password: process.env.BKASH_PASSWORD,
    sandbox: true,
  },
  sslcommerz: {
    storeId: process.env.SSLCOMMERZ_STORE_ID,
    storePassword: process.env.SSLCOMMERZ_STORE_PASSWORD,
    sandbox: true,
  },
});

Per-Call Override Example

import { charge } from 'bdpayments';

// This apiKey overrides whatever was set in configure()
await charge({
  gateway: 'stripe',
  apiKey: 'sk_test_TENANT_B_KEY',
  amount: 1000,
  currency: 'usd',
});

Quick Start

Get up and running in three steps: install, configure, and call.

import { configure, charge, refund, retrieve, execute } from 'bdpayments';

// 1. Configure credentials once
configure({
  stripe: { apiKey: 'sk_test_...' },
  bkash: {
    appKey: '...', appSecret: '...',
    username: '...', password: '...',
    sandbox: true,
  },
});

// 2. Charge — same function, any gateway
const payment = await charge({
  gateway: 'stripe',
  amount: 1000,
  currency: 'usd',
  paymentMethod: 'pm_card_visa',
  confirm: true,
});

console.log(payment.transactionId); // "pi_..."
console.log(payment.status);        // "succeeded"

// 3. Refund
const refundResult = await refund({
  gateway: 'stripe',
  transactionId: payment.transactionId,
  amount: 500,
});

// 4. Retrieve
const details = await retrieve({
  gateway: 'stripe',
  transactionId: payment.transactionId,
});

Supported Gateways

Each gateway is loaded lazily — only the SDK you actually use gets imported at runtime.

Stripe

PaymentIntents API. Supports payment methods, customers, metadata, and confirmations.

API Key SDK Required

SSLCommerz

Bangladesh's leading payment gateway. Session-based checkout with IPN support.

Store ID No SDK Needed

bKash

Tokenized checkout API. Token-grant authentication with create → execute flow.

Token Grant No SDK Needed

Nagad

RSA-encrypted checkout. Two-step initialize → complete with digital signatures.

RSA Encrypted No SDK Needed

Stripe Integration Guide

Complete guide to using Stripe with BDPayments.

Configuration

import { configure } from 'bdpayments';

configure({
  stripe: { apiKey: 'sk_test_...' }
});

Charging

const payment = await charge({
  gateway: 'stripe',
  amount: 1000, // Amount in smallest unit (e.g., cents for USD)
  currency: 'usd',
  paymentMethod: 'pm_card_visa',
  confirm: true,
  description: 'Payment for Order #1234'
});

SSLCommerz Integration Guide

Complete guide to using SSLCommerz with BDPayments.

Configuration

import { configure } from 'bdpayments';

configure({
  sslcommerz: { 
    storeId: '...',
    storePassword: '...',
    sandbox: true 
  }
});

Charging

const payment = await charge({
  gateway: 'sslcommerz',
  amount: 1000,
  currency: 'BDT',
  transactionId: 'TXN-001',
  successUrl: 'https://example.com/success',
  failUrl: 'https://example.com/fail',
  cancelUrl: 'https://example.com/cancel',
  customerName: 'John Doe',
  customerEmail: 'john@example.com'
});
// Use payment.gatewayPageURL to redirect the customer for payment.

bKash Integration Guide

Complete guide to using bKash with BDPayments.

Configuration

import { configure } from 'bdpayments';

configure({
  bkash: { 
    appKey: '...',
    appSecret: '...',
    username: '...',
    password: '...',
    sandbox: true 
  }
});

Charging

const payment = await charge({
  gateway: 'bkash',
  amount: 500,
  invoiceNumber: 'INV-001',
  payerReference: '01700000000',
  callbackURL: 'https://example.com/bkash/callback'
});
// Redirect the customer to payment.bkashURL.

Nagad Integration Guide

Complete guide to using Nagad with BDPayments.

Configuration

import { configure } from 'bdpayments';

configure({
  nagad: { 
    merchantId: '...',
    publicKey: '...',
    privateKey: '...',
    sandbox: true 
  }
});

Charging

const payment = await charge({
  gateway: 'nagad',
  amount: 500,
  orderId: 'ORD-001',
  callbackURL: 'https://example.com/nagad/callback'
});
// Use payment.callBackUrl to redirect customer.

Charge

Create a payment through any gateway. Pass gateway plus the relevant options.

Stripe

const result = await charge({
  gateway: 'stripe',
  amount: 2000,        // $20.00 in cents
  currency: 'usd',
  paymentMethod: 'pm_card_visa',
  confirm: true,
  description: 'Order #1234',
  metadata: { orderId: '1234' },
});

bKash

const result = await charge({
  gateway: 'bkash',
  amount: 500,
  invoiceNumber: 'INV-001',
  payerReference: '01700000000',
  callbackURL: 'https://example.com/bkash/callback',
});

// Redirect customer to result.bkashURL for approval

SSLCommerz

const result = await charge({
  gateway: 'sslcommerz',
  amount: 1000,
  currency: 'BDT',
  transactionId: 'TXN-001',
  successUrl: 'https://example.com/success',
  failUrl: 'https://example.com/fail',
  cancelUrl: 'https://example.com/cancel',
  customerName: 'John Doe',
  customerEmail: 'john@example.com',
});

// Redirect customer to result.gatewayPageURL

Nagad

const result = await charge({
  gateway: 'nagad',
  amount: 500,
  orderId: 'ORD-001',
  callbackURL: 'https://example.com/nagad/callback',
});

// Redirect customer to result.callBackUrl

Refund

Refund a payment. Pass the transactionId from the original charge.

import { refund } from 'bdpayments';

// Full refund
const result = await refund({
  gateway: 'stripe',
  transactionId: 'pi_...',
});

// Partial refund
const partial = await refund({
  gateway: 'stripe',
  transactionId: 'pi_...',
  amount: 500,  // Refund $5.00
});

// bKash refund (requires trxID from execute step)
const bkashRefund = await refund({
  gateway: 'bkash',
  transactionId: 'payment_id',
  trxID: 'trx_id_from_execute',
  amount: 200,
  reason: 'Customer requested',
});

Retrieve / Validate

Retrieve payment details and status from any gateway, or securely validate IPN and success callbacks (e.g. SSLCommerz).

1. Retrieve Payment Details (Stripe, bKash, SSLCommerz, Nagad)

import { retrieve } from 'bdpayments';

const details = await retrieve({
  gateway: 'stripe',
  transactionId: 'pi_...',
});

console.log(details.status);         // "succeeded"
console.log(details.amount);         // 1000
console.log(details.currency);       // "usd"
console.log(details.gatewayResponse); // Raw Stripe response

2. Secure callback / IPN Validation (SSLCommerz)

Use the valId returned in the redirect query/IPN body to securely validate the payment status directly against SSLCommerz servers:

import { retrieve } from 'bdpayments';

const validation = await retrieve({
  gateway: 'sslcommerz',
  valId: 'val_id_received_from_callback',
});

if (validation.success) {
  console.log('Payment validated successfully:', validation.transactionId);
  console.log('Status:', validation.status); // e.g. "VALID" or "VALIDATED"
}

Normalized Response

All functions return a consistent shape regardless of the gateway:

{
  "success": true,
  "transactionId": "pi_...",
  "status": "succeeded",
  "amount": 1000,
  "currency": "usd",
  "gatewayResponse": { /* raw gateway response */ }
}

Execute

Execute a payment through a supported gateway (e.g. bKash tokenized checkout).

import { execute } from 'bdpayments';

const result = await execute({
  gateway: 'bkash',
  paymentID: 'TR0011...',
});

console.log(result.status);         // "Completed"
console.log(result.gatewayResponse); // Raw gateway response

Error Handling

BDPayments provides a structured error hierarchy for precise error handling.

import {
  charge,
  PaymentError,
  GatewayNotFoundError,
  ConfigurationError,
} from 'bdpayments';

try {
  await charge({ gateway: 'stripe', amount: 1000 });
} catch (error) {
  if (error instanceof ConfigurationError) {
    // Missing API keys
    console.log('Missing:', error.missingKeys);
    // → ["apiKey"]
  } else if (error instanceof GatewayNotFoundError) {
    // Unknown gateway name
    console.log('Unsupported gateway');
  } else if (error instanceof PaymentError) {
    // Gateway-specific failure
    console.log(error.gateway);       // "stripe"
    console.log(error.code);          // "CHARGE_FAILED"
    console.log(error.originalError); // Raw SDK error
  }
}
Error Class Code When
PaymentError CHARGE_FAILED / REFUND_FAILED / RETRIEVE_FAILED Gateway API call fails
GatewayNotFoundError GATEWAY_NOT_FOUND Invalid gateway name passed
ConfigurationError MISSING_CREDENTIALS Required API keys are missing

TypeScript Support

Full type definitions are included. Options are narrowed by gateway name using discriminated unions.

import {
  charge,
  configure,
  type ChargeOptions,
  type PaymentResult,
  type GatewayName,
} from 'bdpayments';

// TypeScript knows exactly which fields are valid
const result: PaymentResult = await charge({
  gateway: 'stripe',
  amount: 1000,
  currency: 'usd',
  paymentMethod: 'pm_card_visa',
  // TS will error if you add bkash-specific fields here
});

// Gateway name is a strict union type
const gw: GatewayName = 'bkash'; // ✅
// const gw: GatewayName = 'venmo'; // ❌ Type error

API Reference

Functions

Function Description Returns
configure(configs) Set global credentials for one or more gateways. void
clearConfig() Clear all stored global configuration. void
charge(options) Create a payment/charge through any gateway. Promise<PaymentResult>
refund(options) Refund a previous payment. Promise<RefundResult>
retrieve(options) Retrieve payment details and status. Promise<RetrieveResult>
execute(options) Execute a payment (e.g., bKash tokenized checkout). Promise<PaymentResult>
getSupportedGateways() Returns array of supported gateway names. string[]

Gateway Capabilities

Gateway Charge Execute Refund Retrieve Auth Method SDK
Stripe ✅ PaymentIntents API Key stripe
SSLCommerz ✅ Session Store ID/Password fetch
bKash ✅ Tokenized Token Grant fetch
Nagad ✅ Checkout RSA Encrypted fetch

Environment Variables

Set these environment variables and skip configure() entirely. The package reads them as a fallback when no credentials are provided programmatically.

Gateway Environment Variables
Stripe STRIPE_API_KEY
SSLCommerz SSLCOMMERZ_STORE_ID, SSLCOMMERZ_STORE_PASSWORD, SSLCOMMERZ_SANDBOX
bKash BKASH_APP_KEY, BKASH_APP_SECRET, BKASH_USERNAME, BKASH_PASSWORD, BKASH_SANDBOX
Nagad NAGAD_MERCHANT_ID, NAGAD_PUBLIC_KEY, NAGAD_PRIVATE_KEY, NAGAD_SANDBOX

Example .env file

STRIPE_API_KEY=sk_test_...

BKASH_APP_KEY=your_app_key
BKASH_APP_SECRET=your_app_secret
BKASH_USERNAME=your_username
BKASH_PASSWORD=your_password
BKASH_SANDBOX=true

SSLCOMMERZ_STORE_ID=your_store_id
SSLCOMMERZ_STORE_PASSWORD=your_store_password
SSLCOMMERZ_SANDBOX=true