# Charging subscribers

Source: <https://docs.gjold.com/notes/subscribers>

You decide when to charge a subscriber, and how much: we keep no schedule. That makes three things yours to get right: the schedule, what to do when a charge fails, and how to get a new card when the old one stops working.

## One subscriber per payer

Create a subscriber once for each payer, and keep its `"id"` with your customer record. Give it your customer ID as its `"ref"`, which seq returns with it and with each of its charges.

When the payer's card expires, or they come back after cancelling, [renew](https://docs.gjold.com/v1/subscribers/renew) the subscriber rather than create a new one: it keeps its `"id"`, so your records of it, and of its charges, stay as they are.

## The schedule

Keep the schedule in your database: for each subscription, when it is next due, and what to charge. A job that runs, say, every hour charges what is due:

```
for each s in Due(now) do
    key := LoadOrCreateKey(s, s.period, s.attempt)  -- one key per period
    res := Charge(s.subid, s.items, s.orderid, key)
    if res is 200 then MarkPaid(s, s.period, res.id)
    else if res is not 4xx or is 408 then Failed(s, res)  -- see below
    else Alert(res)                                 -- a fault in the request
end for
```

The key is per subscription, period, and attempt, made before the attempt and stored, so that a crash or a timeout can't charge a period twice: a retry of the attempt with its key gets the first answer. `Failed` retries the attempt with its key when there was no answer, or a `408`, `502`, `503`, or `504`, and otherwise counts the attempt up, so that tomorrow's try is a new request with a new key, as a failed charge's answer is stored under its key too. See [Retries and idempotency](https://docs.gjold.com/notes/retries).

A charge waits for the acquirer, and can take seconds. Charge one subscriber at a time per card, and never two charges of the same subscriber at once: both can go through.

## When a charge fails

Whatever the version, a charge can fail after the acquirer authorized it, as when an `"autocapture"` capture fails. So before you try a failed charge again with a new key, synchronize: if seq has a charge with the period's `"orderid"`, the period is charged. A failed charge that did not happen leaves no transaction, so seq does not return it: record failures yourself.

In v1, a failed charge is a `500` with a message that starts with `charge failed:`, followed by where it failed and why, as `500 charge failed: nets error: not sufficient funds`, with no `transient` or `permanent`. A decline, a fault at the acquirer, and a fault of ours look alike, so after synchronizing, try again once a day, at most five times in all, and then ask the payer to renew. A card that has expired, or a message that names a lost, stolen, or closed card, will not succeed: ask the payer to renew at once.

In v2, a charge that the acquirer declines is a [`402`](https://docs.gjold.com/v2/subscribers/charge#declines) with a message that starts with `transient` or `permanent`:

- **`transient`**: it may succeed later, as when the account lacks the money today. Try again tomorrow.
- **`permanent`**: it will not succeed on this card. Don't try again, as the card schemes fine you for it, but ask the payer to renew.

A schedule for `transient` failures that keeps within the schemes' limits: try again once a day, at most five times in all, then treat it as permanent. In v2, any other error is not a decline: the request was wrong, or we failed.

In both, the limits themselves, and why they exist, are in the knowledge base's [Declined charges](https://docs.gjold.com/learn/declined-charges). A `4xx` won't succeed if you send it again unchanged, and no answer at all, or a `502`, `503`, or `504`, is safe to retry with the same key.

## Getting a new card

A card stops working when it expires, is replaced, or the payer closes the account. Plan for it:

- Know when the card expires, from the `"exp"` in the subscriber's [`"method"`](https://docs.gjold.com/v1/subscribers#the-subscriber-object), as seq returns it. Ask the payer to renew in the month before.
- Tell the payer at the first failure, so that they can fix it while you retry. After the last try, or a failure that will not go away, such as v2's `permanent`, send them a link to renew: create it with [Renew subscriber](https://docs.gjold.com/v1/subscribers/renew), with the failed amount as an initial charge if they owe it, and send the `"url"` by email.
- Pause the subscription until the subscriber is renewed, which seq tells you with a `"renew"` act.

## Charging fairly

The card schemes, and the payer's bank in a dispute, expect the payer to have agreed to each charge, to be told before an unexpected one, and to be able to cancel. The knowledge base's [Stored credentials](https://docs.gjold.com/learn/stored-credentials) has the rules. When a payer cancels, stop charging. In v2, [delete](https://docs.gjold.com/v2/subscribers/delete) the subscriber if you will never charge it again. In v1, which can't delete one, take it off your schedule and forget its `"id"`.
