Node, PHP and Python libraries
Install an official library, create payments, verify webhooks and handle errors in your own language.
The official libraries wrap the API with typed objects, automatic idempotency and retries, cursor pagination and webhook verification. None of them has a runtime dependency.
| Library | Package | Needs |
|---|---|---|
| Node.js | @bezanbecard/node | Node 18 or later (the global fetch); ESM and CommonJS; TypeScript types included |
| PHP | bezanbecard/bezanbecard-php | PHP 7.4 or 8.x with ext-curl and ext-json |
| Python | bezanbecard | Python 3.8 or later, standard library only; type hints with py.typed |
Install
yarn add @bezanbecard/nodeCreate a client
The key decides the mode: sk_test_… sees only test data, sk_live_… only live data. Keep it on your server.
import Bezanbecard from '@bezanbecard/node';
// CommonJS: const { Bezanbecard } = require('@bezanbecard/node');
const bezanbecard = new Bezanbecard(process.env.BEZANBECARD_SECRET_KEY);Methods
The resources and methods are the same in all three. The table names them as Node does: PHP calls the same names with -> ($bezanbecard) and lists with all and deletes with delete; Python spells every name in snake_case (bezanbecard.payment_links.list(), attach_deposit) and deletes with delete.
| Resource | Methods |
|---|---|
payments | create, retrieve, update, list, cancel, topup, attachDeposit, detachDeposit, approve, resolveOverpayment |
receipts | list, retrieve, create, approve, reject |
deposits | list, retrieve, create, ignore, restore |
paymentLinks | create, retrieve, update, list |
customers | create, retrieve, update, list, del |
events | retrieve, list |
webhookEndpoints | create, retrieve, update, list, del |
cards, devices | retrieve, list |
account | retrieve |
testHelpers.deposits | create |
Create and confirm a payment
const payment = await bezanbecard.payments.create({
amount: 12_500_000,
reference: 'order-1042',
customer_details: { name: 'Test Customer', phone: '09900001234' },
return_url: 'https://shop.example/orders/1042/thanks',
});
// redirect to payment.checkout_url; later:
const current = await bezanbecard.payments.retrieve(payment.id);
if (current.status === 'succeeded') fulfilOrder(current.reference);Errors
Every library raises one class per error type, carrying type, code, param, message and the request id.
| Node and Python | PHP | When |
|---|---|---|
InvalidRequestError | InvalidRequestException | 400, 402, 404, 409 |
AuthenticationError | AuthenticationException | 401 |
PermissionError | PermissionException | 403 |
IdempotencyError | IdempotencyException | A reused or busy Idempotency-Key |
RateLimitError | RateLimitException | 429 after the retries |
APIError | ApiErrorException | 5xx after the retries |
ConnectionError (Python: APIConnectionError) | ApiConnectionException | No answer: network or timeout |
SignatureVerificationError | Signature | A webhook failed verification |
import { InvalidRequestError } from '@bezanbecard/node';
try {
await bezanbecard.payments.create({ amount: 500 });
} catch (error) {
if (error instanceof InvalidRequestError && error.code === 'amount_too_small') console.log(error.param, error.requestId);
else throw error;
}The codes are listed in errors.
Retries, idempotency and webhooks
- Every
POSTcarries anIdempotency-Key, reused on retries. Network failures,409idempotency conflicts,429and5xxare retried twice by default with a growing, jittered wait that respectsRetry-After. Pass your own key to stay idempotent across restarts (idempotency). - Lists iterate every page for you (pagination).
constructEvent/Webhook::constructEvent/Webhook.construct_eventverify the signature on the raw body and accept eitherv1during a secret roll (webhooks).
Configuration
| Option | Node | PHP | Python |
|---|---|---|---|
| API version | apiVersion | bezanbecard_version | api_version |
| Base URL | baseUrl | api_base | base_url |
| Timeout | timeout (ms) | timeout, connect_timeout (s) | timeout (s) |
| Retries | maxNetworkRetries | max_network_retries | max_network_retries |
Per-request options (a different key, an idempotency key, a version) go in the last argument of each method, so one process can act for several accounts.