Charge subscriber
Charge a subscriber's saved card, without the payer. We send the charge to your acquirer as a merchant-initiated transaction, and answer when it is authorized, and captured unless you say not to, or when it has failed.
Request
POST https://{subid}is the subscriber's"id", from seq.
The key needs the charge permission.
Headers
| HTTP header | Description |
|---|---|
Authorization |
Required. Your API key, after |
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. Always send one with a charge: see Retrying. |
Fields
An address you send is this charge's, in place of the subscriber's whole, and one you leave out is the subscriber's.
| Field | Type | Description |
|---|---|---|
items |
array, required | What the payer pays for: one or more items, whose totals add up to the amount to pay. All in one currency, and together more than 0. |
items[].total |
amount, required | The price of the item, its whole quantity together, as a string with
its currency, as |
items[].quantity |
integer | How many, a positive integer. The default is |
items[].name |
string | The name of the product or service, for your records and the dashboard. The payment window does not show it. |
items[].sku |
string | Your SKU for the product. We accept it, but don't store it, so seq does not return it. |
orderid |
string | Your ID for what the charge pays, such as the subscription and its period. Seq returns it with the charge, which is how you match the charge to your records, and the acquirer passes it to the payer's bank, as for a payment link. Optional, but give it, as a string: a number is ignored. |
autocapture |
boolean | Capture the charge as soon as it is authorized, which is the default, true, unlike for a payment link. With false, it is only authorized, and you capture it later. If a capture fails, the authorization is voided, and the charge fails. |
billing |
object | The billing address for this charge. See Addresses. |
shipping |
object | The shipping address for this charge. |
Every string field must be a JSON string here, unlike in Create payment link, and a field of another type may be ignored rather than refused. After the JSON object, the body may have only white space.
Example
Charge a month of a subscription, with a key made for that month and its first attempt:
curl https://api.gjold.com/v1/subscribers/19/charge \
-u {apikey} \
-H 'Idempotency-Key: sub19-2026-12-try1-7f3a9c2e5b1d4f60' \
-d @charge.json
{
"orderid": "M-7192-2026-12",
"items": [
{
"name": "Membership, December",
"total": "99 DKK"
}
],
"autocapture": true
}
Response
We answer 200 OK with the charge, a transaction, once the acquirer
has authorized it, and captured it with "autocapture":
| Field | Type | Description |
|---|---|---|
type |
string | Always "charge". |
id |
integer | The transaction's ID, by which you can capture or refund it. |
totals.authorized |
amount | What the bank authorized: the items' total. |
{
"type": "charge",
"id": 1043,
"totals": {
"authorized": "99 DKK"
}
}
Seq returns the whole transaction too, as a
charge, with its act of capture if it had
"autocapture". A charge is never partly authorized: if the bank
approves only part of the amount, we void that, and the charge fails
with 500 charge failed: {acquirer} error: partial authorization.
Headers
| HTTP header | Description |
|---|---|
Idempotency-Status: OK |
Sent with every answer to a request that has an Idempotency-Key, the first and its replays alike. See Idempotency. |
Timing
A charge waits for the acquirer, once to authorize, and again to capture: a second or two, as a rule, but up to 1 minute per call with Clearhaus, or 10 minutes with Nets, when the acquirer is slow. See Timeouts.
Errors
Declines
Every charge that fails answers 500, with a message that starts with
charge failed: and names the party that failed, the acquirer or one
of ours, and its reason:
HTTP/1.1 500 charge failed: nets error: not sufficient funds
HTTP/1.1 500 charge failed: clearhaus error: card expired
| Status and message | Description |
|---|---|
500 charge failed: {acquirer} error: {why} |
The acquirer declined the charge, did not answer in time, or approved only part of it. {acquirer} is nets or clearhaus, and {why} its reason. |
500 charge failed: subscriber database error: {why} |
The shop has no subscriber with that {subid}, or it has no saved card. Check the {subid}, or have the payer renew the subscriber. |
500 charge failed: {why} |
Anything else that stopped the charge, as items that are missing or add up to 0. |
v1 does not say whether a decline may pass. {why} is the acquirer's
reason, which acquirers word differently, so read it for your logs
and support, not to branch on. Treat a card that has expired, been
blocked, or been reported lost, or a payer who stopped your charges,
as final, and have the payer renew the subscriber; try
anything else again later, with a new key, but not the same day. See
When a charge fails and
the knowledge base's
Declined charges.
A declined charge leaves no transaction, so seq does not return it; record it yourself. When the acquirer did not answer in time, the payer's bank may have authorized the charge without our knowing. There is then no transaction to capture, so the bank releases the amount after some days; until then, the payer may see it held. Waiting a day before the next try keeps two holds from piling up.
Other errors
Besides the errors that any request can give, which Errors lists:
| Status and message | Description |
|---|---|
400 invalid json in {where}: {why} |
The body is not JSON, an item's total can't be read, has no currency, or is in another currency than the items before it, or there is more than white space after the object. See Invalid JSON. |
500 invalid item total currency |
An item's total is in a currency that is not in the ISO 4217 table. |
500 {why} |
We failed. If the charge reached the acquirer, it may have gone through: synchronize before you try again. |
Retrying
If the connection breaks before you have the answer, send the request
again with the same Idempotency-Key: a charge still running is
waited for, and a finished one answers as before, a failure included.
A new attempt after a failure needs a new key. Without a key, you
can't know whether the charge went through, and a second request
charges the payer twice. For the same reason, never charge the same
subscriber twice at once.
See also
Charging subscribers, and in the knowledge base, Stored credentials and Declined charges.