iDEAL
iDEAL is a Netherlands-based payment method that allows customers to complete transactions online using their bank credentials. All major Dutch banks are members of Currence, the scheme that operates iDEAL, making it the most popular online payment method in the Netherlands with a share of online transactions close to 55%.
iDEAL redirects customers to their online banking environment to authenticate a payment using a second factor of authentication and there is immediate notification about the success or failure of a payment. The exact customer experience depends on their bank.
iDEAL at a glance
| Payment type | Bank Transfer | |
|---|---|---|
| Countries | Any merchants offering services that are legal in the Netherlands. | |
| Currencies |
| |
| Transaction types |
| |
| Transaction limits | €12,000 per transaction limit. | |
| Reporting | You can review your transactions in Optic and the Skrill Business Portal. | |
| Supported languages | NL | |
Prerequisites 
To access this account service, merchants must be onboarded with Skrill's solution.
For Paysafe to create a test account in the sandbox and production environment, we need Merchant's Skrill Pay-to-Email address.
Supported use cases
You can make the following types of transactions:
- Use case 1: Payments
- Use case 2: Refunds
Best practice
We recommend that you follow this best practice guideline:
- Use a webhook or query so that you always know the latest status - for example, you cannot rely on the consumer returning to your website as some consumers may close their browser.
Use case 1: Payments
This use case enables your consumer to choose iDEAL as a payment option on your webstore and to make a payment using their online bank.
To process a transaction using iDEAL, follow these steps:
-
Create a Payment Handle using the Payment Handles API:
-
transactionType = PAYMENT
-
paymentType = IDEAL
-
Endpoint: POST https://api.test.paysafe.com:443/paymenthub/v1/paymenthandles
Within the request, the iDEAL object requires two parameters:
-
consumerId: Email ID of the customer
-
-
Redirect the customer:
-
Paysafe returns a response where the action parameter is set to REDIRECT.
-
The payment_redirect link directs the customer straight to the iDEAL payment page.
-
At this stage, the payment handle status is INITIATED.
-
-
Customer completes authentication:
-
On the iDEAL page, the customer selects their bank and logs into their bank account.
-
If the merchant did not provide first name, last name, and email in the payment handle request, the customer will be prompted to supply these details.
-
-
Transaction outcome:
-
After completing the payment, the customer is redirected to the merchant’s success or failure page.
-
The Payment Handle status updates accordingly:
-
PAYABLE > if the transaction is successful.
-
FAILED > if the transaction is unsuccessful.
-
-
Merchants are notified of this status change via the configured webhook.
-
Happy path
| Payment Handle created successfully, customer completes iDEAL authentication | 201 | Redirect customer to payment_redirect | PAYABLE | Use paymentHandleToken to process the payment (Step 5). |
Negative path
| Invalid request (e.g. missing required parameters such as consumerId) | 400 | INVALID_REQUEST | Correct request and retry | FAILED | Merchant notified via webhook. |
Payment Processing Outcomes
Process the payment:
-
Use the paymentHandleToken from the response to initiate the Payment request:
-
Endpoint: POST https://api.test.paysafe.com:443/paymenthub/v1/paymenthandles
-
Note: The paymentId returned in the response should be stored at the merchant's end for future use, since paymentId is needed for refunds to directly deposit into the bank account that was used for the original transaction.
Happy path
| Payment processed successfully | 201 | None | COMPLETED | Deliver goods/services to customer. Merchant notified via webhook. |
Negative path
| Invalid or expired paymentHandleToken | 400 / 422 | INVALID_HANDLE | Regenerate a new payment handle and retry | FAILED | Merchant notified via webhook. |
Use case 2: Refunds
This use case allows you to return money to a consumer who has already made a payment in your webstore using iDEAL. iDEAL supports a single refund amount which is equal to or less than the original payment amount, or multiple partial refunds (where the sum of the partials must not exceed the original payment amount).
-
Verify payment status
-
A refund can only be initiated once the original payment has a status of COMPLETED.
-
Use the paymentId from the completed payment to reference the transaction.
-
-
Create a refund request
-
Endpoint: POST /paymenthub/v1/settlements/{paymentId}/refunds.
-
Required parameter: amount
-
Equal to the full payment amount > full refund.
-
Less than the payment amount > partial refund.
-
-
Multiple partial refunds can be created, as long as the total refunded amount does not exceed the original payment.
-
-
Receive refund response
-
The response contains:
-
Details of the refunded payment
-
A unique identifier for each refund (full or partial)
-
-
-
Track refund status
-
The refund is first created with status PENDING.
-
Once processed to the customer’s bank account, the status changes to COMPLETED.
-
At each stage, a webhook is triggered to notify the merchant.
-
Happy path
| Refund request accepted | 201 | None | PENDING > COMPLETED | Wait for webhook confirmation once funds are processed to customer’s bank account. |
Negative path
| Refund request rejected (for example, invalid paymentId, payment not in COMPLETED state, amount exceeds original). | 400 / 422 | Varies | Review failure reason and resubmit if applicable. | FAILED | Merchant notified via webhook. |
{
"merchantRefNum": "1684740401",
"transactionType": "PAYMENT",
"profile": {
"firstName": "John",
"lastName": "Doe"
},
"ideal": {
"consumerId": "john@gmail.com"
},
"paymentType": "IDEAL",
"amount": 1000,
"currencyCode": "EUR",
"customerIp": "73.82.192.17",
"billingDetails": {
"street": "71 Cherry Court ",
"city": "Southhampton",
"zip": "SO53 5PD",
"country": "NL"
},
"returnLinks": [
{
"rel": "default",
"href": "http://www.amazon.ca",
"method": "GET"
},
{
"rel": "on_completed",
"href": "https://US_commerce_site/payment/return/success",
"method": "GET"
},
{
"rel": "on_failed",
"href": "https://US_commerce_site/payment/return/failed",
"method": "GET"
}
]
}
{
"id": "55cab390-cc68-428f-a4ae-2e5df1b20622",
"paymentType": "IDEAL",
"paymentHandleToken": "PHwGWMvJ7dfslO94",
"merchantRefNum": "1684740765",
"currencyCode": "EUR",
"txnTime": "2023-05-22T07:32:45Z",
"billingDetails": {
"street": "71 Cherry Court ",
"city": "Southhampton",
"zip": "SO53 5PD",
"country": "NL"
},
"customerIp": "73.82.192.17",
"status": "INITIATED",
"links": [
{
"rel": "redirect_payment",
"href": "https://api.qa.paysafe.com/alternatepayments/v1/redirect?accountId=1021664090&paymentHandleId=55cab390-cc68-428f-a4ae-2e5df1b20622&token=eyJhbGciOiJIUzI1NiJ9.eyJhY2QiOiIxMDIxNjY0MDkwIiwicHlkIjoiNTVjYWIzOTAtY2M2OC00MjhmLWE0YWUtMmU1ZGYxYjIwNjIyIiwiZXhwIjoxNjg0NzQyNTY3fQ.8sIAAkk6zTaMdkVJyaUq5kjaZZn9rOKDAiJ0tavhqpA"
}
],
"liveMode": false,
"simulator": "EXTERNAL",
"usage": "SINGLE_USE",
"action": "REDIRECT",
"executionMode": "SYNCHRONOUS",
"amount": 1000,
"timeToLiveSeconds": 898,
"gatewayResponse": {
"processor": "SKRILL_QCO",
"sid": "6c93658d65e6a0b58042183d58f18395"
},
"returnLinks": [
{
"rel": "on_failed",
"href": "https://US_commerce_site/payment/return/failed"
},
{
"rel": "default",
"href": "http://www.amazon.ca"
},
{
"rel": "on_completed",
"href": "https://US_commerce_site/payment/return/success"
}
],
"transactionType": "PAYMENT",
"gatewayReconciliationId": "6990b0c9-9205-4dfb-87e6-8d47eda88f93",
"updatedTime": "2023-05-22T07:32:47Z",
"statusTime": "2023-05-22T07:32:47Z",
"ideal": {
"consumerId": "john@gmail.com",
"countryCode": "NL"
},
"profile": {
"firstName": "John",
"lastName": "Doe"
}
}
{
"merchantRefNum": "1684740855",
"amount": 1000,
"currencyCode": "EUR",
"paymentHandleToken": "PHwGWMvJ7dfslO94",
"description": "Consumer Purchase",
"customerIp": "73.82.192.17"
}
{
"id": "abccd023-9fa8-461f-bf4f-eb477dc8f18b",
"paymentType": "IDEAL",
"paymentHandleToken": "PHwGWMvJ7dfslO94",
"merchantRefNum": "1684740892",
"currencyCode": "EUR",
"settleWithAuth": true,
"dupCheck": true,
"txnTime": "2023-05-22T07:32:45Z",
"billingDetails": {
"street1": "71 Cherry Court ",
"city": "Southhampton",
"zip": "SO53 5PD",
"country": "NL"
},
"customerIp": "73.82.192.17",
"status": "COMPLETED",
"gatewayReconciliationId": "6990b0c9-9205-4dfb-87e6-8d47eda88f93",
"amount": 1000,
"availableToRefund": 1000,
"consumerIp": "73.82.192.17",
"liveMode": false,
"simulator": "EXTERNAL",
"updatedTime": "2023-05-22T07:34:51Z",
"statusTime": "2023-05-22T07:34:51Z",
"gatewayResponse": {
"transaction_id": "6990b0c9-9205-4dfb-87e6-8d47eda88f93",
"amount": "10.00",
"mb_transaction_id": "325276681",
"pay_from_email": "john@gmail.com",
"pay_to_email": "elvisstoyanov.qco@sun-fish.com",
"currency": "EUR",
"merchant_id": "298847640",
"id": "325276681",
"processor": "SKRILL_QCO",
"status": "2",
"sid": "6c93658d65e6a0b58042183d58f18395"
},
"availableToSettle": 0,
"profile": {
"firstName": "John",
"lastName": "Doe"
},
"settlements": [
{
"amount": 1000,
"txnTime": "2023-05-22T07:32:45.000+0000",
"availableToRefund": 1000,
"merchantRefNum": "1684740892",
"id": "abccd023-9fa8-461f-bf4f-eb477dc8f18b",
"status": "COMPLETED"
}
]
}
{
"merchantRefNum": "1684740936",
"dupCheck": false,
"amount": 1000,
"paymentType":"IDEAL",
"currencyCode":"EUR"
}
{
"id": "40fe9ccc-ff99-4e8f-bccf-e86a203dad3d",
"paymentType": "IDEAL",
"merchantRefNum": "1684740956",
"currencyCode": "EUR",
"txnTime": "2023-05-22T07:35:54Z",
"status": "PENDING",
"gatewayReconciliationId": "325276694",
"amount": 1000,
"updatedTime": "2023-05-22T07:35:55Z",
"statusTime": "2023-05-22T07:35:55Z",
"liveMode": false,
"simulator": "EXTERNAL",
"gatewayResponse": {
"id": "325276694",
"status": "0",
"merchant_id": "298847640",
"processor": "SKRILL_QCO"
},
"source": "SingleAPI"
}
Appendix
Auto-Settlement and Auto-refund Functionality
In case if merchant does not call Payments API call (paymenthub/v1/payments) and if merchant has opted for auto settlement and auto-refund functionality then:
- If the merchant opts for auto-settle: In case if merchant does not call Payments API call, after fifteen minutes system will automatically trigger Payments API call and payments and settlement will be completed. Also, payment handle gets expired.
- If merchant opts for auto-settle and auto-refund: In case if merchant does not call Payments API call, after fifteen minutes system will automatically trigger Payments API call and payments, settlement and refunds will be completed. Also, the payment handle expires.
To opt for this functionality, merchants should email Integration team integrations@paysafe.com, and it will be enabled from the office.
Webhooks
Payment Handle
- PAYMENT_HANDLE_PAYABLE - This webhook notifies that the payment handle token has been created for the required purpose and can be executed once the preliminary requirements are completed; the next API call with the payment handle can then be made.
- PAYMENT_HANDLE_PROCESSING - This webhook is triggered when the user is successfully redirected to the payment platform page and operation has started for the payment by the user.
- PAYMENT_HANDLE_COMPLETED - This webhook is triggered when the process of the payment handle token is completed after triggering the next API i.e. Payments or Standalone Credit API.
- PAYMENT_HANDLE_EXPIRED - This webhook is triggered when the next step is not initiated after the payment handle is created within the given time frame, the duration can be seen in the response to/paymenthub/v1/paymenthandles API under the tag timeToLiveSeconds.
- PAYMENT_HANDLE_FAILED - This webhook is triggered when the user is successfully redirected to the payment platform page but some technical error occurred and final communication couldn't reach back to Paysafe.
Payments
- PAYMENT_PROCESSING - The payment is in progress. In some cases, there might be delays due to an action pending by the customer or the merchant.
- PAYMENT_PENDING - The payment is pending because the transaction hasn't been completed from the bank account to Skrill wallet to merchant.
- PAYMENT_COMPLETED/SETTLEMENT_COMPLETED - The payment was completed successfully.
- PAYMENT_FAILED - This webhook is triggered when the payment fails during the process.
Refunds
- REFUND_FAILED - This webhook is triggered when the refund is initiated but failed due to a functional error. Example - refund amount is more than the payment amount.
- REFUND_COMPLETED - This webhook is triggered when the refund has been successfully transferred from merchant account to the user's chosen bank account.
- REFUND_PENDING - This webhook is triggered when refund has been initiated but due to various bank delay reasons or time zone issues the actual money transfer has not happened.
Testing using Internal Simulator
The following amount based simulations are used to COMPLETE/FAIL the transactions with internal simulator. We need to send amount value in the request to get the respected result.
Simulator settings: In the request headers, pass INTERNAL value for simulator field.
Refund simulations
| 24.21 | PENDING | COMPLETED | 5 |
| 24.31 | PENDING | FAILED | 10 |
| 26.31 | FAILED | FAILED | 0 |
- Refund would be FAILED, if the refund amount exceeds the original payment amount.
- Any refund transaction other than the above amounts will be persisted as PROCESSED.
Error Codes
Initiate Payment Error Codes
| Skrill PSP Return code | Message Code | Paysafe HTTP Code | Paysafe ERROR Code | Paysafe ERROR Message | Paysafe ERROR Details | Paysafe status | Comments |
| -2 | failed | 502 | 1001 | External Gateway Error | An external Gateway error occurred. | FAILED | Failed (-2) is typically sent when the customer tries to pay, but Skrill's provider declines the transaction. It can also be sent if the transaction is declined by Skrill’s internal fraud engine. |
Initiate Refund Error Codes
| Skrill PSP Return code | Message Code | Paysafe HTTP Code | Paysafe Error Code | Paysafe Error Message | Paysafe Error Details | Paysafe status | Comments |
| -2 | failed | 502 | 1001 | External Gateway Error | An external Gateway error occurred. | FAILED | Failed (-2) can occur in the following scenarios. Refund amount exceeds account balance. Refund amount exceeded original Payment amount. Other generic errors. |