Developers
Build with Billpay,
step by step.
Everything you need to accept payments in your website or app: how a payment flows, a quickstart with copy-paste code, and a sandbox to test it all safely.
1// Create a payment and send the customer to checkout2const response = await fetch("https://api.billpay.et/v1/payments", {3 method: "POST",4 headers: {5 Authorization: "Bearer " + process.env.BILLPAY_SECRET_KEY,6 "Content-Type": "application/json",7 },8 body: JSON.stringify({9 amount: 2450,10 currency: "ETB",11 reference: "order_1042",12 return_url: "https://yourapp.com/success",13 }),14});1516const payment = await response.json();17console.log(payment.checkout_url);How it works
How a payment flows
through Billpay.
Five steps from your server to a confirmed payment. Your code handles two of them.
- 01Your server
Create a payment
Your server sends the amount and order details to the Billpay API.
- 02Billpay
Get a checkout link
Billpay returns a secure checkout URL for that payment.
- 03Customer
Customer pays
They pick their bank or wallet and confirm on Billpay's checkout page.
- 04Billpay
You're notified
Billpay notifies your server as soon as the payment status changes.
- 05Your server
Verify and deliver
Confirm the status with the API, then fulfil the order.
Quickstart
Your first payment
in six steps.
Follow along in the sandbox. The examples use Node.js, but any language that can send an HTTP request works.
- 1
Get your sandbox keys
Create your Billpay account and request sandbox access. You'll get a secret key for test mode. Store it as an environment variable.
Keep your secret key on your server. Never put it in browser or mobile app code.
.env1# Sandbox: test mode, no real money moves2BILLPAY_API_URL=https://api.billpay.et/v13BILLPAY_SECRET_KEY=your_sandbox_secret_key - 2
Create a payment
When a customer checks out, your server creates a payment with the amount, your own order reference, and where Billpay should send notifications.
create-payment.js1const response = await fetch(process.env.BILLPAY_API_URL + "/payments", {2 method: "POST",3 headers: {4 Authorization: "Bearer " + process.env.BILLPAY_SECRET_KEY,5 "Content-Type": "application/json",6 },7 body: JSON.stringify({8 amount: 2450,9 currency: "ETB",10 reference: "order_1042",11 description: "Order #BP-1042",12 callback_url: "https://yourapp.com/billpay/notify",13 return_url: "https://yourapp.com/orders/1042",14 }),15});1617const payment = await response.json(); - 3
Send the customer to checkout
Redirect the customer to the checkout URL in the response. Billpay's page handles choosing a bank or wallet and confirming the payment.
create-payment.js1// Billpay hosts the checkout page, so no card or wallet details touch your server2res.redirect(payment.checkout_url); - 4
Handle the notification
When the payment status changes, Billpay calls your callback URL. Look up the payment, then update your order.
Reply quickly with 200 OK, and make your handler safe to run twice for the same payment.
notify.js1app.post("/billpay/notify", express.json(), async (req, res) => {2 const { reference } = req.body;34 // Don't trust the notification alone: confirm it with the API5 const payment = await verifyPayment(reference);67 if (payment.status === "completed") {8 await markOrderPaid(reference);9 }1011 res.sendStatus(200);12}); - 5
Verify the payment
Before you deliver anything, ask the API for the payment's current status. This is the source of truth.
verify.js1async function verifyPayment(reference) {2 const response = await fetch(3 process.env.BILLPAY_API_URL + "/payments/" + reference,4 { headers: { Authorization: "Bearer " + process.env.BILLPAY_SECRET_KEY } },5 );67 return response.json(); // { reference, status, amount, currency, ... }8} - 6
Go live
Once your business is verified and your tests pass, swap your sandbox key for your live key. Your code stays exactly the same.
Before switching, test a successful payment, a failed one, and a refund in the sandbox.
.env1# Production: live mode, real payments2BILLPAY_API_URL=https://api.billpay.et/v13BILLPAY_SECRET_KEY=your_live_secret_key
Environments
Test safely,
then go live.
Two separate environments with separate keys, so nothing you test can touch real money.
Sandbox
Test modeA safe copy of Billpay for building and testing. Payments are simulated, so no real money moves.
- Simulated bank and wallet payments
- Test successes, failures, and refunds
- Separate test keys
- Safe to experiment
BILLPAY_SECRET_KEY=your_sandbox_secret_key
Production
LiveReal payments from real customers, available once your business is verified.
- Real bank and wallet payments
- Settlements to your bank account
- Enterprise security controls
- High-availability infrastructure
BILLPAY_SECRET_KEY=your_live_secret_key
Resources
Everything else
you need.
Reach out and we'll get you set up.
Get started
Ready to build a better payment experience?
Join businesses across Ethiopia that are choosing Billpay to power their growth.