# Webhook Reference

Use webhooks to confirm payment status server-side. Redirect pages and frontend polling are not the source of truth.

## PHP SDK Handler

```php
use PonponPay\PonponPay;
use PonponPay\WebhookHandler;

$ponponpay = new PonponPay(getenv('PONPONPAY_API_KEY'));

try {
    $data = $ponponpay->webhook()->handle();
    $status = WebhookHandler::resolveStatus($data);

    if ($status === 'paid') {
        // Load local order by merchant order id or trade id.
        // Update it idempotently.
    }

    http_response_code(200);
    echo 'OK';
} catch (\PonponPay\Exception\SignatureException $e) {
    http_response_code($e->getHttpStatus());
    echo $e->getMessage();
}
```

## Implementation Rules

- Use the raw request body for signature verification.
- Return 2xx only after verification and idempotent processing.
- Store processed event IDs or order status transitions to avoid duplicate fulfillment.
- Log failed verification without logging secrets.
- Support retries by keeping the handler idempotent.

## Status Mapping

- `pending`: payment not complete.
- `paid`: payment confirmed or manual recharge.
- `expired`: payment expired.
- `cancelled`: payment cancelled.

## Manual Test

1. Create a low-value order.
2. Open the payment URL.
3. Complete payment or simulate callback in the dashboard.
4. Confirm the local business order changes only after webhook verification.
