payment.* webhooks stay unchanged.
Required setup
- Use an active Skinloop merchant account and a server-side API key with
deposits:createanddeposits:read. Enable Rust, CS2 or both on that key. - In Webhooks, create an HTTPS endpoint and select Also receive player deposit events. Completion and reversal subscriptions are required before creating sessions. Keep the signing secret on your server.
- Add your return domain to the allowed checkout origins under API & Webhooks. Use your own authenticated player ID, not a player ID supplied unchecked by the browser.
Request body
POST /v1/merchant-api/deposit-sessions
Example request
id, creditReference, merchantReference and playerReference in your database before opening hostedUrl. Retry the same request with the same idempotency key if the network response is lost. A changed request with that key, or a reused merchant reference for another session, is rejected.
Session expiry is 30 minutes by default, configurable from 5 minutes to 24 hours. It limits starting a deposit, not settlement of a trade already opened.
Valuation and checkout
The player chooses skins first. Skinloop issues a short-lived server valuation, valid for at most two minutes and never past the session expiry. Confirmation checks the exact items, game, current prices and inclusive limits again. Expired valuations and changed prices require refreshing the inventory and confirming the current selection. A browser cannot set the accepted amount, switch the receiving merchant, change the player reference or attach a second trade to the same session. Once a trade has been reserved, an idempotent retry returns that original trade and accepted value. It does not reprice an existing deposit or create a replacement trade.States and spendable credit
Rust is not credited merely because a trade was created. CS2 remains pending during protection. A countdown ending, a success redirect or a screenshot is never payment confirmation. Instant spendable credit against a CS2 hold is not part of this product.
Signed notifications
Player deposits emit only these dedicated events:deposit.pending, including a transition intohold.deposit.completed.deposit.failed, with a reason such ascanceledordeclined.deposit.reverted.
creditReference identifies the one player deposit, including retries and any later reversal. The actual accepted value is the amount to reconcile, not the session minimum or maximum.
Status lookup
Credit the player once
Your receiver must:- Verify the webhook signature and identify the saved deposit belonging to your merchant.
- Read the authenticated session status for recovery or out-of-order delivery. On lookup failure, retry later; do not assume success.
- In one database transaction, lock your deposit record and verify the stored player reference, currency and accepted amount.
- Credit only for current
completedstatus andcanCreditPlayer: true. Enforce a unique constraint oncreditReferenceand insert the credit and balance change atomically. - Track event IDs and sequence numbers so duplicate or older notifications cannot restore an outdated state. A reversal needs its own unique compensating entry, not deletion of the original credit. If the deposit was never credited, a reversal must not debit the player.
- Acknowledge only after durable processing, or after durably queuing the event for your own worker.
deposit.* event. Skinloop prevents duplicate trade creation and emits durable, unique events. Your server must enforce the single credit in the player ledger it controls.
The public checkout projection omits player and merchant references. Keep the authenticated recovery response on your server.