completePayment() turns authenticated provider evidence into one gateway-neutral payment result. It is the only result your application should use when deciding whether to fulfil an order.
The integration rules on this page apply to every AvraAPI SDK. Laravel 1.2.0 uses AvraAPI::payment() and Node.js SDK 1.2.0 uses client.payment() with the same typed payment options, completion result, and server-only safety rules.
The completion sequence
- Look up the pending order using a trusted provider reference or an opaque return token that your backend created.
- Load the stored
completionContextfor that exact order. - Preserve provider callback or return data in its gateway-required format.
- Call
completePayment()from the webhook, callback, or server return handler. - Fulfil only a verified result with
paymentStatus === PaymentStatus::Succeeded. - Make the order update idempotent because providers can send the same callback more than once.
1. Set the GatewayCode
Use the gateway stored with the pending order. Do not trust a browser query parameter to choose it.
- PHP
- Laravel
- Node.js
2. Load the saved completionContext
The context returned by createOrder() is signed, server-only evidence that binds completion to one prepared payment session. Load it from protected order storage.
- PHP
- Laravel
- Node.js
3. Preserve the provider payload exactly
Each gateway has its own callback or return shape. Preserve raw bodies and signature headers where the provider requires them, then use the gateway-specific SDK payload wrapper. Do not parse and re-encode signed provider data before the wrapper receives it. For the required payload type and exact callback/return handling for each gateway, see Gateway-wise Functions.- PHP
- Laravel
- Node.js
4. Response option: PaymentResponseOptions::short()
short() is the default and recommended production response. It returns the normalized payment result needed for fulfilment without provider-native diagnostic bodies.
- PHP
- Laravel
- Node.js
Actual response shape
This is the raw HTTP response envelope returned by AvraAPI to the SDK transport. Values such as order IDs, provider statuses, and references vary per real payment; the field names and nesting below are the actual completion contract.success: true means AvraAPI processed the completion request successfully. It does not mean the buyer paid. Always decide what to do from data.verified and data.payment_status.Failed, cancelled, pending, and unknown responses
The normalizedpayment_status is the same across released gateways, while provider_status remains gateway-specific. The following are representative, verified PayHere short() envelopes. Other gateways use the same field names but return their own provider status values and reconciliation details.
- Failed
- Cancelled
- Pending
- Unknown
The object returned by completePayment()
SDK developers do not read $response['data']. The SDK reads the raw envelope internally, extracts data and request_id, then returns a PaymentCompletionResult object. SDK integrations use object properties such as $result->amount and $result->paymentStatus->value.
For example, this is the gateway-neutral result that an application can deliberately create from the SDK object for its own protected order record:
- PHP
- Laravel
- Node.js
5. Response option: PaymentResponseOptions::full()
full() adds the exact provider-native operation bodies under native_operations. Use it only in a protected server-side diagnostic workflow when there is a genuine integration or support need.
- PHP
- Laravel
- Node.js
Actual additional response data
full() preserves the normalized fields from short() and adds native_operations. The following is the actual PayHere callback operation structure used by the response projector; provider-native fields differ by gateway and flow.
$diagnosticResult->nativeOperations, not through a data array.
6. Response option: PaymentResponseOptions::include()
include() returns only exact provider-native paths requested by your server. It is safer than full() when a protected workflow needs a small known set of fields.
- PHP
- Laravel
- Node.js
Actual additional response data
include() preserves the normalized result, returns only selected provider data in native_operations, and reports exactly which requested paths were recognised.
include() mode. Use only paths documented for that gateway, and apply the same server-only handling rules as full().
In the PHP SDK, the metadata is available through $selectedResult->include and the selected operation body through $selectedResult->nativeOperations.
7. reconcileProvider option
reconcileProvider is an optional boolean on PaymentCompletionOptions. It defaults to true. When a gateway supports a secondary authenticated status observation, UPG compares it with the callback or return evidence to reduce mismatches.
Enabled — default and recommended
- PHP
- Laravel
- Node.js
pending or unknown, do not fulfil. Retain the pending order and follow the gateway’s retry or support process.
Disabled — only where the gateway permits it
- PHP
- Laravel
- Node.js
8. Handle every outcome and fulfil exactly once
Fulfil only a verified terminal success. Your order update must be idempotent so duplicated callbacks cannot create duplicate delivery, credit, invoice, or balance changes. A verified failed or cancelled result is still useful business evidence, but it must never trigger fulfilment.- PHP
- Laravel
- Node.js
failed and cancelled, update the pending order without fulfilment. For pending and unknown, retain the order and wait for a webhook, retry according to the provider’s rules, or send it to a controlled reconciliation workflow.
Handle completion errors without fulfilment
The SDK throws typed exceptions for unsuccessful HTTP responses. Catch them in your backend, record only safe correlation details, and leave the order unfulfilled.- PHP
- Laravel
- Node.js
Return a safe webhook acknowledgement
After the result is processed, return a short acknowledgement to the provider. Do not echocompletionContext, raw provider data, nativeOperations, or include data.
- PHP
- Laravel
- Node.js
