Skip to main content

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.

2

Processed

safe to fulfill

Payment completed and funds are settled. This is the only status where you should fulfill the order.

5

Cancelled

do not fulfill

The customer cancelled the payment before completing checkout. Allow them to retry or choose a different method.

6

Failed

do not fulfill

The payment attempt failed. The SID is no longer usable — create a fresh session if the customer wants to retry.

-1

Provisional

do not fulfill

A transitional state — payment is not yet final. Do not fulfill until you receive status 2. Store it and wait.

-2

Reversed

do not fulfill

The 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

MD5 hash construction
// Step 1: hash your secret_word
$secretHash = strtoupper(md5($secret_word));
// Step 2: concatenate fields
$str = $merchant_id
. $transaction_id
. $secretHash
. $mb_amount
. $mb_currency
. $status;
// Step 3: hash and uppercase
$sig = strtoupper(md5($str));
// Step 4: compare
return hash_equals($sig, $_POST['md5sig']);

The session flow

Three steps from checkout to confirmed payment.

1

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.

2

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.

3

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

Request parameters
ParameterTypeRequiredDescription
pay_to_emailstringrequired

The Skrill account that receives the payment.

e.g. merchant@example.com
amountnumberrequired

Transaction amount as a decimal.

e.g. 25.00
currencystringrequired

Three-letter ISO currency code.

e.g. EUR
return_urlstringoptional

Where the customer is sent after paying.

e.g. https://example.com/thanks
status_urlstringoptional

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_idstringoptional

Your own reference for the payment.

e.g. order-12345

Response fields

Response fields
FieldTypeDescription
transaction_idstringSkrill transaction ID
statusenum2=Processed, 0=Pending, -2=Failed, -3=Refunded
mb_transaction_idstringSkrill merchant transaction ID
created_atdatetime

Frequently asked questions

Other gateway templates

Looking for a different provider?