A shop never handles card numbers itself. A payment provider does: the shop asks it, through its API, to charge an amount, and the provider answers with the payment it made. Ours lives at the address in PAYMENTS, already written for you.
Sending JSON to another API is one call: requests.post with json= a dictionary, then .json() on the answer. Here a shop asks a gift-card service for a card worth 25:
response = requests.post(GIFTS + "/cards", json={"value": 25, "customer_id": 4})
card = response.json()
print(card["id"])
Two rules. The amount comes from your own database, never from the customer's request: nobody gets to choose their own price. And the shop saves the provider's payment id in the order: it links the order to the provider's record of the money, so you can look the payment up, or refund it, later. Paying is a POST, because it changes things, and it answers 201.
The provider answers like {"id": "pay_1", "status": "succeeded", "amount": 80, "order_id": 8}. Your shop must answer:
GET /orders/8 → 200 {"customer_id": 5, "id": 8, "ordered": "2026-06-02", "payment_id": null, "status": "pending", "total": 80}
POST /orders/8/pay → 201 {"amount": 80, "order_id": 8, "payment_id": "pay_1"}
GET /orders/8 → 200 {"customer_id": 5, "id": 8, "ordered": "2026-06-02", "payment_id": "pay_1", "status": "paid", "total": 80}
POST /orders/10/pay → 201 {"amount": 21, "order_id": 10, "payment_id": "pay_2"}
POST /orders/99/pay → 404 {"error": "Order not found"}
Your task: add POST /orders/<order_id>/pay. Find the order (404 if there is none), ask the provider at PAYMENTS + "/payments" to charge its total, save status = 'paid' and the payment id in the order, and answer 201.
Assignment
Follow the Coding Tutorial to build the route that pays an order through the payment provider.
Hint
Use find_order as get_order does: it also adds up the total. Read the provider's answer with response.json(), and remember db.commit() after the UPDATE.
Free plan: 30 tutor messages. PRO is unlimited.
