Skip to content

Node.js / TypeScript SDK Stable

Official Node.js SDK, TypeScript-first. Works in ESM + CJS, Bun and Deno compatible.

Installation

bash
npm install @zayono/sdk
bash
pnpm add @zayono/sdk
bash
yarn add @zayono/sdk
bash
bun add @zayono/sdk

Configuration

ts
import { Zayono } from '@zayono/sdk'

const zayono = new Zayono({
  apiKey: process.env.ZAYONO_API_KEY!,
  // baseUrl: 'https://backend.zayono.com/api/v1', // default
  // timeout: 30_000, // ms, default: 30s
  // maxRetries: 3,   // default: 3
})

Initialize a payment

ts
const payment = await zayono.payments.create({
  amount: 5000,
  currency: 'XOF',
  description: 'Premium T-shirt',
  return_url: 'https://your-site.com/success',
  customer: {
    email: 'customer@example.com',
    first_name: 'John',
    last_name: 'Doe',
    phone: '+22990123456',
  },
  operator: 'mtn_bj',
  metadata: {
    order_id: 'ORD-12345',
  },
})

console.log(payment.checkout_url)
// → https://app.zayono.com/checkout/abc123...

The SDK is fully typed — your IDE auto-completes every field and flags invalid types at compile time.

Verify a payment

ts
const payment = await zayono.payments.retrieve('019e5eaf-cb99-7351-a6d5-c219e28534db')

if (payment.status === 'success') {
  // Payment confirmed. Fulfil the order.
}

Initialize a payout

ts
const payout = await zayono.payouts.create({
  amount: 10000,
  currency: 'XOF',
  operator: 'mtn_bj',
  description: 'Refund for order ORD-12345',
  recipient: {
    phone: '+22961000000',
    first_name: 'Adele',
    last_name: 'Akpovi',
  },
})

Verify a webhook signature

Express + raw body parser:

ts
import express from 'express'
import { Zayono } from '@zayono/sdk'

const app = express()
const zayono = new Zayono({ apiKey: process.env.ZAYONO_API_KEY! })

// IMPORTANT: read the RAW body, not parsed JSON.
// The signature is computed on the byte-for-byte raw payload.
app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
  const signature = req.header('x-zayono-signature') ?? ''
  const isValid = zayono.webhooks.verify(
    req.body,
    signature,
    process.env.ZAYONO_WEBHOOK_SECRET!,
  )

  if (!isValid) return res.status(401).send('Invalid signature')

  const event = JSON.parse(req.body.toString())
  switch (event.event) {
    case 'payment.successful': /* ... */ break
    case 'payment.failed':    /* ... */ break
  }

  res.status(200).end()
})

Pagination

Payment / payout listing not exposed on v1

The GET /v1/payments (and GET /v1/payouts) endpoint is not yet exposed on the API key surface. Only unit methods (retrieve, verify) are available. Pagination will be added to the SDK once those endpoints are exposed. In the meantime, check transaction history from the Zayono dashboard.

For customers, GET /v1/customers is exposed — async iteration, the SDK paginates automatically:

ts
for await (const customer of zayono.customers.list({ country: 'BJ' })) {
  console.log(customer.id)
}

Error handling

ts
import {
  ZayonoValidationError,
  ZayonoAuthenticationError,
  ZayonoRateLimitError,
} from '@zayono/sdk'

try {
  const payment = await zayono.payments.create({ /* ... */ })
} catch (err) {
  if (err instanceof ZayonoValidationError) {
    // 422 — err.errors is a Record<string, string[]>
    console.error(err.errors)
  } else if (err instanceof ZayonoAuthenticationError) {
    // 401 — revoked or invalid key
  } else if (err instanceof ZayonoRateLimitError) {
    // 429 — err.retryAfter (in seconds)
  }
}

Compatibility

RuntimeStatus
Node.js 18+Supported
Node.js 20 LTSRecommended
Bun 1.0+Supported
Deno 1.40+Supported (via npm: spec)
Cloudflare WorkersSupported (native fetch)
Vercel EdgeSupported

The SDK uses native fetch when available, with node-fetch as a fallback.

Full reference

Official Zayono API documentation