API versionv2 next

API v2 is not live yet: it launches in early 2027, and until then these pages are its spec. Switch to v1 (live)

Refund transaction

Refund all or part of what was captured of a transaction, to the card it was paid with. You can refund several times, up to what was captured in all.

Request

POST https://api.gjold.com/v2/{shopid}:trn:{trnid}/refund

The key needs the refund permission.

Headers

HTTP header Description
Authorization

Required. Your API key, after Basic and base64-encoded. See Authentication.

Idempotency-Key

A key you make up for this request, and send again with each retry of it, so that the request is done once however often it arrives. Up to the 4 KiB of all headers, and kept for 24 hours. See Idempotency.

Fields

Field Type Description
total amount, required How much to refund: more than 0, at most what was captured and not yet refunded, captured - refunded, and in the transaction's currency.
index integer, required

The transaction's index: how many acts it has now, the length of its "acts" as seq last returned it. If an act has been made since, the request fails with 409 index mismatch, and nothing is done. An "autocapture" is an act too, so the first act of yours on such a transaction has index 1. See Index.

history array of objects

What the act covers, item by item, for your records and the dashboard, each as {"item": 0, "quantity": 1, "total": "99.95 DKK"}, where "item" is an index into the transaction's "items". We store it as it is, in the act's "history", without checking it against the act's "total".

Example

Refund one item of a captured order, after the payer returned it:

curl https://api.gjold.com/v2/{shopid}:trn:378/refund \
    -u {apikey} \
    -H 'Idempotency-Key: 9e2f71c04b3a5d68a7b8c9d0e1f2a3b4' \
    -d @refund.json
{
    "total": "99.95 DKK",
    "index": 1,
    "history": [
        {"item": 0, "quantity": 1, "total": "99.95 DKK"}
    ]
}

Response

We answer 200 OK with an empty object, {}, once the act is done: the transaction as it is now comes through seq, with the act in its "acts" and its "rev" one higher.

The refund's act has "act": "refund", and the transaction's totals.refunded goes up by the "total".

Headers

HTTP header Description
Idempotency-Status: OK The answer is a replay: the stored answer to the first request with this Idempotency-Key, which this request did not run again.

Errors

Besides the errors that any request can give, which Errors lists, a refund can fail with:

Status and message Description
400 total must be more than 0 There is no "total", or it is 0.
400 total exceeds captured The "total" is more than was captured and not yet refunded.
400 currency mismatch The "total" is in another currency than the transaction.
400 missing index There is no "index".
409 index mismatch The "index" is not the transaction's number of acts: something acted on it since you last read it. Synchronize, look at it again, and decide afresh.

and with the errors of every act:

Status and message Description
400 invalid json in {where}: {why} The body is not a JSON object, or a field is not as the table says. See Invalid JSON.
404 transaction not found The shop has no transaction with that {trnid}.
409 transaction in use Another act on the transaction is running. Try again in a moment, with a new key.
409 transaction is locked The transaction is locked, and refuses acts until it is unlocked. See "locked".
500 {acquirer} error: {why} The acquirer refused the act, and nothing was done, or did not answer in time, and the act may have gone through. {why} is the acquirer's, such as clearhaus error: card expired. See Acquirer errors.
500 {why} We failed. If the act was sent to the acquirer, it may have gone through: synchronize before you try again.

Acquirer errors

An act is done by your acquirer, and we answer only when it has: in a second or two, as a rule, but after up to 1 minute with Clearhaus, or 10 minutes with Nets, when the acquirer is slow. See Timeouts.

When the acquirer refuses an act, nothing is done. Whether it will refuse again, only its message tells: an authorization that has run out, or a card closed since, refuses however often you try. When it does not answer in time, the act may have gone through without our knowing.

Either way, the answer is stored under the Idempotency-Key, so that a retry with the same key gets the same error. Synchronize first, and if the act is not in seq, send it again with a new key.

Notes

  • A refund goes to the card that paid. The payer usually sees it within a few working days. See the knowledge base's Captures and refunds.
  • If nothing was captured yet, void the transaction instead: the payer gets their money back sooner.