Lesson G2 · Build your own gateway
Charge endpoint
By the end of this track you can write a small service that charges, stores every event and notifies your app.
● Sandbox only3 steps + checkpoint
0/6 finished
Step 1
The idea
POST /charge {order_id, phone, amount} validates the phone (2547XXXXXXXX) and a whole-shilling amount, builds the STK password with an EAT timestamp, calls STK Push, and stores a payments row as accepted with the CheckoutRequestID.
Step 2
How it works
The endpoint
Your app sends an order, a phone and an amount. Validate them, insert a row, call STK Push, and save the CheckoutRequestID.
Python
@app.post("/charge")def charge(): req = request.get_json() phone = normalise(req["phone"]) # 2547XXXXXXXX or reject amount = int(req["amount"]) # whole shillings, > 0 row = db.insert_payment(order_id=req["order_id"], phone=phone, amount=amount, status="created") ack = stk_push(phone, amount, reference=req["order_id"]) db.update(row, checkout_id=ack["CheckoutRequestID"], status="accepted") return {"payment_id": row.id, "status": "accepted"}Why save before replying
A callback can arrive within seconds. If your row isn't saved with its CheckoutRequestID yet, the receiver can't match it and the result gets lost.
Step 3
Common mistakes
- Trusting the app's amount without checking it against the order.
- Returning 'paid' to the app here. It is only accepted.
Sandbox noteStore the row before you return, so a fast callback can find it.
Go deeper
When is this step done?
Answer in your own words first.
Show the answerHide the answer
A sandbox prompt arrives on the phone and the row shows accepted.