@creofam/verifier
v0.1.3
Published
TypeScript SDK for the Verifier API
Readme
@creofam/verifier
Important: Dashen and CBE Birr (wallet) are currently experiencing issues. Working providers are Telebirr, CBE, and Bank of Abyssinia.
This SDK is built on top of my open-source Verifier API (GitHub): https://github.com/Vixen878/verifier-api
TypeScript SDK for Payment Verification API. It normalizes receipt verification across Ethiopian providers into one predictable shape for app developers.
Disclaimer: This project is not affiliated with the official providers and is a project made by Leul for developers who want to verify receipts from Ethiopian providers.
- Docs:
https://verify.leul.et/docs - Node:
>= 18 - License: MIT
Install
pnpm:
pnpm add @creofam/verifiernpm:
npm install @creofam/verifieryarn:
yarn add @creofam/verifierOverview
- Verify by transaction reference (and for CBE/Abyssinia, also a suffix).
- Get consistent, normalized results regardless of provider-specific JSON.
- Response modes:
normalized(default)rawboth(returns{ normalized, raw })
Client Setup
baseUrldefaults to the official API (https://verifyapi.leulzenebe.pro).- Provide your API key via
apiKey. from (https://verify.leul.et)
import { VerifierClient } from "@creofam/verifier";
const client = new VerifierClient({
// baseUrl optional; defaults to official API base
apiKey: process.env.VERIFIER_API_KEY,
timeoutMs: 12000, // optional
});Quick Start
Telebirr:
const tx = await client.verifyTelebirr({ reference: "CJU5RZ5NM3" });
if (tx.ok) {
console.log(tx.data.status, tx.data.amount);
} else {
console.log("Not verified:", tx.error);
}CBE:
const tx = await client.verifyCBE({ reference: "FT25301XQ1W1", accountSuffix: "16825193" });
if (tx.ok) {
console.log(tx.data.receiverAccount, tx.data.reason);
}Abyssinia:
const tx = await client.verifyAbyssinia({ reference: "FT252195GT6N", suffix: "75434" });
console.log(tx.ok ? tx.data.reason : tx.error);Response Modes
normalized(default): normalized verification resultraw: provider’s raw response (or envelope)both:{ normalized, raw }
// raw
const rawTelebirr = await client.verifyTelebirr({ reference: "CJU5RZ5NM3" }, { mode: "raw" });
// both
const bothCbe = await client.verifyCBE(
{ reference: "FT25301XQ1W1", accountSuffix: "16825193" },
{ mode: "both" },
);
console.log(bothCbe.normalized.ok, bothCbe.raw);Minimal API
new VerifierClient(config)baseUrl?: string— optional; defaults to official API baseapiKey?: string— sent asx-api-keytimeoutMs?: number— optional; aborts requests after N msuserAgent?: stringandheaders?: Record<string, string>— optionalmax429Retries?: numberandretryDelayMs?: number— optional backoff tuning
Methods
verifyTelebirr({ reference }, opts?)verifyCBE({ reference, accountSuffix }, opts?)verifyCBEBirr({ reference }, opts?)— currently experiencing issuesverifyDashen({ reference }, opts?)— currently experiencing issuesverifyAbyssinia({ reference, suffix }, opts?)
Options
opts.mode?: "normalized" | "raw" | "both"
Normalized Shape (high-level)
When tx.ok === true, you’ll typically see:
provider: one oftelebirr,cbe,cbebirr,dashen,abyssiniadata:- Common fields:
reference,amount,currency,payerName,receiverName,txnDate - Provider-specific fields:
- Telebirr:
totalAmount,payerPhone,receiverAccount,statusText,status,serviceFee,serviceFeeVAT - CBE:
payerAccount,receiverAccount,reason - Abyssinia:
payerAccount,reason
- Telebirr:
- Common fields:
raw: attached when usingmode: "both"
When tx.ok === false, you’ll get:
provider: provider nameerror: string describing the reason (e.g., mismatch)
Error Handling
import { VerifierClient, RateLimitError, VerifierError } from "@creofam/verifier";
try {
const tx = await client.verifyTelebirr({ reference: "CJU5RZ5NM3" });
if (!tx.ok) {
console.error("Verification failed:", tx.error);
}
} catch (err: any) {
if (err instanceof RateLimitError) {
console.error("Rate limited:", err.status, err.message);
} else if (err instanceof VerifierError) {
console.error("Verifier error:", err.status, err.message);
} else if (err?.name === "AbortError") {
console.error("Request timed out");
} else {
console.error("Unexpected error", err);
}
}JavaScript Examples
ESM:
import { VerifierClient } from "@creofam/verifier";
const client = new VerifierClient({
// baseUrl: process.env.VERIFIER_BASE_URL, -- Optional
apiKey: process.env.VERIFIER_API_KEY,
});
const res = await client.verifyTelebirr({ reference: "CJU5RZ5NM3" });
console.log(res.ok ? res.data.amount : res.error);CJS:
const { VerifierClient } = require("@creofam/verifier");
const client = new VerifierClient({
// baseUrl: process.env.VERIFIER_BASE_URL, -- Optional
apiKey: process.env.VERIFIER_API_KEY,
});
(async () => {
const tx = await client.verifyAbyssinia({ reference: "FT252195GT6N", suffix: "75434" });
console.log(tx.ok ? tx.data.reason : tx.error);
})();