Replace URL token auth with the official webhook secret signature check. Add SETUP.md and separate TEST_TOKEN for the Postmark test endpoint. Co-authored-by: Cursor <cursoragent@cursor.com>
74 lines
1.7 KiB
Markdown
74 lines
1.7 KiB
Markdown
# BTCPay webhook reference
|
|
|
|
## Endpoint
|
|
|
|
```
|
|
POST https://mailer.nxtgroup.org/btcpay-webhook
|
|
```
|
|
|
|
No query-string token. BTCPay signs each request with the **webhook secret** from the store webhook settings.
|
|
|
|
## Authentication
|
|
|
|
BTCPay sends header `BTCPAY-SIG`:
|
|
|
|
```
|
|
sha256=<hmac-sha256-hex>
|
|
```
|
|
|
|
The HMAC is computed over the **raw request body bytes** using the webhook **Secret** shown in BTCPay (same value as `BTCPAY_WEBHOOK_SECRET` in Portainer).
|
|
|
|
## Disable quickly
|
|
|
|
1. **BTCPay** → Store → **Webhooks** → delete or disable the webhook.
|
|
2. **Portainer** → Stacks → `btcpaymailer` → stop/remove the stack.
|
|
|
|
## Event subscribed
|
|
|
|
Only **`InvoiceReceivedPayment`** is processed. Other events return `200` with `"ignored"` (silent unless `DEBUG=true`).
|
|
|
|
## Webhook body (BTCPay → mailer)
|
|
|
|
```json
|
|
{
|
|
"deliveryId": "abc123",
|
|
"webhookId": "wh_xyz",
|
|
"isRedelivery": false,
|
|
"type": "InvoiceReceivedPayment",
|
|
"timestamp": 1717843200,
|
|
"storeId": "your-store-id",
|
|
"invoiceId": "invoice-id-here"
|
|
}
|
|
```
|
|
|
|
The app then fetches the full invoice:
|
|
|
|
```
|
|
GET {BTCPAY_URL}/api/v1/stores/{storeId}/invoices/{invoiceId}
|
|
```
|
|
|
|
## Send conditions
|
|
|
|
1. Valid `BTCPAY-SIG` signature
|
|
2. `type == InvoiceReceivedPayment`
|
|
3. BTCPay API returns invoice
|
|
4. `status == "New"`
|
|
5. `0 < amountPaid < amount`
|
|
6. `metadata.buyerEmail` is set
|
|
|
|
## Response codes
|
|
|
|
| Code | Meaning |
|
|
|------|---------|
|
|
| `401` | Missing or invalid `BTCPAY-SIG` |
|
|
| `400` | Partial payment but no `buyerEmail` |
|
|
| `500` | BTCPay API or Postmark failure |
|
|
| `200` | Ignored, or email sent |
|
|
|
|
## Logging
|
|
|
|
| `DEBUG` | Container logs |
|
|
|---------|----------------|
|
|
| `false` | Evaluation + send result for payment events only |
|
|
| `true` | Full payload and every decision step |
|