TuagoDevelopers

Node.js

@tuago/node

The official, typed Node/TypeScript SDK. Every resource below maps 1:1 to the REST API, use whichever's easier to reach for.

Install

terminal
npm install @tuago/node
index.ts
import { Tuago } from "@tuago/node";

const tuago = new Tuago({
  secretKey: process.env.TUAGO_SECRET_KEY!, // sk_test_… or sk_live_…
});

tuago.live tells you whether the client was built with a live key, useful for a startup assertion in production code.

tuago.checkout, WhatsApp-native checkout

The flagship flow. Sessions are lazy, create() never touches the bank rail, only the payBy*call the customer's chosen method triggers does.

checkout.ts
await tuago.checkout.create(params, opts?)      // → CheckoutSession
await tuago.checkout.get(id)                     // → CheckoutSession
await tuago.checkout.status(reference)           // → { status, reference }
await tuago.checkout.payByBankTransfer(sessionId) // → BankTransferInstructions
await tuago.checkout.payByUssd(sessionId)         // → UssdInstructions
await tuago.checkout.payByCard(sessionId, params) // → CardPaymentResult, server-side only, PCI scope
example
const session = await tuago.checkout.create({
  amount: 1850000, // kobo
  customerEmail: "buyer@example.com",
  mode: "headless",
  subaccount: "sub_…",        // optional, split settlement
  transactionCharge: 100000,  // optional, your platform cut override, kobo
});

// render session.paymentMethods in chat; once the customer picks one:
const instructions = await tuago.checkout.payByBankTransfer(session.id);

tuago.charges, plain REST charges

charges.ts
await tuago.charges.create(params, opts?) // → Charge
await tuago.charges.get(reference)         // → Charge
await tuago.charges.list(params?)          // → Charge[]
await tuago.charges.verify(reference)      // → Charge
await tuago.charges.requery(reference)     // → Charge (pull missed transfers from the bank rail)
example
const charge = await tuago.charges.create(
  { amount: 1850000, reference: orderId, subaccount: "sub_…", transactionCharge: 100000 },
  { idempotencyKey: orderId }, // safe retries, never double-charge
);
// render charge.virtualAccount in your own UI; confirmation arrives via webhook

tuago.subaccounts, split settlement

For platforms (marketplaces, food-delivery apps, anyone collecting on behalf of vendors). One charge splits automatically between your platform cut and the vendor's own settlement account.

subaccounts.ts
await tuago.subaccounts.create(params)      // → Subaccount, resolves + verifies the vendor's bank account
await tuago.subaccounts.get(id)              // → Subaccount
await tuago.subaccounts.list(params?)        // → Subaccount[]
await tuago.subaccounts.update(id, params)   // → Subaccount
await tuago.subaccounts.settle(id)           // → sweep this subaccount's payable to its bank now

tuago.refunds

refunds.ts
await tuago.refunds.create(params, opts?) // → Refund, full or partial; unwinds every split leg
await tuago.refunds.get(id)                // → Refund
await tuago.refunds.list(params?)          // → Refund[]

Balance, settlements, banks

misc.ts
await tuago.balance.get()                                  // → Balance
await tuago.settlements.list(params?)                       // → Settlement[]
await tuago.settlements.get(id)                              // → Settlement
await tuago.banks.list()                                     // → Bank[]
await tuago.banks.resolve(bankCode, accountNumber)            // → { accountName }

Webhooks helper

webhook-route.ts
import { Tuago } from "@tuago/node";

app.post("/tuago-webhook", (req, res) => {
  const event = Tuago.webhooks.constructEvent(
    req.rawBody, // raw bytes, not the parsed body
    req.headers["x-ollie-signature"],
    endpointSecret,
  );
  if (event.type === "charge.success") { /* confirm the order */ }
  res.sendStatus(200);
});

Full signing details on the Webhooks page.

Errors

try-catch.ts
import { TuagoError } from "@tuago/node";

try {
  await tuago.charges.create({ amount: 1850000 });
} catch (e) {
  if (e instanceof TuagoError) {
    console.log(e.code, e.httpStatus, e.message); // e.g. "merchant_cap_exceeded", 403
  }
}

Every stable code is listed on the Errors page, branch on e.code, not the message text.

Money is always integer minor units (kobo), amount: 1850000 means ₦18,500.00. Never pass floats.