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

# Introduction

When integrating with the Subotiz system, merchants can configure a Webhook notification endpoint to receive account-related events in real-time. This enables the backend system to trigger corresponding business logic processing (such as payment status updates, subscription status changes, etc.).

## Notification Principle

When specific events are triggered within the Subotiz system, an HTTPS POST request will be sent to the configured Webhook endpoint. The request contains the following key elements:

* **Request Payload**: A structured event object compliant with JSON format specifications, containing the event identifier, type, and specific business data.
* **Request Headers**: Include specific headers used for authentication and request identification (e.g., X-Timestamp, X-Signature).

## Request Composition

### Request Headers

| **Header Name** | **Example Value**            | **Description**                                              |
| --------------- | ---------------------------- | ------------------------------------------------------------ |
| X-Timestamp     | 1525872629832                | Millisecond timestamp used in signature calculation          |
| Content-Type    | application/json             |                                                              |
| X-Access-No     | 100001                       | Unique access number (`access_no`) for the integrating party |
| X-Signature     | 54ea681fed566566c778a9aa1608 | The signature string                                         |

### Request Body Structure

<Tabs>
  <Tab title="V1">
    | **Field** | **Type** | **Description**                                                                        | **Example**          |
    | --------- | -------- | -------------------------------------------------------------------------------------- | -------------------- |
    | id        | uint64   | Event id                                                                               | 545440011265267736   |
    | type      | string   | Event type                                                                             | payment.success      |
    | created   | string   | Creation time                                                                          | 2025-07-01T10:25:25Z |
    | data      | object   | Business object specific to the event type. The data structure varies for event types. |                      |
  </Tab>

  <Tab title="V2">
    | **Field** | **Type** | **Description**                                                                        | **Example**          |
    | --------- | -------- | -------------------------------------------------------------------------------------- | -------------------- |
    | id        | string   | Event id                                                                               | 545440011265267736   |
    | type      | string   | Event type                                                                             | payment.success      |
    | created   | string   | Creation time                                                                          | 2025-07-01T10:25:25Z |
    | data      | object   | Business object specific to the event type. The data structure varies for event types. |                      |
  </Tab>
</Tabs>

## Event Handling Specifications

### Reliability Verification

Before processing an event, verify the legitimacy of the request through the following steps:

1. **Extract Parameters**: Obtain the X-Timestamp from the request headers (denoted as `timestamp`), and get the raw request body content (denoted as `body`).

2. **Construct Signature Original String**: Format is`${timestamp}.${body}`.

3. **Calculate Signature**: Using the `API Key` assigned by Subotiz as the secret key, compute the signature value via the HMAC-SHA256 algorithm.

   Example code: GO

   ```go theme={null}
   // Calculate Signature
   func CalcSignature(timestamp int64, body []byte, secret string) string {
       mac := hmac.New(sha256.New, []byte(secret))
       mac.Write([]byte(fmt.Sprintf("%d", timestamp)))
       mac.Write([]byte("."))
       mac.Write(body)
       return hex.EncodeToString(mac.Sum(nil))
   }
   ```

<br />

4. **Compare and Verify**: Compare the calculated signature with the X-Signature value from the request headers. If they match, the request is legitimate.

### Handling Signature Verification During Key Rotation

When a key rotation is initiated, Subotiz will continue signing Webhook requests with the **old key** throughout the grace period. Once the old key expires, it automatically switches to the new key.

**It is recommended that your endpoint support signature verification with both keys during the grace period**, using the following approach:

1. First, compute the signature using the **old key** and compare it against X-Signature.
2. If verification fails, recompute using the **new key** and compare again.
3. If both fail, treat the request as illegitimate and reject it.

This ensures no Webhook events are lost during the key transition period.

## Processing Requirements

* **Idempotency**: Implement idempotent processing for duplicate events based on the unique event id to avoid duplicate operations.
* **Event Filtering**: Identify relevant event types based on the typefield. Return an HTTP 200 status code directly for non-relevant types.
* **Order Independence**: The system does not guarantee the order of events. For critical business processes, actively query the latest status via API to synchronize.

## Response and Retry Mechanism

* **Successful Response**: Return an HTTP 200 status code upon successful event processing to indicate successful handling.
* **Failure and Retry**: If a non-200 status code is returned or a timeout occurs, the system will perform retries with backoff within 48 hours, up to 16 times. The initial interval is 1 minute, doubling each time (e.g., 1m, 2m, 4m, ...), with a maximum interval cap of 4 hours between retries.
