Checkout & Pay button
The fastest way to get paid — a hosted, branded payment page and a one-line embeddable Pay button. No card or PIN data ever touches your servers, and a single rail powers the button, programmatic checkout and shareable Payment Links.
Drop-in Pay button
Add the script once, then any element with data-pesabridge becomes a Pay button. It uses your publishable key (pk_…) — your secret stays on your server.
<script src="https://<your-operator>/api/bridgepay/v1/pesabridge.js"></script>
<button data-pesabridge
data-key="pk_live_xxx"
data-amount="250"
data-ref="INV-1001"
data-success="https://your-site.com/thank-you">
Pay with PesaBridge
</button>Or open it from your code
PesaBridge.checkout({
key: "pk_live_xxx",
amount: 250,
reference: "INV-1001",
success_url: "https://your-site.com/thank-you"
});Create a session / Payment Link (server-side)
Create a checkout from your backend (publishable key, or a Bearer token). The returned url is a complete Payment Link — share it in WhatsApp, an email, or behind a QR code.
cURL
curl -X POST https://<your-operator>/api/bridgepay/v1/checkout/create \
-H "Content-Type: application/json" \
-d '{"key":"pk_live_xxx","amount":250,"reference":"INV-1001",
"success_url":"https://your-site.com/thank-you"}'
# -> { "status":"ok", "data":{ "checkout_id":"cs_...", "url":"https://.../pay/cs_..." } }Node.js
const r = await fetch(`${base}/checkout/create`, {
method: "POST", headers: { "Content-Type": "application/json" },
body: JSON.stringify({ key: PUBLISHABLE_KEY, amount: 250,
reference: "INV-1001", success_url: "https://your-site.com/thank-you" }),
});
const { url } = (await r.json()).data; // redirect the customer hereRequest fields
Field | Type | Required | Description |
|---|---|---|---|
key | string | yes* | Publishable key ( |
amount | number | yes | Amount to collect, > 0. |
reference | string | no | Your order/invoice reference, echoed back and on the webhook. |
success_url | string | no | Where the customer is sent after a successful payment. |
cancel_url | string | no | Where to send them if they abandon the payment. |
The flow
The button/your server creates a checkout session and opens its hosted
url.On the branded page the customer enters their phone and approves a prompt-to-pay with their PIN.
On success they're redirected to
success_url, and your webhook firescharge.completedfor reconciliation.
Status
The hosted page polls automatically, but you can also read a session's status:
curl "https://<your-operator>/api/bridgepay/v1/pay/cs_.../status"
# -> { "status":"ok", "data":{ "status":"completed", "charge_ref":"STK0000123" } }Session status | Meaning |
|---|---|
open | Created; the customer hasn't paid yet. |
processing | Prompt sent; awaiting approval. |
completed | Paid — money settled to your account. |
expired | The link timed out (30 minutes). |
failed | The prompt was declined or failed. |
Zero PCI surface
Because the payment happens on the hosted page, sensitive details never reach your servers — you only handle the success_url redirect and the signed webhook.

