Log partial-payment decisions and email results to stdout for Portainer logs; DEBUG enables full webhook payload tracing. Document BTCPay payload and shutdown steps in WEBHOOK.md. Co-authored-by: Cursor <cursoragent@cursor.com>
2.5 KiB
2.5 KiB
BTCPay webhook reference
Endpoint
POST https://mailer.nxtgroup.org/btcpay-webhook?token=YOUR_WEBHOOK_SECRET
Auth is the token query parameter (must match WEBHOOK_SECRET). BTCPay’s optional webhook signing secret is not used by this app.
Disable quickly
- BTCPay → Store → Settings → Webhooks → delete or disable the webhook.
- Portainer → Stacks →
btcpaymailer→ stop/remove the stack.
No emails are sent while the webhook is disabled or the stack is down.
Event subscribed
Only InvoiceReceivedPayment is processed. All other event types return 200 with "ignored" and are silent unless DEBUG=true.
Webhook body (BTCPay → mailer)
Typical payload:
{
"deliveryId": "abc123",
"webhookId": "wh_xyz",
"originalDeliveryId": "abc123",
"isRedelivery": false,
"type": "InvoiceReceivedPayment",
"timestamp": 1717843200,
"storeId": "your-store-id",
"invoiceId": "invoice-id-here"
}
Fields used by this app from the webhook:
| Field | Use |
|---|---|
type |
Must be InvoiceReceivedPayment |
storeId |
Fetch invoice from BTCPay API |
invoiceId |
Fetch invoice from BTCPay API |
The webhook does not include full payment amounts or buyer email. The app calls:
GET {BTCPAY_URL}/api/v1/stores/{storeId}/invoices/{invoiceId}
Invoice fields used (BTCPay API response)
| Field | Use |
|---|---|
amount |
Invoice total |
amountPaid |
Paid so far |
currency |
e.g. USD, BTC |
status |
Must be New for partial-payment email |
metadata.buyerEmail |
Recipient (required to send) |
metadata.orderId |
Shown in email subject/body |
Send conditions (all must pass)
type == InvoiceReceivedPayment- BTCPay API returns invoice successfully
status == "New"0 < amountPaid < amount(partial payment, not zero or full)metadata.buyerEmailis set
Otherwise the handler returns 200 with "ignored" or 400 if buyer email is missing on a qualifying partial payment.
Logging
DEBUG |
What appears in container logs |
|---|---|
false (default) |
Evaluation + send result for InvoiceReceivedPayment only |
true |
Every webhook, full payload, each decision step |
View logs in Portainer → Containers → btcpay-mailer → Logs.
Response codes
| Code | Meaning |
|---|---|
401 |
Wrong or missing token |
400 |
Partial payment but no buyerEmail |
500 |
BTCPay API or Postmark failure |
200 |
Ignored, or email sent successfully |