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

# Webhooks

> Receive automatic notifications whenever something happens in your checkouts and orders.

Webhooks let the platform notify your system the moment something important happens — a checkout starts, a purchase is approved, a cart is abandoned, an order changes status, or a refund is confirmed.

Think of them as push notifications for servers: instead of polling the API asking "did anything change?", your endpoint receives the event data as soon as it happens.

## Why use webhooks?

Without webhooks, your application would have to keep asking the API, every few seconds, "was this purchase approved yet?" — slow and inefficient. With webhooks, the platform tells you immediately, and you can:

* update the status of an order in your system
* fire conversion events in your tracker
* trigger automations — emails, fulfillment, CRM
* record financial movements

All automatically, without polling and without making anyone wait.

## How it works

1. You create an HTTPS endpoint in your system, e.g. `https://yoursite.com/webhooks/pagamerican`.
2. You register that endpoint in **Integrations > Webhooks** and pick which events it should receive.
3. When an enabled event happens, the platform sends a `POST` with `Content-Type: application/json` to your URL.
4. Your system processes the event and responds with a success status (2xx).

One important detail: the body is always a **JSON array containing a single object**, not a plain object.

```json theme={null}
[
  {
    "event": "...",
    "body": { ... }
  }
]
```

Your parser must expect this array and read its first (and only) element. This applies to every event, no exceptions. The registered URL is called exactly as it is — no placeholder substitution (like `{some_value}`) is performed.

## Creating a webhook in the dashboard

<Steps>
  <Step title="Open Integrations > Webhooks">
    This is where you create and manage your notification endpoints. Click to create a new one.
  </Step>

  <Step title="Configure the endpoint">
    Give it a **name** (internal use, to tell your integrations apart) and the HTTPS **URL** that will receive the events.
  </Step>

  <Step title="Pick the events">
    Enable the events this endpoint should receive. Each endpoint has its own toggles, independent from the others.
  </Step>

  <Step title="Set the product scope and save">
    All products, specific products, or specific offers of a single product.
  </Step>
</Steps>

You can register as many endpoints as you need, each with its own URL, events, and product scope — for example, one endpoint just for **Purchase approved** of a specific product and another for all events of all products.

## Supported events

| Event                                                            | When it fires                                                 |
| ---------------------------------------------------------------- | ------------------------------------------------------------- |
| [`checkout.session.initialized.v2`](/webhooks/initiate-checkout) | The buyer starts the checkout                                 |
| [`order.purchase.created.v1`](/webhooks/purchase-approved)       | A purchase is approved — also fires for upsells and downsells |
| [`checkout.session.abandoned.v-1.0.0`](/webhooks/abandoned-cart) | A checkout session is abandoned                               |
| [`order.status.updated.v1`](/webhooks/order-status-updated)      | The order status changes                                      |
| [`refund.transaction.confirmed.v1`](/webhooks/order-refunded)    | A refund is confirmed                                         |

The detailed payload of each event is documented individually in the **Events** section in the sidebar. Every order payload includes an `isTest` flag so you can tell test deliveries apart.

## Tracking parameters

The checkout captures the query string of the link that brought the buyer. Order events return it in the `trackingParameters` object with a fixed set of keys: `src`, `sck`, `utm_source`, `utm_campaign`, `utm_medium`, `utm_content`, and `utm_term`.

Keys outside this set (a custom parameter of your own, for example) are **not** returned. If you need an identifier of yours back in the payload, send it in `src`, `sck`, or one of the `utm_*` parameters.

<Note>
  Exception: [Abandoned cart](/webhooks/abandoned-cart) returns the full captured query string, unfiltered, in the `searchParams` field.
</Note>

## Amounts and commission

Every order-related event includes a `commission` object with the transaction amounts, **always in cents**:

* `totalPriceInCents` — total sale amount (the ticket).
* `userCommissionInCents` — net commission of whoever registered the endpoint (creator or affiliate).
* `gatewayFeeInCents` — fee charged on the transaction.
* `currency` — transaction currency.

Individual item prices are also in cents, in `products[].priceInCents`.

### The `amounts` breakdown

[Purchase approved](/webhooks/purchase-approved), [Order status updated](/webhooks/order-status-updated), and [Order refunded](/webhooks/order-refunded) also include an `amounts` object with the full financial breakdown of the charge — items, coupons, shipping, tax, and the total the customer actually paid:

```json theme={null}
"amounts": {
  "itemsGrossInCents": 29400,
  "itemsCouponInCents": 0,
  "itemsNetInCents": 29400,
  "shippingGrossInCents": 0,
  "shippingCouponInCents": 0,
  "shippingNetInCents": 0,
  "taxesInCents": 1764,
  "totalInCents": 31164,
  "currency": "USD"
}
```

* `itemsGrossInCents`, `itemsCouponInCents`, `itemsNetInCents` — items total, coupon discount on items, and items total after coupons.
* `shippingGrossInCents`, `shippingCouponInCents`, `shippingNetInCents` — the same breakdown for shipping.
* `taxesInCents` — sales tax amount.
* `totalInCents` — the amount actually charged to the customer.
* `currency` — transaction currency, uppercase (e.g. `USD`).

<Note>
  `totalInCents` is the charged amount and is **not always the sum of the other fields**: when the tax is inclusive, it is already embedded in the item price.

  [Initiate checkout](/webhooks/initiate-checkout) and [Abandoned cart](/webhooks/abandoned-cart) don't include `amounts` — tax is only calculated at payment time.
</Note>

## Best practices

* Use HTTPS on every endpoint.
* Respond quickly with a 2xx and process the heavy work asynchronously — each delivery attempt waits at most 10 seconds.
* Process idempotently: deliveries are at-least-once, so duplicates are possible. Use `orderId` + `event` to detect events you already handled.
* Don't assume ordering between events of the same order — use `status` and `updatedAt` from the payload to determine the latest state.
* Don't strictly validate the entire payload schema: new fields may be added over time and shouldn't break your endpoint.

For timeouts, retries, delivery logs, and troubleshooting, see [Delivery and logs](/webhooks/delivery).

<Card title="Need help?" icon="envelope" href="mailto:support@pagamerican.com">
  Our team can help you set up your integration — [support@pagamerican.com](mailto:support@pagamerican.com)
</Card>
