Skip to main content
Version: 4.0.2

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

FieldTypeDescription
charge_idUUIDUnique identifier for the charge. Use it with GET /charge/{charge_id} and to correlate webhooks.
orderobjectThe order the charge was created for: order_id, service_id, order_amount, customer, your_order_reference, order_line_items, your_order_details.
payments[]arrayThe payment attempts under this charge. Each contains a payment_instrument, ledger details, and any surcharge.
sessionobjectBrowser/session context captured during payment, including the configured success/failure return URLs.
status.statusstringThe current charge status. This is the field that determines the payment outcome.
eventobjectThe most recent event applied to the charge: event_number, action (for example complete, refund), source, and resulting status.
summary_amountsobjectRunning totals for the charge — see Summary amounts.
error_messagestringHuman-readable reason for a failed charge, suitable for customer display. Present on failed charges — see Errors.
psp_responses[]arrayRaw 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

StatusOutcomeWebhook fired¹Recommended handling
createdIn progressYesInitial state. Hold the order while payment is in progress.
pending_validationIn progressNoHold; release if your payment timeout elapses.
validatedIn progressNoHold; release if your payment timeout elapses.
pending_authorisationIn progressNoHold; release if your payment timeout elapses.
authorisedIn progressNoHold; release if your payment timeout elapses.
pending_completionIn progressNoHold; release if your payment timeout elapses.
completedSuccessYesPayment approved. Fulfil the order.
settledSuccessNoFunds settled. Normally only seen when querying a charge ~2+ days after completion.
settled_out_of_balanceSuccessNoAs settled.
not_createdFailureYesRelease the order. Customer was not charged.
not_validatedFailureYesRelease the order. Customer was not charged.
not_authorisedFailureYesRelease the order. Customer was not charged.
not_completedFailureYesRelease the order. Customer was not charged.
cancelledFailureYesRelease the order. Customer was not charged.
refundedRefundedYes ²Payment was completed, settled, and subsequently refunded.
(any other status)In progressNoTreat 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:

  1. Receive the charge webhook and acknowledge it with 200 OK.
  2. Extract the charge_id from the webhook payload.
  3. Call GET /charge/{charge_id} and check status.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 (including validated or authorised — 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:

FieldAudienceUsage
error_message (root level)CustomersA display-safe message describing why the payment failed. Show this (or your own copy keyed from it) on your result page.
psp_responses[].psp_errorDevelopersFull processing error detail. Log this for diagnostics and support, but do not display it to customers.
Example — failed charge (abridged)
{
"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:

FieldTypeDescription
instrument_idUUIDUnique identifier for the instrument record.
instrument_typestringThe 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.
instrumentobjectEncrypted payment details (encrypted_data, encrypted_info). Your systems never receive raw payment details.
payerobjectThe paying entity, in the same shape as order.customer.
saved_for_laterbooleanWhether the instrument was tokenised for reuse.
your_instrument_referencestringYour own reference for the instrument, if supplied.

Summary amounts

summary_amounts tracks the financial state of the charge as events are applied to it:

FieldDescription
original_order_totalThe order amount at creation.
current_order_totalThe order amount after subsequent events (for example, 0 after a full refund).
completed_amountAmount successfully captured.
refunded_amountAmount refunded.
settled_amountAmount settled to the merchant.
canceled_amount, disputed_amount, reconciled_amount, reversed_amountAmounts 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.