Refund an order
Gives money back to the customer. Money moves.
An empty body is a full refund. Send no body (or {}) to refund everything on the order that has not been refunded yet. For a partial refund send one of total, tax, items or shipping (items and shipping may go together); the API works out the rest.
An order can have more than one payment. The refund is spread over them, largest payment first and store credit payments last, so the response is a refund_list with one refund per payment used, not a single refund. Each refund has its own success and status; a refund can stay pending until the payment provider confirms it. When every refund fails, the API answers with an error instead and puts the refund_list in the error's meta.refund_list. The order's payment_status becomes refunded once the whole amount is refunded. For each refund, refund:created_success fires when it completes (later, for a pending one) and the customer gets the refund email; refund:created_failure fires when it fails. A chargeback sends no email and cancels the subscription the order belongs to.
To refund one payment of an order, or to record a chargeback on an order with more than one payment, use POST /payments/{payment_id}/refunds.
Needs a secret or trusted token. Limited tokens get 403.
AuthorizationBearer <token>A secret, trusted or limited token. See Authentication.
order_id*stringThe order id.
expand?stringComma-separated child objects to return in full instead of as a URL, for example customer,payments. Use dot notation for nested objects (items.product), up to four levels deep. A single object takes up to 12 paths; a list takes up to 2, applied to every item. Extra paths are dropped without an error. See Expanding objects.
Optional. Leave the body out, or send {}, for a full refund of everything not refunded yet. Send amounts or items for a partial refund.
application/json- body
What to refund. Send no body, or {}, to refund everything that has not been refunded yet (a full refund). For a partial refund send exactly one of total, tax, items or shipping; items and shipping may be sent together. The other amounts are worked out for you. subtotal is never accepted. items works when you refund an order or an invoice, or a payment that belongs to one. A payment with no order or invoice ignores items, so a body with only items refunds that payment in full.
total?numberThe amount to give back, with tax, in the payment currency. The tax part is worked out for you. This plus earlier refunds cannot be more than what was paid. Required when is_chargeback is true.
0 < valuetax?numberRefund only tax, for example when tax was charged by mistake. Cannot be sent with total, items or shipping.
0 < valueshipping?numberThe shipping amount to give back, with tax, in the payment currency. Up to the shipping not refunded yet. May be sent with items.
0 < valueitems?array<>The items to refund, by item_id and quantity. Only for an order, an invoice, or a payment that belongs to one.
1 <= itemsreason?stringWhy you are refunding. Use one of the reasons from GET /refunds/options to keep reports tidy.
comments?stringYour own notes about the refund.
length <= 1024reference?stringYour own reference for the refund. You can filter lists by it.
length <= 100meta?|Your own data for the refund, a string or an object. At most 2048 characters once serialized.
payment_method?Send {"type": "customer_account_balance"} to give the money to the customer's store credit instead of back to the card or wallet they paid with. Leave it out to refund the original payment method.
is_chargeback?booleanSet to true to record a chargeback the bank already took. No money moves. Needs total. Only used on accounts on the agent model (or when Comecero staff send it); otherwise it is ignored without an error and the refund is real: money goes back. On a gateway that Comecero owns, only Comecero staff may send it (400). An order with more than one successful payment must take it on the payment instead. Not allowed when the payment was made from store credit.
record_only?booleanSet to true to write down a refund you paid back some other way. No money moves. Needs record_only_memo. Same limits as is_chargeback.
record_only_memo?stringHow a record-only refund was paid back, at least 5 characters. Required when record_only is true.
5 <= lengthAt least one refund succeeded or is pending. Check failure_count for refunds that failed.
application/json- response
The result of refunding an order. An order can have more than one payment, and the refund is spread over them, largest first (store credit payments last), so this holds one refund per payment used, each with its own result.
object*"refund_list"The object type. Always refund_list.
"refund_list"url*stringThe URL of this result, which you can read again later.
urirefund_list_id*stringThe id of this result.
test*booleanTrue for test refunds.
account_id*|The account the refunds belong to.
currency*|The currency of the refunds.
subtotal*numberThe subtotal of the refunds that completed or are pending, in currency.
shipping*numberThe shipping of the refunds that completed or are pending, in currency.
tax*numberThe tax of the refunds that completed or are pending, in currency.
total*numberThe total of the refunds that completed or are pending, in currency.
success_count*integerHow many refunds succeeded (completed or pending).
failure_count*integerHow many refunds failed.
refunds*array<>The refunds made.
curl -X POST 'https://api.comecero.com/api/v1/orders/string/refunds' \ -H 'Content-Type: application/json' \ -d '{}'{ "object": "refund_list", "url": "https://api.comecero.com/api/v1/refund_list/0090374314470RlA8kWm3T", "refund_list_id": "0090374314470RlA8kWm3T", "test": true, "account_id": "AB1234", "currency": "USD", "subtotal": 49.95, "shipping": 0, "tax": 0, "total": 49.95, "success_count": 1, "failure_count": 0, "refunds": [ { "object": "refund", "url": "https://api.comecero.com/api/v1/refunds/0090374314462Rec3PffZ5", "refund_id": "0090374314462Rec3PffZ5", "account_id": "AB1234", "success": true, "status": "completed", "reference": null, "date_created": "2026-11-03T10:12:40Z", "date_modified": "2026-11-03T10:12:41Z", "date_completed": "2026-11-03T10:12:41Z", "test": true, "currency": "USD", "subtotal": 49.95, "shipping": 0, "tax": 0, "total": 49.95, "reason": "Customer request", "apply_to_balance": false, "is_chargeback": false, "record_only": false, "record_only_memo": null, "response_code": "OK", "response_message": "OK", "gateway_transaction_id": "re_test_3PffZ5", "gateway_error_code": null, "gateway_error_message": null, "gateway": "https://api.comecero.com/api/v1/gateways/0089584408915Gtf5AsdJ8", "comments": null, "payment_method": "https://api.comecero.com/api/v1/refunds/0090374314462Rec3PffZ5/payment_method", "settlement_currency": "USD", "settlement_subtotal": 49.95, "settlement_shipping": 0, "settlement_tax": 0, "settlement_total": 49.95, "fx_rate": 1, "reporting_currency": "USD", "reporting_subtotal": 49.95, "reporting_shipping": 0, "reporting_tax": 0, "reporting_total": 49.95, "reporting_fx_rate": 1, "items": "https://api.comecero.com/api/v1/refunds/0090374314462Rec3PffZ5/items", "customer": "https://api.comecero.com/api/v1/customers/0093717976099CuAiEBXu4", "order": "https://api.comecero.com/api/v1/orders/7393-GMRFY-954", "payment": "https://api.comecero.com/api/v1/payments/0093717991362PyRYN1qc6", "invoice": null, "fees": "https://api.comecero.com/api/v1/refunds/0090374314462Rec3PffZ5/fees", "fee_summary": "https://api.comecero.com/api/v1/refunds/0090374314462Rec3PffZ5/fee_summary", "commissions": "https://api.comecero.com/api/v1/refunds/0090374314462Rec3PffZ5/commissions", "meta": null } ]}