# Webhook Event

The **Payment Processing Completed Webhook** is sent by Convergegate to notify your system when a payment has reached a **finalized state**.\
This webhook enables real-time updates in your application without polling the API.

***

#### 🔒 Authorization

* **Type:** `SignatureAuth`
* **Signature Algorithm:** `HMAC-SHA256`
* **Secret:** Shop Signing Key
* **Header Parameter Name:** `Signature`
* The signature is computed from the **raw JSON request body** using the Shop Signing Key as the HMAC secret.

> **⚠️ Important:**\
> The `Signature` header is only included **after** a **Signing Key** has been generated for the shop.\
> Without a Signing Key, webhook requests will **not** include this header.\
> You can generate a Signing Key in the merchant back office.

***

#### Webhook URL

The webhook endpoint must be implemented by the merchant and exposed via HTTPS.\
Your server should respond with **HTTP 200 OK** to confirm successful receipt. Any non-2xx response will trigger retries according to Convergegate retry policy.

***

#### Payload Structure

**Content-Type:** `application/json`

| Field                        | Type                 | Description                                                            |
| ---------------------------- | -------------------- | ---------------------------------------------------------------------- |
| `id`                         | string (≤ 32 chars)  | Payment ID.                                                            |
| `referenceId`                | string (≤ 256 chars) | Merchant-provided reference ID.                                        |
| `created`                    | string (ISO 8601)    | Payment creation date/time (UTC).                                      |
| `paymentType`                | string               | One of: `DEPOSIT`, `WITHDRAWAL`, `REFUND`.                             |
| `state`                      | string               | Final state: `COMPLETED`, `DECLINED`, `CANCELLED`.                     |
| `description`                | string (≤ 512 chars) | Transaction description.                                               |
| `parentPaymentId`            | string (≤ 32 chars)  | ID of the initial payment in the chain.                                |
| `paymentMethod`              | string               | One of: `BASIC_CARD`, `BASIC_CARD_HPP`, `PIX`, `OPEN_BANKING`, `BLIK`. |
| `paymentMethodDetails`       | object               | Amount, currency, and provider-specific info.                          |
| `errorCode` / `errorMessage` | string               | Populated for failed payments.                                         |
| `customer`                   | object               | Customer and billing details.                                          |
| `redirectUrl`                | string               | Redirect URL for the customer (if applicable).                         |

**Example Webhook Body**

```json
{
  "id": "a1b2c3d4e5f6g7h8i9j0",
  "referenceId": "ORDER-12345",
  "created": "2025-08-14T15:32:00Z",
  "paymentType": "DEPOSIT",
  "state": "COMPLETED",
  "description": "Payment for ORDER-12345",
  "parentPaymentId": "z9y8x7w6v5u4t3s2r1q0",
  "paymentMethod": "BLIK",
  "paymentMethodDetails": {
    "amount": 100.00,
    "currency": "PLN"
  },
  "customer": {
    "billingAddress": {
      "line1": "Main Street 123",
      "city": "Warsaw",
      "country": "PL",
      "zip": "00-410"
    }
  }
}
```

#### Verifying the Signature

1. Retrieve the `Signature` header from the webhook request.
2. Compute `HMAC-SHA256` over the **raw JSON body** using the **Shop Signing Key**.
3. Compare the result to the value in the `Signature` header.
4. Reject the request if the values do not match.

***

#### Best Practices

* Always validate the signature before processing the webhook.
* Store and log the raw webhook payload for troubleshooting.
* Use **idempotency** in your processing logic to avoid double updates.
* Make sure your webhook endpoint is **publicly accessible** and **HTTPS-secured**.
