The request
Look up a payment by the reference that initialise returned, which has the formVPY_TXN_….
transaction.not_found.
The response
Payment statuses
Only
success means paid. Treat anything else as not paid, and do not guess from the channel or from timing.
The fulfilment decision
Fulfil when both conditions hold:data.statusissuccess.data.amountequals the amount you expected for that order.
success but the amount differs, do not fulfil. Hold the order and investigate, because the payment may belong to a different order or to a tampered request. Compare amounts as strings or decimals, never as binary floats.
Idempotent fulfilment
Webhooks are retried and customers reload callback pages. Your fulfilment code will run more than once for the same payment. Design for that.- Load the order by reference.
- If it is already marked paid, return HTTP 200 and stop.
- Call verify. If the payment is
successand the amount matches, mark the order paid and fulfil in a single atomic step, using a database transaction, a conditional update or a unique constraint.
Splits on verify
When the payment was initialised with a distribution, verify includes asplit object once the payment has been allocated. Allocation follows success by a short moment, so a verify call made in the first instant after payment may not yet include it. The payment is still success and safe to fulfil.
The allocation rules are explained on Distribution.
Errors and retries
If a payment stays
pending or processing for longer than you expect, keep it in a waiting state rather than failing the order. Webhooks and later verify calls will reflect the final outcome. For anything that looks stuck, contact tech@vestrapay.com with the reference.
Checkout helpers
The access-code endpoints GET/v1/payment/checkout/status, GET /v1/payment/checkout/verify and GET /v1/payment/checkout/events are for pay screens that want to show progress. They are not a substitute for your server’s secret-key verify before fulfilling.