Charge Data Model
This page describes the charge object returned by GET /charge/{charge_id}, the charge status lifecycle, and how to interpret payment results — including how to determine whether a payment is actually approved.
The charge object
| Field | Type | Description |
|---|---|---|
charge_id | UUID | Unique identifier for the charge. Use it with GET /charge/{charge_id} and to correlate webhooks. |
order | object | The order the charge was created for: order_id, service_id, order_amount, customer, your_order_reference, order_line_items, your_order_details. |
payments[] | array | The payment attempts under this charge. Each contains a payment_instrument, ledger details, and any surcharge. |
session | object | Browser/session context captured during payment, including the configured success/failure return URLs. |
status.status | string | The current charge status. This is the field that determines the payment outcome. |
event | object | The most recent event applied to the charge: event_number, action (for example complete, refund), source, and resulting status. |
summary_amounts | object | Running totals for the charge — see Summary amounts. |
error_message | string | Human-readable reason for a failed charge, suitable for customer display. Present on failed charges — see Errors. |
psp_responses[] | array | Raw processing responses for diagnostics — see Errors. |
Monetary values are integers in minor units with two implied decimal places — for example, an order_amount.value of 100000 represents 1,000.00 in the order currency.
Charge status lifecycle
A charge progresses through validation, authorisation, and completion phases. The typical successful flow is:
A failed payment ends in one of the failure statuses (not_created, not_validated, not_authorised, not_completed, cancelled) instead. The customer is not charged when a charge ends in a failure status.
Status reference
| Status | Outcome | Webhook fired¹ | Recommended handling |
|---|---|---|---|
created | In progress | Yes | Initial state. Hold the order while payment is in progress. |
pending_validation | In progress | No | Hold; release if your payment timeout elapses. |
validated | In progress | No | Hold; release if your payment timeout elapses. |
pending_authorisation | In progress | No | Hold; release if your payment timeout elapses. |
authorised | In progress | No | Hold; release if your payment timeout elapses. |
pending_completion | In progress | No | Hold; release if your payment timeout elapses. |
completed | Success | Yes | Payment approved. Fulfil the order. |
settled | Success | No | Funds settled. Normally only seen when querying a charge ~2+ days after completion. |
settled_out_of_balance | Success | No | As settled. |
not_created | Failure | Yes | Release the order. Customer was not charged. |
not_validated | Failure | Yes | Release the order. Customer was not charged. |
not_authorised | Failure | Yes | Release the order. Customer was not charged. |
not_completed | Failure | Yes | Release the order. Customer was not charged. |
cancelled | Failure | Yes | Release the order. Customer was not charged. |
refunded | Refunded | Yes ² | Payment was completed, settled, and subsequently refunded. |
| (any other status) | In progress | No | Treat as a pending payment. |
¹ Default behaviour. Which statuses trigger webhook delivery to your endpoint is configurable in the Merchant Portal.
² Refunds are initiated from the Merchant Portal, outside the normal payment flow. A refund fires a webhook to your endpoint and is also visible via GET /charge/{charge_id}. The refund webhook payload can vary, so confirm the refund by calling GET /charge/{charge_id}, which returns the canonical charge object.
All statuses are visible at any time via GET /charge/{charge_id}, whether or not a webhook fires for them.
Determining whether a payment is approved
A payment is approved when status.status is completed.
Confirm this on your backend:
- Receive the charge webhook and acknowledge it with
200 OK. - Extract the
charge_idfrom the webhook payload. - Call
GET /charge/{charge_id}and checkstatus.status.
Do not treat any of the following as confirmation of payment:
- The customer arriving at your success redirect URL.
- Frontend payment events alone.
- Any charge status other than
completed(includingvalidatedorauthorised— these are intermediate states).
See the End-to-End Payment Flow guide for where this fits in the overall integration.
Errors
Failed charges expose error information at two levels:
| Field | Audience | Usage |
|---|---|---|
error_message (root level) | Customers | A display-safe message describing why the payment failed. Show this (or your own copy keyed from it) on your result page. |
psp_responses[].psp_error | Developers | Full processing error detail. Log this for diagnostics and support, but do not display it to customers. |
{
"charge_id": "89ebd8e4-d4b4-4a25-8196-378ec8914b79",
"status": { "status": "not_authorised" },
"error_message": "Transaction Not Permitted. High risk transaction"
}
For the full catalogue of error types, response codes, and whether each error is retryable, see Error Messages.
Payment instruments
Each payment under a charge carries a payment_instrument:
| Field | Type | Description |
|---|---|---|
instrument_id | UUID | Unique identifier for the instrument record. |
instrument_type | string | The type of payment instrument used. The set of values available to you depends on the payment methods enabled in your merchant configuration and is provided during onboarding. |
instrument | object | Encrypted payment details (encrypted_data, encrypted_info). Your systems never receive raw payment details. |
payer | object | The paying entity, in the same shape as order.customer. |
saved_for_later | boolean | Whether the instrument was tokenised for reuse. |
your_instrument_reference | string | Your own reference for the instrument, if supplied. |
Summary amounts
summary_amounts tracks the financial state of the charge as events are applied to it:
| Field | Description |
|---|---|
original_order_total | The order amount at creation. |
current_order_total | The order amount after subsequent events (for example, 0 after a full refund). |
completed_amount | Amount successfully captured. |
refunded_amount | Amount refunded. |
settled_amount | Amount settled to the merchant. |
canceled_amount, disputed_amount, reconciled_amount, reversed_amount | Amounts in the corresponding exception states. |
out_of_balance_amounts[] | Any amounts that did not reconcile cleanly. |
For example, after a full refund of a 1,000.00 charge: original_order_total: 100000, current_order_total: 0, completed_amount: 0, refunded_amount: 100000, and status.status is refunded.
Sample response — completed charge
GET /charge/{charge_id} (abridged — encrypted payloads and empty optional fields trimmed):
{
"charge_id": "fd4880f7-b4e2-4919-9b4e-bb3d15e8d5ed",
"order": {
"order_id": "d54e5faa-2b84-4700-89b9-9fed1f396446",
"service_id": "9c21b1e5-5618-475c-b338-9c1f229c1bac",
"order_amount": {
"value": 100000,
"currency": { "currency_code": "KRW" }
},
"customer": {
"entity_id": "20ff48fa-6c2d-46a4-87e1-da5b21126656",
"entity_type": "person",
"entity_details": {
"name": { "first": "Jane", "last": "Example" },
"email": "jane.example@example.com",
"phone_number": {
"type": "mobile",
"details": { "unformatted_number": "+61400000000" }
}
}
},
"your_order_reference": "your-order-123",
"your_order_details": [
{ "key": "merchant_order_ref", "value": "your-order-123" },
{ "key": "merchant_customer_ref", "value": "customer-456" }
]
},
"payments": [
{
"payment_instrument": {
"instrument_id": "3963993b-a6bc-4332-8d31-70d6dda6c6f2",
"instrument": {
"encrypted_data": "<encrypted>",
"encrypted_info": "<encrypted>"
},
"saved_for_later": false,
"instrument_type": "<instrument-type>"
},
"ledger_type": "card"
}
],
"status": { "status": "completed" },
"event": {
"event_number": 0,
"action": "complete",
"source": "api",
"status": "completed"
},
"summary_amounts": {
"original_order_total": 100000,
"current_order_total": 100000,
"completed_amount": 100000,
"refunded_amount": 0,
"settled_amount": 0
},
"psp_responses": [
{
"psp_id": "25693472358246",
"type": "card",
"details": {
"status_code": "200",
"charge_responses": {
"authorization_id": "",
"acquirer_response_code": "",
"network_unique_id": ""
}
}
}
]
}
After a refund, the same charge returns status.status: "refunded", event.action: "refund", and the summary amounts shift accordingly.