Skip to main content

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, and follows the 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 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:

ChargeHow to recognize it
Publica One redemptionA payment has sale_type publica_one_redemption.
Shipping charge aloneEvery payment has sale_type shipping.
First charge of a subscriptioncharge.recurring_cycle is 1.
Subscription renewalcharge.recurring_cycle is greater than 1.
One-time purchasecharge.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, which is sent only for the first purchase.

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

Payload​

{
"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": "[email protected]",
"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"
}
]
}
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​

FieldTypeDescription
gateway_typestringPayment gateway that processed the charge, for example stripe.
gateway_transaction_idstring or nullTransaction id at the payment gateway. Every payment of the charge has it.
statusstringAlways approved in this event.
recurring_cycleinteger or nullBilling cycle of a recurring subscription the charge pays, starting at 1. null for other charges. See Tell charges apart.
amount_in_centsintegerAmount charged, tax included.
tax_in_centsintegerTax included in amount_in_cents.
currency_idstring or nullISO 4217 currency code of the charge.
paid_atstringISO 8601 UTC charge date, as the gateway reported it.

data.order, data.user and data.products​

The same fields as in order.paid: 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. Earlier charges of the order are not included.

  • Webhooks: Endpoints, request format, signature verification and delivery.
  • order.paid: The event sent once per order, and the fields of order, user, products and payments.
  • Orders API: The order types and fields this event mirrors.