BMM CONNECT DOCUMENTATION
Payment webhooks
Receive signed payment and refund notifications for your account, with or without BMM Connect.
Configure webhooks →Receive notifications on your server when someone buys you a treat or contributes to your goal. You do not need to register a BMM Connect application. Open Developers → Payment webhooks, enter your endpoint and save the signing secret on your server.
What is included
One endpoint per creator and payment environment. Sandbox and Live are separate; the settings page shows the current BMM payment environment. Only checkouts created after the endpoint was first registered are eligible. There is no historical backfill. Group payments are not included in this version.
payment.succeeded: BMM verified the payment. The amount is the gross contribution, not your available balance or net earnings.payment.refunded: a refund has been verified.refunded_amount_minoris the cumulative gross amount refunded, not an additional amount to subtract. Pending or unverified refunds do not produce this event.
Amounts use integer minor units: NGN 500 is 50000. Treat quantity may be null for custom amounts or goal contributions. payment_id is the BMM contribution ID, not a payment-provider ID. Events have unique, stable IDs and a UTC creation timestamp.
Supporter email addresses are never sent. Names are included only for public, non-anonymous contributions. Messages are omitted for private, anonymous, non-public or hidden contributions. These permissions are evaluated when the immutable event is created. Never rely on a display name to identify a player. This feature does not create player/order references or implement game entitlements.
Verify every request
BMM sends an HTTPS POST with Content-Type: application/json, BMM-Event-ID and BMM-Signature: t=TIMESTAMP,v1=HEX_DIGEST.
The digest is HMAC-SHA256 of timestamp + "." + rawRequestBody, using your full whsec_... signing secret. Check the signature before parsing or acting on the payload. Reject timestamps outside five minutes; keep your server clock synchronized. Each delivery attempt is signed with a fresh timestamp.
Delivery and retries
Return a 2xx response after durably accepting an event. BMM treats all other HTTP responses, redirects and timeouts as failures. It does not follow redirects. The endpoint must be a public HTTPS hostname with public IPv4 resolution on port 443. IP-literal URLs and private/internal destinations are rejected, including when DNS changes between attempts.
The worker checks for due deliveries every 15 seconds while the application is running. HTTP delivery has a 10-second deadline. Retries start at 30 seconds and increase to a maximum interval of one hour. After 12 unsuccessful attempts, a delivery is marked failed. Use Retry delivery to start another cycle.
Delivery is at least once. Requests can be duplicated and events can arrive out of order. Deduplicate using the event ID, not the signature. Do not grant access solely from a browser redirect. A refund may arrive before the success notification; retain refunded state so a later success event cannot undo it.
The dashboard shows delivery status, attempt count for the current retry cycle, last HTTP response code and a safe error summary. Delivered means your endpoint returned 2xx, not that downstream processing succeeded. Response bodies are not stored.
Saving a replacement endpoint, rotating its secret, or disabling it cancels queued deliveries for the old configuration. Cancelled events are not automatically replayed. A request already in flight may still reach the old endpoint. Store a new secret immediately and coordinate endpoint changes with your integration.
Operating BMM
Run the committed database migration before starting the updated application. Configure a dedicated WEBHOOK_ENCRYPTION_KEY on every replica. Generate it locally with:
The key must decode to exactly 32 bytes. Hex and standard padded Base64 are accepted; openssl rand -base64 32 also works.
Store the output in your deployment secret manager. Do not commit or share it. It encrypts endpoint signing secrets at rest using AES-256-GCM; retain it across restarts and back it up securely. Changing it without re-encrypting existing secrets breaks delivery. Creators must rotate their endpoint secrets if the encryption key is replaced without migration.
The persistent Node worker starts automatically in production. CREATOR_WEBHOOK_WORKER_ENABLED=false pauses it without discarding queued events. Local development requires CREATOR_WEBHOOK_WORKER_ENABLED=true to opt in. No extra cron service is required, but the application must remain running.
Events and pending deliveries are committed with verified payment/refund updates. No network delivery happens inside those transactions. No historical events are generated by the database migration. Event history currently has no automatic retention purge; monitor table growth and define a retention policy before pruning delivered records.