Skip to Content
FluxStore is currently invite-only. Some sections of this documentation are still being written and expanded.
APIWebhooksOverview

Webhooks

Receive real-time HTTP notifications when events occur in your store. Webhooks allow you to integrate FluxStore with external services such as Discord bots, CRMs, analytics platforms, and custom applications.

Overview

When an event occurs in your store (e.g. a payment is completed), FluxStore sends an HTTP POST request to your configured webhook URL with a JSON payload describing the event. Your endpoint should respond with a 2xx status code to acknowledge receipt.

Webhooks are a Pro plan feature.

Setup

  1. Navigate to Dashboard > Webhooks
  2. Enter your webhook URL
  3. Toggle the events you want to receive
  4. Optionally use the Package Filter to scope webhooks to a specific set of packages (see below)
  5. Save your configuration

A signing secret is automatically generated when you create your webhook endpoint. Use this secret to verify that incoming requests are genuinely from FluxStore.

Package filter

The Package Filter controls which packages trigger webhooks for events that are scoped to a package (all order.*, subscription.* events). Events without package context (refunds, chargebacks) ignore the filter.

Pick one of two modes:

  • Deny-list (default): webhooks fire for every package except the ones you list. Use this when you have a few packages you don’t want to notify your plugin about: donations, in-game currency, cosmetic-only rewards, etc.
  • Allow-list: webhooks fire only for the packages you list. Use this when your plugin handles a narrow subset and you don’t want noise from the rest of the store.

For a mixed-cart order, the rule applies to the order as a whole:

  • Deny-list: the order is skipped only when every item is on the list. An order with one listed package and one unlisted package still fires; your plugin sees the full items array and should ignore the listed IDs.
  • Allow-list: the order fires when any item matches the list. Again the payload contains the full items array; filter on your end.

An empty allow-list means nothing passes. The dashboard will ask you to confirm before saving an enabled webhook with an empty allow-list.

Event types

Payment events

EventDescription
order.completedA payment has been successfully processed. See order.completed
order.createdA new order has been placed (before payment is confirmed). See order.created
payment.declinedA payment attempt has been rejected by the payment provider. See payment.declined
payment.refundedA payment has been refunded (via dashboard or payment provider). See payment.refunded

Dispute events

EventDescription
dispute.openedA chargeback or payment dispute has been initiated. See dispute.*
dispute.wonA dispute has been resolved in your favor. See dispute.*
dispute.lostA dispute has been resolved against you. See dispute.*
dispute.closedA dispute has been closed. See dispute.*

Subscription events

EventDescription
subscription.startedA new subscription has been created. See subscription.started
subscription.renewedA recurring subscription payment has been processed. See subscription.renewed
subscription.cancelledA subscription cancellation has been requested. See subscription.cancelled
subscription.resumedA cancelled subscription has been resumed before the billing period ended. See subscription.resumed
subscription.server_changedA subscriber’s renewal server has been changed (by the customer or an admin). See subscription.server_changed
subscription.endedA subscription has been fully terminated. See subscription.ended

Utility events

EventDescription
test.pingSent when you click “Test Webhook” in the dashboard. See test.ping

Webhook payload

All webhooks are sent as POST requests with a Content-Type: application/json header. Every payload follows the same envelope structure:

{ "event": "order.completed", "timestamp": "2026-03-09T12:00:00Z", "store_id": "a1b2c3d4-...", "data": { // Event-specific data } }

Request headers

Every webhook request includes the following headers:

HeaderDescription
Content-TypeAlways application/json
X-Webhook-SignatureHMAC-SHA256 signature of the request body
X-Webhook-EventThe event type (e.g. order.completed)
X-Webhook-IdUnique delivery ID for idempotency

Delivery & retries

  • Webhooks are delivered within seconds of the event occurring
  • If your endpoint returns a non-2xx status code or times out, FluxStore will retry up to 3 times
  • Retries are attempted every 10 seconds
  • After 3 failed attempts, the delivery is marked as failed
  • All delivery attempts are logged in the Delivery Logs section of the Webhooks dashboard
  • Request timeout is 15 seconds

Best practices

  1. Always verify signatures. Verify the X-Webhook-Signature header on every request before processing any data. This is the only reliable way to confirm a request is genuinely from FluxStore.
  2. Respond quickly. Return a 200 OK as soon as possible. Process the webhook data asynchronously if needed.
  3. Handle duplicates. Use the X-Webhook-Id header for idempotency. The same event may be delivered more than once.
  4. Use HTTPS. Always use an HTTPS endpoint to protect webhook data in transit.
  5. Don’t rely on IP allowlisting alone. Requests come from Cloudflare’s IP ranges, which are shared across many services. Signature verification is the authoritative method of authentication.
  6. Log everything. Keep your own logs of received webhooks for debugging and auditing.

For details on signing and verification, see Security & verification. For per-event payload shapes, browse the Events section.