Docs/Payment-API
SPICEPAY DEVELOPER DOCS

Webhook events

SpicePay posts signed event envelopes to the shop's configured endpoint.

How it works

SpicePay posts signed event envelopes to the shop's configured endpoint. Payment, refund, dispute, mandate, payout, subscription and invoice updates can all arrive through this channel.

Implementation

Verify the signature before parsing trusted content, persist or queue the event, then acknowledge with 2xx. Deduplicate by event_id and make order updates idempotent. Events may overlap or arrive out of order, so retrieve the resource when reconciling uncertain state. Check test_mode before fulfilment and compare amount and currency to the order. Full capture produces payment_succeeded; partial capture should not automatically fulfil an entire order. Unknown event types should be acknowledged without side effects.

Payload

content.type content.object
payment_details The payment, as GET /payments/{payment_id} returns it
refund_details The refund
dispute_details The dispute
mandate_details The mandate
payout_details The payout
subscription_details See Subscription payloads
merchant_invoice_details The invoice or credit note
shop_risk_details The shop's risk band escalation

Payments

Event Payment status
payment_succeeded succeeded (includes a full capture)
payment_failed failed or declined
payment_processing processing or partially_captured_and_processing
payment_authorized requires_capture
payment_partially_authorized partially_authorized_and_requires_capture
payment_captured partially_captured or partially_captured_and_capturable
payment_cancelled cancelled
payment_cancelled_post_capture cancelled_post_capture
payment_expired expired
action_required requires_customer_action, requires_merchant_action or conflicted

Refunds, disputes and mandates

Event Meaning
refund_succeeded Refund completed
refund_failed Refund failed
dispute_opened Dispute opened
dispute_challenged Evidence submitted
dispute_accepted You accepted
dispute_won Resolved in your favour
dispute_lost Resolved in the buyer's favour
dispute_expired Response deadline passed
dispute_cancelled Withdrawn
mandate_active Mandate can be charged
mandate_revoked Mandate revoked

Subscriptions

Event Meaning
subscription_created Created through the API; waiting for the buyer
subscription_active Active for the first time
subscription_past_due Now unpaid
subscription_paused Paused
subscription_resumed Active after a pause, or scheduled cancellation undone
subscription_cancelled Cancelled, or cancellation scheduled for period end
subscription_expired Now in_active
invoice_paid Billing cycle paid
invoice_payment_failed Renewal attempt failed; not necessarily past due
invoice_disputed A cycle the billing processor collected was charged back

Invoices and risk

Event Meaning
merchant_invoice_finalized Invoice or credit note issued; invoice.kind says which
merchant_invoice_voided Issued invoice voided
shop_risk_band_escalated Shop's risk band rose between two assessments

Subscription payloads

Event Object
invoice_paid Subscription with the paid cycle in invoice; payment is null when the billing processor collected it
invoice_disputed The chargeback: dispute_id, subscription_id, invoice_id, amount, currency, dispute_status, test_mode, processor IDs
Other subscription events Snapshot: subscription_id, status, transition_id, test_mode, current_period_end, cancelled_at, cancellation_reason, cancel_at_period_end

Retries

Response Result
2xx Delivered
Network error, timeout, 5xx, 408, 429 Retried; Retry-After (seconds) on 429 respected
401, 403 6 retries over about 41 minutes
Other 4xx No retry

HTTP example

json
{
  "merchant_id": "mer_xxxxx",
  "event_id": "evt_xxxxx",
  "event_type": "payment_succeeded",
  "timestamp": "2026-07-13T10:24:31Z",
  "content": {
    "type": "payment_details",
    "object": {
      "payment_id": "pay_xxxxx",
      "status": "succeeded",
      "amount": 1000,
      "currency": "USD",
      "test_mode": false,
      "metadata": { "order_id": "2042" }
    }
  }
}

Request examples

bash
curl -X POST https://api.spicepay.net/events/mer_xxxxx \
  -H 'api-key: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"object_id": "pay_xxxxx", "limit": 20}'
bash
curl https://api.spicepay.net/events/mer_xxxxx/evt_xxxxx/attempts \
  -H 'api-key: YOUR_API_KEY'

curl -X POST https://api.spicepay.net/events/mer_xxxxx/evt_xxxxx/retry \
  -H 'api-key: YOUR_API_KEY'