Test mode
A qb_test_sk_… key works on the sandbox app. You can run the whole flow without any real money.
What changes with a test key
- No call is made to Wave.
- No invoice email is sent.
- Invoice numbers start with
TEST-INV-. - Webhook events carry
livemode: false.
The simulated checkout page
Call payments.initiate (POST /v1/payments/initiate) with a test key: the answer holds a redirectUrl, which leads to a QBill test checkout page. That page has two buttons, Pay and Decline.
curl -X POST https://api.qbill.dev/v1/payments/initiate \
-H "x-api-key: qb_test_sk_…" \
-H "content-type: application/json" \
-d '{"invoice_id":"<invoice id>","phone_number":"+2250700000000","provider":"wave"}'
- Pay: the invoice becomes
paidand theinvoice.paidevent is sent. - Decline: the payment becomes
failedand reminders start (see Dunning).
With the Node SDK (coming to npm): qbill.payments.initiate({ invoice_id, phone_number }).
To receive the events, see Webhooks.
Going live
Create a qb_live_sk_… key on the live app and swap it in for the test key. Your code does not change: same routes, same request bodies. Only the key changes, and with it the app (see Authentication & keys).