# Payments Webhook

The **Payments Webhook** notifies your server whenever a **successful payment** occurs, including subscription transactions (trial start, initial purchase, renewal, reactivation) and one-time (consumable) purchases.

Use this webhook to sync revenue events, unlock purchased content, log payment activity, and trigger post-purchase workflows (emails, CRM events, fulfillment, etc.).

## **When This Is Triggered**

A callback is sent whenever Zotlo records one of the following successful payment events:

| Event Type          | Description                                            |
| ------------------- | ------------------------------------------------------ |
| **trial**           | A free or paid trial has started                       |
| **start\_paid**     | A subscription started without trial                   |
| **trial\_to\_paid** | Trial converted into a paid subscription               |
| **renewal**         | A recurring subscription renewal succeeded             |
| **reactive**        | A canceled subscription was reactivated with a payment |
| **consumable**      | A one-time purchase was completed                      |

{% hint style="warning" %}
Refunds are **not** included here — they are handled by the [Refunds Webhook](https://docs.zotlo.com/integrating-zotlo/webhooks/refunds-webhook).
{% endhint %}

## Example Payload

{% code overflow="wrap" %}

```json
{
  "queue": {
    "type": "TransactionInsert",
    "eventType": "transaction",
    "requestID": "4fee-9169-a6b45555f89b",
    "createDate": {
      "date": "2024-06-15 11:51:35.807000",
      "timezone_type": 3,
      "timezone": "UTC"
    },
    "appId": 1
  },
  "parameters": {
    "id": "38359",
    "payment_type": "subscription",
    "original_transaction_id": "6kab56hfs773-a25f3ebf8e2f",
    "transaction_id": "ba3325ge3ad6791-49f4-9693-a25f3ebf8e2f",
    "package_id": "weekly_",
    "team_id": 22,
    "app_id": 1,
    "status": "trial",
    "create_date": "2024-06-15 11:51:35",
    "purchase_date": "2024-06-15 11:51:35",
    "original_purchase_date": "2024-06-15 11:51:35",
    "price": "0.00",
    "currency": "USD",
    "country": "US",
    "expire_date": "2024-06-22 11:51:35",
    "subscriber_id": "test@zotlo.com",
    "credit_card": "41111111****1111",
    "refund_price": null,
    "refund_date": null,
    "refund_reason": null,
    "is_refund": "0",
    "provider_id": 2222263,
    "provider_transaction_id": "417705901",
    "provider_status": "mastercard",
    "provider_name": "Credit Card",
    "quantity": 1,
    "package_price": 0,
    "subscription_id": "9292132",
    "custom_parameters": {
      "clientUuid": "0bb45b80-1ff5-42ee-a382-a5ee06e641c9",
      "dataWarehouse": {
        "paymentModule": "generate",
        "siteId": 38,
        "flowId": 600,
        "appId": 7,
        "teamId": 7,
        "acceptPolicy": true,
        "fullName": "test",
        "epinCode": "test1235"
      },
      "utm": {
        "source": null,
        "medium": null,
        "campaign": null,
        "term": null,
        "content": null
      },
      "cardBrand": "mastercard",
      "threeds": "1",
      "installment": "1",
      "bank": "lidio3p"
    },
    "paymentMethod": "creditCard",
    "installment": 1,
    "exchange": {
      "status": false,
      "detail": []
    },
    "coupon_campaign": {
      "isUsedCouponCode": false,
      "code": null,
      "discountType": null,
      "discountValue": null
    },
    "language": "en"
  }
}
```

{% endcode %}

## **Field Reference**

#### **queue**

Event metadata.

| Field                | Description                |
| -------------------- | -------------------------- |
| **queue.type**       | Always `TransactionInsert` |
| **queue.eventType**  | Always `transaction`       |
| **queue.requestID**  | Unique webhook delivery ID |
| **queue.createDate** | Payment timestamp          |
| **queue.appId**      | Project ID in Zotlo        |

#### **parameters**

Details about the successful payment.

#### **Core Transaction Fields**

| Field                         | Description                                                      |
| ----------------------------- | ---------------------------------------------------------------- |
| **id**                        | Internal payment record ID                                       |
| **payment\_type**             | `subscription` or `consumable` (one-time)                        |
| **transaction\_id**           | The unique ID used for refunds                                   |
| **original\_transaction\_id** | First transaction in a subscription chain                        |
| **status**                    | Payment lifecycle event (`trial`, `start_paid`, `renewal`, etc.) |
| **purchase\_date**            | Payment timestamp                                                |
| **expire\_date**              | Next billing date (subscriptions only)                           |
| **price**                     | Charged amount                                                   |
| **currency**                  | Payment currency                                                 |
| **country**                   | Country determined via IP                                        |
| **subscriber\_id**            | User email or phone                                              |
| **credit\_card**              | Masked card number                                               |
| **provider\_name**            | Payment provider (e.g., Credit Card, PayPal)                     |
| **provider\_transaction\_id** | Processor transaction ID                                         |
| **provider\_status**          | Card type, issuer, etc.                                          |

#### **Refund-Related Fields**

(Always null for payment webhook events, but included for consistency.)

| Field              | Description                                  |
| ------------------ | -------------------------------------------- |
| **refund\_price**  | Refunded amount (null for non-refund events) |
| **refund\_date**   | Refund date                                  |
| **refund\_reason** | Reason for refund                            |
| **is\_refund**     | Always `0` for this webhook                  |

#### **Subscription & Package Fields**

| Field                | Description                                |
| -------------------- | ------------------------------------------ |
| **package\_id**      | Purchased packageId                        |
| **package\_price**   | Defined package price                      |
| **quantity**         | Units/seats purchased                      |
| **subscription\_id** | Subscription ID (0 for one-time purchases) |

#### **Custom Metadata**

| Field                                | Description                                |
| ------------------------------------ | ------------------------------------------ |
| **custom\_parameters.clientUuid**    | User session identifier                    |
| **custom\_parameters.dataWarehouse** | Internal sales metadata (site, flow, team) |
| **custom\_parameters.utm**           | Campaign data                              |
| **custom\_parameters.epinCode**      | e-pin code if applicable                   |
| **custom\_parameters.cardBrand**     | Visa, Mastercard, etc.                     |
| **custom\_parameters.threeds**       | Whether 3DS was used                       |
| **custom\_parameters.installment**   | Installment count                          |

#### **Coupon Info**

| Field                | Description            |
| -------------------- | ---------------------- |
| **isUsedCouponCode** | Indicates coupon usage |
| **code**             | Coupon code            |
| **discountType**     | Percentage / fixed     |
| **discountValue**    | Discount amount        |

## **How To Use This Webhook**

Common use cases:

* Grant access to premium features after successful payment
* Log successful transactions in your backend billing system
* Trigger purchase confirmation emails
* Update dashboards or BI pipelines
* Trigger fulfillment (e-pin codes, digital goods)
* Enrich CRM events with revenue details
* Record internal audit logs

## **Best Practices**

* Use **transaction\_id** for all refund operations
* Use **payment\_type** to distinguish between subscriptions & one-time purchases
* Use **idempotency** on your side: ignore duplicate webhook deliveries
* Always return **HTTP 200** once processed successfully
