Skip to main content
Skinloop sends signed events to your server when a payment changes. Verify the signature, store the event, and return 2xx after saving it or queuing the work. Deliveries may repeat or arrive out of order.

Available events

Enable Also receive player deposit events for deposit.* subscriptions. Other payment lifecycle types (initiated, active, hold, canceled, declined, failed) appear in the payload schema but are not endpoint subscription options. Use status polling for those states. Retries and manual replays keep the same event ID. Deduplicate using both the Skinloop-Event-Id header and matching body id; a replay is not a new payment. The optional data.merchantOrderId connects a hosted checkout event to your order. The webhook body is JSON, but signature verification must use its exact raw bytes.

Endpoint URL and signing secret

The endpoint URL is an HTTPS address your server or store platform hosts before you register it in Skinloop. It is not the merchant’s storefront URL and Skinloop does not create the receiving server for you. For a platform integration, the platform supplies the exact webhook URL to the merchant. The merchant registers it in API & Webhooks in their Skinloop dashboard and subscribes to the desired events. Skinloop generates a whsec_... signing secret for that endpoint when it is created; copy it once into the receiver’s secure server configuration, not browser code or a checkout URL. A platform serving multiple stores should maintain separate merchant credentials and webhook secrets. Route a request to the expected installation and verify its signature with that installation’s secret before using untrusted payload fields to identify an order. See Store platform integration for the full setup.

Completed delivery

This is a complete payment.completed request. The hexadecimal signature shown is illustrative; Skinloop calculates a different signature with the signing secret for your endpoint and the exact raw body bytes.
Only payment.completed with data.status: "completed" and data.fulfillmentAllowed: true permits fulfillment. Record completion and enqueue the unique durable job before returning 2xx; do not deliver the merchant order inside this HTTP request.

Non-completed delivery

A CS2 payment in provider hold is not ready for fulfillment:
Keep the order reserved during hold. Do not fulfill, credit, delete, or release it. holdUntil is included only for a CS2 payment.hold event when the hold start is known; it is not a completion time or permission to fulfill.

Field meanings

Map and deduplicate

After verifying the signature:
  1. Confirm Skinloop-Event-Id exactly equals the body id.
  2. Insert the authenticated event using id as a unique key.
  3. Look up your local order using data.merchantOrderId.
  4. Verify data.requiredAmount and data.currency exactly match the stored order. Parse decimal strings to integer cents without binary floating point.
  5. Verify data.amount >= data.requiredAmount and data.overpaymentAmount === data.amount - data.requiredAmount. A greater data.amount is valid overpayment and must not change the order price or quantity delivered.
  6. Apply the status transition without assuming events arrive in order.
  7. For completion, call the same durable enqueue operation used by status polling.
  8. Return 2xx after the event and any fulfillment job are committed.
Do not compare data.amount directly to the original order price: that would reject legitimate skin overpayment. Do not accept a changed requiredAmount, currency, merchant order ID, or payment identity. If any of those fields conflict, stop fulfillment and reconcile with the checkout status endpoint. A retried event with the same id and same authenticated body is already accepted: return 2xx without applying it again. The same id with different authenticated bytes is a conflict and must not be processed automatically. Webhook event deduplication does not replace fulfillment-job idempotency; use both. Your endpoint must be public HTTPS and must not rely on redirects. Return any 2xx response after authenticating and durably recording the event and any unique fulfillment job. Do not call an external fulfillment service inside the webhook request. Enqueue only for payment.completed; pending and hold events are informative. Next: implement signature verification before testing retries and duplicates, then implement safe fulfillment.