> ## Documentation Index
> Fetch the complete documentation index at: https://docs.publica.la/llms.txt
> Use this file to discover all available pages before exploring further.

# charge.paid

Announces that a payment gateway charge was approved: a first purchase, a subscription renewal, a Publica One redemption or any later charge of an order. The payload below goes in the `data` field of the [envelope](./overview.md#envelope), and follows the [payload conventions](./overview.md#payload-conventions).

## When it is sent

Once per approved charge. A charge is what the gateway charged in one transaction; Publica.la records it as one payment per product of the order, plus a shipping payment when the order ships, all sharing `gateway_transaction_id`.

It is sent for every approved charge, with no filter:

- The first purchase of an order, every subscription renewal, and charges a 100% discount coupon covers.
- Publica One redemptions.
- A shipping charge alone.
- A charge approved on an order that is already cancelled, expired, refunded or otherwise closed.

Rejected, pending and refunded payments do not send it. A gateway notification Publica.la already recorded sends nothing again.

The idempotency key is `charge.paid:order:<order id>:charge:<gateway transaction id>`. It includes the order because a gateway can reuse a transaction id across orders.

### Relation to `order.paid`

The first purchase of an order sends both [`order.paid`](./order-paid.md) and `charge.paid`, with the same payments. They are independent deliveries and can arrive in any order. Subscribe to `order.paid` to hear about each order once; subscribe to `charge.paid` to hear about every charge, renewals included.

## Tell charges apart

Every charge sends the same event. Use these fields to tell what kind of charge it is:

| Charge                         | How to recognize it                                                            |
| ------------------------------ | ------------------------------------------------------------------------------ |
| Publica One redemption         | A payment has `sale_type` `publica_one_redemption`.                            |
| Shipping charge alone          | Every payment has `sale_type` `shipping`.                                      |
| First charge of a subscription | `charge.recurring_cycle` is `1`.                                               |
| Subscription renewal           | `charge.recurring_cycle` is greater than `1`.                                  |
| One-time purchase              | `charge.recurring_cycle` is `null`, and the charge is none of the cases above. |

A later charge on an order that does not bill again, which is rare, also has `recurring_cycle` `null`. To tell it from the purchase, keep the ids of the orders you already received, or use [`order.paid`](./order-paid.md), which is sent only for the first purchase.

`data.order.status` tells whether the order was closed when the charge arrived.

## Payload

```json
{
  "charge": {
    "gateway_type": "stripe",
    "gateway_transaction_id": "pi_example_0001",
    "status": "approved",
    "recurring_cycle": null,
    "amount_in_cents": 2248,
    "tax_in_cents": 390,
    "currency_id": "USD",
    "paid_at": "2026-01-15T14:30:00Z"
  },
  "order": {
    "id": "1001",
    "uuid": "9b2f6c1e-4a7d-4e8b-9f3a-2c5d8e1f0a42",
    "external_id": "ORD-1001",
    "status": "approved",
    "type": "internal",
    "recurring": false,
    "currency_id": "USD",
    "amount_in_cents": 2248,
    "tax_in_cents": 390,
    "gateway_type": "stripe",
    "payment_method": "card",
    "created_at": "2026-01-15T14:30:00Z"
  },
  "user": {
    "id": "501",
    "uuid": "3e7a1d2c-8b4f-4c6e-a9d1-7f2b5c8e0d13",
    "external_id": "USR-501",
    "email": "buyer@example.com",
    "name": "Jane Buyer",
    "billing_information": {
      "national_id": "20123456789",
      "national_id_type": "CUIT",
      "address_line_1": "Av. Example 123",
      "address_line_2": null,
      "city": "Buenos Aires",
      "state": "CABA",
      "country": "AR",
      "postal_code": "C1001",
      "other_information": null
    }
  },
  "products": [
    {
      "id": "2001",
      "type": "content",
      "amount_in_cents": 1349,
      "currency_id": "USD",
      "content": {
        "id": "301",
        "external_id": "9780000000001",
        "name": "An Example Book",
        "file_type": "epub"
      },
      "plan": null,
      "coupon": {
        "code": "WELCOME10",
        "discount_percentage": 10,
        "shipping_discount_percentage": null,
        "take_quantity": null,
        "pay_quantity": null
      }
    },
    {
      "id": "2002",
      "type": "content",
      "amount_in_cents": 899,
      "currency_id": "USD",
      "content": {
        "id": "302",
        "external_id": "9780000000002",
        "name": "Another Example Book",
        "file_type": "pdf"
      },
      "plan": null,
      "coupon": {
        "code": "WELCOME10",
        "discount_percentage": 10,
        "shipping_discount_percentage": null,
        "take_quantity": null,
        "pay_quantity": null
      }
    }
  ],
  "payments": [
    {
      "id": "4001",
      "product_id": "2001",
      "gateway_transaction_id": "pi_example_0001",
      "status": "approved",
      "sale_type": "retail",
      "recurring_cycle": null,
      "amount_in_cents": 1349,
      "tax_in_cents": 234,
      "tax_rate": 21,
      "sale_country": "AR",
      "sale_state": "CABA",
      "currency_id": "USD",
      "exchange_rate_to_usd": 1,
      "tenant_payout_in_cents": 1003,
      "payout_currency_id": "USD",
      "paid_at": "2026-01-15T14:30:00Z",
      "created_at": "2026-01-15T14:30:05Z"
    },
    {
      "id": "4002",
      "product_id": "2002",
      "gateway_transaction_id": "pi_example_0001",
      "status": "approved",
      "sale_type": "retail",
      "recurring_cycle": null,
      "amount_in_cents": 899,
      "tax_in_cents": 156,
      "tax_rate": 21,
      "sale_country": "AR",
      "sale_state": "CABA",
      "currency_id": "USD",
      "exchange_rate_to_usd": 1,
      "tenant_payout_in_cents": 669,
      "payout_currency_id": "USD",
      "paid_at": "2026-01-15T14:30:00Z",
      "created_at": "2026-01-15T14:30:05Z"
    }
  ]
}
```

:::info Tax in amounts
Every `amount_in_cents` includes tax, with the tax it carries in `tax_in_cents`. The charge's is what the gateway charged, and equals the sum of its payments' `amount_in_cents`. In the example, `1349 + 899 = 2248`.
:::

## `data.charge`

| Field                    | Type            | Description                                                                                                                                        |
| ------------------------ | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| `gateway_type`           | string          | Payment gateway that processed the charge, for example `stripe`.                                                                                   |
| `gateway_transaction_id` | string or null  | Transaction id at the payment gateway. Every payment of the charge has it.                                                                         |
| `status`                 | string          | Always `approved` in this event.                                                                                                                   |
| `recurring_cycle`        | integer or null | Billing cycle of a recurring subscription the charge pays, starting at 1. `null` for other charges. See [Tell charges apart](#tell-charges-apart). |
| `amount_in_cents`        | integer         | Amount charged, tax included.                                                                                                                      |
| `tax_in_cents`           | integer         | Tax included in `amount_in_cents`.                                                                                                                 |
| `currency_id`            | string or null  | ISO 4217 currency code of the charge.                                                                                                              |
| `paid_at`                | string          | ISO 8601 UTC charge date, as the gateway reported it.                                                                                              |

## `data.order`, `data.user` and `data.products`

The same fields as in [`order.paid`](./order-paid.md#dataorder): the order the charge belongs to, its buyer and every product of the order, not only the ones the charge pays for.

`order.status` is the status the charge leaves the order in: `approved` when the charge approved or renewed it, or the order's current status, such as `cancelled`, when the order was already closed.

## `data.payments`

The payments of this charge only, sorted by `id`, with the same fields as in [`order.paid`](./order-paid.md#datapayments). Earlier charges of the order are not included.

## Related Documentation

- [Webhooks](./overview.md): Endpoints, request format, signature verification and delivery.
- [`order.paid`](./order-paid.md): The event sent once per order, and the fields of `order`, `user`, `products` and `payments`.
- [Orders API](../rest-api-v3/orders/orders-v3-overview.md): The order types and fields this event mirrors.
