The SID expires in 15 minutes.
Skrill's MB signature is an MD5 inside an MD5.
Skrill is a digital wallet, not just a card processor. Customers pay from their Skrill balance or add cards through Skrill's hosted checkout. You get a session ID (SID) and redirect. When payment completes, Skrill sends a form-encoded IPN to your server — along with an MD5 signature you must verify before trusting any field.
Session ID
SID-based redirect
Verification
MB signature
To start
0 signup
Skrill (formerly Moneybookers) is a digital wallet gateway popular in gaming, forex trading, and global e-commerce. Its checkout flow works differently from most gateways: instead of redirecting to a payment URL, you first create a session and receive a SID (session ID). You then send the customer to pay.skrill.com?sid=SESSION_ID. The SID expires after 15 minutes, so you cannot create sessions in advance or cache them.
Skrill's IPN arrives as a form-encoded POST to your status_url — not a JSON webhook. The notification contains merchant_status_code which tells you the outcome: 2 = processed and funds settled, 5 = customer cancelled, 6 = payment failed. Codes -1 and -2 are provisional states. Your handler must read form fields, not parse JSON.
The MB signature is Skrill's method for verifying that an IPN came from Skrill. The formula is MD5 of merchant_id + transaction_id + MD5(secret_word).toUpperCase() + amount + currency + status — concatenated in that order. The nested hash (MD5 inside MD5) is unusual and often implemented incorrectly. If the computed hash doesn't match mb_hash in the IPN, you must reject it.
Merchant status codes
Skrill's IPN includes a merchant_status_code field that determines how you should respond. These are not HTTP status codes — they are Skrill-specific values. Your IPN handler must branch on all of them.
Processed
safe to fulfillPayment completed and funds are settled. This is the only status where you should fulfill the order.
Cancelled
do not fulfillThe customer cancelled the payment before completing checkout. Allow them to retry or choose a different method.
Failed
do not fulfillThe payment attempt failed. The SID is no longer usable — create a fresh session if the customer wants to retry.
Provisional
do not fulfillA transitional state — payment is not yet final. Do not fulfill until you receive status 2. Store it and wait.
Reversed
do not fulfillThe transaction was reversed after originally being processed. Update your order status and investigate.
MB signature verification
Every IPN Skrill sends includes an md5sig field. This is Skrill's way of proving the IPN actually came from them and hasn't been tampered with.
Your server must independently compute the same hash using your secret_word and compare it. If they don't match, discard the IPN entirely.
Without this check, anyone can POST a crafted form to your status_url with a fake merchant_status_code=2 and trigger order fulfillment.
Warning
Skrill sends IPN as form POST (application/x-www-form-urlencoded). Never attempt to parse it as JSON.
Signature formula
The session flow
Three steps from checkout to confirmed payment.
Create a payment session
POST your order details to get a SID. This session expires after 15 minutes, so only create it when the customer is ready to pay.
Redirect to Skrill checkout
Send the customer to pay.skrill.com?sid=YOUR_SID. Skrill handles card entry, 3D Secure, and wallet selection on their hosted page.
Receive and verify IPN
Skrill POSTs to your status_url as form-encoded data. Verify the MD5 signature, then branch on the merchant_status_code.
curl -X POST https://mockgateway.dev/api/base/skrill/init \
-H "Authorization: Bearer YOUR_MOCK_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"pay_to_email": "merchant@yourcompany.com",
"amount": "49.99",
"currency": "EUR",
"transaction_id": "ORD-SKR-8821",
"return_url": "https://yourapp.com/checkout/return",
"cancel_url": "https://yourapp.com/checkout/cancel",
"status_url": "https://yourapp.com/webhooks/skrill",
"language": "EN"
}'Request parameters
Sent to POST /api/base/skrill/init
| Parameter | Type | Required | Description |
|---|---|---|---|
pay_to_email | string | required | The Skrill account that receives the payment. e.g. merchant@example.com |
amount | number | required | Transaction amount as a decimal. e.g. 25.00 |
currency | string | required | Three-letter ISO currency code. e.g. EUR |
return_url | string | optional | Where the customer is sent after paying. e.g. https://example.com/thanks |
status_url | string | optional | Where Skrill posts the signed result. This is how the outcome arrives — there is no verify call. e.g. https://example.com/skrill/ipn |
transaction_id | string | optional | Your own reference for the payment. e.g. order-12345 |
Response fields
| Field | Type | Description |
|---|---|---|
transaction_id | string | Skrill transaction ID |
status | enum | 2=Processed, 0=Pending, -2=Failed, -3=Refunded |
mb_transaction_id | string | Skrill merchant transaction ID |
created_at | datetime |
Frequently asked questions
Other gateway templates
Looking for a different provider?