BirrJS
Concepts

Payment Providers

Integrate payment gateways with the PaymentProvider interface.

BirrJS uses a provider interface to abstract payment gateway logic. Each provider implements the same three methods.

Provider Interface

interface PaymentProvider {
  initializeTransaction(request: TransactionRequest): Promise<TransactionResponse>;
  verifyTransaction(txRef: string): Promise<VerificationResponse>;
  handleWebhook(payload: unknown, rawBody: string | Buffer, headers: Record<string, string>): Promise<WebhookEvent>;
}

TransactionRequest → TransactionResponse

type TransactionRequest = {
  amount: number;       // Minor units (e.g. 2990 = 29.90 ETB)
  currency: string;
  email: string;
  firstName?: string;
  lastName?: string;
  phoneNumber?: string;
  txRef: string;        // Unique transaction reference
  callbackUrl: string;
  returnUrl?: string;
  metadata?: Record<string, string>;
  customization?: {
    title?: string;
    description?: string;
  };
};

type TransactionResponse = {
  success: boolean;
  checkoutUrl?: string;
  paymentInstructions?: PaymentInstructions;
  txRef?: string;
  error?: string;
};

type PaymentChannel = {
  type: "telebirr" | "cbe" | "awash";
  label: string;
  value: string;
  accountHolder?: string;
};

type PaymentInstructions = {
  amount: number;
  channels: PaymentChannel[];
};

Available providers

BirrJS ships with the following provider packages. Each has its own dedicated page with full setup and usage details.

Chapa — redirect-based checkout

import { chapa } from "@birrjs/chapa";

Redirect users to a Chapa checkout page for payment. Supports webhooks, callback URLs, and automatic subscription activation. See the Chapa provider page for configuration, events, and known gaps.

Telebirr — web checkout with QR or OTP

import { telebirr } from "@birrjs/telebirr";

Redirect users to Telebirr's web checkout, where they pay by scanning a QR code with the Telebirr app (or phone + OTP). Signed preOrder requests, server-to-server notify plus a browser redirect — both verified by re-querying the order before activation. See the Telebirr provider page for configuration, the sandbox testing walkthrough, and troubleshooting.

Vodit — receipt-based manual payment

import { vodit } from "@birrjs/vodit";

Display bank account instructions for users to send money directly, then verify via receipt URL. Supports Telebirr, CBE, and Awash. See the Vodit provider page for setup, per-bank parsing details, and recipient verification.

Verify.et — automated receipt verification

import { verifyEt } from "@birrjs/verifyet";

Universal receipt verification via verify.et — detects the bank from any receipt format and checks payments against your configured accounts. See the Verify.et provider page for setup and bank-specific details.

Verify Checkout — hosted checkout

import { verifyCheckout } from "@birrjs/verify-checkout";

Redirect users to Verify Checkout's hosted page, where they pay one of your receiving accounts and submit the transfer reference. Signed webhooks (destination configured in the Verify Checkout dashboard), an obligatory API re-query before activation, and a polling fallback when webhooks aren't set up. See the Verify Checkout provider page for the dashboard setup checklist and sandbox walkthrough.

Switching Providers

Your app code never references the provider directly — all calls go through the PaymentProvider interface. Swapping from Chapa to Vodit means changing one import:

// Before
import { chapa } from "@birrjs/chapa";
// After
import { vodit } from "@birrjs/vodit";

createBirr({
  provider: vodit({
    apiKey: process.env.VODIT_API_KEY!,
    channels: [
      { type: "telebirr", value: "0912345678", name: "Abebe Kebede" },
      { type: "cbe", value: "1000200030004000", name: "Abebe Kebede" },
    ],
  }),
  // Everything else stays the same
  database: process.env.DATABASE_URL,
  plans: [free, pro],
});

Your subscribe(), check(), report(), and webhook handler all work identically regardless of which provider is configured.

Adding a New Provider

Create a new package (e.g. @birrjs/arifpay) with:

  1. A provider factory function that returns PaymentProvider
  2. Types for provider-specific request/response shapes
  3. A Zod schema for webhook payload validation

Chapa, Telebirr, Vodit, Verify.et and Verify Checkout are available now. The provider system is designed to make adding new ones straightforward — planned providers include ArifPay, Santim Pay and more.

On this page

Provider InterfaceTransactionRequest → TransactionResponseAvailable providersChapa — redirect-based checkoutTelebirr — web checkout with QR or OTPVodit — receipt-based manual paymentVerify.et — automated receipt verificationVerify Checkout — hosted checkoutSwitching ProvidersAdding a New Provider