Webhook Event Types
All payment events sent by GriffNode webhooks
GriffNode fires a webhook for each significant change in a transaction's state. Subscribe to only the events you need from the dashboard.
Available Events
| Event | Trigger |
|---|---|
payment.created |
A transaction was just created and is awaiting payment |
payment.pending |
A payment was detected on-chain and is awaiting the required confirmations |
payment.completed |
Transaction reached the required number of confirmations and is fully paid |
payment.overpaid |
Fully paid, but the amount received exceeded what was owed |
payment.partial |
An amount less than required was detected on the deposit address, transaction enters indefinite hold |
payment.expired |
The 60-minute payment window elapsed with no payment detected |
payment.failed |
A system-level failure prevented the transaction from completing normally |
payment.paid_late |
Coins arrived on the deposit address within 6 hours after the payment window closed. The funds are in your wallet but the order is NOT completed automatically (the locked price expired): you decide in the dashboard, Mark as paid (you then also get payment.completed) or Dismiss after refunding. status is expired, exception is paid_late |
payment.needs_review |
ETH/ERC-20 only: the deposit address balance dropped while the checkout was open (funds were sent out of that wallet account), so whether the customer paid can't be determined. Check your wallet, then Mark as paid or Dismiss in the dashboard. status is pending, exception is needs_review |
Payload Fields
| Field | Type | Description |
|---|---|---|
event |
string | Event name, e.g. payment.completed |
timestamp |
string (ISO 8601) | Time the event was fired |
transaction_id |
string | Transaction ID, e.g. MTX-A1B2C3D4 |
status |
string | New transaction status at time of event |
exception |
string, optional | Present only when the payment waits for your decision: paid_late or needs_review |
currency_crypto |
string | Cryptocurrency used, e.g. BTC |
amount_fiat |
string | USD amount as a decimal string, e.g. "25.00" |
amount_crypto |
string | Crypto amount as a decimal string, e.g. "0.00025431" |
currency_fiat |
string | Fiat currency of the amounts, e.g. EUR |
amount_usd |
string | USD-equivalent amount as a decimal string, e.g. "107.60" |
receipt_url |
string | Shareable proof-of-payment link. Present on payment.completed and payment.overpaid only. |
order_id |
string | Your order/reference ID, if provided when creating the transaction. Use this to automate fulfillment. |
metadata |
object | Your free-form key/value pairs, returned verbatim. Only present if metadata was supplied at creation. |
Recurring Payment Events
Sent for recurring payment requests (Dashboard → Payment Links → Recurring payments). Every payload carries schedule_id and your own reference (the customer or order id you entered), so you can match it without a lookup. The customer's payment also fires the normal payment.* events.
| Event | When it fires |
|---|---|
recurring.confirmed | The customer confirmed they want the payment requests (nothing is sent before this) |
recurring.payment.completed | The customer paid a period. Includes period_no and transaction_id |
recurring.payment.unpaid | A period's link expired unpaid. The schedule is paused (status: paused) until you resume or cancel it. Includes period_no |
recurring.stopped | The schedule ended without you: reason is stopped_by_customer, bounced (the email address doesn't work) or unconfirmed (not confirmed within 7 days) |
Fields: schedule_id, reference, customer_email, description, amount_fiat, currency_fiat, interval, status, plus period_no / transaction_id / reason where noted. The envelope (id, event, timestamp) and the signature are the same as for payment events.
Example Payloads
payment.completed
{
"event": "payment.completed",
"timestamp": "2026-03-08T10:30:00Z",
"transaction_id": "MTX-A1B2C3D4",
"status": "completed",
"currency_crypto": "BTC",
"currency_fiat": "EUR",
"amount_fiat": "100.00",
"amount_usd": "107.60",
"amount_crypto": "0.00109462",
"order_id": "ORDER-1234",
"metadata": { "user_id": "usr_443", "plan": "pro" }
}
payment.partial
{
"event": "payment.partial",
"timestamp": "2026-03-08T10:35:00Z",
"transaction_id": "MTX-A1B2C3D4",
"status": "partial",
"currency_crypto": "BTC",
"currency_fiat": "USD",
"amount_fiat": "25.00",
"amount_usd": "25.00",
"amount_crypto": "0.00010000"
}
payment.expired
{
"event": "payment.expired",
"timestamp": "2026-03-08T11:30:00Z",
"transaction_id": "MTX-A1B2C3D4",
"status": "expired",
"currency_crypto": "BTC",
"currency_fiat": "USD",
"amount_fiat": "25.00",
"amount_usd": "25.00",
"amount_crypto": "0.00025431"
}