رفتن به محتوا

Payments

این محتوا هنوز به زبان شما در دسترس نیست.

You leave a card with us and are charged per delivery. The card is held for the price when a job is booked and captured when it is delivered or returned. A job that is cancelled or fails has its hold released and costs nothing.

The card number never reaches us. It goes from your browser straight to the payment provider, and what we keep is a token, the brand and the last four digits. No endpoint accepts a card number.

Most merchants add their card in the merchant portal, under Billing. To do it from your own system:

  1. POST /v1/payment-methods/setup starts a setup and returns a client_secret and customer_id for the payment provider’s card form, shown to the person adding the card.

  2. When the provider has the card, send us its reference:

    Terminal window
    curl -u "$COURIER_KEY:$COURIER_SECRET" "$COURIER_API/v1/payment-methods" \
    -H 'Content-Type: application/json' \
    -d '{ "provider_ref": "pm_...", "make_default": true }'
{
"id": "0199d1aa-3c4d-7e5f-8a9b-0c1d2e3f4a5b",
"brand": "visa",
"last_four": "4242",
"expiry_month": 12,
"expiry_year": 2029,
"status": "active",
"is_default": true,
"attached_at": "2026-10-10T11:50:00+00:00",
"dead_reason": null
}

Deliveries are charged to the default card. GET /v1/payment-methods lists your cards, POST /v1/payment-methods/{id}/default chooses another, and DELETE /v1/payment-methods/{id} removes one.

When a card stops working — expired, reported lost, refused for good — its status changes, dead_reason says why, and you receive the payment_method.dead webhook. Add another card before your next busy evening.

GET /v1/charges

Your last 50 charges, one per job:

[
{
"id": "0199d2c6-7a8b-7c9d-8e0f-1a2b3c4d5e6f",
"job_id": "0199d2c5-1f3a-7d10-8b2e-6c4a9e0f2d31",
"status": "captured",
"currency": "GBP",
"amount_minor": 918,
"refunded_amount_minor": 0,
"raised_at": "2026-10-10T12:04:33+00:00",
"captured_at": "2026-10-10T12:31:06+00:00",
"decline_code": null,
"last_error": null
}
]
status Meaning
pending Raised, not yet presented to the bank.
authorised Held. The money is set aside but not taken — the state a job spends its life in.
captured Taken. You have paid.
voided The hold was released without taking anything — the delivery never happened.
failed The bank refused and will keep refusing. decline_code says why.
refunded Captured and then given back, in full or in part — see refunded_amount_minor.

In the sandbox the card number decides what happens. They are the numbers Stripe publishes, so tests you already have keep working. Pass them as pm_sandbox_<number>:

Terminal window
curl -u "$COURIER_KEY:$COURIER_SECRET" "$COURIER_API/v1/payment-methods" \
-H 'Content-Type: application/json' \
-d '{ "provider_ref": "pm_sandbox_4242424242424242", "make_default": true }'
Number What happens
4242424242424242 Works.
4000000000000002 Declined, no reason given. Never retried.
4000000000009995 Declined for insufficient funds — about today, not about the card.
4000000000000069 Expired. The card is finished; a new one is needed.
4000000000009987 Reported lost. Taken out of use.
4000000000000119 The provider can’t be reached. Not a decline — retried.

A card number on its own, without pm_sandbox_, is refused in both environments.