How to Issue USD Virtual Cards & Stablecoin Top-Ups with the Payscribe Node.js SDK
← Back to blog

How to Issue USD Virtual Cards & Stablecoin Top-Ups with the Payscribe Node.js SDK

7/29/2026Engineering

Virtual cards have become one of the most popular ways for African fintechs and ecommerce platforms to give customers a spendable USD balance without issuing physical plastic. Payscribe's official Node.js/TypeScript SDK makes integrating this feature including cards funded with stablecoins far simpler than hand-building requests against their REST API. This guide walks through installing the SDK, configuring it, and issuing your first virtual card start to finish.

What You Need Before You Start

  • Node.js 18+
  • A Payscribe secret API key

Installing the SDK

npm install @payscribe/sdk

Setting Up Your Environment

Create a .env file in your project and add:

PAYSCRIBE_SECRET_KEY=ps_sk_test_YOUR_SECRET_KEY
PAYSCRIBE_ENVIRONMENT=sandbox
PORT=3000

Choose your environment: "sandbox" | "production"

Each one points to a different address on Payscribe's servers:

Note: If environment is omitted, the SDK defaults to sandbox.

Setting Up the Client

import { Payscribe } from "@payscribe/sdk";

const payscribe = new Payscribe({
  secretKey: process.env.PAYSCRIBE_SECRET_KEY!,
  environment: "sandbox"
});
Note: For internal testing against a custom endpoint, you can override the baseUrl directly:
const payscribe = new Payscribe({
  secretKey: process.env.PAYSCRIBE_SECRET_KEY!,
  baseUrl: "https://sandbox.payscribe.ng/api/v1/"
});

With the client set up, you're ready to start issuing virtual cards.

Virtual Cards

Create Virtual Card

Use this to issue a USD virtual card for an existing Payscribe customer.

const card = await payscribe.virtualCards.create({
  customerId: "customer-uuid",
  currency: "USD",
  brand: "VISA",
  amount: 10,
  type: "virtual",
  reference: "card_ref_123"
});

For a contactless card, include contactless and optional card limits:

const card = await payscribe.virtualCards.create({
  customerId: "customer-uuid",
  brand: "MASTERCARD",
  amount: 25,
  reference: "contactless_card_ref_123",
  contactless: true,
  cardLimits: {
    dailyLimit: 100,
    transactionLimit: 25
  }
});
import type { CreateVirtualCardInput } from "@payscribe/sdk";

const body: CreateVirtualCardInput = {
  customerId: "customer-uuid",
  brand: "VISA",
  amount: 10,
  reference: "card_ref_123"
};

Funding a Virtual Card with Stablecoin

If you'd rather fund the card from an on-chain stablecoin deposit than your Payscribe USD balance, use this instead:

const order = await payscribe.virtualCards.createWithStablecoin({
  customerId: "customer-uuid",
  currency: "USD",
  brand: "VISA",
  amount: 5,
  type: "virtual",
  reference: "stablecoin_card_ref_123",
  stablecoinCurrency: "USDT",
  stablecoinNetwork: "Tron",
  stablecoinChain: "TRC20"
});
Note: Payscribe returns a deposit address and amount. The card is created after the stablecoin deposit is confirmed.

Topping Up a Virtual Card

const result = await payscribe.virtualCards.topUp("card-uuid", {
  amount: 10,
  reference: "topup_ref_123"
});

Or with stablecoins:

const order = await payscribe.virtualCards.topUpWithStablecoin("card-uuid", {
  amount: 10,
  reference: "stablecoin_topup_ref_123",
  stablecoinCurrency: "USDT",
  stablecoinNetwork: "Tron",
  stablecoinChain: "TRC20"
});

Withdrawing from a Virtual Card

const result = await payscribe.virtualCards.withdraw("card-uuid", {
  amount: 5,
  reference: "withdraw_ref_123"
});

Checking a Card and Its Transactions

const card = await payscribe.virtualCards.get("card-uuid");

Get virtual card transactions:

const transactions = await payscribe.virtualCards.transactions("card-uuid", {
  startDate: "2024-07-01",
  endDate: "2024-07-30",
  pageSize: 20,
  page: 1
});

Virtual Card Controls

// Freezing
await payscribe.virtualCards.freeze("card-uuid", {
  reference: "freeze_ref_123"
});

// Unfreezing
await payscribe.virtualCards.unfreeze("card-uuid", {
  reference: "unfreeze_ref_123"
});

// Terminating a card
await payscribe.virtualCards.terminate("card-uuid", {
  reference: "terminate_ref_123"
});

Need to swap the card out or fix a stuck record? There's a method for that too:

await payscribe.virtualCards.replace("card-uuid");
await payscribe.virtualCards.regularize("card-uuid");

Updating a Cardholder's Contact Details

const result = await payscribe.virtualCards.updateContact("card-uuid", {
  email: "john.doe@example.com",
  mobile: "+2348012345678",
  billingDetails: {
    address1: "12 Broad Street",
    address2: "Suite 4",
    city: "Lagos",
    state: "Lagos",
    zipcode: "100001",
    country: "NG"
  }
});

SDK Reference

Full method signatures, typed inputs, and additional configuration options are available in the SDK package itself:

https://www.npmjs.com/package/@payscribe/sdk

Need More Details?

For full endpoint references, request/response schemas, and additional configuration options, check out the official API documentation: [https://docs.payscribe.co]

Need a Hand?

Questions, edge cases, or something not working as expected? Our team's got you reach out at support@payscribe.co