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

# Webhooks (Transactions)

> Sync your wallet with smatvirtual events via real-time bulk webhooks.

Webhooks allow your system to receive real-time notifications from **smatvirtual** whenever a transaction occurs. Our system uses a **Bulk Payload** architecture to ensure high throughput and reliability, especially during high-traffic tournament events.

## Configuration

1. Log in to the **smatvirtual Merchant Dashboard**.
2. Navigate to the **Webhook Settings** section.
3. Enter your listener URL and save the changes.
4. You can enable receiving webhooks for specific event types to a specific URL only, by checking the checkbox for the seperate webhook URL field.

***

## Event Types

All events share a similar payload structure but represent different financial movements.

| Event                    | Description                                                           |
| :----------------------- | :-------------------------------------------------------------------- |
| `charge.debit`           | Standard game entry or stake deduction.                               |
| `charge.credit`          | Winnings distribution at the end of a game round.                     |
| `tournament.bulk.credit` | **Flagship Engine:** Bulk reward distribution for tournament winners. |
| `charge.refund`          | Reversals for failed transactions or **Retention Refunds**.           |

***

## Payload Structure

Every request sent to your webhook URL will follow this bulk format. Even if there is only one transaction, it will be sent inside an array (`bulkData`) to maintain consistency.

```json JSON theme={null}
{
  "event": "charge.debit" | "charge.credit" | "charge.refund",
  "data": {
    "playerId": "10039913",
    "roundId": "unique-round-id",
    "sessionId": "sess_12345",
    "gameName": "Cube+ Color",
    "status": "PENDING" | "ENDED",
    "transactionId": "unique-transaction-id",
    "stakeAmount": 10.0,
    "amountWon": 0,
    "metadata": "{type: "DEBIT", gameType: "DICE_COLOR", gameName: "Cube+ Color"}",
    "currency": "NGN"
  }
}
```

***

## Field Definitions

* transactionId: A unique ID for the specific transaction. Required for idempotency checks.
* status: `PENDING` if the game round is ongoing; `ENDED` if the round is finalized.
* stakeAmount: The amount to be deducted (in debits) or the original bet (in credits).
* amountWon: The amount to be added to the player's wallet.

***

## Specialized Refund Logic

The `charge.refund` event is unique to smatvirtual and is triggered in two specific scenarios:

1. Technical Anomalies: If a debit cannot be validated or a system error occurs, a refund is issued to ensure player fairness.
2. Retention Strategy: To enhance player satisfaction, our system automatically triggers a refund if a player suffers five (5) consecutive losses within a single session.

***

## Response Requirements

Your server `must` acknowledge the webhook by returning an HTTP 200 or 201 status code.

| Status Code    | Meaning                                                       |
| :------------- | ------------------------------------------------------------- |
| 200 OK         | Event received and processed successfully.                    |
| 201 Created    | Event acknowledged.                                           |
| Any other code | smatvirtual will consider this a failure and attempt retries. |

<CodeGroup>
  ```json Success.json theme={null}
  {
    "status": 200,
    "message": "processed"
  }
  ```
</CodeGroup>

<Note>
  If your system is not ready to process the transaction immediately, it is
  better to return a 200 OK with a "pending" message than to return an error.
  This prevents unnecessary retry attempts.
</Note>

## Best Practices & Security

<AccordionGroup>
  <Accordion icon="shield-check" title="Implement Idempotency">
    Always store the transactionId. If you receive a webhook with an ID you have
    already processed, return 200 OK immediately without adjusting the player's
    balance a second time.
  </Accordion>

  <Accordion icon="clock" title="Handling Timeouts">
    Your webhook should respond within 2 seconds. If your wallet processing
    takes longer, acknowledge the webhook first and process the transaction in
    the background.
  </Accordion>

  <Accordion icon="filter" title="Verify IP Origin">
    For enhanced security, ensure that your webhook endpoint only accepts
    traffic from smatvirtual's authorized IP addresses.
  </Accordion>
</AccordionGroup>

<Note>
  Need to test? Use a tool like Webhook.site or Ngrok during development to
  inspect the raw payloads sent from the smatvirtual dashboard.
</Note>
