Skip to main content

Purpose

Use GET /v1/merchant-api/checkouts/{checkoutId}/status with the merchant API key to recover the current hosted checkout. Use signed webhooks as the primary notification path and status polling for recovery. Never infer completion from the browser return URL. The normal forward path is created → initiated → pending or active → optional hold → completed. A checkout may instead move to an unsuccessful terminal state. Observable intermediate states can be skipped. Provider state is authoritative, so do not manufacture missing transitions.

Polling schedule and stopping rules

  • For a hosted checkout, poll every 3 seconds for the first 30 seconds, every 5 seconds until two minutes, then every 15 seconds until the offer deadline.
  • Move pending or active work to a background job when the customer leaves.
  • For hold, stop browser polling and use webhooks plus a background status check no more often than once per minute.
  • For checkout-deposit status, use the returned pollAfterSeconds as the minimum interval.
  • Stop ordinary polling on completed, canceled, declined, failed, reverted, or pre-trade expired.
  • Stop automation on reconciliation_required; only an operator may resume it.
Each request uses the bounded retry policy. Do not keep an HTTP request or browser tab running for the full lifetime of a trade.

Customer messaging

These are suggested merchant UI messages, not additional API fields.

Expiry and protected trades

expiresAt is the deadline for attaching a trade to the checkout. If a checkout is still created when that deadline passes, it becomes pre-trade expired; release the reservation and allow an explicit new attempt with a new idempotency key. Once a deposit is attached, the offer deadline does not cancel the protected trade. Its deposit status capability remains valid after expiresAt, and the trade can still progress through pending, active, hold, and completed. Do not release or replace an attached trade merely because the original checkout deadline passed. For CS2, reservationRequired is true. Once hold begins, keep the order reserved and do not fulfill, credit, delete, or release it until payment.completed. Use holdUntil from the API, not a browser timer. fulfillmentAllowed is false until completion. On canceled, declined, or failed outcomes it remains false and you may release the reservation. For reverted, first determine whether fulfillment or credit already occurred; if it may have, keep the order protected and reconcile.

Confirm and enqueue

Conflicting and out-of-order observations

Skinloop accepts only valid provider lifecycle transitions, ignores delayed lower-state callbacks, and exposes the provider payment state when one exists. Your integration must still handle network reordering:
  1. Authenticate webhooks before using them.
  2. Deduplicate each webhook by event id.
  3. Require the event type and body status to agree.
  4. Match the webhook merchant order ID, external payment ID, requiredAmount, and currency against stored values. The webhook amount is the actual accepted skin value and can be higher than requiredAmount.
  5. Require the actual accepted amount to be at least the required amount and verify the reported overpayment difference using integer cents.
  6. If a webhook appears older than local state or conflicts with polling, fetch the current checkout status and use that current projection.
  7. Never move from completed back to an in-progress state.
  8. Treat reverted after completion as a reversal requiring reconciliation, not as a new checkout attempt.
  9. Stop automation on any identity conflict.

reconciliation_required operator process

  1. Stop polling retries, fulfillment, reservation release, and new checkout creation for the order.
  2. Keep the order and any CS2 reservation protected.
  3. Save the merchant order ID, checkout ID, deposit ID when available, latest request ID, webhook event IDs, and observed timestamps.
  4. Check whether a fulfillment job exists or a destination delivery may already have occurred.
  5. Contact Skinloop support without sending API keys or webhook secrets.
  6. Resume only after the payment and delivery outcome are confirmed. Record the operator decision in an audit trail.
Expected result: one order is fulfilled at most once, only after completed. Polling and webhook handlers call the same enqueue operation. Implement the worker and crash recovery in Safe fulfillment. Use webhooks for durable notifications and review the state map for endpoint-specific enums.