Appearance
Integration with Iframe
Embed the Skinslink deposit page directly into your platform using an iframe. This approach keeps users on your site while leveraging Skinslink's hosted deposit UI.
Flow Overview
Your Platform Skinslink
───────────── ─────────
│ │
│ 1. POST /merchant/create-intent│
│ ──────────────────────────────► │
│ │
│ { id, merchant_tx_id, url } │
│ ◄────────────────────────────── │
│ │
│ 2. Load `url` in iframe │
│ ──────────────────────────────► │
│ │
│ User selects items, │
│ confirms trade inside │
│ the iframe │
│ │
│ 3. PostMessage: status update │
│ ◄────────────────────────────── │
│ │
│ 4. Webhook: trade status │
│ ◄────────────────────────────── │Step 1: Create a Deposit Intent
Call Create Intent from your backend. You'll get back a url to embed.
Step 2: Embed in Iframe
Use the url from the response as the iframe src:
html
<iframe
src="https://skinslink.com/deposit/d66pbg9uvduc73ba5n30"
width="100%"
height="700"
frameborder="0"
allow="clipboard-write"
></iframe>The user will see the Skinslink deposit page inside your site where they can browse their inventory, select items, and confirm the deposit.
Step 3: Listen for PostMessage Events
Since the iframe is on a different domain, communication happens via window.postMessage. The iframe sends status updates to the parent window.
Message Format
Each message in event.data contains:
| Field | Type | Description |
|---|---|---|
type | string | Always skinslink:deposit-status — use this to filter messages |
txId | string | Transaction ID |
status | string | Current deposit status |
Statuses
| Status | Meaning |
|---|---|
new | Deposit page opened, user hasn't taken action yet |
active | Deposit created, waiting for the user to accept the Steam trade offer |
hold | Trade accepted, items are on Steam trade hold |
completed | Trade successful — items received, safe to credit the user's balance |
canceled | User canceled the trade |
failed | Something went wrong (trade declined, API error) |
Example
typescript
window.addEventListener('message', (event) => {
const { type, txId, status } = event?.data || {};
if (type !== 'skinslink:deposit-status') return;
switch (status) {
case 'completed':
// Close iframe, refresh balance
console.log(`Deposit ${txId} completed`);
break;
case 'failed':
case 'canceled':
// Close iframe, show error or retry
console.log(`Deposit ${txId} ${status}`);
break;
case 'active':
// User is accepting the trade offer
console.log(`Deposit ${txId} in progress`);
break;
}
});WARNING
Always validate event.data.type === 'skinslink:deposit-status' before processing. Other scripts or browser extensions may also send messages to your window.
Step 4: Receive Webhook
PostMessage events are for real-time UI updates only. Always use server-side webhooks as the source of truth for crediting user balances.
TIP
Use PostMessage for instant UI feedback (close iframe, show success screen) and webhooks for reliable backend processing (credit balance, update order status).
