Please let us know if you have any questions regarding the guides, references or implementation. We’re here to help!
Introduction
Welcome to Online Payment Platform (OPP). We are glad that you want to integrate our product into your service. We provide several options in order to make your payment setup and financial flows compliant to laws (PSD2) and local schemes. This document describes how to communicate with the OPP REST API. You will be able to create merchants, bank accounts, transactions, mandates and more! You will learn what responses to expect, and more importantly, which calls to make for a seamless integration.
Our API works with raw JSON, which means all GETs will return JSON, and all POSTs accept and return only JSON as well. Within every chapter, we will provide an example request and response if possible.
Terminology
OPP uses some basic terminology. Find their explanations in the table below.
Term | Explanation |
Partner | You, the platform, who will be integrating OPP. |
Merchant | Any customer of your platform. Any receiver of money. |
Know Your Customer (KYC) | By law, OPP is obliged to know who we pay-out money to. Therefore, we apply compliance levels to fulfil to the KYC procedure. |
Ultimate Beneficial Owner (UBO) | Representative of the company. An UBO is a natural person that has:
|
Transaction | A transaction is created whenever a buyer pays money to another merchant |
Settlement | The "balance" of a merchant. Once the settlement period expires, OPP will pay-out the merchant. |
Escrow | Money that has been paid by a buyer, but has not yet been put on the settlement of the receiving merchant. |
Chargeback | Revert all the money of a transaction that is in escrow back to the buyer who paid the money. |
Refund | Revert (part of) the money of a transaction that is on the settlement of the receiving merchant. |
Environments
OPP knows two environments. A sandbox environment, in which you will be able to test all sorts of scenarios, and a production environment, which will be used for live customers.
Both environments use a different API key. You authenticate to the environment and its API by providing one of the API keys in every request you perform. You can view your API keys through your Partner/Merchant Login.
Please keep in mind that API keys provide many privileges. Make sure to keep them safe.
Sandbox environment
The OPP Sandbox is a virtual testing environment that mimics the live OPP production environment. You will be using the Sandbox version of the API and application. All resources created on sandbox are tests and will not be available in production. No actual payments are made or processed. Where needed a simulation mode will be provided to test various scenarios.
Please bear in mind, as the sandbox environment is a direct copy of our production environment, it will not be possible to delete data or clear the sandbox and start fresh.
In order to use the sandbox environment successfully, please whitelist the IP:
- 18.193.11.50
- 18.159.20.179
Postman collection
To make testing single requests in sandbox and production easier, we have created a fully functional Postman collection, free for you to use. In order to use the collections below, you should create an environment containing the following variables:
{{api_key}}
- Your API key{{url}}
- The base url of our API{{notify_url}}
- The webhook of your platform{{return_url}}
- If preferred, the return_url of the merchant/transaction{{merchant_uid}}
- If preferred, your test merchant for transactions{{token}}
- In case of mandates, your test mandate token
You can download the collections according to your needs:
Go-Live
OPP will perform quality control on the implementation of the features in your platform. All necessary notifications should be handled correctly, and furthermore, the following functionality will be checked. For all below functionality, please have a look at the Guides.
KYC / Merchant onboarding requirements
- The email address is verified by the platform before creating an OPP account
- The merchant needs to agree with the terms and conditions of OPP
- KYC Low: Connecting merchant bank account enabled
- KYC Low: Merchant phone number provided
- KYC High: Merchant identity check enabled
- KYC Business: UBO, Chamber of Commerce extract and Organization structure check enabled
Merchant account / profile requirements
- Merchant is able to see current
merchant.status
andmerchant.compliance.status
- Merchant is able to see outstanding compliance requirements
Besides the above required functionality, we highly recommend to also implement the following, in order to reduce questions and support load:
- Merchant account / profile - Merchant is able to see the connected bank account for payouts
- Merchant account / profile - Merchant is able to change the connected bank account
Partner backoffice requirements
- Partner backoffice is able to see the merchant's current
merchant.status
andmerchant.compliance.status
- Partner backoffice is able to see the merchant's outstanding compliance requirements
Transactions requirements
- Complete checkout flow, including unhappy flows
- Platform prevents users from paying multiple times for the same order
- The buyer agrees with the Terms and Conditions of OPP before the transaction is completed
Mandates requirements (if applicable)
- Complete mandate checkout flow, including unhappy flows
- Platform prevents users from paying multiple times for the same order
- Platform implemented fall-back system in case of chargebacks
Production key
Your production key will be provided to you once the following actions have taken place or files have been delivered:
- Sales: Signed partner contract with OPP
- Compliance: Signed Partner Onboarding form
- Compliance: Completed RISK assessment
-
Integrations: Delivered signed implementation checklists:
- Merchants API
- Transactions API
- Mandates API (if applicable)
- Integrations: Demo of the required OPP functionality
Production environment
In order to use the production environment successfully, please whitelist the IP's:
- 18.197.215.227
- 3.120.97.52
- 3.121.39.192
API Basics
Before we dive into the deep matter of the OPP API, we first need to explain some basics. This chapter will guide you through all the basic functionalities necessary for you to get the most out of our product!
Responses
Example response - Transaction creation without providing the required merchant_uid:
{
"error": {
"code": 400,
"message": "Missing required merchant_uid"
}
}
OPP uses the default HTTP response codes to indicate failure or success of an API request. We will always return a JSON string, even if an error has occurred.
Code | Message | Description |
200 | OK | Success |
400 | Bad Request | Missing parameter(s) |
401 | Unauthorized | Invalid or revoked API key |
404 | Not Found | Resource doesn't exist |
409 | Conflict | Conflict due to concurrent request |
410 | Gone | Resource doesn't exist anymore |
50X | Server Errors | Temporary problem on our side |
API Authentication
Example header of a request
headers: {
"Authorization": "Bearer {{api_key}}",
}
-H "Authorization: Bearer {{api_key}}"
In order to communicate with our API, authentication is required. You received an API key from your Implementation Manager. This API key differs for both the environments, therefore it is advised to keep them separate from one another.
Every request you send to our API needs to have a header with Bearer Token Authentication: Authorization : Bearer {{api_key}}
.
In case your API request does not have a correct API key in its header, you will see the error at the right.
API Restrictions
Example response error
{
"error": {
"type": "not_found",
"message": "Unrecognized URL requested or no permissions to view request URL. See https://docs.onlinepaymentplatform.com for valid endpoints or contact support if you have any questions.",
"parameter": null
}
}
Every platform has its own way of working, with its own set of features to be activated. Every part of our API can be individually (in)activated upon request. Whenever you feel like you are missing a set of features, or would like to expand your current set of features to improve your platform, please contact your Implementation Manager.
Once you try to call on an API endpoint, which is not activated, you will get the same response as when you did not provide a valid API key. In this case, first check whether your request header actually contains the API key. Afterwards, check with your Implementation Manager whether the feature has been activated for your account.
API Status
Example request - Status check
GET https://api-sandbox.onlinebetaalplatform.nl/status
curl https://api-sandbox.onlinebetaalplatform.nl/status \
-H "Authorization: Bearer {{api_key}}"
Example response
{
"status": "online",
"date": 1611321273
}
In order for partners to check whether our APIs are still up and running, we provided an endpoint to reach out to. Please find the example request and response on the right.
Idempotency
Example header of a request
headers: {
"Authorization": "Bearer {{api_key}}",
"Content-Type": "application/json",
"Idempotency-Key": "{{key}}"
}
The API supports idempotency, a mechanism to allow safely retrying requests without performing the same operation twice, for all POST requests.
To perform an idempotent request, you must provide an additional header to the request:
Idempotency-Key: {key}
Please be aware of the following:
- This mechanism will ensure that you get the same response as the first time you have sent the request
- The response for an idempotency key is stored only if the request is valid and returned a valid (OK) response
- Idempotency keys and their response may be removed from the system after 60 minutes
- The idempotency key must be a unique value though your application must understand how the key is generated to ensure subsequent retries of the same request send the same key
The best practice to use this solution is to use your own unique ID of an object, which will not refresh every time a request is sent to our APIs. Also, make sure the rest of your application knows how to deal with this situation. For example when providing a refund, you would normally receive an error when a refund is provided twice, because of insufficient funds. Using the idempotency solution, you will not get an error, but the same response twice.
In cases where multiple requests with the same idempotency key arrive simultaneously, you might receive a HTTP status 409 - Conflict, as is described in the security section.
Pagination
Example request - Retrieve page 2 of the transactions list:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/transactions?page=2&perpage=10 \
-H "Authorization: Bearer {{api_key}}"
GET "https://api-sandbox.onlinebetaalplatform.nl/v1/transactions?page=2&perpage=10"
Example response:
{
"livemode": true,
"object": "list",
"url": "/v1/transactions",
"has_more": true,
"total_item_count": 259,
"items_per_page": 10,
"current_page": 2,
"last_page": 26,
"data": []
}
When retrieving lists of objects, OPP creates pages to keep the transferred objects small. Use the pagination functionality to navigate when sorting through many results. The pages can be switched by adding the following parameters to the GET call:
Parameter | Description |
page integer | The number of the current page. |
perpage integer | The limit of objects to be returned. Limit can range between 1 and 100 items. |
Basic pagination usage:
?page=2&perpage=10
The response sent can be seen below.
Response | Description |
object string | value: list |
url string | The url that was called upon. |
has_more: boolean | Whether the object list has more pages. |
total_item_count integer | Total number of objects in the list. |
items_per_page integer | The number of items per page requested. |
current_page integer | The current page requested. |
last_page integer | The number of the last page that can be requested. |
data array | The actual data object list. |
Notifications
Example response - Notification of a status change of a merchant's bank account status:
{
"uid": "{{notification_uid}}",
"type": "bank_account.status.changed",
"created": 1554199810,
"object_uid": "{{bank_account_uid}}",
"object_type": "bank_account",
"object_url": "https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/bank_accounts/{{bank_account_uid}}",
"parent_uid": "{{merchant_uid}}",
"parent_type": "merchant",
"parent_url": "https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}",
"verification_hash": "5678ikmnaw9pe89fkanwbpf9kw"
}
OPP provides a number of notifications which will be POST to the provided webhook or notify_url
.
The notifications are structured as described below. You may use the object_type
to determine the related resource (e.g. a bankaccount or a transaction) and use the object_url
to retrieve the object directly via API. You may receive notifications for nested resources, such as status updates for a multi transaction or a transaction. We add parent
details to these notifications which makes it easier to find the related merchant for these resources.
Notification object | Description |
uid string | Unique identifier of the notification. |
type string | Type of the notification. |
created timestamp | Timestamp when object is created. |
verification_hash string | Hash that can be used for validating notifications. |
object_uid string | Unique object identifier to which the type belongs. |
object_type string | Type of the object. |
object_url string | Direct link to the object. |
parent_uid string | Unique parent object identifier to which the type belongs. |
parent_type string | Type of the parent object. |
parent_url string | Direct link to the parent object. |
Use the notification type
to determine the required action you would need to take in your own system. Use the object uid
and type
to determine the related resource. Follow the object_url
to retrieve the resource details.
To retrieve the updated details, you must query the API for the updated resource again. For security reasons you may block all notifications which do not originate from the IP ranges of the Sandbox/Production environment.
When we send notifications please ensure that your system handles the notification and responds with a 200 OK, 201 CREATE, 202 ACCEPTED or 204 NO CONTENT within 10 seconds. If we do not receive one of these statuses or when the notification times out, we will try to send the notification again using the following interval/scheme: after 1 minute, after 2 minutes and every 5 minutes after that for up to 10 tries.
Notification Types
A list of all possible notification types can be found below:
Bank Account notifications | Description |
bank_account.status.changed | The status of the merchant's bank_account has changed. |
Contact notifications | Description |
contact.status.changed | The status of the merchant's contact object has changed (ID verification). |
Dispute notifications | Description |
dispute.message.added | A message was added to the dispute. |
dispute.status.changed | The status of the dispute has changed. |
iDEAL QR notifications | Description |
ideal_qr.status.changed | The status of the iDEAL QR has changed. |
Mandate notifications | Description |
mandate.status.changed | The status of the mandate has changed. |
Merchant notifications | Description |
merchant.compliance_level.changed | The compliance level of the merchant has changed. |
merchant.compliance_requirement.created | The merchant has a new compliance requirement that needs to be fulfilled. This only occurs after the creation process. |
merchant.compliance_requirement.status.changed | One of the merchant's compliance requirement statuses has changed. |
merchant.compliance_status.changed | The compliance status of the merchant has changed. |
merchant.contact.phonenumber.updated | The merchant has updated his/her phonenumber. |
merchant.profile.balance.changed | The balance of a merchant's profile has changed. |
merchant.profile.status.changed | The status of a merchant's profile has changed. |
merchant.status.changed | The account status of the merchant has changed. |
merchant.withdrawal.status.changed | The status of a merchant withdrawal has changed. |
Multi transaction notifications | Description |
multi_transaction.status.changed | The status of the multi transaction has changed. |
multi_transaction_import.status.changed | The status of the multi transaction import has changed. |
Payment reference notifications | Description |
payment_reference.transaction.denied | A payment reference transaction was denied. |
payment_reference.transaction.registered | A new payment reference transaction was registered. |
Signup notifications | Description |
signup.status.changed | The status of a signup has changed. |
Transaction notifications | Description |
transaction.amount.changed | The authorization amount of your creditcard has changed (partial capture). |
transaction.status.changed | The status of a transaction has changed. |
Virtual IBAN notifications | Description |
virtual_iban.transaction.registered | A transaction on the virtual IBAN has been registered. |
UBO notifications | Description |
ubo.status.updated | The status of an UBO has been updated. |
Withdrawal notifications | Description |
withdrawal.status.changed | The status of a withdrawal has changed. |
Validating Notifications (Signed Notifications)
The notification requests will be signed using the Signature scheme
from the http-signatures document published by the Internet Engineering Task Force (IETF).
This document is in draft but is used widely and provides our partners a solid method to ensure messages received from us are not tampered with.
Each request to a webhook endpoint will have a header containing a signing signature. This signature is composed by defined parts of the request. Tampering with the request will result in the invalidity of the signature. A secret key (pair) will be used to create and verify the signature assuring only OPP can create the signature.
The signature will be added to the headers of the request and is created from other headers.
The body is included in the signature using a hash of the body contents which is added as the Digest
header.
A complete request message could look like this:
POST /notify HTTP/1.1 Content-Length: 246 Accept: */* Content-Type: application/json Host: onlinepaymentplatform.com Date: Wed, 15 Jun 2022 08:27:14 GMT Digest: SHA-256=GmUCOfLhpwG/mnmzlLmaqgEVvsxv4BUc1DWtAyxRvE8= Signature: keyId="nsk_7b0f85351b52",algorithm="hmac-sha256",headers="(request-target) host date digest",signature="7aBAXZkkZXBYfM8Rxv+FtarqwaqOnlBYNoFSqwE33wI=" {"uid":"not_3e0f7595152b","type":"transaction.status.changed","created":1655274434,"object_uid":"sta_50473c4b0a4d","object_type":"transaction","object_url":""}
Signature Parameters
Signature parameter | Description |
keyId | UID identifier of the secret key used to create the signature. OPP will store secret keys per partner. These secret keys can be rotated. By using the keyId our partner can determine which secret key is used for the signature. Should OPP update the way these signatures are composed in the future, OPP can relate a signature version to the keyId. |
algorithm | The algorithm used to create the signature. |
headers |
The headers used to create the signature. In our case (request-target) host date digest :
(request-target): post /notify host: onlinepaymentplatform.com date: Wed, 15 Jun 2022 08:27:14 GMT digest: SHA-256=GmUCOfLhpwG/mnmzlLmaqgEVvsxv4BUc1DWtAyxRvE8= |
signature | The created signature. |
Verify the HTTP Signature Header
To verify the HTTP Signature header in an incoming webhook request, you would need to perform the following steps:
- Parse the HTTP Signature header and extract the relevant components, including the key ID, signature algorithm, and signature value.
- Retrieve the notification secret associated with the key ID from a trusted source, such as a key server or a configuration file.
- Calculate the expected signature value for the message using the same signature algorithm and input data as the sender.
- Compare the expected signature value with the signature value included in the HTTP Signature header.
- If the two values match, the signature is valid and the message can be processed. Otherwise, the message should be rejected as potentially tampered with or originating from an unauthorized source.
DEPRECATED - Validating Notifications (verification_hash)
In addition to whitelisting our notification servers' IP addresses you can also verify that a notification has been sent by us by verifying the verification_hash
.
The verification_hash
can be compared using the notification_secret
.
Create a HMAC hash of the notification_secret
, and compare this to the verification_hash
.
This will return true when the notification was sent by OPP. False if it was not. The notification_secret
can be found in your partner interface, or ask your implementation manager to provide it to you.
To check the hash, you can use the bash example below, or translate this to any programming language that is preferred.
$ echo -n "{{NOTIFICATION_UID}}" | openssl sha256 -hmac "{{NOTIFICATION_SECRET}}"
Filter & Order
Example request - Transactions belonging to a certain merchant:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/transactions?filter[merchant]={{merchant_uid}}
-H "Authorization: Bearer {{api_key}}"
GET https://api-sandbox.onlinebetaalplatform.nl/v1/transactions?filter[merchant]={{merchant_uid}}
Example request - Transactions between a given datetime range:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/transactions\
?filter[0][name]=date_completed\
&filter[0][operand]=between\
&filter[0][value]=2020-01-01 00:00:00, 2020-09-30 23:59:59 \
-H "Authorization: Bearer {{api_key}}"
GET https://api-sandbox.onlinebetaalplatform.nl/v1/transactions?filter[0][name]=date_completed&filter[0][operand]=between&filter[0][value]=2020-01-01 00:00:00, 2020-09-30 23:59:59
Filter Parameter
You may filter data retrieved via API by adding the filter parameter to your API call. OPP supports two different ways of using the filter parameter: simple and extended.
Before passing information into the filter, always make sure that you have encoded your input to make it readable in URLs, otherwise special characters like +
, &
or ?
might be interpreted in a different way.
A simple filter allows for a direct comparison on given VALUE in given FILTER.
Basic filter usage:
?filter[FILTER]=VALUE
An extended filter allows for complicated filters on given VALUE(S) in given FILTER using OPERATOR Extended filter usage:
?filter[KEY][name]=FILTER
&filter[KEY][operand]=OPERATOR
&filter[KEY][value]=VALUE
The following operators are accepted:
Operator | Description | Expected value(s) |
lt |
less than | single value |
lte |
less than or equal to | single value |
gt |
greater than | single value |
gte |
greater than or equal to | single value |
in |
in given set | comma separated values |
notin |
not in given set | comma separated values |
null |
value null | empty value |
notnull |
value not null | empty value |
eq |
equals | single value |
notequals |
does not equal | single value |
between |
between given set | comma separated values |
Filtering Metadata
You may filter metadata by a specific key/value pair by providing both metadata
as your filter name as well as your metadata key
and value
as your search field and value.
This will result in a filter such as ?filter[metadata][KEY]=VALUE
.
Order Parameter
You may order data retrieved via API by adding the order parameter to your API call. OPP supports both ordering data ascending and descending.
Order ascending:
?order[]=VALUE
Order descending:
?order[]=-VALUE
Every object can be ordered by the variables created
and updated
by using the order parameters date_created
and date_updated
respectively.
Expanding objects
Example request - Expand the transaction with the order details:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/transactions/{{transaction_uid}}\
?expand[]=order \
-H "Authorization: Bearer {{api_key}}"
GET "https://api-sandbox.onlinebetaalplatform.nl/v1/transactions/{{transaction_uid}}?expand[]=order"
Example response:
{
"livemode": true,
"uid": "{{transaction_uid}}",
"object": "transaction",
"metadata": [],
"statuses": [],
"order": {
"uid": "{{order_uid}}",
"object": "order",
"created": 1554113700,
"updated": 1554113700,
"processed": true,
"price": 6000,
"shipping": 695,
"discount": 0,
"street": "van den Brinkring",
"housenumber": "174",
"housenumber_addition": null,
"zipcode": "7391 SW",
"city": "Nieuwediep",
"state": "Groningen",
"country": null,
"customer": {}
}
}
curl https://api-sandbox.onlinebetaalplatform.nl/v1/merchants\
?expand[]=contacts \
-H "Authorization: Bearer {{api_key}}" \
-d country=nld \
-d emailaddress=email@domain.com \
-d phone=0612345678 \
-d notify_url=https://platform.com/notify \
-d return_url=https://platform.com/return
POST "https://api-sandbox.onlinebetaalplatform.nl/v1/merchants?expand[]=contacts"
{
"country": "nld",
"emailaddress": "email@domain.com",
"phone": "0612345678",
"notify_url": "https://platform.com/notify",
"return_url": "https://platform.com/return"
}
Many objects contain a reference to another object. Those objects can be expanded inline with the expand
parameter. The availability of the expand
parameter and its options differ per request and are noted in the descriptions of the objects.
You can nest expand requests with the dot property. For example, requesting a transaction including the related order and customer details can be done by requesting order
and order.customer
. The order property will be expanded into a full order object, and the customer property within the order object will be transformed into a full customer object.
Expands can be used both when fetching a list of resources and when fetching a single resource.
Expands are also available on POST requests, to receive expanded data in the response.
Arguments | |
expand string | name of expandable object |
Metadata
Example request:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/transactions/{{transaction_uid}}/metadata \
-H "Authorization: Bearer {{api_key}}"
-d "metadata[external_id]=2015486"
POST "https://api-sandbox.onlinebetaalplatform.nl/v1/transactions/{{transaction_uid}}/metadata"
{
"metadata":
{
"external_id": "2015486"
}
}
Most objects support metadata. You can add this to the resource in your requests to store additional key/value data to the object. Any metadata set on the object will be returned when the object is retrieved. Use this to keep track of your own internal identifiers or other relevant data. A useful example could be to store your corresponding unique identifier of an OPP object.
Information about filtering metadata can be found in filter & order
Updating or deleting metadata
In all cases, where metadata can be added, it is possible to update or delete metadata after creating the object.
GET /v1/transactions/{{transaction_uid}}/metadata
POST /v1/transactions/{{transaction_uid}}/metadata
DELETE /v1/transactions/{{transaction_uid}}/metadata
The key is the unique identifier in this metadata, meaning that if the key does not yet exist, the key/value pair will be added to the metadata. Should the key exist, the old value will be overwritten.
Deleting all metadata is possible by calling the delete method.
Filtering metadata
You may filter metadata by a specific key/value pair by providing both metadata
as your filter name as well as your metadata key
and value
as your search field and value.
This will result in a filter such as ?filter[metadata][KEY]=VALUE
.
Limitations
As any technical product, we continuously strive to improve our services and possibilities. As new features and products are implemented, this documentation page will be updated.
Online Payment Platform is obliged to follow Dutch laws, and must adhere to terms and conditions that are laid upon us by the Dutch National Bank, integrated payment methods, etc. This means that the API currently has the following limitations:
- If you are building a web-/native app, iDEAL payments cannot be done in any in-app browser. iFrames, WebViews, or other in-app browsing solutions are not permitted, and we cannot guarantee a working solution here. Any other payment method might work, depending on what the provider allows. We cannot guarantee a working solution if you are using any kind of in-app browsing method.
- Credit card payments are provided by our credit card acquirer WorldLine. Worldline makes sure that all rules according to 3DS and privacy are met. This also means that for credit card payments, you will be redirected to a webpage of Worldline.
- Currently, not all objects within the OPP system will trigger a notification on a status change. For a full list of the current notifications, please take a look here.
Security
Another reason some limitations exist is due to security reasons, and prevention of cyber-attacks.
- For security reasons API requests containing a direct reference to
localhost
,127.0.0.1
or similar, for example in notify or return URLs, are not permitted and will be blocked. OPP will throw an HTTP status response 403 - Forbidden in this case. You may use a service such as xip.io or nip.io as a workaround or set up a local test-domain which can be referenced in the*_url
fields. - OPP requires partners to throttle requests and send them sequentially to ensure the system does not get overloaded and partners do not get blacklisted due to DDOSing the system. To enforce this, OPP has implemented an HTTP status response 409 - Conflict. You will receive the error message
"The request could not be completed."
. When this happens, please retry the request at a later moment in time. - Please note that our API is a so called System-to-System API. This means that reaching it via a Frontend system will not work and lead to e.g. CORS errors. Due to security reasons (mainly having the API key available in the frontend), you will only be able to reach the API when using a suitable backend.
Currencies and minor units
The table below lists the supported currencies and their corresponding ISO 4217 currency codes for our API:
Supported currencies
Currency | ISO 4217 code | Decimals |
---|---|---|
Euro | EUR |
2 |
British pound | GBP |
2 |
Minor units
Our API requires amounts to be submitted in minor units, which denote the smallest currency denomination based on the number of decimals.
- EUR 1: EUR has two decimals, so in minor units submit an amount of 100
- GBP 1: GBP has two decimals, so in minor units submit an amount of 100
Merchants
OPP defines two kinds of merchants: Business merchants and Consumer merchants. This chapter will provide you all the necessary information about merchants and the functionalities of a merchant object. OPP provides a Seamless API onboarding for merchants, which ensures that you do not have to use two registration forms. Via the merchant onboarding, you as a partner have complete influence on what is happening in the workflow. OPP often only functions in the background when the merchant API is used (except for file upload).
We have already provided a Postman collection on the Merchant API for you to start with. Also, we have provided a step-by-step guide on how to onboard Business and Consumer merchants.
Merchant
Object Definition - Merchant
The merchant object contains the following variables.
Variable | Description |
uid string | Merchant unique identifier. up to 20 characters |
object string | value: merchant |
created timestamp | Timestamp in CE(S)T when object is created. |
updated timestamp | Timestamp in CE(S)T when object is updated. |
status string | Status of the merchant object. One of: newpendinglivesuspendedterminatedblockeddeleted |
compliance object | Object that states all compliance requirements for the merchant. See Compliance. |
type string | Merchant type. One of: consumerbusiness |
coc_nr string | Chamber of Commerce number of the merchant. up to 45 characters nullable ( BUSINESS ONLY! ) |
name string | (Business) Name of the merchant. up to 45 characters |
phone string | Phonenumber provided when creating the merchant. up to 45 characters |
vat_nr string | Value added tax identification number. up to 45 characters ( BUSINESS ONLY! ) |
country string | Country code of the merchant shown as a ISO 3166-1 alpha-3 country code. |
sector string | Sector in which merchant is affiliate with. up to 45 characters nullable |
addresses object | Object that states all addresses of the merchant. See Adress. |
trading_names array | Object that states all trading names of the merchant. nullable See Trading Names. ( BUSINESS ONLY! ) |
contacts array | Object containing contact information of the merchant. See Contact. |
profiles array | Profile object of the merchant. See Profile. |
payment_methods array | The available payment methods of the merchant. See Payment Methods. |
notify_url string | Notification url to receive status updates for this merchant. up to 255 characters |
return_url string | URL to which the merchant will be directed when closing the verification screens. |
metadata array | Set of key / value pairs to store additional data. nullable |
Merchant status
The merchant status is a status indication about the merchant account in the OPP system.
The merchant status is NOT linked to the compliance status. A live merchant, does not mean that the merchant is approved, and thus able to receive payouts.
Only when a merchant status is live
and when the compliance status is verified
, the merchant will be able to receive payouts.
The possible status flows can be found below:
Status | Explanation |
new | Merchant is created. |
pending | Merchant is pending to be monitored. |
live | Merchant is live and ready to be used. |
terminated | Manually terminated by the partner or OPP, merchant cannot receive payouts and no transactions can be created. Can be undone by partner or OPP. |
suspended | Merchant is temporarily blocked by partner or OPP, no transactions can be made and merchant cannot be paid out. Can be unsuspended by OPP compliance. |
blocked | Permanent block of the merchant. No payouts can be done and no transactions can be created. Cannot be undone. |
deleted | Merchant requested GDPR deletion of data. Cannot be undone. |
Please note that the statuses can be forced in sandbox. See Merchant status simulations.
Notification Example - Merchant
Example notification:
{
"uid": "{{notification_uid}}",
"type": "merchant.status.changed",
"created": 1619182391,
"object_uid": "{{merchant_uid}}",
"object_type": "merchant",
"object_url": "https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}",
"verification_hash": "{{hash}}"
}
Please find a notification example to the right.
Merchant countries
OPP is licensed to onboard almost all countries in the European Economic Area. The current countries that are allowed for onboarding and thus payouts are: Belgium, Bulgaria, Cyprus, Denmark, Germany, Estonia, Finland, France, Greece, Hungary, Ireland, Italy, Croatia, Lithuania, Latvia, Luxembourg, Malta, The Netherlands, Norway, Austria, Poland, Portugal, Romania, Slovenia, Slovakia, Spain, Czech Republic, Great-Britain, Sweden.
The list of countries that are allowed according to our licence can always be seen here.
Create Merchant
Example request - Creating a consumer merchant:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/merchants \
-H "Authorization: Bearer {{api_key}}" \
-d country=nld \
-d emailaddress=email@domain.com \
-d phone=0612345678 \
-d notify_url=https://platform.com/notify \
-d return_url=https://platform.com/return
POST https://api-sandbox.onlinebetaalplatform.nl/v1/merchants
{
"country": "nld",
"emailaddress": "email@domain.com",
"phone": "0612345678",
"notify_url": "https://platform.com/notify",
"return_url": "https://platform.com/return"
}
Example response:
{
"uid": "{{merchant_uid}}",
"object": "merchant",
"created": 1554113700,
"updated": 1554113700,
"status": "pending",
"compliance": {
"level": 100,
"status": "verified",
"overview_url": "https://sandbox.onlinebetaalplatform.nl/nl/{{slug}}/{{merchant_uid}}/{{hash}}/overzicht",
"requirements": []
},
"type": "consumer",
"coc_nr": null,
"name": "John Tester",
"phone": "31601234567",
"vat_nr": null,
"country": "nld",
"sector": null,
"addresses": [],
"trading_names": [],
"contacts": [],
"profiles": [],
"payment_methods": [],
"notify_url": "https://platform.com/notify",
"return_url": "https://platform.com/return",
"metadata": []
}
You can create a merchant using the Merchant API.
The merchant_uid
will be known immediately after creating the merchant, even when the compliance part has not been finalised by the user yet.
Creating a merchant can be done by calling a post to the merchant API: /v1/merchants
.
The required fields for creating a merchant are:
- Country:
country
- Email address:
emailaddress
- Notify URL:
notify_url
- ( BUSINESS ONLY! ) Type:
type = business
- ( BUSINESS ONLY! ) CoC Number:
coc_nr
The more fields of the merchant object you fill in when creating a merchant, the easier the Know Your Customer (KYC) check on our side can be done. Below are all merchant object variables that can be used in the POST request when creating a merchant.
Variable | Description | ||||||||||
type string | Merchant type. One of: consumerbusiness |
||||||||||
country string | Country code of the merchant, use ISO 3166-1 alpha-3 country code. |
||||||||||
locale string | The language in which the text on the verification screens is being displayed and tickets are sent. Default is en One of: nl en fr de |
||||||||||
name_first string | First name of the merchant. ( CONSUMER ONLY! ) | ||||||||||
name_last string | Last name of the merchant. ( CONSUMER ONLY! ) | ||||||||||
is_pep boolean | Whether or not the merchant is a PEP. This will mark the contact that is automatically created as a PEP. ( CONSUMER ONLY! ) | ||||||||||
coc_nr string | Chamber of Commerce number of the merchant. up to 45 characters nullable ( BUSINESS ONLY! ) |
||||||||||
vat_nr string | Value added tax identification number. up to 45 characters ( BUSINESS ONLY! ) |
||||||||||
legal_name string | (Business) Name of the merchant. up to 45 characters |
||||||||||
legal_entity string | Business entity of the merchant. One of the legal_entity_code from the legal entity list ( BUSINESS ONLY! ) |
||||||||||
trading_names array | Array with one or more trading names. | ||||||||||
|
|||||||||||
emailaddress string | Email address of the merchant. Must be unique for every merchant. |
||||||||||
phone string | Phone number of the merchant. | ||||||||||
settlement_interval string | The settlement interval of the merchant. Default is set contractually. Can only be provided after agreement with OPP. One of: daily weekly monthly yearly continuous |
||||||||||
notify_url string | URL to which the notifications of the merchant will be sent. | ||||||||||
return_url string | URL to which the merchant will be directed when closing the verification screens. | ||||||||||
metadata object with key-value pairs | Additional data that belongs to the merchant object. | ||||||||||
addresses array | Address array of the merchant with name/value pairs. | ||||||||||
|
Retrieve Merchant
Example request - Retrieve a single merchant:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}} \
-H "Authorization: Bearer {{api_key}}"
GET https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}
Example response:
{
"uid": "{{merchant_uid}}",
"object": "merchant",
"created": 1554113700,
"updated": 1554113700,
"status": "pending",
"compliance": {
"level": 100,
"status": "verified",
"overview_url": "https://sandbox.onlinebetaalplatform.nl/nl/{{slug}}/{{merchant_uid}}/{{hash}}/overzicht",
"requirements": []
},
"type": "consumer",
"coc_nr": null,
"name": "John Tester",
"phone": "31601234567",
"vat_nr": null,
"country": "nld",
"sector": null,
"addresses": [],
"trading_names": [],
"contacts": [],
"profiles": [],
"payment_methods": [],
"notify_url": "https://platform.com/notify",
"return_url": "https://platform.com/return",
"metadata": []
}
Example request - Retrieve all merchants:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/merchants \
-H "Authorization: Bearer {{api_key}}"
GET https://api-sandbox.onlinebetaalplatform.nl/v1/merchants
Example response:
{
"object": "list",
"url": "/v1/merchants",
"has_more": true,
"total_item_count": 178,
"items_per_page": 10,
"current_page": 1,
"last_page": 18,
"data": [
{
"uid": "{{merchant_uid}}",
"object": "merchant",
"created": 1606988065,
"updated": 1606988065,
"status": "pending",
"compliance": {
"level": 400,
"status": "unverified",
...
},
"type": "business",
...
"metadata": []
},
...
]
}
You can retrieve an individual merchant as well as a list of all merchants. Certain data, such as profiles, addresses, trading names and payment methods may be expanded.
The following filters can be used when retrieving merchants:
Filter name | Description |
status | Shows merchants with a certain status |
type | Shows merchants with a certain type |
legal_name | Shows merchants with a certain legal name |
compliance_status | Shows merchants with a certain compliance status |
compliance_level | Shows merchants with a certain compliance level |
emailaddress | Shows merchant with a certain emailaddress |
created | Shows merchants created on or between given date(s) |
Merchant Trading Names
Example response - expanding trading_names:
{
"livemode": false,
"uid": "{{merchant_uid}}",
"object": "merchant",
...
"trading_names": [
{
"uid": "mtn_06275a6fcd44",
"object": "trading_name",
"created": 1613486266,
"updated": 1613486266,
"name": "Testing BV"
},
{
"uid": "mtn_7e453883c8ea",
"object": "trading_name",
"created": 1613486266,
"updated": 1613486266,
"name": "Testing NV"
}
],
...
}
When expanding certain objects, they will appear when requested. Objects that do not have any CRUD functionality, but are either set by OPP or only set when creating the merchant can be found here.
Variable | Description |
uid string | Merchant Trading Name unique identifier. up to 20 characters |
object string | value: trading_name |
created timestamp | Timestamp in CE(S)T when object is created. |
updated timestamp | Timestamp in CE(S)T when object is updated. |
name string | Trading name of the merchant. |
Merchant Payment Methods
Example response - Expanding payment_methods:
{
"livemode": false,
"uid": "{{merchant_uid}}",
"object": "merchant",
...
"payment_methods": [
{
"uid": "mpm_6b2917f3a0b6",
"object": "payment_method",
"name": "ideal",
"status": "active"
},
{
"uid": "mpm_cc8a94c50d5a",
"object": "payment_method",
"name": "bcmc",
"status": "active"
},
{
"uid": "mpm_c34fc02123e6",
"object": "payment_method",
"name": "sepa",
"status": "active"
}
],
...
}
Example request - Retrieve the payment methods of a merchant.
curl https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/payment_methods \
-H "Authorization: Bearer {{api_key}}"
POST https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/payment_methods
Example response:
{
"object": "list",
"url": "/v1/merchants/{{merchant_uid}}/payment_methods",
"has_more": false,
"total_item_count": 3,
"items_per_page": 10,
"current_page": 1,
"last_page": 1,
"data": [
{
"uid": "mpm_6b2917f3a0b6",
"object": "payment_method",
"name": "ideal",
"status": "active"
},
{
"uid": "mpm_cc8a94c50d5a",
"object": "payment_method",
"name": "bcmc",
"status": "active"
},
{
"uid": "mpm_c34fc02123e6",
"object": "payment_method",
"name": "sepa",
"status": "active"
}
],
}
Merchant payment methods can either be retrieved by expanding the merchant object, or by using the payment_methods endpoint, as can be seen on the right.
Variable | Description |
uid string | Merchant Payment Method unique identifier. up to 20 characters |
object string | value: payment_method |
name string | Payment method name. |
status string | Status of the merchant payment method. One of: activeinactive |
Update Merchant
Example request - Update a merchant:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}} \
-H "Authorization: Bearer {{api_key}}" \
-d notify_url=https://platform.com/notify \
-d return_url=https://platform.com/return
POST https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}
{
"notify_url": "https://platform.com/notify",
"return_url": "https://platform.com/return"
}
Example response:
{
"uid": "{{merchant_uid}}",
"object": "merchant",
"created": 1554113700,
"updated": 1554113700,
"status": "pending",
"compliance": {
"level": 100,
"status": "verified",
"overview_url": "https://sandbox.onlinebetaalplatform.nl/nl/{{slug}}/{{merchant_uid}}/{{hash}}/overzicht",
"requirements": []
},
"type": "consumer",
"coc_nr": null,
"name": "John Tester",
"phone": "31601234567",
"vat_nr": null,
"country": "nld",
"sector": null,
"addresses": [],
"trading_names": [],
"contacts": [],
"profiles": [],
"payment_methods": [],
"notify_url": "https://platform.com/notify",
"return_url": "https://platform.com/return",
"metadata": []
}
You are able to update a merchant by performing a POST on the merchant object. You can update one variable at a time, or multiple as you desire. The following fields can be updated:
Variable | Description |
status string | Merchant status. Merchant can be updated from live to terminated , terminated to live and live to suspended . |
emailaddress string | Update a merchant's emailaddress. Note that this will overwrite the currently used emailaddress. |
is_pep boolean | Whether or not the merchant is a PEP. This will mark the contact that is automatically created as a PEP. ( CONSUMER ONLY! ) |
notify_url string | URL to which the notifications of the merchant will be sent. |
return_url string | URL to which the merchant will be directed when closing the verification screens. |
Migrate Merchant
Example request - Migrate a merchant to business merchant:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/migrate \
-H "Authorization: Bearer {{api_key}}" \
-d coc_nr=12345678 \
-d country=nld
POST https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/migrate
{
"coc_nr": "12345678",
"country": "nld"
}
Created a consumer merchant, but wanted to create a business merchant? You can migrate the merchant by calling the API with a Chamber of Commerce number and the country in which the business merchant operates. Please note that it is not possible (and not permitted) to migrate a merchant from business back to consumer. In this case, you will always need to terminate the business account and create a new consumer merchant.
Delete Merchant
curl https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}} \
-H "Authorization: Bearer {{api_key}}" \
-d status=terminated
POST https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}
{
"status": "terminated"
}
Example response:
{
"uid": "{{merchant_uid}}",
"object": "merchant",
"created": 1554113700,
"updated": 1554113700,
"status": "terminated",
"compliance": {
"level": 100,
"status": "verified",
"overview_url": "https://sandbox.onlinebetaalplatform.nl/nl/{{slug}}/{{merchant_uid}}/{{hash}}/overzicht",
"requirements": []
},
"type": "consumer",
...
}
Due to legal reasons, we can never fully delete merchants. Therefore, it will not be possible for you to delete merchants in the sandbox nor the production environment. You can however, update the merchant status in order to let us know the account needs to be closed.
Please note that updating the merchant status means the merchant will not receive payouts anymore.
We distinguish two reasons and statuses for deleting merchants:
- Termination -
terminated
- The merchant account is closed and will not be used anymore. - Suspension -
suspended
- The merchant has committed fraud and the user will (temporarily) be blocked.
Sandbox Simulation - Merchant
Example request - Update the merchant status
curl https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/update-status \
-H "Authorization: Bearer {{api_key}}" \
-d status=live
POST https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/update-status
{
"status": "live"
}
The status of the merchant can be changed using a post to the endpoint at the right
Update merchant status parameters | |
status required | One of: pending live terminated suspended blocked |
The flows that can be simulated are:
- new -> pending -> live
- new -> pending -> live -> suspended
- new -> pending -> live -> terminated
- new -> pending -> live -> blocked
- suspended -> live
- terminated -> live
Address
Object Definition - Address
The merchant address object contains the following variables.
Variable | Description |
uid string | Merchant Address unique identifier. |
object string | value: address |
created timestamp | Timestamp in CE(S)T when object is created. |
updated timestamp | Timestamp in CE(S)T when object is updated. |
verified timestamp | Timestamp in CE(S)T when object is verified. |
type string | Address type. One of: defaultmanuallyinvoice |
address_line_1 string | First address line of the addressee. up to 150 characters |
address_line_2 string | Second address line of the addressee. up to 150 characters |
zipcode string | Zip code of the addressee. up to 20 characters |
city string | City of the addressee. up to 100 characters |
country string | Country code of the addressee, use ISO 3166-1 alpha-3 country code. |
Create Address
Example request - Create address object for the merchant:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/addresses \
-H "Authorization: Bearer {{api_key}}" \
-d "address_line_1=Kerklaan 1" \
-d zipcode=1234AB \
-d city=Amsterdam \
-d country=nld
POST https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/addresses
{
"address_line_1": "Kerklaan 1",
"zipcode": "11234AB",
"city": "Amsterdam",
"country": "nld"
}
Example response:
{
"uid": "{{merchant_address_uid}}",
"object": "merchant_address",
"created": 1554199810,
"updated": 1554199810,
"verified": 1554201030,
"type": "default",
"address_line_1": "Kerklaan 1",
"address_line_2": null,
"zipcode": "1234AB",
"city": "Amsterdam",
"country": "Netherlands"
}
You can create a merchant address using the Merchant API. Below are all merchant address object variables that can be used in the POST request when creating a merchant address.
Variable | Description |
type string | Address type. One of: defaultmanuallyinvoice |
address_line_1 string | First address line of the addressee. up to 150 characters |
address_line_2 string | Second address line of the addressee. up to 150 characters |
zipcode string | Zip code of the addressee. up to 20 characters |
city string | City of the addressee. up to 100 characters |
country string | Country code of the addressee, use ISO 3166-1 alpha-3 country code. |
Retrieve Address
Example request - Retrieve a single address object from the merchant, using the address_uid:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/addresses/{{merchant_address_uid}} \
-H "Authorization: Bearer {{api_key}}" \
GET https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/addresses/{{merchant_address_uid}}
Example response:
{
"uid": "{{merchant_address_uid}}",
"object": "merchant_address",
"created": 1554199810,
"updated": 1554199810,
"verified": 1554201030,
"type": "default",
"address_line_1": "Kerklaan 1",
"address_line_2": null,
"zipcode": "1234AB",
"city": "Amsterdam",
"country": "Netherlands"
}
Example request - Retrieve all address objects from the merchant:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/addresses \
-H "Authorization: Bearer {{api_key}}" \
GET https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/addresses
Example response:
{
"object": "list",
"url": "//v1/merchants/{{merchant_uid}}/addresses",
"has_more": true,
"total_item_count": 7,
"items_per_page": 5,
"current_page": 1,
"last_page": 2,
"data": [
{
"uid": "{{merchant_address_uid}}",
"object": "merchant_address",
"created": 1554199810,
"updated": 1554199810,
"verified": 1554201030,
"type": "default",
"address_line_1": "Kerklaan 1",
"address_line_2": null,
"zipcode": "1234AB",
"city": "Amsterdam",
"country": "Netherlands"
},
...
]
}
You can retrieve an individual address of a merchant as well as a list of all addresses of a merchant. The following filters can be used when retrieving merchant addresses:
Filter name | Description |
Currently, no filters are available for addresses. |
Update Address
Example request - Update address object for the merchant:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/addresses/{{merchant_address_uid}} \
-H "Authorization: Bearer {{api_key}}" \
-d "address_line_1=Kerklaan 1" \
-d zipcode=1234AB \
-d city=Amsterdam \
-d country=nld
POST https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/addresses//{{merchant_address_uid}}
{
"address_line_1": "Kerklaan 1",
"zipcode": "11234AB",
"city": "Amsterdam",
"country": "nld"
}
Example response:
{
"uid": "{{merchant_address_uid}}",
"object": "merchant_address",
"created": 1554199810,
"updated": 1554199810,
"verified": 1554201030,
"type": "default",
"address_line_1": "Kerklaan 1",
"address_line_2": null,
"zipcode": "1234AB",
"city": "Amsterdam",
"country": "Netherlands"
}
You are able to update a merchant address by performing a POST on the merchant object. You can update one variable at a time, or multiple as you desire. The following fields can be updated:
Variable | Description |
type string | Address type. One of: defaultmanuallyinvoice |
address_line_1 string | First address line of the addressee. up to 150 characters |
address_line_2 string | Second address line of the addressee. up to 150 characters |
zipcode string | Zip code of the addressee. up to 20 characters |
city string | City of the addressee. up to 100 characters |
country string | Country code of the addressee, use ISO 3166-1 alpha-3 country code. |
Delete address
It is not possible to delete an address. In case an address is not valid anymore, please create a new address with the valid information. The latest address wil be used by OPP if needed.
Bank Account
Object Definition - Bank Account
The merchant bank account object contains the following variables.
Variables | Description | ||||
uid string | Bank account unique identifier. up to 20 characters |
||||
object string | Value: bank_account | ||||
created timestamp | Timestamp when object is created. | ||||
updated timestamp | Timestamp when object is updated. | ||||
verified timestamp | Timestamp when bank account is verified. nullable |
||||
verified_with string | Verification method of the object. nullable One of: transactionfileformocr |
||||
verification_url string | Url for verification of the bank account. up to 255 characters |
||||
status string | One of: newpendingapproveddisapproved | ||||
account object | Contains: | ||||
|
|||||
Bank object | Contains: | ||||
|
|||||
reference string | up to 45 characters | ||||
return_url string | The return url the customer is redirected to, once the bank account is verified. up to 255 characters |
||||
notify_url string | Notification url to receive status updates. up to 255 characters |
||||
is_default boolean | One of:
true
false Indicates whether the bank account is merchant's default bank account when creating a new profile. NOTE: This does not mean the bank_account will be the default bank_account for payouts! |
||||
disapprovals object | Object that states all disapproval reasons for the merchant's bank account. See Disapproval Reasons. Empty when no disapprovals are found. |
Bank Account status
The merchant bank_account status is a status indication about the merchant bank_account verification in the OPP system.
The merchant bank_account status is DIRECTLY linked to the compliance status, when the compliance level is >= 200.
Only when a merchant status is live
and when the compliance status is verified
, the merchant will be able to receive payouts.
The possible status flows can be found below:
Status | Explanation |
new | The bank_account is created and still needs to be verified by the merchant. |
pending | The bank_account has been verified by the merchant and is awaiting approval by our compliance department. |
approved | The bank_account is approved and linked for payouts. |
disapproved | The bank_account is disapproved by our compliance department. |
Please note that the statuses can be forced in sandbox. See Merchant bank account status simulations.
Bank Account Disapproval Reasons
Example response:
{
...
"disapprovals": [
{
"name": "bank_account_document_front_missing",
"created": 1685698690
}
]
}
A bank account object can be disapproved for various reasons. To make sure you can help your merchants as good as possible, OPP provides the disapproval reasons in the bank account object via the API. If no disapproval reasons can be found, the array will be empty. If the bank account has multiple rejections, the reasons will be added at the end of the list.
Variable | Description |
name string | The name of the disapproval reason |
created timestamp | Timestamp when object is created. |
The reasons for merchants used can be found below.
Name | Description | Consumer / Business |
bank_account_business | The consumer merchant provided a business bank account where a consumer bank account is required. | Consumer |
bank_account_creditcard_without_iban | The merchant provided a creditcard which does not display the IBAN. In order to get approved, a picture is required that has the IBAN shown. | Consumer Business |
bank_account_document_both_sides_needed | The merchant did not upload both sides of the bank card. In order to get approved, please provide both sides of the document. | Business |
bank_account_document_expired | The document provided is older than 3 months. Please upload a bank statement that is not older than 3 months. | Business |
bank_account_document_front_missing | The merchant did not upload both sides of the bank card. In order to get approved, please provide both sides of the document. | Consumer |
bank_account_document_incorrect | The merchant provided a document that is incorrect and cannot be processed. | Consumer Business |
bank_account_document_unreadable | The merchant provided a document that is unreadable or blanked out too much and cannot be processed. | Consumer Business |
bank_account_from_unlicensed_country | The merchant provided a bank account which is not in one of our merchant countries. OPP is only able to provide payouts towards merchants with an IBAN inside the licensed area. | Consumer Business |
bank_account_iban_different_from_document | The merchant provided an IBAN which differs from the IBAN on the bank statement or bank card. Please make sure that both IBAN match. | Consumer Business |
bank_account_is_not_allowed | The merchant provided a bank account which is not allowed with this type of business. Please make sure a matching bank account is provided. | Business |
bank_account_joint_not_allowed | The merchant provided a joint bank account, which is not allowed with this type of business. Please make sure a matching bank account is provided. | Business |
bank_does_not_match_coc_name | The merchant provided a bank card or bank statement of which the names do not match with the provided coc number / coc extract. Please make sure both names match. | Business |
other_reason | The merchant provided a bank card or bank statement that was declined for another reason than the above-mentioned. | Consumer Business |
Notification Example - Bank Account
Example notification:
{
"uid": "{{notification_uid}}",
"type": "bank_account.status.changed",
"created": 1653488841,
"object_uid": "{{bank_account_uid}}",
"object_type": "bank_account",
"object_url": "https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/bank_accounts/{{bank_account_uid}}",
"parent_uid": "{{merchant_uid}}",
"parent_type": "merchant",
"parent_url": "https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}",
"verification_hash": "{{hash}}"
}
Please find a notification example to the right.
Create Bank Account
Example request - Create contact object for the merchant:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/bank_accounts \
-H "Authorization: Bearer {{api_key}}" \
-d return_url=https://platform.example.com/return \
-d notify_url=https://platform.example.com/notify
POST https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/bank_accounts
{
"return_url": "{{return_url}}",
"notify_url": "{{notify_url}}"
}
Example response:
{
"uid": "{{bank_account_uid}}",
"object": "bank_account",
"created": 1554200096,
"updated": 1554200096,
"verified": null,
"verified_with": null,
"verification_url": "https://onlinebetaalplatform.nl/nl/
{partner_name}/merchants/{{merchant_uid}}/verificatie/
bankgegevens/{{bank_account_uid}}/7a8d3c308b0739ef96320720017d070533912548",
"status": "new",
"account": {
"account_iban": null
},
"bank": {
"bic": null
},
"reference": null,
"return_url": "https://platform.example.com/return",
"notify_url": "https://platform.example.com/notify",
"is_default": true,
"disapprovals": [
{
"name": "bank_account_document_front_missing",
"created": 1685698690
}
]
}
You can create a merchant bank account using the Merchant API.
Below are all merchant bank_account object variables that can be used in the POST request when creating a merchant bank account.
Every bank account you create needs to be verified using the verification_url
.
Variable | Description |
return_url required | The return url the customer is redirected to, once the bank account is verified. up to 255 characters |
notify_url required | Notification url to receive status updates. up to 255 characters |
is_default optional | One of:
true
false Indicates whether the bank account is merchant's default bank account when creating a new profile. NOTE: This does not mean the bank_account will be the default bank_account for all payouts! |
reference optional | string, max 50 characters |
verification_method optional | Empty or sepa |
account_name optional | Account holder's name. Only available and required when using files API. |
account_iban optional | Account holder's IBAN. Only available and required when using files API. |
account_bic optional | Account holder's BIC. Only available when using files API. |
Retrieve Bank Account
Example request - Retrieve a single bank_account object from the merchant, using the bank_account_uid:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/bank_accounts/{{bank_account_uid}} \
-H "Authorization: Bearer {{api_key}}"
GET https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/bank_accounts/{{bank_account_uid}}
Example response:
{
"uid": "{{bank_account_uid}}",
"object": "bank_account",
"created": 1554200096,
"updated": 1554200096,
"verified": null,
"verified_with": null,
"verification_url": "https://onlinebetaalplatform.nl/nl/
{partner_name}/merchants/{{merchant_uid}}/verificatie/
bankgegevens/{{bank_account_uid}}/7a8d3c308b0739ef96320720017d070533912548",
"status": "new",
"account": {
"account_iban": null
},
"bank": {
"bic": null
},
"reference": null,
"return_url": "https://platform.example.com/return",
"notify_url": "https://platform.example.com/notify",
"is_default": true,
"disapprovals": [
{
"name": "bank_account_document_front_missing",
"created": 1685698690
}
]
}
Example request - Retrieve all bank accounts objects from the merchant:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/bank_accounts \
-H "Authorization: Bearer {{api_key}}"
GET https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/bank_accounts
Example response:
{
"object": "list",
"url": "//v1/merchants/{{merchant_uid}}/bank_accounts",
"has_more": false,
"total_item_count": 5,
"items_per_page": 5,
"current_page": 1,
"last_page": 1,
"data": [
{
"uid": "{{bank_account_uid}}",
"object": "bank_account",
"created": 1554200096,
"updated": 1554200096,
"verified": null,
"verified_with": null,
"verification_url": "https://onlinebetaalplatform.nl/nl/
{partner_name}/merchants/{{merchant_uid}}/verificatie/
bankgegevens/{{bank_account_uid}}/7a8d3c308b0739ef96320720017d070533912548",
"status": "new",
"account": {
"account_iban": null,
"account_name": null
},
"bank": {
"bic": null
},
"reference": null,
"return_url": "https://platform.example.com/return",
"notify_url": "https://platform.example.com/notify",
"is_default": true,
"disapprovals": [
{
"name": "bank_account_document_front_missing",
"created": 1685698690
}
]
}
...
]
}
You can retrieve an individual bank account of a merchant as well as a list of all bank accounts of a merchant. The following filters can be used when retrieving merchant bank accounts:
Filter name | Description |
status | Shows bank accounts with a specific status. |
Update Bank Account
Example request - Update bank_account object for the merchant:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/bank_accounts/{{bank_account_uid}} \
-H "Authorization: Bearer {{api_key}}" \
-d reference=bank-123 \
-d return_url=https://platform.example.com/return \
-d notify_url=https://platform.example.com/notify
POST https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/bank_accounts/{{bank_account_uid}}
{
"reference": "bank-123",
"return_url": "https://platform.example.com/return",
"notify_url": "https://platform.example.com/notify"
}
Example response:
{
"uid": "{{bank_account_uid}}",
"object": "bank_account",
"created": 1554200096,
"updated": 1554200096,
"verified": null,
"verified_with": null,
"verification_url": "https://onlinebetaalplatform.nl/nl/
{partner_name}/merchants/{{merchant_uid}}/verificatie/
bankgegevens/{{bank_account_uid}}/7a8d3c308b0739ef96320720017d070533912548",
"status": "new",
"account": {
"account_iban": null
},
"bank": {
"bic": null
},
"reference": bank-123,
"return_url": "https://platform.example.com/return",
"notify_url": "https://platform.example.com/notify",
"is_default": true,
"disapprovals": [
{
"name": "bank_account_document_front_missing",
"created": 1685698690
}
]
}
You are able to update a merchant bank account by performing a POST on the merchant object. You can update one variable at a time, or multiple as you desire. The following fields can be updated:
Variable | Description |
return_url | The return url the customer is redirected to, once the bank account is verified. up to 255 characters |
notify_url | Notification url to receive status updates. up to 255 characters |
reference | string up to 50 characters. |
Delete Bank Account
It is not possible to delete a bank account. In case a bank_account is not valid anymore, please create a new bank_account with the valid information. The latest bank_account information wil be used by OPP for payouts.
Sandbox Simulation - Bank Account
Example request - Update the merchant bank_account status
curl https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/bank_accounts/{{bank_account_uid}}/update-status \
-H "Authorization: Bearer {{api_key}}" \
-d status=approved
POST https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/bank_accounts/{{bank_account_uid}}/update-status
{
"status": "approved"
}
The status of the merchant bank account can be changed using a post to the endpoint at the right.
Update merchant bank account status parameters | |
status required | One of: pending approved disapproved |
The flows that can be simulated are:
- new -> pending -> approved
- new -> pending -> disapproved
- approved -> disapproved -> approved
Contact
Object Definition - Contact
The merchant contact object contains the following variables.
Variables | Description | ||
uid string | Merchant Contact unique identifier. | ||
object string | value: contact |
||
created timestamp | Timestamp in CE(S)T when object is created. | ||
updated timestamp | Timestamp in CE(S)T when object is updated. | ||
verified timestamp | Timestamp in CE(S)T when object is verified. | ||
verified_with string | Verification method of the object. nullable One of: transactionfileidinitsmeidnow |
||
status string | Status of the contact verification.
one of: unverified pending verified |
||
verification_url string | Verification url to which the user should be redirected to verify his/her identity. | ||
type string | Contact type. One of: representativetechnicalfinancial |
||
titlestring | Title. One of: mrmrs |
||
name_initials string | Initials of the contact. | ||
name_first string | First name of the contact. | ||
name_last string | Last name of the contact. | ||
names_given string | Given names of the contact. | ||
birthdate string | Date of birth Format: YYYY-MM-DD |
||
partner_name_last string | Last name of the contact's partner. | ||
emailaddresses array | Array of emailaddresses[#][emailaddress]=value pair. | ||
|
|||
phonenumbers array | Array of phonenumbers[#][phonenumber]=value pair. | ||
|
|||
is_pep boolean | Whether or not the contact is a PEP. ( CONSUMER ONLY! ) | ||
disapprovals object | Object that states all disapproval reasons for the merchant's contact. See Disapproval Reasons. Empty when no disapprovals are found. |
Contact status
The merchant contact status is a status indication about the merchant representative verification in the OPP system.
The merchant contact status is DIRECTLY linked to the compliance status, when the compliance level is >= 400.
Only when a merchant status is live
and when the compliance status is verified
, the merchant will be able to receive payouts.
The possible status flows can be found below:
Status | Explanation |
unverified | The contact is not yet verified or disapproved by our compliance department. |
pending | The contact has identified him-/herself and is awaiting approval by our compliance department. |
verified | The contact is verified. |
Please note that the statuses can be forced in sandbox. See Merchant contact status simulations.
Contact Disapproval Reasons
Example response:
{
...
"disapprovals": [
{
"name": "contact_document_expired",
"created": 1685698690
}
]
}
A contact object can be disapproved for various reasons. To make sure you can help your merchants as good as possible, OPP provides the disapproval reasons in the contact object via the API. If no disapproval reasons can be found, the array will be empty. If the contact has multiple rejections, the reasons will be added at the end of the list.
Variable | Description |
name string | The name of the disapproval reason |
created timestamp | Timestamp when object is created. |
The reasons used can be found below.
Name | Description | Consumer / Business |
contact_document_both_sides_needed | The merchant provided an ID document from which one side is missing. Please upload both front and backside in order to proceed with the onboarding. | Consumer Business |
contact_document_expired | The merchant provided an ID document that has expired. Please provide us with a valid document. | Consumer Business |
contact_document_incorrect | The merchant provided a document that is incorrect and cannot be processed. | Consumer Business |
contact_document_unreadable | The merchant provided a document that is (partially) unreadable and cannot be processed. | Consumer Business |
contact_id_does_not_match_bank_account | The merchant provided an ID verification that does not match the name on the bank account. | Consumer Business |
contact_id_does_not_match_joint_bank_account | The merchant provided an ID verification from a name that is not visible within the joint bank account information we currently have. Please provide us with either an ID verification that is in line with the joint bank account, or provide us with a copy of your bank card that shows you are indeed an owner of the account. | Consumer Business |
contact_id_does_not_match_legal_representative | The merchant provided an ID verification that does not match one of the legal representatives on the business registration extract. | Business |
contact_proof_of_address | The merchant provided an ID document that is outside our merchant countries. In order to complete onboarding, we need a proof that the user lives within our licensed area. | Consumer Business |
contact_under_18_years_of_age | The merchant provided an ID verification, but the merchant is under the age of 18. In some cases or special agreement with some platforms, we might decline merchants due to their age. | Consumer |
other_reason | The merchant provided an ID verification that was declined for another reason than the above-mentioned. | Consumer Business |
Notification Example - Contact
Example notification contact status:
{
"uid": "{{notification_uid}}",
"type": "contact.status.changed",
"created": 1653488996,
"object_uid": "{{contact_uid}}",
"object_type": "contact",
"object_url": "https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/contacts/{{contact_uid}}",
"parent_uid": "{{merchant_uid}}",
"parent_type": "merchant",
"parent_url": "https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}",
"verification_hash": "{{hash}}"
}
Example notification contact phone number:
{
"uid": "{{notification_uid}}",
"type": "contact.status.changed",
"created": 1653488996,
"object_uid": "{{contact_uid}}",
"object_type": "contact",
"object_url": "https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/contacts/{{contact_uid}}",
"parent_uid": "{{merchant_uid}}",
"parent_type": "merchant",
"parent_url": "https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}",
"verification_hash": "{{hash}}"
}
Please find a notification example to the right.
Create Contact
Example request - Create contact object for the merchant:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/contacts \
-H "Authorization: Bearer {{api_key}}" \
-d type=representative \
-d title=mr \
-d gender=m \
-d name[initials]=T \
-d name[names_given]=Tinus \
-d name[first]=Tinus \
-d name[last]=Tester \
-d birthdate=1970-10-10 \
-d emailaddresses[0][emailaddress]=tinus@tester.com \
-d phonenumbers[0][phonenumber]=0612345678
POST https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/contacts
{
"type": "representative",
"title": "mr",
"gender": "m",
"name":
{
"initials": "t",
"names_given": "Tinues",
"first": "Tinus",
"last": "Tester"
},
"birthdate": "1970-10-10",
"emailaddresses": [
{
"emailaddress": "tinus@tester.com"
},
{
"emailaddress": "tinus2@tester.com"
}
],
"phonenumbers": [
{
"phonenumber": "0612345678"
},
{
"phonenumber": "0687654321"
}
]
}
Example response:
{
"livemode": false,
"uid": "{{contact_uid}}",
"object": "contact",
"created": 1594297774,
"updated": 1594297774,
"verified": null,
"verified_with": null,
"status": "unverified",
"verification_url": "https://sandbox.onlinebetaalplatform.nl/nl/testindividual/merchants/{{merchant_uid}/verificatie/contactgegevens/{{contact_uid}}/d4e3e1cec62b9f25458367b416d7a58ac3f20b7e",
"type": "representative",
"title": "mr",
"name_initials": "t",
"name_first": "Tinus",
"name_last": "Tester",
"names_given": "Tinues",
"birthdate": 13,
"partner_name_last": 14,
"emailaddresses": [
{
"uid": "ema_23d902800c7c",
"object": "emailaddress",
"created": 1594297774,
"updated": 1594297774,
"verified": null,
"emailaddress": "tinus@tester.com"
},
{
"uid": "ema_d7d123643921",
"object": "emailaddress",
"created": 1594297774,
"updated": 1594297774,
"verified": null,
"emailaddress": "tinus2@tester.com"
}
],
"phonenumbers": [
{
"uid": "pho_785e81851ab6",
"object": "phonenumber",
"created": 1594297774,
"updated": 1594297774,
"verified": null,
"phonenumber": "0612345678"
},
{
"uid": "pho_ea6610cc8154",
"object": "phonenumber",
"created": 1594297774,
"updated": 1594297774,
"verified": null,
"phonenumber": "0687654321"
}
],
"is_pep": null,
"disapprovals": [
{
"name": "contact_document_expired",
"created": 1685698690
}
]
}
You can create a merchant contact using the Merchant API.
Below are all merchant contact object variables that can be used in the POST request when creating a merchant contact.
Every contact you create needs to be verified using the verification_url
.
Variable | Description | ||||||||
type string, required | Contact type. One of: representativetechnicalfinancial |
||||||||
genderstring, optional | Gender. One of: mfother Required if type=representative |
||||||||
titlestring, optional | Title. One of: mrmrs Required if type=representative |
||||||||
birthdate string, optional | Date of birth Format: YYYY-MM-DD |
||||||||
name array | Name array of the merchant with key/value pairs. | ||||||||
|
|||||||||
emailaddresses array, optional | Array of emailaddresses[#][emailaddress]=value pair. | ||||||||
|
|||||||||
phonenumbers array, optional | Array of phonenumbers[#][phonenumber]=value pair. | ||||||||
|
|||||||||
is_pep boolean, optional | Whether or not the contact is a PEP. ( CONSUMER ONLY! ) |
Retrieve Contact
Example request - Retrieve a single contact object from the merchant, using the contact_uid:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/contacts/{{contact_uid}} \
-H "Authorization: Bearer {{api_key}}"
GET https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/contacts/{{contact_uid}}
Example response:
{
"uid": "{{contact_uid}}",
"object": "contact",
"created": 1594297774,
"updated": 1594297774,
"verified": null,
"verified_with": null,
"status": "unverified",
"verification_url": "https://sandbox.onlinebetaalplatform.nl/nl/testindividual/merchants/{{merchant_uid}/verificatie/contactgegevens/{{contact_uid}}/d4e3e1cec62b9f25458367b416d7a58ac3f20b7e",
"type": "representative",
"title": "mr",
"name_initials": "t",
"name_first": "Tinus",
"name_last": "Tester",
"names_given": "Tinues",
"birthdate": 13,
"partner_name_last": 14,
"emailaddresses": [
{
"uid": "ema_23d902800c7c",
"object": "emailaddress",
"created": 1594297774,
"updated": 1594297774,
"verified": null,
"emailaddress": "tinus@tester.com"
},
{
"uid": "ema_d7d123643921",
"object": "emailaddress",
"created": 1594297774,
"updated": 1594297774,
"verified": null,
"emailaddress": "tinus2@tester.com"
}
],
"phonenumbers": [
{
"uid": "pho_785e81851ab6",
"object": "phonenumber",
"created": 1594297774,
"updated": 1594297774,
"verified": null,
"phonenumber": "0612345678"
},
{
"uid": "pho_ea6610cc8154",
"object": "phonenumber",
"created": 1594297774,
"updated": 1594297774,
"verified": null,
"phonenumber": "0687654321"
}
],
"is_pep": null,
"disapprovals": [
{
"name": "contact_document_expired",
"created": 1685698690
}
]
}
Example request - Retrieve all contact objects from the merchant:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/contacts \
-H "Authorization: Bearer {{api_key}}"
GET https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/contacts
Example response:
{
"object": "list",
"url": "//v1/merchants/{{merchant_uid}}/contacts",
"has_more": false,
"total_item_count": 3,
"items_per_page": 5,
"current_page": 1,
"last_page": 1,
"data": [
{
"uid": "{{contact_uid}}",
"object": "contact",
"created": 1568205415,
"updated": 1612165832,
"verified": null,
"verified_with": null,
"status": "pending",
"verification_url": "https://sandbox.onlinebetaalplatform.nl/nl/testindividual/merchants/{{merchant_uid}}/verificaties/contact-gegevens/{{contact_uid}}/eaf0ea30cbd2e048c0d9c9b6282b95acc7e99300",
"type": "representative",
"title": "mr",
"name_initials": "t",
"name_first": "Tinus",
"name_last": "Tester",
"names_given": "Tinues",
"birthdate": 13,
"partner_name_last": 14,
"emailaddresses": [
{
"uid": "ema_23d902800c7c",
"object": "emailaddress",
"created": 1594297774,
"updated": 1594297774,
"verified": null,
"emailaddress": "tinus@tester.com"
},
{
"uid": "ema_d7d123643921",
"object": "emailaddress",
"created": 1594297774,
"updated": 1594297774,
"verified": null,
"emailaddress": "tinus2@tester.com"
}
],
"phonenumbers": [
{
"uid": "pho_785e81851ab6",
"object": "phonenumber",
"created": 1594297774,
"updated": 1594297774,
"verified": null,
"phonenumber": "0612345678"
},
{
"uid": "pho_ea6610cc8154",
"object": "phonenumber",
"created": 1594297774,
"updated": 1594297774,
"verified": null,
"phonenumber": "0687654321"
}
]
},
...
]
}
You can retrieve an individual contact of a merchant as well as a list of all contacts of a merchant. The following filters can be used when retrieving merchant contacts:
Filter name | Description |
type | Shows contacts with a specific type. |
status | Shows contacts with a specific status. |
emailaddress | Shows contacts with a specific emailaddress. |
Update Contact
Example request - Update contact object for the merchant:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/contacts/{{contact_uid}} \
-H "Authorization: Bearer {{api_key}}" \
-d type=representative \
-d title=mr \
-d gender=m \
-d name[initials]=T \
-d name[names_given]=Tinus \
-d name[first]=Tinus \
-d name[last]=Tester \
-d birthdate=1970-10-10 \
-d emailaddresses[0][emailaddress]=tinus@tester.com \
-d phonenumbers[0][phonenumber]=0612345678
POST https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/contacts/{{contact_uid}}
{
"type": "representative",
"title": "mr",
"gender": "m",
"name":
{
"initials": "t",
"names_given": "Tinues",
"first": "Tinus",
"last": "Tester"
},
"birthdate": "1970-10-10",
"emailaddresses": [
{
"emailaddress": "tinus@tester.com"
},
{
"emailaddress": "tinus2@tester.com"
}
],
"phonenumbers": [
{
"phonenumber": "0612345678"
},
{
"phonenumber": "0687654321"
}
]
}
Example response:
{
"uid": "{{contact_uid}}",
"object": "contact",
"created": 1594297774,
"updated": 1594297774,
"verified": null,
"verified_with": null,
"status": "unverified",
"verification_url": "https://sandbox.onlinebetaalplatform.nl/nl/testindividual/merchants/{{merchant_uid}/verificatie/contactgegevens/{{contact_uid}}/d4e3e1cec62b9f25458367b416d7a58ac3f20b7e",
"type": "representative",
"title": "mr",
"name_initials": "t",
"name_first": "Tinus",
"name_last": "Tester",
"names_given": "Tinues",
"birthdate": 13,
"partner_name_last": 14,
"emailaddresses": [
{
"uid": "ema_23d902800c7c",
"object": "emailaddress",
"created": 1594297774,
"updated": 1594297774,
"verified": null,
"emailaddress": "tinus@tester.com"
},
{
"uid": "ema_d7d123643921",
"object": "emailaddress",
"created": 1594297774,
"updated": 1594297774,
"verified": null,
"emailaddress": "tinus2@tester.com"
}
],
"phonenumbers": [
{
"uid": "pho_785e81851ab6",
"object": "phonenumber",
"created": 1594297774,
"updated": 1594297774,
"verified": null,
"phonenumber": "0612345678"
},
{
"uid": "pho_ea6610cc8154",
"object": "phonenumber",
"created": 1594297774,
"updated": 1594297774,
"verified": null,
"phonenumber": "0687654321"
}
],
"is_pep": null,
"disapprovals": [
{
"name": "contact_document_expired",
"created": 1685698690
}
]
}
You are able to update a merchant contact by performing a POST on the merchant object. You can update one variable at a time, or multiple as you desire. The following fields can be updated:
Variable | Description | ||||||||
type string, required | Contact type. One of: representativetechnicalfinancial |
||||||||
genderstring, optional | Gender. One of: mfother Required if type=representative |
||||||||
titlestring, optional | Title. One of: mrmrs Required if type=representative |
||||||||
birthdate string, optional | Date of birth Format: YYYY-MM-DD |
||||||||
name array | Name array of the merchant with key/value pairs. | ||||||||
|
|||||||||
emailaddresses array, optional | Array of emailaddresses[#][emailaddress]=value pair. | ||||||||
|
|||||||||
phonenumbers array, optional | Array of phonenumbers[#][phonenumber]=value pair. | ||||||||
|
|||||||||
is_pep boolean | Whether or not the contact is a PEP. ( CONSUMER ONLY! ) |
Delete Contact
It is not possible to delete a contact. In case a contact is not valid anymore, please create a new contact with the valid information. The latest contact information wil be used by OPP if needed.
Sandbox Simulation - Contact
Merchant Contact statuses
Example request - Update the merchant contact status
curl https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/contacts/{{contact_uid}}/update-status \
-H "Authorization: Bearer {{api_key}}" \
-d status=verified
POST https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/contacts/{{contact_uid}}/update-status
{
"status": "verified"
}
The status of the merchant contact can be changed using a post to the endpoint at the right.
Update merchant contact status parameters | |
status required | One of: pending verified unverified |
The flows that can be simulated are:
- pending -> unverified
- pending -> verified
- unverified -> verified
iDIN verification
You can skip the whitelabel screens and immediately force an iDIN status when appending the redirect_url with the following:
https://onlinebetaalplatform.nl/nl/{{partner}}/merchants/{{merchant_uid}}/ verificatie/contactgegevens /{{contact_uid}}/{{hash}}?verification_type=idin&issuer={{issuer}}
You can use one of the issuers below for automatic testing:
Issuer | Result |
CURRNL2A | Use Currence issuer |
RABONL2U | Use Rabobank iDIN issuer simulation |
openHIO400OIHtest | iDIN status: open |
expiredHIO300OIHtest | iDIN status: expired |
cancelledHIO200OIHtest | iDIN status: cancelled |
failureHIO500OIHtest | iDIN status: failed |
succesHIO100OIHtest | iDIN status: success |
Phone verification
Phone numbers are obliged by OPP in order to receive payouts.
These phone numbers will only be verified by our Compliance department when we suspect fraud or any other problems with the merchant account.
When you want to trigger the phone verification process of a merchant, please contact your Implementation Manager.
In sandbox, you will not receive an SMS in relation to this process, the code is always 12345
.
Profile
Object Definition - Profile
Every merchant has at least one profile. This profile is created automatically, and most of the time will not be noticed by you as a partner, nor by the merchant. A profile might be used to distinguish groups of transactions that belong to one certain event. When a bank account is created, this is automatically linked to a merchant's profile.
The merchant profile object contains the following variables.
Variable | Description |
uid string | Merchant profile unique identifier. up to 20 characters |
object string | Value profile |
created timestamp | Timestamp when object is created. |
updated timestamp | Timestamp when object is updated. |
status string | One of: newpendingawaitingliveterminatedsuspended |
name string | Name of the (sub)organization or unit of the merchant. up to 100 characters |
sector -DEPRECATED-string | Sector the merchants profile is affiliate with. up to 45 characters |
url string | up to 150 characters |
po_number string | Payout reference. up to 40 characters |
contact -DEPRECATED-array | Expanded by default. nullable |
settings -DEPRECATED-array | Expanded by default. nullable |
bank_account array | Bank account that is linked to the profile. Expanded by default. nullable |
payment_methods array | See payment_methods object, can be expanded. nullable |
files -DEPRECATED- array | Can not be expanded, nullable |
messages -DEPRECATED-array | Can not be expanded, nullable |
metadata object with key-value pairs | Additional data that belongs to the merchant object. |
virtual_ibans array | Array of virtual IBANs available in the profile. |
risk_level_weight integer | One of: 100 - Low 200 - Normal 300 - High 400 - Unacceptable |
Profile status
The profile status is a status indication about the merchant profile in the OPP system.
The profile status is NOT linked to the compliance status. A live profile, does not mean that the merchant is approved, and thus able to receive payouts.
Only when a merchant status is live
, profile status is live
and when the compliance status is verified
, the merchant will be able to receive payouts.
The possible status flows can be found below:
Status | Explanation |
new | Merchant profile is created. |
pending | Merchant profile is pending to be monitored. |
awaiting | Merchant profile has been found insufficient by compliance team. Please direct the merchant to the ticket to provide more information. |
live | Merchant profile is live and ready to be used. |
terminated | Manually terminated by the partner or OPP, merchant cannot receive payouts through this profile and no transactions can be created. Can be undone by partner or OPP. |
suspended | Merchant profile is blocked by OPP, no transactions can be made and merchant profile cannot be paid out. Can be unsuspended by OPP compliance. |
Notification Example - Profile
Example notification profile status:
{
"uid": "{{notification_uid}}",
"type": "merchant.profile.status.changed",
"created": 1691482031,
"object_uid": "{{profile_uid}}",
"object_type": "merchant_profile",
"object_url": "https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/profiles/{{profile_uid}}",
"parent_uid": "{{merchant_uid}}",
"parent_type": "merchant",
"parent_url": "https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}",
"verification_hash": "{{hash}}"
}
Example notification profile balance:
{
"uid": "{{notification_uid}}",
"type": "merchant.profile.balance.changed",
"created": 1619182391,
"object_uid": "{{profile_uid}}",
"object_type": "merchant_profile",
"object_url": "https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/profiles/{{profile_uid}}",
"parent_uid": "{{merchant_uid}}",
"parent_type": "merchant",
"parent_url": "https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}",
"verification_hash": "{{hash}}"
}
Please find a notification example to the right.
Create Profile
Example request - Create profile object for the merchant:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/profiles \
-H "Authorization: Bearer {{api_key}}" \
-d "name=Profile1" \
-d "url=https://www.onlinepaymentplatform.com" \
-d "po_number=payout of Profile1" \
-d bank_account_uid={{bank_account_uid}}
POST https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/profiles
{
"name": "Profile1",
"url": "https://www.onlinepaymentplatform.com",
"po_number": "payout of Profile1",
"bank_account_uid": {{bank_account_uid}}
}
Example response:
{
"livemode": false,
"uid": "{{profile_uid}}",
"object": "profile",
"created": 1645008161,
"updated": 1645008161,
"status": "pending",
"name": "Profile1",
"sector": null,
"url": "https://www.onlinepaymentplatform.com",
"contact": {
"phonenumber": null,
"emailaddress": null
},
"settings": {
"modules": {
"payment_requests": {
"time_of_validity": 345600
}
}
},
"bank_account": "{{bank_account_uid}}",
"payment_methods": [],
"files": {},
"messages": {},
"metadata": [],
"virtual_ibans": [],
"risk_level_weight": 100
}
You can create a merchant profile using the Profiles API. Below are all merchant profile object variables that can be used in the POST request when creating a merchant profile.
Variable | Description |
name string, required | Name of the profile. Up to 100 characters. |
url string, required | URL belonging to the profile. If non available, please provide the platform URL. |
po_numberstring, optional | Payout description of the profile. Will overwrite default settlement payout description. |
bank_account_uid string, optional | Bank account used for payouts. If not provided, the default bank_account_uid is used. |
metadata object with key-value pairs | Additional data that belongs to the merchant object. |
Retrieve Profile
Example request - Retrieve a single profile object from the merchant, using the profile_uid:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/profiles/{{profile_uid}} \
-H "Authorization: Bearer {{api_key}}"
Example response:
{
"uid": "{{profile_uid}}",
"object": "profile",
"created": 1645008161,
"updated": 1645008161,
"status": "pending",
"name": "Profile1",
"sector": null,
"url": "https://www.onlinepaymentplatform.com",
"contact": {
"phonenumber": null,
"emailaddress": null
},
"settings": {
"modules": {
"payment_requests": {
"time_of_validity": 345600
}
}
},
"bank_account": "{{bank_account_uid}}",
"payment_methods": [],
"files": {},
"messages": {},
"metadata": [],
"virtual_ibans": [],
"risk_level_weight": 100
}
Example request - Retrieve all profile objects from the merchant:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/profiles \
-H "Authorization: Bearer {{api_key}}"
Example response:
{
"object": "list",
"url": "/v1/merchants/{{merchant_uid}}/profiles",
"has_more": false,
"total_item_count": 1,
"items_per_page": 10,
"current_page": 1,
"last_page": 1,
"data": [
{
"uid": "{{profile_uid}}",
"object": "profile",
"created": 1645008161,
"updated": 1645008161,
"status": "pending",
"name": "Profile1",
"sector": null,
"url": "https://www.onlinepaymentplatform.com",
"contact": {
"phonenumber": null,
"emailaddress": null
},
"settings": {
"modules": {
"payment_requests": {
"time_of_validity": 345600
}
}
},
"bank_account": "{{bank_account_uid}}",
"payment_methods": [],
"files": {},
"messages": {},
"metadata": [],
"virtual_ibans": [],
"risk_level_weight": 100
}
]
}
You can retrieve an individual profile of a merchant as well as a list of all profiles of a merchant. The following filters can be used when retrieving merchant profiles:
Filter name | Description |
Currently, no filters are available for profiles. |
Update Profile
Example request - Update profile object for the merchant:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/profiles/{{profile_uid}} \
-H "Authorization: Bearer {{api_key}}" \
-d "name=Profile1" \
-d "url=https://www.onlinepaymentplatform.com" \
-d "po_number=payout of Profile1" \
-d bank_account={{bank_account_uid}}
POST https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/profiles/{{profile_uid}}
{
"name": "Profile1",
"url": "https://www.onlinepaymentplatform.com",
"po_number": "payout of Profile1",
"bank_account_uid": {{bank_account_uid}}
}
Example response:
{
"uid": "{{profile_uid}}",
"object": "profile",
"created": 1645008161,
"updated": 1645008161,
"status": "pending",
"name": "Profile1",
"sector": null,
"url": "https://www.onlinepaymentplatform.com",
"contact": {
"phonenumber": null,
"emailaddress": null
},
"settings": {
"modules": {
"payment_requests": {
"time_of_validity": 345600
}
}
},
"bank_account": "{{bank_account_uid}}",
"payment_methods": [],
"files": {},
"messages": {},
"metadata": [],
"virtual_ibans": [],
"risk_level_weight": 100
}
You are able to update a merchant profile by performing a POST on the merchant object. You can update one variable at a time, or multiple as you desire. The following fields can be updated:
Variable | Description |
name string | Name of the profile. Up to 100 characters. |
status string | Status of the profile. Profile can be updated from pending to terminated , terminated to pending and live to terminated . |
url string | URL belonging to the profile. If non available, please provide the platform URL. Up to 150 characters. |
po_numberstring | Payout description of the profile. Will overwrite default settlement payout description. Up to 40 characters. |
bank_account_uid string | Bank account used for payouts. Provide null as a string to detach any bank_account. |
Delete Profile
Example request - Delete profile:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/profiles/{{profile_uid}} \
-H "Authorization: Bearer {{api_key}}" \
-X DELETE
DELETE https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/profiles/{{profile_uid}}
A profile can only be deleted when the following rules apply:
- Merchant should have another default profile
- Profile shouldn't have virtual IBANs
- Profile shouldn't have a record in settlements (transactions, withdrawals, charges, etc.)
- Profile shouldn't have a mandate
Ultimate Beneficial Owner (UBO)
Object Definition - UBO
The merchant UBO object contains the following variables.
UBO object | Description |
uid string | Merchant UBO unique identifier. up to 20 characters |
object string | Value: ubo |
created timestamp | Timestamp when object is created. |
updated timestamp | Timestamp when object is updated. |
status string | One of: newpendingverifiedunverified |
verified boolean | True when the UBO is verified. False if not. Null when initialized. |
names_first string | First names of the UBO. up to 45 characters |
name_prefix string | Prefix of the UBO. up to 40 characters |
name_last string | Last name of the UBO. up to 40 characters |
date_of_birth string | Date of birth of the UBO. Must be formatted as yyyy-mm-dd |
country_of_residence string | Country code of the country of residence of the UBO shown as a ISO 3166-1 alpha-3 country code. |
share integer | Amount of share of the UBO. |
is_decision_maker boolean | Whether the UBO is a decision maker. |
decision_maker_percentage float | How much decision power the UBO has, expressed as a percentage. |
is_shareholder boolean | Whether the UBO is a shareholder. |
shareholder_percentage float | The percentage of shares the UBO holds in the company. |
is_pep boolean | Whether the UBO is a Politically Exposed Persons (PEP). |
UBO status
The merchant ubo status is a status indication about the merchant ubo verification in the OPP system.
The merchant ubo status is DIRECTLY linked to the compliance status, when the compliance level is >= 400.
Only when a merchant status is live
and when the compliance status is verified
, the merchant will be able to receive payouts.
The possible status flows can be found below:
Status | Explanation |
new | The ubo is created and still needs to be verified by the merchant. |
pending | The ubo has been verified by the merchant and is awaiting approval by our compliance department. |
unverified | The ubo is disapproved by our compliance department. |
verified | The ubo is approved by our compliance department. |
UBO Disapproval Reasons
Example response:
{
...
"disapprovals": [
{
"name": "ubo_confirmed_false_information",
"created": 1685698690
}
]
}
A UBO object can be disapproved for various reasons. To make sure you can help your merchants as good as possible, OPP provides the disapproval reasons in the UBO object via the API. If no disapproval reasons can be found, the array will be empty. If the UBO has multiple rejections, the reasons will be added at the end of the list.
Variable | Description |
name string | The name of the disapproval reason |
created timestamp | Timestamp when object is created. |
The reasons used can be found below.
Name | Description | Consumer / Business |
ubo_confirmed_false_information | The merchant provided an ubo with false information. Please make sure the ubo information is correct. | Business |
ubo_contains_no_natural_person | The merchant provided an ubo which is not a natural person. Please make sure the ubo information contains natural persons only. | Business |
ubo_contains_pep | The merchant provided an ubo that is a political exposed person (pep). Please make sure the merchant answers the questions as provided in an email. | Business |
ubo_doesnt_match_coc_extract | The merchant provided an ubo that does not match with the business registration extract. Please make sure that all ubos are in the business registration extract. | Business |
ubo_missing | An UBO is missing. Please provide all ubos of the business. | Business |
other_reason | The merchant provided a ubo information that was declined for another reason than the above-mentioned. | Business |
Notification Example - UBO
Example notification:
{
"uid": "{{notification_uid}}",
"type": "ubo.status.updated",
"created": 1668414803,
"object_uid": "{{ubo_uid}}",
"object_type": "ubo",
"object_url": "https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/ubos/{{ubo_uid}}",
"parent_uid": "{{merchant_uid}}",
"parent_type": "merchant",
"parent_url": "https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}",
"verification_hash": "{{hash}}"
}
Please find a notification example to the right.
Create UBO
Example request - Create ubo object for the merchant:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/ubos \
-H "Authorization: Bearer {{api_key}}" \
-d names_first=Tinus \
-d "name_prefix=van der" \
-d name_last=Tester \
-d date_of_birth=1978-01-04 \
-d is_decision_maker=true \
-d decision_maker_percentage=33.33 \
-d is_pep=false \
-d country_of_residence=NLD \
-d is_shareholder=true \
-d shareholder_percentage=66.67
POST https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/ubos
{
"names_first" : "Tinus",
"name_prefix" : "van der",
"name_last" : "Tester",
"date_of_birth" : "1978-01-04",
"is_decision_maker" : true,
"decision_maker_percentage" : 33.33,
"is_pep" : false,
"country_of_residence": "NLD",
"is_shareholder": true,
"shareholder_percentage": 66.67
}
Example response:
{
"livemode": false,
"uid": "{{ubo_uid}}",
"object": "ubo",
"status": "pending",
"created": 1594303127,
"updated": 1594303127,
"verified": null,
"names_first": "Tinus",
"name_prefix": "van der",
"name_last": "Tester",
"date_of_birth": "1978-01-04",
"country_of_residence": nld,
"share": 30,
"is_decision_maker": true,
"decision_maker_percentage": 33.33,
"is_shareholder": true,
"shareholder_percentage": 66.67,
"is_pep": false
}
You can create a merchant ubo using the Merchant API. Below are all merchant ubo object variables that can be used in the POST request when creating an ubo.
An UBO needs to be created for every business merchant that has more than one owner. This UBO will then be checked by the compliance department. Notifications will be sent to the merchant's notify_url
.
The compliance object of the merchant will contain the URL in which the UBO is able to identify himself/herself, this is not visible in the UBO object.
Variable | Description |
names_first required | The first names of the UBO. |
name_prefix |
Prefix of the UBO. |
name_last required | Last name of the UBO. |
date_of_birth required | Date of birth of the UBO. Must be formatted as yyyy-mm-dd |
country_of_residence required | Country of residence of the UBO. Use ISO 3166-1 alpha-3 country code. |
is_decision_maker | Whether the UBO is a decision maker. |
decision_maker_percentage | How much decision power the UBO has, expressed as a percentage. |
is_shareholder | Whether the UBO is a shareholder. |
shareholder_percentage | The percentage of shares the UBO holds in the company. |
is_pep | Whether the UBO is a Politically Exposed Persons (PEP). |
Retrieve UBO
Example request - Retrieve a single ubo object from the merchant, using the ubo_uid:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/ubos/{{ubo_uid}} \
-H "Authorization: Bearer {{api_key}}"
GET https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/ubos/{{ubo_uid}}
Example response:
{
"livemode": false,
"uid": "{{ubo_uid}}",
"object": "ubo",
"status": "pending",
"created": 1594303127,
"updated": 1594303127,
"verified": null,
"names_first": "Tinus",
"name_prefix": "van der",
"name_last": "Tester",
"date_of_birth": "1978-01-04",
"country_of_residence": nld,
"share": 30,
"is_decision_maker": true,
"is_shareholder": true,
"is_pep": false
}
Example request - Retrieve all ubo objects from the merchant:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/ubos \
-H "Authorization: Bearer {{api_key}}"
GET https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/ubos
Example response:
{
"object": "list",
"url": "/v1/merchants/{{merchant_uid}}/ubos",
"has_more": false,
"total_item_count": 3,
"items_per_page": 10,
"current_page": 1,
"last_page": 1,
"data": [
{
"livemode": false,
"uid": "{{ubo_uid}}",
"object": "ubo",
"status": "pending",
"created": 1594303127,
"updated": 1594303127,
"verified": null,
"names_first": "Tinus",
"name_prefix": "van der",
"name_last": "Tester",
"date_of_birth": "1978-01-04",
"country_of_residence": nld,
"share": 30,
"is_decision_maker": true,
"is_shareholder": true,
"is_pep": false
}
]
}
You can retrieve an individual UBO of a merchant as well as a list of all UBOs of a merchant. The following filters can be used when retrieving merchant UBOs:
Filter name | Description |
Currently, no filters are available for UBOs. |
Update UBO
Example request - Update ubo object for the merchant:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/ubos/{{ubo_uid}} \
-H "Authorization: Bearer {{api_key}}" \
-d names_first=Tinus \
-d "name_prefix=van der" \
-d name_last=Tester \
-d date_of_birth=1978-01-04 \
-d is_decision_maker=true \
-d decision_maker_percentage=66.67
-d is_pep=false \
-d country_of_residence=NLD \
-d is_shareholder=true \
-d shareholder_percentage=33.33
POST https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/ubos/{{ubo_uid}}
{
"names_first": "Tinus",
"name_prefix": "van der",
"name_last": "Tester",
"date_of_birth": "1978-01-04",
"is_decision_maker": true,
"decision_maker_percentage": 66.67,
"is_pep": false,
"country_of_residence": "NLD",
"is_shareholder": true
"shareholder_percentage": 33.33
}
Example response:
{
"livemode": false,
"uid": "{{ubo_uid}}",
"object": "ubo",
"status": "pending",
"created": 1594303127,
"updated": 1594303127,
"verified": null,
"names_first": "Tinus",
"name_prefix": "van der",
"name_last": "Tester",
"date_of_birth": "1978-01-04",
"country_of_residence": nld,
"share": 30,
"is_decision_maker": true,
"decision_maker_percentage": 66.67
"is_shareholder": true,
"shareholder_percentage": 33.33
"is_pep": false
}
You are able to update a UBO by performing a POST on the UBO object. You can update one variable at a time, or multiple as you desire.
The following fields can be updated:
Variable | Description |
names_first required | The first names of the UBO. |
name_prefix |
Prefix of the UBO. |
name_last string | Last name of the UBO. |
date_of_birth string | Date of birth of the UBO. Must be formatted as yyyy-mm-dd |
country_of_residence string | Country of residence of the UBO. Use ISO 3166-1 alpha-3 country code. |
is_decision_maker boolean | Whether the UBO is a decision maker. |
decision_maker_percentage float | How much decision power the UBO has, expressed as a percentage. |
is_shareholder boolean | Whether the UBO is a shareholder. |
shareholder_percentage float | The percentage of shares the UBO holds in the company. |
is_pep boolean | Whether the UBO is a Politically Exposed Persons (PEP). |
Delete UBO
It is not possible to delete an UBO. In case an UBO is not valid anymore, please contact our support department.
Sandbox Simulation - UBO
Merchant UBO statuses
Example request - Update the merchant ubo status
curl https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/ubos/{{ubo_uid}}/update-status \
-H "Authorization: Bearer {{api_key}}" \
-d status=verified
POST https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/ubos/{{ubo_uid}}/update-status
{
"status": "verified"
}
The status of the merchant ubo can be changed using a post to the endpoint at the right.
Update merchant ubo status parameters | |
status required | One of: pending verified unverified |
The flows that can be simulated are:
- pending -> unverified
- pending -> verified
- unverified -> verified
Compliance
Object Definition - Compliance
Example - Compliance object
"compliance": {
"level": 400,
"status": "unverified",
"overview_url": "https://sandbox.onlinebetaalplatform.nl/en/testindividual/{{merchant_uid}}/15c0bdb17283475ec5f274cad0a2a0245dda11ff/overview",
"requirements": [
{
"type": "contact.verification.required",
"status": "unverified",
"object_type": "contact",
"object_uid": "[contact_uid]",
"object_url": "https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/contacts/{{contact_uid}}",
"object_redirect_url": "https://sandbox.onlinebetaalplatform.nl/nl/testindividual/merchants/{{merchant_uid}}/verificatie/contactgegevens/{{contact_uid}}/e23405b8d2fc98d6fef9a5999dde0a0a7db26f6a"
},
{
"type": "ubo.verification.required",
"status": "unverified",
"object_type": "ubo",
"object_uid": "[ubo_uid]",
"object_url": "https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/ubos/{{ubo_uid}}",
"object_redirect_url": "https://sandbox.onlinebetaalplatform.nl/nl/testindividual/merchants/{{merchant_uid}}/verificatie/ubogegevens/15c0bdb17283475ec5f274cad0a2a0245dda11ff"
},
{
"type": "bank_account.verification.required",
"status": "unverified",
"object_type": "bank_account",
"object_uid": "[bank_account_uid]",
"object_url": "https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/bank_accounts/{{bank_account_uid}}",
"object_redirect_url": "https://sandbox.onlinebetaalplatform.nl/nl/testindividual/merchants/{{merchant_uid}}/verificatie/bankgegevens/{{bank_account_uid}}/fc0b7c490a5021069ae04b50a1a2ee4b2be1b691"
}
]
}
The merchant compliance object contains the following variables.
Variable | Description | ||||||||||
level integer | This level determines which requirements merchant should meet. between 100 and 500 |
||||||||||
status string | Compliance status of the merchant. One of: unverifiedpendingverified | ||||||||||
overview_url string | Url containing all open verifications. The merchant can be directed to this url to fulfill all requirements at once. | ||||||||||
requirements array | The Array of the requirements that merchant still needs to fulfil. Contains zero, one or more compliance requirement objects. | ||||||||||
|
Compliance status
The merchant compliance status is a status indication about the merchant compliance in the OPP system.
Only when a merchant status is live
and when the compliance status is verified
, the merchant will be able to receive payouts.
The compliance status will always be the same as the lowest status of the compliance requirements. So in case any of the requirements is unverified, the overall compliance status will also be unverified.
The possible status flows can be found below:
Status | Explanation |
unverified | Merchant is unverified and unable to receive payouts. Merchant should meet all unverified ‘compliance requirements’ to get to the ‘verified’ state. Unverified means that no verifications have been done yet, or delivered verifications have been disapproved. |
pending | Merchant compliance status is pending and is unable to receive payouts. Merchant is awaiting the review of the merchant's updated ‘compliance requirements’ by OPP. |
verified | Merchant compliance status is verified and the merchant is able to receive payouts. |
Compliance Requirements
Each compliance requirement states the compliance requirement type and details the related object. Merchant should be redirect to object_redirect_url
in order to get to the (whitelabel) OPP page where the required actions will be explained.
You also have the possibility to redirect the merchant to the overview_url
. In this case, the user can fulfill all open requirements at once.
We will send out notifications for each change in compliance requirements and compliance status. We advise you to not save details of each compliance requirement but always to retrieve the latest data via API whenever there is a change.
The compliance requirement types are used to describe the requirement in a simplified way. We currently list the following compliance requirement types:
Compliance Requirement type | Description |
bank_account.required | No bank account available while at least one is required. |
bank_account.verification.required | No verified bank account available while at least one verified bank account is required. |
contact.verification.required | No verified merchant contact available. |
contact.phonenumber.required | No phonenumber available, while at least one is required. |
contact.phonenumber.verification.required | The phonenumber that has been entered needs to be verified by a text message. |
source_of_funds.required | The merchant is receiving funds for which OPP requires to know the source. |
coc_extract.required | ( BUSINESS ONLY! ) Compliance does not have a state of the art extract, and will trigger the option to deliver it. |
organization_structure.required | ( BUSINESS ONLY! ) Compliance cannot create a clear view on the organization structure, and will trigger the option to deliver it. |
ubo.required | ( BUSINESS ONLY! ) No UBO is created yet, but is necessary in order to continue the screening. |
ubo.verification.required | ( BUSINESS ONLY! ) The merchant has to fill / verify all UBO’s. |
Phone number requirement
{
"type": "contact.phonenumber.required",
"status": "unverified",
"object_type": "contact_phonenumber",
"object_uid": null,
"object_url": null,
"object_redirect_url": "https://sandbox.onlinebetaalplatform.nl/en/testindividual/merchants/{{merchant_uid}}/verifications/phonenumber-form/{{contact_uid}}/ef8c16a33cb6b6e93c737d176538328be501f2a7"
},
We are legally bound to have a phone number and verified email address linked to every merchant in order to contact him/her when something is wrong with a transaction or verification. You as a partner have to deal with the verification of an email address before creating the merchant.
You will find the contact.phonenumber.required
requirement in the compliance object of the merchant.
You can then choose to fill the merchant's phonenumber using the object_redirect_url
or performing a POST on the contact object.
If the telephone number does not belong to the Merchant or the validity of the phone number is questioned, a verification in our system will be triggered.
In that case OPP will send a verification text.
You will find a object_redirect_url
in the contact.phonenumber.verification.required
compliance requirement.
Redirect the user to this url, where (s)he can fill in the phone number to be verified.
A text message will be sent to the phone number, which needs to be filled in to verify the phone number.
The requirement will then disappear.
CoC Disapproval Reasons
Example response:
{
...
"disapprovals": [
{
"name": "coc_business_deregistered",
"created": 1685698690
}
]
}
A coc object can be disapproved for various reasons. To make sure you can help your merchants as good as possible, OPP provides the disapproval reasons in the coc object via the API. If no disapproval reasons can be found, the array will be empty. If the coc has multiple rejections, the reasons will be added at the end of the list.
Variable | Description |
name string | The name of the disapproval reason |
created timestamp | Timestamp when object is created. |
The reasons used can be found below.
Name | Description | Consumer / Business |
coc_additional_required | Additional business registration extracts are required to complete the onboarding. Please upload additional business registration extracts that are in line with your company structure. | Business |
coc_business_deregistered | The document is disapproved because the company is deregistered. The merchant cannot be onboarded under this business registration number. | Business |
coc_document_does_not_match_number | The document has a different business registration number compared to what was provided in the account. Please make sure the document matches the number provided in the account. | Business |
coc_document_expired | The document provided is older than 3 months. Please make sure to upload a document that is at maximum 3 months old. | Business |
coc_incorrect_number | The business registration number provided did not result in any business in our research. Please make sure the business registration number is correct. | Business |
coc_invalid_document | The document provided is invalid. Please provide a correct business registration extract as is provided in our Legal Entity Object. | Business |
coc_legal_representative_not_included | The document does not include the legal representative that was provided. Please make sure the legal representative is visible in the business registration extract. | Business |
other_reason | The merchant provided a business registration extract that was declined for another reason than the above-mentioned. | Business |
Organization Structure Disapproval Reasons
Example response:
{
...
"disapprovals": [
{
"name": "organization_structure_contains_no_natural_persons",
"created": 1685698690
}
]
}
A organization structure object can be disapproved for various reasons. To make sure you can help your merchants as good as possible, OPP provides the disapproval reasons in the organization structure object via the API. If no disapproval reasons can be found, the array will be empty. If the organization structure has multiple rejections, the reasons will be added at the end of the list.
Variable | Description |
name string | The name of the disapproval reason |
created timestamp | Timestamp when object is created. |
The reasons used can be found below.
Name | Description | Consumer / Business |
organization_structure_contains_no_natural_persons | The merchant provided an organization structure document which did not contain any natural persons. Please upload a complete structure with all beneficiaries. | Business |
organization_structure_missing_percentages_control_interest | The merchant provided an organization structure document which did not contain any percentages of control or interest. Please upload a complete structure with all percentages. | Business |
organization_structure_parent_companies_excluded_from_document | The merchant provided an organization structure document which did not include parant companies. Please upload a complete structure with all connected companies. | Business |
organization_structure_ubo_information_not_in_document | The merchant provided an organization structure document which did not contain all UBO information. Please upload a complete structure with all UBO information: names, date of birth, country of residence and percentage of share. | Business |
other_reason | The merchant provided an organization structure that was declined for another reason than the above-mentioned. | Business |
Notification Example - Compliance
Example notification merchant compliance status:
{
"uid": "{{notification_uid}}",
"type": "merchant.compliance_status.changed",
"created": 1619182391,
"object_uid": "{{merchant_uid}}",
"object_type": "merchant",
"object_url": "https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}",
"verification_hash": "{{hash}}"
}
Example notification merchant compliance level:
{
"uid": "{{notification_uid}}",
"type": "merchant.compliance_level.changed",
"created": 1619182391,
"object_uid": "{{merchant_uid}}",
"object_type": "merchant",
"object_url": "https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}",
"verification_hash": "{{hash}}"
}
Example notification merchant compliance requirement created:
{
"uid": "{{notification_uid}}",
"type": "merchant.compliance_requirement.created",
"created": 1684937637,
"object_uid": "{{merchant_uid}}",
"object_type": "merchant",
"object_url": "https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}",
"verification_hash": "{{hash}}"
}
Example notification merchant compliance requirement status:
{
"uid": "{{notification_uid}}",
"type": "merchant.compliance_requirement.status.changed",
"created": 1653488667,
"object_uid": "{{merchant_uid}}",
"object_type": "merchant",
"object_url": "https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}",
"verification_hash": "{{hash}}"
}
Please find a notification example to the right.
Sandbox Simulation - Compliance Requirements
The sandbox simulation for compliance requirements has 2 options. Creating a requirement, and changing its status.
Create coc_extract.required
Example request - Create the coc_extract.required requirement
curl https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/compliance_requirements/require-coc-extract \
-H "Authorization: Bearer {{api_key}}" \
POST https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/compliance_requirements/require-coc-extract
Please find the POST request to create the coc_extract.required requirement for your business merchant to the right.
Create organization_structure.required
Example request - Create the organization_structure.required requirement
curl https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/compliance_requirements/require-organization-structure \
-H "Authorization: Bearer {{api_key}}" \
POST https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/compliance_requirements/require-organization-structure
Please find the POST request to create the organization_structure.required requirement for your business merchant to the right.
Change the requirement status
Example request - Change the requirement status
curl https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/compliance_requirements/change-compliance-status \
-H "Authorization: Bearer {{api_key}}" \
-d "type=coc_extract" \
-d "status=verified"
POST https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/compliance_requirements/change-compliance-status
{
"type": "coc_extract",
"status": "verified"
}
The status of the compliance requirement can be changed using a post to the endpoint at the right.
Update compliance requirement parameters | |
type required | One of: coc_extract organization_structure |
status required | One of: pending verified unverified |
The flows that can be simulated are:
- unverified -> pending -> verified
- unverified -> pending -> unverified
- verified -> unverified -> verified
Merchant Ticket
OPP allows partners to have insight into ticket statuses and inform merchants accordingly. Please note that due to GDPR regulations, it is not possible to have insight into the actual information in the ticket.
Object Definition - Merchant Ticket
The Merchant Ticket object contains the following variables.
Merchant Ticket object | Description |
uid string | Merchant Ticket unique identifier. up to 20 characters |
object string | Value: ticket |
created timestamp | Timestamp when object is created. |
updated timestamp | Timestamp when object is updated. |
category string | One of: paymentfraudgeneralcontact |
status string | One of: openrepliedawaitingclosed |
Merchant Ticket status
The merchant ticket status is a status indication about the ticket in the OPP system.
The possible status flows can be found below:
Status | Explanation |
open | The ticket has been created by either OPP or the merchant. |
replied | OPP replied to the ticket and is now awaiting action from the merchant. |
awaiting | The merchant replied to the ticket and is now awaiting action from OPP. |
closed | The ticket is resolved and thus closed. |
Create Merchant Ticket
It is not possible to create a Merchant Ticket using the API. In case the merchant would like to create a ticket, please redirect to our support page and have them click "Create a Ticket" under the "Buyer" section.
Retrieve Merchant Ticket
Example request - Retrieve a single ticket object from the merchant, using the ticket_uid:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/tickets/{{ticket_uid}} \
-H "Authorization: Bearer {{api_key}}"
GET https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/tickets/{{ticket_uid}}
Example response:
{
"livemode": false,
"uid": "{{ticket_uid}}",
"object": "ticket",
"created": 1663154081,
"updated": 1663154081,
"category": "payment",
"status": "replied"
}
Example request - Retrieve all ticket objects from the merchant:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/tickets \
-H "Authorization: Bearer {{api_key}}"
GET https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/tickets
Example response:
{
"object": "list",
"url": "/v1/merchants/{{merchant_uid}}/ubos",
"has_more": false,
"total_item_count": 3,
"items_per_page": 10,
"current_page": 1,
"last_page": 1,
"data": [
{
"livemode": false,
"uid": "{{ticket_uid}}",
"object": "ticket",
"created": 1663154081,
"updated": 1663154081,
"category": "payment",
"status": "replied"
}
]
}
You can retrieve an individual Ticket of a merchant as well as a list of all tickets of a merchant. The following filters can be used when retrieving merchant tickets:
Filter name | Description |
status | Shows tickets with a certain status |
category | Shows tickets with a certain category |
date_updated | Only in extended filter. Shows tickets with a certain date_updated |
Update Merchant Ticket
It is not possible to update a Merchant Ticket.
Delete Merchant Ticket
It is not possible to delete a Merchant Ticket. In case you would like to have a Merchant Ticket closed, please contact our support department.
Sandbox Simulation - Ticket
Create a ticket
Example request - Create a merchant ticket
curl https://api-sandbox.onlinebetaalplatform.nl//v1/merchants/{{merchant_uid}}/tickets/simulation \
-H "Authorization: Bearer {{api_key}}" \
-d category=general
POST https://api-sandbox.onlinebetaalplatform.nl//v1/merchants/{{merchant_uid}}/tickets/simulation
{
"category": "general"
}
A ticket can be created in the sandbox environment using a post to the endpoint at the right.
Create ticket | |
category required | One of: payment fraud general contact |
Update a ticket
Example request - Update the merchant ticket
curl https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/tickets/{{ticket_uid}}/simulation/update-status \
-H "Authorization: Bearer {{api_key}}" \
-d status=general
POST https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/tickets/{{ticket_uid}}/simulation/update-status
{
"status": "awaiting"
}
A ticket can be updated in the sandbox environment using a post to the endpoint at the right.
Update ticket | |
status required | One of: open replied awaiting closed |
The flows that can be simulated are:
- open -> replied
- replied -> awaiting
- awaiting -> replied
- replied -> closed
- awaiting -> closed
Notification Example - Merchant Ticket
Example notification - merchant.ticket.created:
{
"uid": "{{notification_uid}}",
"type": "merchant.ticket.created",
"created": 1663154082,
"object_uid": "{{ticket_uid}}",
"object_type": "ticket",
"object_url": "https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/tickets/{{ticket_uid}}",
"parent_uid": "{{merchant_uid}}",
"parent_type": "merchant",
"parent_url": "https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}",
"verification_hash": "{{hash}}"
}
Example notification - merchant.ticket.status.changed:
{
"uid": "{{notification_uid}}",
"type": "merchant.ticket.status.changed",
"created": 1663154082,
"object_uid": "{{ticket_uid}}",
"object_type": "ticket",
"object_url": "https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/tickets/{{ticket_uid}}",
"parent_uid": "{{merchant_uid}}",
"parent_type": "merchant",
"parent_url": "https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}",
"verification_hash": "{{hash}}"
}
Please find notification examples to the right.
Legal Entity Object
Example request - Retrieve the legal entity list:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/legal-entities \
-H "Authorization: Bearer {{api_key}}"
GET https://api-sandbox.onlinebetaalplatform.nl/v1/legal-entities
Example response:
{
"object": "list",
"url": "/v1/legal-entities",
"has_more": true,
"total_item_count": 109,
"items_per_page": 10,
"current_page": 1,
"last_page": 11,
"data": [
{
"object": "legal_entity",
"country": "DEU",
"language": "de",
"legal_entity_code": "fb",
"legal_entity_name": "Freiberufler",
"registry_number": "Umsatzsteuer-Identifikationsnummer",
"registry_name": "Standeskammer oder anderes Verzeichnis",
"registry_file": "Nachweis der freiberuflichen Tätigkeit",
"bank_account_type": "both"
},
{
"object": "legal_entity",
"country": "DEU",
"language": "de",
"legal_entity_code": "eU",
"legal_entity_name": "Einzelunternehmen",
"registry_number": "Umsatzsteuer-Identifikationsnummer",
"registry_name": "Gewerberegister",
"registry_file": "Gewerberegisterauszug",
"bank_account_type": "both"
},
{
"object": "legal_entity",
"country": "DEU",
"language": "de",
"legal_entity_code": "eK",
"legal_entity_name": "eingetragener Kaufmann/Kauffrau",
"registry_number": "Handelsregisternummer",
"registry_name": "Handelsregister",
"registry_file": "Handelsregisterauszug",
"bank_account_type": "both"
},
...
]
}
When performing business onboarding, you are able to speed up the process by guiding your merchants as well as possible.
In order to do so, we have provided an extended list of legal entities for every country in our license area.
The list provides you with information on the entity and the necessary documents for the KYC of OPP.
Please provide the legal_entity_code
in the merchant request.
Legal Entity object | Description |
object string | Value: legal_entity |
country string | Country of the legal entity |
language string | Language in which the content is delivered |
legal_entity_code string | Abbreviation of the legal entity, to be provided in legal_entity when creating the merchant |
legal_entity_name string | The full name of the legal entity |
registry_number string | The name of the registry number to be provided in coc_nr when creating the merchant |
registry_name string | The name of the registry from which we need the coc extract |
registry_file string | The specific file that we require from the registry |
bank_account_type string | One of: business (only business bank accounts allowed) both (both business and consumer bank accounts allowed) |
The following filters can be used when retrieving legal entities:
Filter name | Description |
country | Shows legal entities with a specific country |
Settlement Object
Example request - Retrieve a merchant's settlement:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/settlements/{{settlement_uid}} \
-H "Authorization: Bearer {{api_key}}"
GET https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/settlements/{{settlement_uid}}
Example response:
{
"uid": "{{settlement_uid}}",
"object": "settlement",
"created": 1554069900,
"updated": 1554200096,
"status": "paid",
"paid": null,
"period_start": 1554073200,
"period_end": 1554159599,
"total_number_of_transactions": 4,
"number_of_refunds": 0,
"total_volume": 24000,
"transaction_volume": 24000,
"refund_volume": 0,
"total_transaction_costs": 159,
"transaction_costs": 159,
"refund_costs": 0,
"total_order_fees": 0,
"total_refund_fees": 0,
"total_amount": 23841,
"amount_paid": 3500,
"amount_payable": 20341,
"po_number": null,
"specifications": [
{
"uid": "{{settlement_specification_uid}}",
"object": "specification",
...
}
],
"currency": "EUR"
}
Example request - Retrieve all settlements of a merchant:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/settlements \
-H "Authorization: Bearer {{api_key}}"
GET https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/settlements
The settlement of a merchant is his/her current "balance". Together with OPP, you as a partner decided on a settlement period (daily, weekly, bi-weekly, monthly, yearly). Once the settlement period ends, OPP will pay-out the merchant.
You can retrieve an individual settlement as well as a list of all settlements for a merchant. Be it in a list or as a single result, the data or settlement object will contain the following details. A settlement always has a default period.
Settlement object | Description |
uid string | Settlement unique identifier. up to 20 characters |
object string | Value: settlement |
created timestamp | Timestamp when object is created. |
updated timestamp | Timestamp when object is updated. |
status string | One of: currenttransferpaidcancelled |
paid timestamp | Timestamp when settlement is paid. |
period_start timestamp | Timestamp when settlement period is started. |
period_end timestamp | Timestamp when settlement period is finalized. |
total_number_of_transactions integer | Total number of transactions within this settlement including refunds, withdrawals, mandates, internal_transfers and multi_transactions |
number_of_transactions integer | Number of transactions within this settlement. |
number_of_refunds integer | Number of refunds within this settlement. |
number_of_withdrawals integer | Number of withdrawals within this settlement. |
number_of_mandates integer | Number of mandates within this settlement. |
number_of_internal_transfers integer | Number of internal_transfers within this settlement. |
number_of_multi_transactions integer | Number of multi_transactions within this settlement. |
total_volume big integer | Resulting transaction volume after deducting refunds. (total_volume = transaction_volume - refund_volume) |
transaction_volume big integer | Transaction volume. |
refund_volume integer | Refund volume. |
withdrawal_volume integer | Withdrawal volume. |
mandate_volume integer | Mandate volume |
internal_transfer_volume integer | Internal transfer volume. |
multi_transaction_volume integer | Multi transaction volume |
total_transaction_costs integer | Total transaction costs for transactions and refunds within this settlement. (total_transaction_costs = transaction_costs + refund_costs) |
transaction_costs integer | Transaction costs for transactions within this settlement. |
refund_costs integer | Transaction costs for refunds within this settlement. |
withdrawal_costs integer | Transaction costs for withdrawal within this settlement. |
mandate_costs integer | Transaction costs for mandate within this settlement. |
internal_transfer_costs integer | Transaction costs for internal transfers within this settlement. |
multi_transaction_costs integer | Transaction costs for multi_transactions within this settlement. |
total_order_fees integer | Total fees for all orders. |
total_refund_fees integer | Total fees for all refunds. |
total_gateway_fees integer | Total gateway fees. |
total_amount integer | Total amount of the settlement. (total_amount = total_volume - total_transaction_costs - total_order_fees - total_refund_fees) |
amount_paid integer | DEPRECATED! Amount already paid before end of settlement period. |
amount_payable integer | Amount payable. (amount_payable = total_amount - amount_paid) |
payout_type string | Payout type of the settlement. |
po_number varchar | Payout number. |
specifications array | The specifications of the current settlement. |
currency string | ISO 4217 currency code. |
Settlement Specifications
Example request - Retrieve the settlement specification rows:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/settlements/{{settlement_uid}}/specifications/{{specificiation_uid}}/rows \
-H "Authorization: Bearer {{api_key}}"
GET https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/settlements/{{settlement_uid}}/specifications/{{specificiation_uid}}/rows
Each settlement contains a specifications
attribute.
This attribute is an array, containing all sub-settlements of the current settlement.
The specification
object is the same as the settlement object above, except that it also contains a source
attribute.
A specification
is created for every profile the merchant has. In most cases, this will only be one.
Each specification consists of one or more rows based on the number of transactions, mandates, charges, etc. for the merchant in a given settlement period.
You can find all transactions in a settlement specification by doing the call on the right.
Partner Settlement
Example request - Retrieve partner settlements:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/settlements \
-H "Authorization: Bearer {{api_key}}"
GET https://api-sandbox.onlinebetaalplatform.nl/v1/settlements
As a partner, you also have a settlement, with a different payout period than the merchants on your platform.
For you as a partner, a specification
allows you to see how much of your current settlement has been provided by
a specific merchant.
This can be done by checking the source.object
and source.uid
respectively.
The partner settlement can be retrieved via the call on the right. The specifications and transactions can be retrieved the same way as the merchant specifications and transactions, but with the partner base URL.
Balance Object
Example request - Retrieve a merchant's profile balance:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/profiles/{{profile_uid}}/balance \
-H "Authorization: Bearer {{api_key}}"
GET https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/profiles/{{profile_uid}}/balance
Example response:
{
"livemode": false,
"object": "balance",
"currency": "EUR",
"amount": 10000,
"amount_planned": 0,
"amount_reserved": 5000
}
The balance object is only visible to merchants that have a continuous
settlement (e.g. wallet users).
The balance endpoint provides a simple way to create an overview of the changes on the balance, without needing to retrieve the settlement specifications.
Balance object | Description |
object string | Value: balance |
currency string | ISO 4217 currency code. |
amount integer | Current available amount. |
amount_planned integer | Current amount that is planned to be withdrawn. NOTE that this amount is not subtracted from amount ! |
amount_reserved integer | Current amount that is to be added (e.g. escrow payments). NOTE that this amount is not added to amount ! |
Notification Example - Balance
Example notification:
{
"uid": "{{notification_uid}}",
"type": "merchant.profile.balance.changed",
"created": 1660744872,
"object_uid": "{{profile_uid}}",
"object_type": "merchant_profile",
"object_url": "https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/profiles/{{profile_uid}}",
"parent_uid": "{{merchant_uid}}",
"parent_type": "merchant",
"parent_url": "https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}",
"verification_hash": "{{hash}}"
}
Please find a notification example to the right.
Do note that the object_url
does not direct to the balance endpoint immediately, but rather to the profile object.
Files
The Files API allows files to be submitted to the OPP system.
Please note that the Files API has a different URL.
Authentication takes place in the same way you do for the OPP API.
If preferred we can provide you with an additional partner API key to connect to the Files API.
Sandbox:
https://files-sandbox.onlinebetaalplatform.nl/v1
Production:
https://files.onlinebetaalplatform.nl/v1
Allowed Objects
In order to know what objects, file groups and files are supported, you can retrieve the complete object list via API.
Retrieve Allowed Objects
Example request - Retrieve allowed objects:
curl https://files-sandbox.onlinebetaalplatform.nl/v1/objects \
-H "Authorization: Bearer {{api_key}}" \
GET https://files-sandbox.onlinebetaalplatform.nl/v1/objects
Example response:
{
"object": "list",
"url": "https://files-sandbox.onlinebetaalplatform.nl/v1/objects",
"has_more": false,
"total_item_count": 3,
"items_per_page": 10,
"current_page": 1,
"last_page": 1,
"data": [
{
"type": "bank_account",
"file_groups": [
{
"name": "debit_card",
"restricted_to": "",
"number_of_files_required": 1,
"files": [
{
"purpose": "bank_account_debit_card",
"allowed_upload_size": "7M",
"allowed_mime_types": [
"image/jpg",
"image/png",
"application/pdf",
"image/jpeg",
"image/heic",
"image/heif"
]
},
{
"purpose": "bank_account_debit_card_backside",
"allowed_upload_size": "7M",
"allowed_mime_types": [
"image/jpg",
"image/png",
"application/pdf",
"image/jpeg",
"image/heic",
"image/heif"
]
}
]
},
{
"name": "bank_statement",
"restricted_to": "",
"number_of_files_required": 1,
"files": [
{
"purpose": "bank_account_bank_statement",
"allowed_upload_size": "7M",
"allowed_mime_types": [
"image/jpg",
"image/png",
"application/pdf",
"image/jpeg",
"image/heic",
"image/heif"
]
},
{
"purpose": "bank_account_bank_statement_backside",
"allowed_upload_size": "7M",
"allowed_mime_types": [
"image/jpg",
"image/png",
"application/pdf",
"image/jpeg",
"image/heic",
"image/heif"
]
}
]
}
]
},
{
"type": "merchant",
"file_groups": [
{
"name": "business_information",
"restricted_to": "",
"number_of_files_required": 0,
"files": [
{
"purpose": "coc_extract",
"allowed_upload_size": "7M",
"allowed_mime_types": [
"image/jpg",
"image/png",
"application/pdf",
"image/jpeg",
"image/heic",
"image/heif"
]
},
{
"purpose": "organization_structure",
"allowed_upload_size": "7M",
"allowed_mime_types": [
"image/jpg",
"image/png",
"application/pdf",
"image/jpeg",
"image/heic",
"image/heif"
]
}
]
}
]
},
{
"type": "merchant_contact",
"file_groups": [
{
"name": "passport",
"restricted_to": "",
"number_of_files_required": 1,
"files": [
{
"purpose": "representative_passport",
"allowed_upload_size": "7M",
"allowed_mime_types": [
"image/jpg",
"image/png",
"application/pdf",
"image/jpeg",
"image/heic",
"image/heif"
]
}
]
},
{
"name": "id_card",
"restricted_to": "",
"number_of_files_required": 2,
"files": [
{
"purpose": "representative_id_card_front",
"allowed_upload_size": "7M",
"allowed_mime_types": [
"image/jpg",
"image/png",
"application/pdf",
"image/jpeg",
"image/heic",
"image/heif"
]
},
{
"purpose": "representative_id_card_backside",
"allowed_upload_size": "7M",
"allowed_mime_types": [
"image/jpg",
"image/png",
"application/pdf",
"image/jpeg",
"image/heic",
"image/heif"
]
}
]
},
{
"name": "drivers_license",
"restricted_to": "nld",
"number_of_files_required": 2,
"files": [
{
"purpose": "representative_drivers_license_front",
"allowed_upload_size": "7M",
"allowed_mime_types": [
"image/jpg",
"image/png",
"application/pdf",
"image/jpeg",
"image/heic",
"image/heif"
]
},
{
"purpose": "representative_drivers_license_backside",
"allowed_upload_size": "7M",
"allowed_mime_types": [
"image/jpg",
"image/png",
"application/pdf",
"image/jpeg",
"image/heic",
"image/heif"
]
}
]
}
]
}
]
}
Object Definition - Files Objects
The Transaction object contains the following variables.
Variables | Description |
type string | Refers to the object as known in OPP and within the compliance requirement. One of: merchant_contact merchant bank_account |
file_groups array | Refers to the accepted file groups, see File Groups below |
Object Definition - File Groups
Variables | Description |
name string | A label describing the file group. For object type bank_account , one of:debit_card bank_statement. For object type merchant_contact , one of:drivers_license id_card passport For object type merchant , one of:coc_extract organization_structure |
restricted_to string | A comma separated list of countries that are allowed for this group. E.g. a drivers_license may be uploaded only if merchant is from nld . |
number_of_files_required integer | Number of files that are required for the upload. In some exceptional cases, extra files could be optional. |
files array | refers to the accepted (and required) files, see Files below. |
Object Definition - Files
Variables | Description |
purpose string | A valid file purpose, dependant on the file group. |
allowed_upload_size string | A representation of the allowed upload size in Megabytes. |
allowed_mime_types array | A collection of allowed mime types for this file. |
One-Time File Link
Online Payment Platform now supports one-time links for files API uploads. This allows our partners to have their merchants upload their required KYC directly via the front-end of the partner website or application. This allows for a seamless KYC procedure while also ensuring that the partner is not processing any data such as bank statements, passports and the like.
The file upload process is as follows:
Request > The partner requests a file upload via the files API
Response < The files API responds with a file upload link and token
Request > Partner uploads a file via the upload link and token
Response < The files API responds with an "OK" on success or error on failure
Keep in mind that the correct number of files uploaded depends on the selected KYC procedure and available methods of verification. For details of the available objects, file groups and files, please read the documentation above.
Object Definition - File Link
The File link object contains the following variables.
Variables | Description |
uid string | File unique identifier. up to 20 characters |
created timestamp | Timestamp when file link is created. |
updated timestamp | Timestamp when file link is updated. |
expired timestamp | Timestamp when file link will expire. |
merchant_uid string | Merchant to which the file link belongs. |
object_uid string | Merchant object to which the file link belongs. |
purposestring | Purpose of the file upload. |
token string | One time token to authenticate the file link. |
url string | One time file upload link. |
Create File link
Example request - Create file link:
curl https://files-sandbox.onlinebetaalplatform.nl/v1/uploads \
-H "Authorization: Bearer {{api_key}}" \
-d "purpose=bank_account_bank_statement" \
-d merchant_uid={{merchant_uid}} \
-d "object_uid={{bank_account_uid}}"
POST https://files-sandbox.onlinebetaalplatform.nl/v1/uploads
{
"purpose": "bank_account_bank_statement",
"merchant_uid": "{{merchant_uid}}",
"object_uid": "{{bank_account_uid}}"
}
Example response:
{
"uid": "{{file_uid}}",
"created": 1606003200,
"updated": 1606003200,
"expired": 1606004100,
"merchant_uid": "{{merchant_uid}}",
"object_uid": "{{bank_account_uid}}",
"purpose": "bank_account_bank_statement",
"token": "{{token}}",
"url": "https://files-sandbox.onlinebetaalplatform.nl/v1/uploads/{{file_uid}}"
}
You can create a one-time file link using the Files API. Below are all file link object variables that can be used in the POST request when creating a file link.
Variable | Description |
purpose required | A valid file purpose, dependant on the file group. |
merchant_uid required | Merchant_uid for which the upload is to be used. |
object_uid required | Object_uid for which the upload is to be used. |
Upload File
Example request - Create file link:
curl https://files-sandbox.onlinebetaalplatform.nl/v1/uploads/{{file_uid}} \
-H "x-opp-files-token: {{token}}" \
-d file={{uploaded_file}}
POST https://files-sandbox.onlinebetaalplatform.nl/v1/uploads/{{file_uid}}
Headers
{
"x-opp-files-token": "{{token}}"
}
Parameters
{
"file": "{{uploaded_file}}"
}
Example response - OK:
{
"result": "OK"
}
Example response - NOT OK (token):
{
"error": "Unauthorized. Token invalid or invalidated."
}
Example response - NOT OK (validation):
{
"error": "Invalid parameters for request.",
"parameters": {
"file": [
"File type does not match purpose"
]
}
}
Upload a file via https://files-sandbox.onlinebetaalplatform.nl/v1/uploads/{{file_uid}}
Transactions
Transactions need to be created whenever something is bought from a merchant, or a service is delivered. With our advanced payment flow integration it is possible to create several transactions with a wide variety on additional features, like escrow. This chapter will provide you all the necessary information of a transaction object.
We already provided a Postman collection on the Transaction API for you to start with. Also, we provided a step-by-step guide on how to create transactions.
Transaction
Object Definition - Transaction
The Transaction object contains the following variables.
Variables | Description |
uid string | Transaction unique identifier. up to 20 characters |
object string | Value: transaction |
created timestamp | Timestamp when transaction is created. |
updated timestamp | Timestamp when transaction is updated. |
completed timestamp | Timestamp when transaction is completed. |
merchant_uid string | Merchant to which the transaction belongs. |
profile_uid string | Merchant Profile to which the transaction belongs. |
buyer_uid string | Buyer merchant to which the transaction belongs. |
has_checkoutboolean | One of: true false Whether checkout is used for this transaction. |
payment_method string | see Payment methods |
payment_flow string | One of: directemail Shows whether the payment email or payment page is used. |
payment_details array | See Payment details |
amount integer | Transaction amount in cents. |
return_url string | The customer is directed to this url, once the payment is completed. up to 255 characters |
redirect_url string | The customer is directed to this url, for making the payment. up to 255 characters |
notify_url string | Notification url to receive status updates. up to 255 characters |
status string | Current status of the object. one of: createdpendingplannedcompletedreservedcancelledfailedexpiredrefundedchargeback |
metadata array | Set of key / value pairs to store additional data. nullable |
statuses array | Current and previous transaction statuses. |
order array | The order that has been placed. See Transaction order. |
escrow array | The specifications of the escrow period.See Transaction escrow. |
fees object | The specifications of the fees. See Transaction fees |
refunds object | The refund that belongs to this transaction, if any. See Transaction refunds |
Transaction Status
The transaction status is a status indication about the transaction in the OPP system. According to this status, you should handle the flow on your platform accordingly.
The possible status flows can be found below:
Status | Explanation |
created | Transaction is created, no action has taken place yet. |
pending | User has opened the redirect_url, OPP is awaiting final state from the issuer. |
planned | Money is reserved on the issuer's side, but not claimed by OPP yet. |
completed | Transaction is successfully completed and settled in order to payout. |
reserved | Transaction is successfully completed and put in escrow. |
cancelled | Transaction was manually cancelled by the user. A new transaction needs to be created. |
expired | The expiration time of the transaction has passed. A new transaction needs to be created. |
failed | The transaction has failed due to an error at the issuer or OPP. A new transaction needs to be created. If you keep receiving status failed, please contact your implementation manager. |
refunded | The transaction has been initiated for (partial) refund. Once the refund has been initiated, OPP will refund the given amount within 24 hours. Depending on your bank or card supplier, this will be visible at a later period on your account. |
chargeback | The transaction has been initiated for full refund, while it was in escrow. Once the refund has been initiated, OPP will refund the total amount within 24 hours. Depending on your bank or card supplier, this will be visible at a later period on your account. |
Notification Example - Transaction
Example notification:
{
"uid": "{{notification_uid}}",
"type": "transaction.status.changed",
"created": 1653401173,
"object_uid": "{{transaction_uid}}",
"object_type": "transaction",
"object_url": "https://api-sandbox.onlinebetaalplatform.nl/v1/transactions/{{transaction_uid}}",
"verification_hash": "{{hash}}"
}
Please find a notification example to the right.
Create Transaction
Example request - Create transaction:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/transactions \
-H "Authorization: Bearer {{api_key}}" \
-d merchant_uid={{merchant_uid}} \
-d "products[0][name]=WakeUp Light" \
-d products[0][price]=250 \
-d products[0][quantity]=1 \
-d total_price=250 \
-d checkout=false \
-d return_url=https://platform.example.com/return/ \
-d notify_url=https://platform.example.com/notify/ \
-d metadata[external_id]=2015486
POST https://api-sandbox.onlinebetaalplatform.nl/v1/transactions
{
"merchant_uid": "{{merchant_uid}}",
"products": [
{
"name": "WakeUp Light",
"price": 250,
"quantity": 1
}
],
"return_url": "https://platform.example.com/return/",
"notify_url": "https://platform.example.com/notify/",
"total_price": 250,
"checkout": false,
"metadata":
{
"external_id": "2015486"
}
}
Example response:
{
"uid": "{{transaction_uid}}",
"object": "transaction",
"created": 1613741183,
"updated": 1613741183,
"completed": null,
"merchant_uid": "{{merchant_uid}}",
"profile_uid": "{{profile_uid}}",
"buyer_uid": "{{buyer_uid}}",
"has_checkout": false,
"payment_method": null,
"payment_flow": "direct",
"payment_details": [],
"amount": 250,
"return_url": "https://platform.example.com/return/",
"redirect_url": "https://sandbox.onlinebetaalplatform.nl/nl/6bfa1c3e1d1d/betalen/verzendgegevens/{{transaction_uid}}?vc=db2242295ee6565a7b2c8b69632ff530",
"notify_url": "https://platform.example.com/notify/",
"status": "created",
"metadata": [
{
"key": "external_id",
"value": "2015486"
}
],
"statuses": [
{
"uid": "sta_8b03f99bbd54",
"object": "status",
"created": 1613741183,
"updated": 1613741183,
"status": "created"
}
],
"order": [],
"escrow": null,
"fees": {},
"refunds": {}
}
You can create a transaction using the Transaction API. Below are all transaction object variables that can be used in the POST request when creating a transaction.
OPP provides the option to put money in escrow. By doing so, you can provide a secure feeling to buyer and seller. OPP will put the money in the settlement of the merchant, only when the escrow period ends, or is manually ended by you as a partner.
The escrow period can be set by setting escrow = true
and either escrow_period = [days]
or escrow_date = [date]
.
OPP charges fees for every transaction that has been done. As a partner, you will be able to provide partner fees towards merchants, to charge these fees towards the merchants, and if wanted, add some fee for you as a partner as well.
You can add partner fees by providing the partner_fee
attribute in the transaction.
Variable | Description | ||||||||||||
merchant_uid required | Unique identifier of a merchant. | ||||||||||||
profile_uid optional | Unique identifier of a merchants profile. default is: first merchant profile UID |
||||||||||||
locale optional |
Locale used for transaction, one of: nl en fr de |
||||||||||||
checkout optional | Whether or not to use the whitelabel checkout flow designed by OPP. This page lets the buyer fill in their
personal data. Default is: true one of: true false In case checkout is true, an email will be sent to the buyer with an order overview. |
||||||||||||
payment_method optional |
Default is: null, one of: ideal bcmc pi-single sepa paypal-ppcp creditcard apple-pay mybank |
||||||||||||
payment_flow optional |
Default is: direct one of: direct(a direct payment with or without a checkout option) - DEPRECATED - email(an e-mail will be send to the e-mailaddress of the customer with a link to process the payment) |
||||||||||||
issuer optional | Available when payment_method is ideal An issuer can be provided to be redirected to the bank immediately. See iDEAL issuers. |
||||||||||||
country optional | Country to be pre-selected when payment_method is pi-single Mandatory when an issuer is given combined with pi-single. |
||||||||||||
escrow optional |
Default is: false one of: false true If true, one of escrow_period or escrow_date is required
|
||||||||||||
escrow_period optional | Escrow period in days. Minimum: 1 |
||||||||||||
escrow_date optional | Escrow end datetime format: YYYY-MM-DD HH:MM:SS Minimum: 15 minutes |
||||||||||||
skip_confirmation_page optional |
Whether or not to skip the confirmation page.
Available when checkout = true Default is: false one of: true false |
||||||||||||
buyer_name_first optional | If payment_flow = email the buyer's first name, up to 45 characters |
||||||||||||
buyer_name_last optional | If payment_flow = email the buyer's last name, up to 45 characters |
||||||||||||
buyer_emailaddress optional | Required when payment_flow = email | ||||||||||||
date_expired optional | Available when payment_method = sepa SEPA Expiration date. OPP always adds 5 days to this variable because of bank transfer delays. |
||||||||||||
total_price required | Total price in cents for all products quantities * prices, maximum: 99999999 |
||||||||||||
shipping_costs optional | Shipping costs in cents, maximum: 99999999, default is account setting |
||||||||||||
discount optional | Default is: 0, discount in cents, maximum: 99999999 |
||||||||||||
partner_fee optional | Partner fee in cents. | ||||||||||||
payout_description optional | Description the merchant sees on his bank account. Available when partner contract has individual payouts. up to 125 characters |
||||||||||||
virtual_iban_uid optional | The viban UID that should be displayed for this transaction. Only available for SEPA payments. | ||||||||||||
verification_merchant_uid optional | The merchant_uid for which you want this payment to be the bank_account verification payment. | ||||||||||||
address optional | Address of the buyer. array with name/value pairs |
||||||||||||
|
|||||||||||||
products required | Products to be added to the payment page, array of one or more products objects |
||||||||||||
|
|||||||||||||
return_url required | The return url the customer is redirected to once the payment is completed. up to 255 characters |
||||||||||||
notify_url required | Notification url to receive status updates up to 255 characters |
||||||||||||
metadata object with key-value pairs | Additional data that belongs to the transaction object. |
Retrieve Transaction
Example request - Retrieve a single transaction object:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/transactions/{{transaction_uid}} \
-H "Authorization: Bearer {{api_key}}"
GET https://api-sandbox.onlinebetaalplatform.nl/v1/transactions/{{transaction_uid}}
Example response:
{
"uid": "{{transaction_uid}}",
"object": "transaction",
"created": 1613741183,
"updated": 1613741183,
"completed": null,
"merchant_uid": "{{merchant_uid}}",
"profile_uid": "{{profile_uid}}",
"buyer_uid": "{{buyer_uid}}",
"has_checkout": false,
"payment_method": null,
"payment_flow": "direct",
"payment_details": [],
"amount": 250,
"return_url": "https://platform.example.com/return/",
"redirect_url": "https://sandbox.onlinebetaalplatform.nl/nl/6bfa1c3e1d1d/betalen/verzendgegevens/{{transaction_uid}}?vc=db2242295ee6565a7b2c8b69632ff530",
"notify_url": "https://platform.example.com/notify/",
"status": "created",
"metadata": [
{
"key": "external_id",
"value": "2015486"
}
],
"statuses": [
{
"uid": "sta_8b03f99bbd54",
"object": "status",
"created": 1613741183,
"updated": 1613741183,
"status": "created"
}
],
"order": [],
"escrow": null,
"fees": {},
"refunds": {}
}
Example request - Retrieve all transactions:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/transactions \
-H "Authorization: Bearer {{api_key}}"
GET https://api-sandbox.onlinebetaalplatform.nl/v1/transactions
Example response:
{
"object": "list",
"url": "/v1/transactions",
"has_more": true,
"total_item_count": 439,
"items_per_page": 10,
"current_page": 1,
"last_page": 44,
"data": [
{
"uid": "{{transaction_uid}}",
"object": "transaction",
"created": 1613741183,
"updated": 1613741183,
"completed": null,
"merchant_uid": "{{merchant_uid}}",
"profile_uid": "{{profile_uid}}",
"buyer_uid": "{{buyer_uid}}",
"has_checkout": false,
"payment_method": null,
"payment_flow": "direct",
"payment_details": [],
"amount": 250,
"return_url": "https://platform.example.com/return/",
"redirect_url": "https://sandbox.onlinebetaalplatform.nl/nl/6bfa1c3e1d1d/betalen/verzendgegevens/{{transaction_uid}}?vc=db2242295ee6565a7b2c8b69632ff530",
"notify_url": "https://platform.example.com/notify/",
"status": "created",
"metadata": [
{
"key": "external_id",
"value": "2015486"
}
],
"statuses": [
{
"uid": "sta_8b03f99bbd54",
"object": "status",
"created": 1613741183,
"updated": 1613741183,
"status": "created"
}
],
"order": [],
"escrow": null,
"fees": {},
"refunds": {}
},
...
]
}
You can retrieve an individual transaction as well as a list of all transactions. The following filters can be used when retrieving transactions:
Filter name | Description |
status | Shows transactions with a specific status. |
refund | Shows the transaction belonging to a refund_uid. |
payment_method | Shows the transactions with a specific payment_method. |
merchant | Shows the transactions belonging to a specific merchant. |
date_completed | Only in extended filter. Shows the transactions within a specific completed date. |
Transaction Order
Example response - expanding order, order.customer and order.products:
{
"livemode": false,
"uid": "tra_6af0fb03d44c",
"object": "transaction",
...
"order": {
"uid": "{{order_uid}}",
"object": "order",
"created": 1615552253,
"updated": 1615552253,
"processed": false,
"price": 2500,
"shipping": 0,
"discount": 0,
"street": "",
"housenumber": "",
"housenumber_addition": null,
"zipcode": "",
"city": "",
"state": null,
"country": "Netherlands",
"customer": {
"uid": "{{{customer_uid}}}",
"object": "customer",
"created": 1615552253,
"updated": 1615552253,
"name_first": null,
"name_prefix": null,
"name_last": null,
"birthdate": null,
"emailaddress": null,
"phonenumber": null,
"company": null
},
"products": [
{
"uid": "{{product_uid}}",
"object": "product",
"created": 1615552253,
"updated": 1615552253,
"name": "WakeUp Light mini",
"ean": null,
"code": null,
"quantity": 2,
"price": 1250
}
]
},
...
}
When expanding certain objects, they will appear when requested. Objects that do not have any CRUD functionality, but are either set by OPP or only set when creating the transaction can be found here.
Order Variable | Description |
uid string | Order unique identifier. up to 20 characters |
object string | value: order |
created timestamp | Timestamp in CE(S)T when object is created. |
updated timestamp | Timestamp in CE(S)T when object is updated. |
processed boolean | Whether the order is checked as processed in the partner dashboard. |
price integer | Total order price. |
shipping integer | Order shipping costs. |
discount integer | Order discount. |
street string | Order shipping street. |
housenumber string | Order shipping housenumber. |
housenumber_addition string, nullable | Order shipping housenumber addition. |
zipcode string | Order shipping zipcode. |
city string | Order shipping city. |
state string, nullable | Order shipping state. |
country string | Order shipping country. |
customer array | Order customer, see below. |
products array | Order products, see below. |
Customer Variable | Description |
uid string | Customer unique identifier. up to 20 characters |
object string | value: customer |
created timestamp | Timestamp in CE(S)T when object is created. |
updated timestamp | Timestamp in CE(S)T when object is updated. |
name_first string, nullable | Customer first name. |
name_prefix string, nullable | Customer name prefix. |
name_last string, nullable | Customer last name. |
birthdate string, nullable | Customer birthday. |
emailaddress string, nullable | Customer emailaddress. |
phonenumber string, nullable | Customer phonenumber. |
company string, nullable | Customer company. |
Products Variable | Description |
uid string | Product unique identifier. up to 20 characters |
object string | value: product |
created timestamp | Timestamp in CE(S)T when object is created. |
updated timestamp | Timestamp in CE(S)T when object is updated. |
name string | Product name. |
ean string, nullable | Product EAN. |
code string, nullable | Product code. |
quantity integer | Product quanity. |
price integer | Product price in cents. |
Transaction Escrow
Example response - Expanding escrow:
{
"livemode": false,
"uid": "{{merchant_uid}}",
"object": "merchant",
...
"escrow": {
"uid": "{{escrow_uid}}",
"object": "escrow",
"period": 21,
"start": 1615125366,
"end": 1616943600
}
...
}
Variable | Description |
uid string | Escrow unique identifier. up to 20 characters |
object string | value: escrow |
period integer | Escrow period in days. |
start string | Timestamp in CE(S)T when escrow starts. |
end string | Timestamp in CE(S)T when escrow ends. |
Transaction Fees
Example response - Expanding fees:
{
"livemode": false,
"uid": "tra_6af0fb03d44c",
"object": "transaction",
...
"fees": {
"merchant_gateway_fee": 0,
"merchant_transaction_fee": 0,
"merchant_order_fee": 45,
"merchant_payable_amount": 2455,
"gateway_fee": 25,
"transaction_fee": 15,
"order_fee": 0,
"payable_amount": 5
},
...
}
Variable | Description |
merchant_gateway_fee integer | Gateway fee that the merchant pays in cents. |
merchant_transaction_fee integer | Transaction fee that the merchant pays in cents. |
merchant_order_fee integer | The partner_fee that you provide in the transaction request. |
merchant_payable_amount integer | Payable amount to the merchant in cents. |
gateway_fee integer | Gateway fee that the partner pays in cents. |
transaction_fee integer | Transaction fee that the partner pays in cents. Defined in the partner contract |
order_fee integer | Order fee that the partner pays in cents. |
payable_amount integer | Payable amount to the partner in cents. (= merchant_order_fee - transaction_fee) |
Transaction Refunds
Example response - Expanding refunds:
{
"livemode": false,
"uid": "{{merchant_uid}}",
"object": "merchant",
...
"refunds": [
{
"uid": "{{refund_uid}}",
"object": "refund",
"created": 1615244407,
"updated": 1615274174,
"paid": 1615274174,
"amount": 1200,
"status": "completed",
"message": null,
"internal_reason": null,
"fees": {},
"payout_description": null
}
]
}
Variable | Description |
uid string | Refund unique identifier. up to 20 characters |
object string | value: refund |
created timestamp | Timestamp in CE(S)T when object is created. |
updated timestamp | Timestamp in CE(S)T when object is updated. |
paid timestamp | Timestamp in CE(S)T when refund is paid. |
amount integer | Amount of the refund. |
status string | Current status of the refund. one of: createdpendingplannedcompleted |
message string, nullable | Message sent to customer in email, if buyer emailaddress is known. |
internal_reason string | Internal reason for refund. |
fees object | Fees of the refund, same as fees |
payout_description string | Description to be added to the bank account description. Appended to (Partial) Refund for {{transaction_uid}} |
Update Transaction
Example request - Update transaction:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/transactions/{{transaction_uid}} \
-H "Authorization: Bearer {{api_key}}"
-d escrow_date=2021-04-30 09:00:00
POST https://api-sandbox.onlinebetaalplatform.nl/v1/transactions/{{transaction_uid}}
{
"escrow_date": "2021-04-30 09:00:00"
}
Example response:
{
"uid": "{{transaction_uid}}",
"object": "transaction",
"created": 1613741183,
"updated": 1613741183,
"completed": null,
"merchant_uid": "{{merchant_uid}}",
"profile_uid": "{{profile_uid}}",
"buyer_uid": "{{buyer_uid}}",
"has_checkout": false,
"payment_method": null,
"payment_flow": "direct",
"payment_details": [],
"amount": 250,
"return_url": "https://platform.example.com/return/",
"redirect_url": "https://sandbox.onlinebetaalplatform.nl/nl/6bfa1c3e1d1d/betalen/verzendgegevens/{{transaction_uid}}?vc=db2242295ee6565a7b2c8b69632ff530",
"notify_url": "https://platform.example.com/notify/",
"status": "reserved",
"metadata": [
{
"key": "external_id",
"value": "2015486"
}
],
"statuses": [
{
"uid": "sta_8basda43bd54",
"object": "status",
"created": 1613741183,
"updated": 1613741183,
"status": "created"
},
{
"uid": "sta_f9926sehg5y",
"object": "status",
"created": 1613741183,
"updated": 1613741183,
"status": "pending"
},
{
"uid": "sta_8b03f99bbd54",
"object": "status",
"created": 1613741183,
"updated": 1613741183,
"status": "reserved"
}
],
"order": [],
"escrow": null,
"fees": {},
"refunds": {}
}
You are able to update a transaction by performing a POST on the transaction. You can update one variable at a time, or multiple as you desire.
The following fields can be updated:
Variable | Description |
notify_url string | Notification url to receive status updates up to 255 characters Only possible when transaction has one of the following statuses: created pending planned reserved completed refunded |
partner_fee integer | Partner fee in cents |
escrow_date string | Escrow end datetime format: YYYY-MM-DD HH:MM:SS |
date_expired string | Date expired for SEPA transactions. Only possible when transaction has one of the following statuses: created pending format: YYYY-MM-DD HH:MM:SS |
Delete Transaction
Example request - Delete SEPA transaction:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/transactions/{{transaction_uid}} \
-H "Authorization: Bearer {{api_key}}" \
-X DELETE
DELETE https://api-sandbox.onlinebetaalplatform.nl/v1/transactions/{{transaction_uid}}
Example response:
{
"livemode": false,
"uid": "{{transaction_uid}}",
"object": "transaction",
"created": 1615543352,
"updated": 1615543388,
"completed": null,
"merchant_uid": "{{merchant_uid}}",
"profile_uid": "{{profile_uid}}",
"buyer_uid": "{{buyer_uid}}",
"has_checkout": false,
"payment_method": "sepa",
"payment_flow": "direct",
"payment_details": {
"provider_bank_account_name": "Online Payments Foundation",
"provider_bank_account_iban": "NL96INGB0674534352",
"provider_bank_account_bic": "INGBNL2A",
"reference": "J6X7PT",
"expired": 1619906399
},
"amount": 3500,
"return_url": "https://platform.example.com/return/",
"redirect_url": "https://sandbox.onlinebetaalplatform.nl/nl/6bfa1c3e1d1d/transactie/start/{{transaction_uid}}",
"notify_url": "https://platform.example.com/notify/",
"status": "cancelled",
"metadata": [
{
"key": "external_id",
"value": "2015496"
}
],
"statuses": [
{
"uid": "sta_91226e8a2320",
"object": "status",
"created": 1615543352,
"updated": 1615543352,
"status": "created"
},
{
"uid": "sta_673b7d3ce622",
"object": "status",
"created": 1615543388,
"updated": 1615543388,
"status": "cancelled"
}
],
"order": [],
"escrow": null,
"fees": {},
"refunds": {}
}
Only when a transaction has payment_method = sepa
, you are able to delete the transaction.
When a SEPA transaction is not needed anymore, you are able to delete it. This is only possible when the transaction has created
or pending
state.
Please note that if you delete the transaction while the buyer has already transferred the funds, the funds will automatically bounce back to the buyer.
After the transaction is successfully deleted, it will return with status cancelled
.
Sandbox Simulation - Transaction
OPP Simulation statuses
Use the following amounts to trigger transaction statuses on sandbox mode using any payment method.
You will not need to follow up the payment using the redirect_url.
A direct status will be given on the transaction.
Please note that you will always need to provide a payment_method
for simulations to work.
In order for escrow simulations to work, you will need to provide escrow_period
or escrow_date
in the transaction.
Amount | Status |
101 | created |
201 | pending |
301 | expired |
401 | cancelled |
501 | completed |
601 | chargeback |
701 | failed |
801 | refunded |
901 | reserved |
1201 | planned |
any other amount | created |
Bancontact / Creditcard statuses
These simulations work for Bancontact as well as Creditcard, as the simulation page of Worldline is the same. Please note that you will only be able to use credit card as a payment method when the process for receiving credit card credentials from Worldline has started. Once at the page of Worldline, use any expiry date after the current month/year and any 3-digit security code. Use the following card numbers to simulate statuses:
Card number | Status |
5017670000000000 | completed |
5017670000001404 | failed |
Multi Transaction
Multi transactions allow you to handle multiple transactions, for different merchants or different cases, in one API call. For example when you would like to combine transactions and let the user pay them at once.
Object Definition - Multi Transaction
The Multi Transaction object contains the following variables.
Variables | Description |
uid string | Transaction unique identifier. up to 20 characters |
object string | Value: multi_transaction |
created timestamp | Timestamp when transaction is created. |
updated timestamp | Timestamp when transaction is updated. |
completed timestamp | Timestamp when transaction is completed. |
merchant_uid string | The partner merchant, owner of the multi transaction container. |
payment_method string | see Payment methods |
payment_flow string | One of: directemail Shows whether the payment email or payment page is used. |
payment_details array | See Payment details |
amount integer | Transaction amount in cents. |
currency string | ISO 4217 currency code. |
return_url string | The customer is directed to this url, once the payment is completed. up to 255 characters |
redirect_url string | The customer is directed to this url, for making the payment. up to 255 characters |
notify_url string | Notification url to receive status updates. This notify_url will be copied into the underlying transactions. up to 255 characters |
status string | Single-field representation of the last updated status value one of: createdpendingcompletedcancelledfailedexpired |
metadata array | Set of key / value pairs to store additional data. nullable |
statuses array | Current and previous transaction statuses. |
fees object | The specifications of the fees. See Multi transaction fees. |
transactions array | The list of transactions that are within the multi transaction. See Transactions object. |
Multi Transaction Status
The multi transaction status is a status indication about the multi transaction in the OPP system. According to this status, you should handle the flow on your platform accordingly.
When a multi-transaction goes into an unsuccessful state such as cancelled, failed or expired, this will always affect all sub transactions 1:1.
For example when a multi transaction is cancelled, all sub transactions will be cancelled.
Therefore for sub transactions we do not send status notifications for unsuccessful states separately.
When a multi-transaction goes into a successful state (completed), this may affect each sub transaction in a different way.
For example one sub transaction may go to a completed state and one sub transaction may go to a reserved state due to escrow.
Therefore we do send status notifications for a successful multi transaction payment separately.
The possible status flows can be found below:
Status | Explanation |
created | Transaction is created, no action has taken place yet. |
pending | User has opened the redirect_url, OPP is awaiting final state from the issuer. |
completed | Transaction is successfully completed and settled in order to payout. |
cancelled | Transaction was manually cancelled by the user. A new transaction needs to be created. |
expired | The expiration time of the transaction has passed. A new transaction needs to be created. |
failed | The transaction has failed due to an error at the issuer or OPP. A new transaction needs to be created. If you keep receiving status failed, please contact your implementation manager. |
Notification Example - Multi Transaction
Example notification:
{
"uid": "{{notification_uid}}",
"type": "multi_transaction.status.changed",
"created": 1653401132,
"object_uid": "{{multi_transaction_uid}}",
"object_type": "multi_transaction",
"object_url": "https://api-sandbox.onlinebetaalplatform.nl/v1/multi_transactions/{{multi_transaction_uid}}",
"verification_hash": "{{hash}}"
}
Please find a notification example to the right.
Create Multi Transaction
Example request - Create multi transaction:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/multi_transactions \
-H "Authorization: Bearer {{api_key}}"
-d total_price=5000 \
-d currency=EUR \
-d payment_method=ideal \
-d checkout=false \
-d return_url=https://platform.example.com/return/ \
-d notify_url=https://platform.example.com/notify/ \
-d transactions[0][merchant_uid]={{merchant_uid}} \
-d transactions[0][total_price]=2500 \
-d transactions[0][partner_fee]=100 \
-d transactions[0][products][0][name]=Product A \
-d transactions[0][products][0][quantity]=1 \
-d transactions[0][products][0][price]=2500 \
-d transactions[1][merchant_uid]={{merchant_uid}} \
-d transactions[1][total_price]=2500 \
-d transactions[1][partner_fee]=100 \
-d transactions[1][products][0][name]=Product A \
-d transactions[1][products][0][quantity]=1 \
-d transactions[1][products][0][price]=2500
POST https://api-sandbox.onlinebetaalplatform.nl/v1/multi_transactions
{
"checkout" : false,
"payment_method": "ideal",
"total_price": 5000,
"currency": "EUR",
"transactions": [
{
"merchant_uid": "{{merchant_uid}}",
"total_price": 2500,
"partner_fee": 100,
"products": [
{
"name": "Product A",
"quantity": 1,
"price": 2500
}
]
},
{
"merchant_uid": "{{merchant_uid}}",
"total_price": 2500,
"partner_fee": 100,
"products": [
{
"name": "Product B",
"quantity": 1,
"price": 2500
}
]
}
],
"return_url": "https://platform.example.com/return/",
"notify_url": "https://platform.example.com/notify/"
}
Example response:
{
"uid": "{{multi_transaction_uid}}",
"object": "multi_transaction",
"created": 1616593428,
"updated": 1616593428,
"completed": null,
"merchant_uid": "{{partner_merchant_uid}}",
"payment_method": "ideal",
"payment_details": null,
"description": "",
"amount": 5000,
"currency": "EUR",
"return_url": "https://platform.example.com/return/",
"redirect_url": "https://onlinebetaalplatform.nl/nl/{{partner_slug}}/transactie/start/{{multi_transaction_container_uid}}",
"notify_url": "https://platform.example.com/notify/",
"status": "created",
"metadata": [],
"statuses": [
{
"uid": "mts_b3e27e523130",
"object": "status",
"created": 1616593428,
"updated": 1616593428,
"status": "created"
}
],
"fees": {},
"transactions": [
{
"uid": "{{transaction_uid}}",
"object": "transaction",
"created": 1616593428,
"updated": 1616593428,
"completed": null,
"merchant_uid": "{{merchant_uid}}",
"profile_uid": "{{profile_uid}}",
"buyer_uid": "{{buyer_uid}}",
"has_checkout": false,
"payment_method": "multi",
"payment_flow": "direct",
"payment_details": [],
"amount": 2500,
"currency": "EUR",
"return_url": "https://platform.example.com/return/",
"redirect_url": null,
"notify_url": "https://platform.example.com/notify/",
"status": "created",
"metadata": [],
"statuses": [
{
"uid": "sta_cc6c1d9b127b",
"object": "status",
"created": 1616593428,
"updated": 1616593428,
"status": "created"
}
],
"order": [],
"escrow": null,
"fees": {},
"refunds": {}
},
{
"uid": "{{transaction_uid}}",
"object": "transaction",
"created": 1616593428,
"updated": 1616593428,
"completed": null,
"merchant_uid": "{{merchant_uid}}",
"profile_uid": "{{profile_uid}}",
"buyer_uid": "{{buyer_uid}}",
"has_checkout": false,
"payment_method": "multi",
"payment_flow": "direct",
"payment_details": [],
"amount": 2500,
"currency": "EUR",
"return_url": "https://platform.example.com/return/",
"redirect_url": null,
"notify_url": "https://platform.example.com/notify/",
"status": "created",
"metadata": [],
"statuses": [
{
"uid": "sta_d382b590a7a7",
"object": "status",
"created": 1616593428,
"updated": 1616593428,
"status": "created"
}
],
"order": [],
"escrow": null,
"fees": {},
"refunds": {}
}
]
}
You can create a multi transaction using the Multi Transaction API. Below are all multi transaction object variables that can be used in the POST request when creating a multi transaction.
OPP provides the option to put money in escrow. By doing so, you can provide a secure feeling to buyer and seller. OPP will put the money in the settlement of the merchant, only when the escrow period ends, or is manually ended by you as a partner.
The escrow period can be set per individual transaction by setting escrow = true
and either escrow_period = [days]
or escrow_date = [date]
.
OPP charges fees for every transaction that has been done. As a partner, you will be able to provide partner fees towards merchants, to charge these fees towards the merchants, and if wanted, add some fee for you as a partner as well.
You can add partner fees per individual transaction by providing the partner_fee
attribute in the transaction.
Multi Transaction Variable | Description |
merchant_uid optional | Merchant UID whose credentials will be used for gateways like Creditcard or PayPal. If none are provided, partner settings will be used |
profile_uid optional | Profile UID whose credentials will be used for gateways like Creditcard or PayPal. If none are provided, merchant settings will be used |
locale optional |
Locale used for transaction, one of: nl en fr de |
checkout optional | Whether or not to use the whitelabel checkout flow designed by OPP. This page lets the buyer fill in their
personal data. Default is: false one of: true false In case checkout is true, an email will be send to the buyer with an order overview. |
payment_method required | one of: ideal bcmc sepa pi-single paypal-ppcp creditcard apple-pay mybank |
issuer optional | Available when payment_method is ideal An issuer can be provided to be redirected to the bank immediately. See iDEAL issuers. |
date_expired optional | Available when payment_method = sepa SEPA Expiration date. OPP always adds 5 days to this variable because of bank transfer delays. |
description optional | Description visible on the OPP payment screen up to 255 characters |
total_price required | Total price in cents for all products quantities * prices, maximum: 99999999 |
currency string | ISO 4217 currency code. |
shipping_costs optional | Shipping costs in cents, maximum: 99999999, default is account setting |
virtual_iban_uid optional | The viban UID that should be displayed for this transaction. Only available for SEPA payments. |
verification_merchant_uid optional | The merchant_uid for which you want this payment to be the bank_account verification payment. |
return_url required | The return url the customer is redirected to once the payment is completed. up to 255 characters |
notify_url required | Notification url to receive status updates up to 255 characters |
metadata object with key-value pairs | Additional data that belongs to the transaction object. |
transactions required | Array of transaction objects that need to be combined in this multi transaction. |
There are some small differences between the variables that are allowed in the Single Transaction object, and the transactions that can be posted in the Multi Transaction transactions array. Below you can find all variables of a transaction that can be given in the transactions array of the Multi Transaction object create.
Transaction Variable | Description | ||||||||||||
merchant_uid required | Unique identifier of a merchant. | ||||||||||||
profile_uid optional | Unique identifier of a merchants profile. default is: first merchant profile UID |
||||||||||||
escrow optional |
Default is: false one of: false true If true, one of escrow_period or escrow_date is required
|
||||||||||||
escrow_period optional | Escrow period in days. Minimum: 1 |
||||||||||||
escrow_date optional | Escrow end datetime format: YYYY-MM-DD HH:MM:SS Minimum: 15 minutes |
||||||||||||
buyer_name_first optional | If payment_flow = email the buyer's first name, up to 45 characters |
||||||||||||
buyer_name_last optional | If payment_flow = email the buyer's last name, up to 45 characters |
||||||||||||
buyer_emailaddress optional | Required when payment_flow = email | ||||||||||||
total_price required | Total price in cents for all products quantities * prices, maximum: 99999999 |
||||||||||||
shipping_costs optional | Shipping costs in cents, maximum: 99999999, default is account setting |
||||||||||||
discount optional | Default is: 0, discount in cents, maximum: 99999999 |
||||||||||||
partner_fee optional | Partner fee in cents. | ||||||||||||
payout_description optional | Description the merchant sees on his bank account. Available when partner contract has individual payouts. up to 125 characters |
||||||||||||
address optional | Address of the buyer. array with name/value pairs |
||||||||||||
|
|||||||||||||
products required | Products to be added to the payment page, array of one or more products objects |
||||||||||||
|
|||||||||||||
metadata object with key-value pairs | Additional data that belongs to the transaction object. |
Retrieve Multi Transaction
Example request - Retrieve a multi transaction object:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/multi_transactions/{{multi_transaction_uid}} \
-H "Authorization: Bearer {{api_key}}" \
GET https://api-sandbox.onlinebetaalplatform.nl/v1/multi_transactions/{{multi_transaction_uid}}
Example response:
{
"uid": "{{multi_transaction_uid}}",
"object": "multi_transaction",
"created": 1616593428,
"updated": 1616593428,
"completed": null,
"merchant_uid": "{{partner_merchant_uid}}",
"payment_method": "ideal",
"payment_details": null,
"description": "",
"amount": 5000,
"currency": "EUR",
"return_url": "https://platform.example.com/return/",
"redirect_url": "https://onlinebetaalplatform.nl/nl/{{partner_slug}}/transactie/start/{{multi_transaction_container_uid}}",
"notify_url": "https://platform.example.com/notify/",
"status": "created",
"metadata": [],
"statuses": [
{
"uid": "mts_b3e27e523130",
"object": "status",
"created": 1616593428,
"updated": 1616593428,
"status": "created"
}
],
"fees": {},
"transactions": [
{
"uid": "{{transaction_uid}}",
"object": "transaction",
"created": 1616593428,
"updated": 1616593428,
"completed": null,
"merchant_uid": "{{merchant_uid}}",
"profile_uid": "{{profile_uid}}",
"buyer_uid": "{{buyer_uid}}",
"has_checkout": false,
"payment_method": "multi",
"payment_flow": "direct",
"payment_details": [],
"amount": 2500,
"currency": "EUR",
"return_url": "https://platform.example.com/return/",
"redirect_url": null,
"notify_url": "https://platform.example.com/notify/",
"status": "created",
"metadata": [],
"statuses": [
{
"uid": "sta_cc6c1d9b127b",
"object": "status",
"created": 1616593428,
"updated": 1616593428,
"status": "created"
}
],
"order": [],
"escrow": null,
"fees": {},
"refunds": {}
},
{
"uid": "{{transaction_uid}}",
"object": "transaction",
"created": 1616593428,
"updated": 1616593428,
"completed": null,
"merchant_uid": "{{merchant_uid}}",
"profile_uid": "{{profile_uid}}",
"buyer_uid": "{{buyer_uid}}",
"has_checkout": false,
"payment_method": "multi",
"payment_flow": "direct",
"payment_details": [],
"amount": 2500,
"currency": "EUR",
"return_url": "https://platform.example.com/return/",
"redirect_url": null,
"notify_url": "https://platform.example.com/notify/",
"status": "created",
"metadata": [],
"statuses": [
{
"uid": "sta_d382b590a7a7",
"object": "status",
"created": 1616593428,
"updated": 1616593428,
"status": "created"
}
],
"order": [],
"escrow": null,
"fees": {},
"refunds": {}
}
]
}
Example request - Retrieve all multi transactions:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/multi_transactions \
-H "Authorization: Bearer {{api_key}}" \
GET https://api-sandbox.onlinebetaalplatform.nl/v1/multi_transactions
Example response:
{
"object": "list",
"url": "/v1/multi_transactions",
"has_more": false,
"total_item_count": 2,
"items_per_page": 10,
"current_page": 1,
"last_page": 1,
"data": [
{
"uid": "{{multi_transaction_uid}}",
"object": "multi_transaction",
"created": 1616593428,
"updated": 1616593428,
"completed": null,
"merchant_uid": "{{partner_merchant_uid}}",
"payment_method": "ideal",
"payment_details": null,
"description": "",
"amount": 5000,
"currency": "EUR",
"return_url": "https://platform.example.com/return/",
"redirect_url": "https://onlinebetaalplatform.nl/nl/{{partner_slug}}/transactie/start/{{multi_transaction_container_uid}}",
"notify_url": "https://platform.example.com/notify/",
"status": "created",
"metadata": [],
"statuses": [
{
"uid": "mts_b3e27e523130",
"object": "status",
"created": 1616593428,
"updated": 1616593428,
"status": "created"
}
],
"fees": {},
"transactions": [
{
"uid": "{{transaction_uid}}",
"object": "transaction",
"created": 1616593428,
"updated": 1616593428,
"completed": null,
"merchant_uid": "{{merchant_uid}}",
"profile_uid": "{{profile_uid}}",
"buyer_uid": "{{buyer_uid}}",
"has_checkout": false,
"payment_method": "multi",
"payment_flow": "direct",
"payment_details": [],
"amount": 2500,
"currency": "EUR",
"return_url": "https://platform.example.com/return/",
"redirect_url": null,
"notify_url": "https://platform.example.com/notify/",
"status": "created",
"metadata": [],
"statuses": [
{
"uid": "sta_cc6c1d9b127b",
"object": "status",
"created": 1616593428,
"updated": 1616593428,
"status": "created"
}
],
"order": [],
"escrow": null,
"fees": {},
"refunds": {}
},
...
]
},
...
]
}
You can retrieve an individual multi transaction as well as a list of all multi transactions.
Please note that all transactions within the multi transaction have their own transaction_uid
and can thus be retrieved using Retrieve Transaction.
The following filters can be used when retrieving transactions:
Filter name | Description |
status | Shows multi-transactions with a specific status. |
payment_method | Shows the multi-transactions with a specific payment_method. |
completed_date | Only in extended filter. Shows the multi-transactions within a specific completed date. |
Multi Transaction Fees
Example response - Expanding fees:
{
"livemode": false,
"uid": "tra_6af0fb03d44c",
"object": "transaction",
...
"fees": {
"partner_gateway_fee": 25,
"transaction_fee": 15,
"merchant_gateway_fee": 0,
"merchant_transaction_fee": 0,
"payable_amount": 5
},
...
}
When expanding certain objects, they will appear when requested. Objects that do not have any CRUD functionality, but are either set by OPP or only set when creating the transaction can be found here.
Variable | Description |
partner_gateway_fee integer | Gateway fee that the partner pays in cents. |
partner_transaction_fee integer | Transaction fee that the partner pays in cents. Defined in the partner contract. |
merchant_gateway_fee integer | Gateway fee that the merchant pays in cents. |
merchant_transaction_fee integer | Transaction fee that the merchant pays in cents. |
payable_amount integer | Payable amount to the partner in cents. |
Retrieve Multi Transaction Transactions
Example request - Retrieve all transactions within a multi transaction object:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/multi_transactions/{{multi_transaction_uid}}/transactions \
-H "Authorization: Bearer {{api_key}}" \
GET https://api-sandbox.onlinebetaalplatform.nl/v1/multi_transactions/{{multi_transaction_uid}}/transactions
Example response:
{
"object": "list",
"url": "/v1/multi_transactions/{{multi_transaction_uid}}/transactions",
"has_more": true,
"total_item_count": 36,
"items_per_page": 10,
"current_page": 1,
"last_page": 4,
"data": [
{
"uid": "{{transaction_uid}}",
"object": "transaction",
"created": 1665519530,
"updated": 1665519591,
"completed": null,
"merchant_uid": "{{merchant_uid}}",
"profile_uid": "{{profile_uid}}",
"buyer_uid": "{{buyer_uid}}",
"has_checkout": false,
"payment_method": "multi",
"payment_flow": "direct",
"payment_details": [],
"amount": 5500,
"currency": "EUR",
"return_url": "https://platform.example.com/return/",
"redirect_url": null,
"notify_url": "https://platform.example.com/notify/",
"status": "created",
"metadata": [],
"statuses": [
{
"uid": "sta_f951c5277008",
"object": "status",
"created": 1665519530,
"updated": 1665519530,
"status": "created"
}
],
"order": [],
"escrow": {
"uid": "{{escrow_uid}}",
"object": "escrow",
"period": 90,
"start": 1665519591,
"end": 1673299191
},
"fees": {},
"refunds": {}
},
...
]
}
If you are using over 20 transactions within the Multi Transaction, the Multi Transaction object will not return any transactions. Instead, you will need to use a different endpoint in order to retrieve the list of transactions. Please find an example to the right.
Update Multi Transaction
Example request - Update multi transaction:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/multi_transactions/{{multi_transaction_uid}} \
-H "Authorization: Bearer {{api_key}}"
-d date_expired=2021-04-30 09:00:00
POST https://api-sandbox.onlinebetaalplatform.nl/v1/multi_transactions/{{multi_transaction_uid}}
{
"date_expired": "2021-04-30 09:00:00"
}
Example response:
{
"livemode": false,
"uid": "{{multi_transaction_uid}}",
"object": "multi_transaction",
"created": 1711701852,
"updated": 1711701852,
"completed": 1711701852,
"merchant_uid": "{{merchant_uid}}",
"payment_method": "sepa",
"payment_details": {
"provider_bank_account_name": "Online Payments Foundation",
"provider_bank_account_iban": "NL96INGB0674534352",
"provider_bank_account_bic": "INGBNL2A",
"reference": "NY2MVC",
"expired": 1712267999,
"customer": {...}
},
"description": "",
"amount": 5000,
"return_url": "https://onlinepaymentplatform.com/",
"redirect_url": "https://onlinebetaalplatform.nl/nl/{{partner_slug}}/transactie/start/{{multi_transaction_container_uid}}",
"notify_url": "https://notify.url/",
"status": "created",
"metadata": [],
"statuses": [
{
"uid": "mts_e90b72c32e88",
"object": "status",
"created": 1711701852,
"updated": 1711701852,
"status": "created"
}
],
"fees": {},
"transactions": [...],
"currency": "EUR"
}
You are able to update a multi transaction by performing a POST on the multi transaction. You can update one variable at a time, or multiple as you desire. Please note that it is not possible to update transactions in a multi transaction via this endpoint. If you want to update a transaction within the multi transaction, please have a look at Update Transactions.
The following fields can be updated:
Variable | Description |
notify_url string | Notification url to receive status updates up to 255 characters Only possible when transaction has one of the following statuses: created pending planned reserved completed refunded |
date_expired string | Date expired for SEPA transactions. Only possible when multi transaction has one of the following statuses: created pending format: YYYY-MM-DD HH:MM:SS |
Delete Multi Transaction
Example request - Delete SEPA Multi transaction:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/multi_transactions/{{multi_transaction_uid}} \
-H "Authorization: Bearer {{api_key}}" \
-X DELETE
DELETE https://api-sandbox.onlinebetaalplatform.nl/v1/multi_transactions/{{multi_transaction_uid}}
Example response:
{
"livemode": false,
"uid": "{{multi_transaction_uid}}",
"object": "multi_transaction",
"created": 1683904191,
"updated": 1683904206,
"completed": null,
"merchant_uid": "{{partner_merchant_uid}}",
"payment_method": "sepa",
...
"status": "cancelled",
...
}
Only when a multi transaction has payment_method = sepa
, you are able to delete the transaction.
When a SEPA multi transaction is not needed anymore, you are able to delete it. This is only possible when the multi transaction has created
or pending
state.
Please note that if you delete the multi transaction while the buyer has already transferred the funds, the funds will automatically bounce back to the buyer.
After the multi transaction is successfully deleted, it will return with status cancelled
.
Sandbox Simulation - Multi Transaction
OPP Simulation statuses
Use the following amounts to trigger transaction statuses on sandbox mode using any payment method. You will not need to follow up the payment using the redirect_url. A direct status will be given on the transaction.
Amount | Status |
101 | created |
201 | pending |
301 | expired |
401 | cancelled |
501 | completed |
701 | failed |
any other amount | created |
Bancontact / Creditcard statuses
These simulations work for Bancontact as well as Creditcard, as the simulation page of Worldline is the same. Please note that you will only be able to use credit card as a payment method when the process for receiving credit card credentials from Worldline has started. Once at the page of Worldline, use any expiry date after the current month/year and any 3-digit security code. Use the following card numbers to simulate statuses:
Card number | Status |
5017670000000000 | completed |
5017670000001404 | failed |
Multi Transaction Import
This endpoint is similar to the Multi Transaction endpoint with the key difference being the asynchronous nature of the action behind this endpoint. The import will be able to process up to 10.000 splits per Multi Transaction, however this may take up to 30 minutes to process, and you will receive a notification stating that the process has been completed.
The process contains three steps:
- Create the Multi Transaction Import. OPP Returns a Multi Transaction Import object.
- Processing. OPP will process the Multi Transaction Import in the background (asynchronous).
- Completion. OPP sends a notification that the process has been completed. Partner can fetch the Multi Transaction and its splits.
Object Definition - Multi Transaction Import
The Multi Transaction Import object contains the following variables.
Variables | Description |
uid string | Import unique identifier. up to 20 characters |
object string | Value: multi_transaction_import |
created timestamp | Timestamp when import is created. |
updated timestamp | Timestamp when import is updated. |
completed timestamp | Timestamp when import is completed. |
status string | Single-field representation of the last updated status value one of: createdpendingplannedcompletedreservedcancelledfailedexpiredrefundedchargeback |
merchant_uid string | The partner merchant, owner of the multi transaction container. |
profile_uid string | The partner merchant profile, owner of the multi transaction container. |
multi_transaction_uid string | The Multi Transaction UID that was created using this import. Nullable |
notify_url string | Notification url to receive status updates. This notify_url will be copied into the underlying transactions. up to 255 characters |
number_of_transactions integer | Number of transactions in the Multi Transaction. |
volume_of_transactions integer | Volume of all transactions in the Multi Transaction. |
currency string | ISO 4217 currency code. |
Multi Transaction Import Status
The multi transaction import status is a status indication about the multi transaction import in the OPP system. According to this status, you should handle the flow on your platform accordingly.
The possible status flows can be found below:
Status | Explanation |
created | Import is created, no action has taken place yet. |
pending | Import is currently processing. |
completed | Import is successfully completed and transactions are created. |
cancelled | Import got cancelled by OPP. |
failed | The import has failed due to an error. A new import needs to be created. If you keep receiving status failed, please contact your implementation manager. |
Notification Example - Multi Transaction Import
Example notification:
{
"uid": "{{notification_uid}}",
"type": "multi_transaction_import.status.changed",
"created": 1653400863,
"object_uid": "{{multi_transaction_import_uid}}",
"object_type": "multi_transaction_import",
"object_url": "https://api-sandbox.onlinebetaalplatform.nl/v1/multi_transaction_imports/{{multi_transaction_import_uid}}",
"verification_hash": "{{hash}}"
}
Please find a notification example to the right.
Create Multi Transaction Import
Example request - Create multi transaction import:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/multi_transaction_imports \
-H "Authorization: Bearer {{api_key}}"
-d total_price=142000 \
-d currency=EUR \
-d payment_method=sepa \
-d checkout=false \
-d return_url=https://platform.example.com/return/ \
-d notify_url=https://platform.example.com/notify/ \
-d transactions[0][merchant_uid]={{merchant_uid}} \
-d transactions[0][total_price]=2500 \
-d transactions[0][partner_fee]=100 \
-d transactions[0][products][0][name]=Product A \
-d transactions[0][products][0][quantity]=1 \
-d transactions[0][products][0][price]=2500 \
-d transactions[1][merchant_uid]={{merchant_uid}} \
-d transactions[1][total_price]=2500 \
-d transactions[1][partner_fee]=100 \
-d transactions[1][products][0][name]=Product A \
-d transactions[1][products][0][quantity]=1 \
-d transactions[1][products][0][price]=250
...
POST https://api-sandbox.onlinebetaalplatform.nl/v1/multi_transaction_imports
{
"checkout" : false,
"payment_method": "sepa",
"total_price": 142000,
"currency": "EUR",
"transactions": [
{
"merchant_uid": "{{merchant_uid}}",
"total_price": 2500,
"partner_fee": 100,
"products": [
{
"name": "Product A",
"quantity": 1,
"price": 2500
}
]
},
{
"merchant_uid": "{{merchant_uid}}",
"total_price": 2500,
"partner_fee": 100,
"products": [
{
"name": "Product B",
"quantity": 1,
"price": 2500
}
]
},
...
],
"return_url": "https://platform.example.com/return/",
"notify_url": "https://platform.example.com/notify/"
}
Example response:
{
"livemode": false,
"uid": "{{multi_transaction_import_uid}}",
"object": "multi_transaction_import",
"created": 1653400180,
"updated": 1653400180,
"completed": null,
"status": "created",
"merchant_uid": "{{merchant_uid}}",
"profile_uid": "{{profile_uid}}",
"multi_transaction_uid": null,
"notify_url": "https://platform.example.com/notify/",
"number_of_transactions": 142,
"volume_of_transactions": 142000,
"currency": "EUR"
}
You can create a multi transaction import using the Multi Transaction Import API. Below are all multi transaction object variables that can be used in the POST request when creating a multi transaction.
OPP provides the option to put money in escrow. By doing so, you can provide a secure feeling to buyer and seller.
OPP will put the money in the settlement of the merchant only when the escrow period ends, or is manually ended by you as a partner.
The escrow period can be set per individual transaction by setting escrow = true
and either escrow_period = [days]
or escrow_date = [date]
.
OPP charges fees for every transaction that has been done.
As a partner, you will be able to provide partner fees towards merchants, to charge these fees towards the merchants, and if wanted, add some fee for you as a partner as well.
You can add partner fees per individual transaction by providing the partner_fee
attribute in the transaction.
Multi Transaction Import Variable | Description |
locale optional |
Locale used for transaction, one of: nl en fr de |
checkout optional | Whether or not to use the whitelabel checkout flow designed by OPP. This page lets the buyer fill in their personal data. Default is: false one of: true false In case checkout is true, an email will be send to the buyer with an order overview. |
payment_method required | one of: sepa |
issuer optional | Available when payment_method is ideal An issuer can be provided to be redirected to the bank immediately. See iDEAL issuers. |
date_expired optional | Available when payment_method = sepa SEPA Expiration date. OPP always adds 5 days to this variable because of bank transfer delays. |
description optional | Description visible on the OPP payment screen up to 255 characters |
total_price required | Total price in cents for all products quantities * prices, maximum: 99999999 |
shipping_costs optional | Shipping costs in cents, maximum: 99999999, default is account setting |
return_url required | The return url the customer is redirected to once the payment is completed. up to 255 characters |
notify_url required | Notification url to receive status updates up to 255 characters |
metadata object with key-value pairs | Additional data that belongs to the transaction object. |
transactions required | Array of transaction objects that need to be combined in this multi transaction. |
currency optional | ISO 4217 currency code. |
There are some small differences between the variables that are allowed in the Single Transaction object, and the transactions that can be posted in the Multi Transaction transactions array. Below you can find all variables of a transaction that can be given in the transactions array of the Multi Transaction object create.
Transaction Variable | Description | ||||||||||||
merchant_uid required | Unique identifier of a merchant. | ||||||||||||
profile_uid optional | Unique identifier of a merchants profile. default is: first merchant profile UID |
||||||||||||
escrow optional |
Default is: false one of: false true If true, one of escrow_period or escrow_date is required
|
||||||||||||
escrow_period optional | Escrow period in days. Minimum: 1 |
||||||||||||
escrow_date optional | Escrow end datetime format: YYYY-MM-DD HH:MM:SS Minimum: 15 minutes |
||||||||||||
buyer_name_first optional | If payment_flow = email the buyer's first name, up to 45 characters |
||||||||||||
buyer_name_last optional | If payment_flow = email the buyer's last name, up to 45 characters |
||||||||||||
buyer_emailaddress optional | Required when payment_flow = email | ||||||||||||
total_price required | Total price in cents for all products quantities * prices, maximum: 99999999 |
||||||||||||
shipping_costs optional | Shipping costs in cents, maximum: 99999999, default is account setting |
||||||||||||
discount optional | Default is: 0, discount in cents, maximum: 99999999 |
||||||||||||
partner_fee optional | Partner fee in cents. | ||||||||||||
payout_description optional | Description the merchant sees on his bank account. Available when partner contract has individual payouts. up to 125 characters |
||||||||||||
address optional | Address of the buyer. array with name/value pairs |
||||||||||||
|
|||||||||||||
products required | Products to be added to the payment page, array of one or more products objects |
||||||||||||
|
|||||||||||||
metadata object with key-value pairs | Additional data that belongs to the transaction object. |
Retrieve Multi Transaction Import
Example request - Retrieve a multi transaction import object:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/multi_transaction_imports/{{multi_transaction_import_uid}} \
-H "Authorization: Bearer {{api_key}}" \
GET https://api-sandbox.onlinebetaalplatform.nl/v1/multi_transaction_imports/{{multi_transaction_import_uid}}
Example response:
{
"uid": "{{multi_transaction_import_uid}}",
"object": "multi_transaction_import",
"created": 1653400180,
"updated": 1653400180,
"completed": null,
"status": "created",
"merchant_uid": "{{merchant_uid}}",
"profile_uid": "{{profile_uid}}",
"multi_transaction_uid": null,
"notify_url": "https://platform.example.com/notify/",
"number_of_transactions": 142,
"volume_of_transactions": 142000,
"currency": "EUR"
}
Example request - Retrieve all multi transaction imports:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/multi_transaction_imports \
-H "Authorization: Bearer {{api_key}}" \
GET https://api-sandbox.onlinebetaalplatform.nl/v1/multi_transaction_imports
Example response:
{
"object": "list",
"url": "/v1/multi_transaction_imports",
"has_more": false,
"total_item_count": 2,
"items_per_page": 10,
"current_page": 1,
"last_page": 1,
"data": [
{
"uid": "{{multi_transaction_import_uid}}",
"object": "multi_transaction_import",
"created": 1653400180,
"updated": 1653400180,
"completed": null,
"status": "created",
"merchant_uid": "{{merchant_uid}}",
"profile_uid": "{{profile_uid}}",
"multi_transaction_uid": null,
"notify_url": "https://platform.example.com/notify/",
"number_of_transactions": 142,
"volume_of_transactions": 142000,
"currency": "EUR"
},
...
]
}
You can retrieve an individual multi transaction import as well as a list of all multi transaction imports. The following filters can be used when retrieving multi transaction imports:
Filter name | Description |
Currently, no filters are available for multi transaction imports. |
Update Multi Transaction Import
It is not possible to update a multi transaction import. If you want to update a transaction within the multi transaction, please have a look at Update Transactions.
Delete Multi Transaction Import
It is not possible to delete a multi transaction import.
Refund
Object Definition - Refund
The Refund object contains the following variables.
Variables | Description |
uid string | Refund unique identifier. up to 20 characters |
object string | value: refund |
created timestamp | Timestamp in CE(S)T when object is created. |
updated timestamp | Timestamp in CE(S)T when object is updated. |
paid timestamp | Timestamp in CE(S)T when refund is paid. |
amount integer | Amount of the refund. |
currency string | ISO 4217 currency code. |
status string | Current status of the refund. one of: createdpendingplannedcompleted |
message string, nullable | Message sent to customer in email, if buyer emailaddress is known. |
internal_reason string | Internal reason for refund. |
fees object | Fees of the refund, same as fees |
payout_description string | Description to be added to the bank account description. Appended to (Partial) Refund for {{transaction_uid}} |
Refund Status
The refund status is a status indication about the refund in the OPP system. According to this status, you should handle the flow on your platform accordingly.
The possible status flows can be found below:
Status | Explanation |
created | Refund is created, no action has taken place yet. |
pending | Refund is currently being processed. |
completed | Refund is completed and ready for payout. |
Create Refund
Example request - Create refund:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/transactions/{{transaction_uid}}/refunds \
-H "Authorization: Bearer {{api_key}}"
-d amount=6750 \
-d currency=EUR \
-d payout_description="Refund from Product A"
POST https://api-sandbox.onlinebetaalplatform.nl/v1/transactions/{{transaction_uid}}/refunds
{
"amount": 6750,
"amount": "EUR",
"payout_description": "Refund from Product A"
}
Example response:
{
"uid": "{{refund_uid}}",
"object": "refund",
"created": 1596204264,
"updated": 1596204264,
"paid": null,
"amount": 6750,
"amount": "EUR",
"status": "created",
"message": null,
"internal_reason": null,
"fees": {},
"payout_description": "Refund from Product A"
}
You can create a refund using the Transaction API. A refund will revert (part of) the amount of a transaction that is on the settlement of the receiving merchant. A refund is only possible if the funds of the transaction have not yet been entirely refunded and enough funds are available on the settlement of the merchant. Direct PayPal transactions cannot be refunded from within OPP but have to be refunded from the PayPal environment itself. Note that PayPal refunds are not possible any later than 180 days after payment.
In case a transaction is still in escrow, and you provide a full refund, the transaction will then get status chargeback
. In all other cases, it will get the status refunded
. Do note that in case of a partial refund of a transaction in escrow, you will not get a notification of the completed
status of the transaction. Only a notification of the refunded
status will be sent.
Below are all refund object variables that can be used in the POST request when creating a refund.
Variable | Description |
amount integer | Refund amount in cents. |
currency string | ISO 4217 currency code. |
message string | Message sent to customer in email, if buyer emailaddress is known. |
internal_reason string | Internal reason for refund. |
payout_description string | Description to be added to the bank account description. Max 63 characters. Appended to (Partial) Refund for {{transaction_uid}} |
Retrieve Refund
Example request - Retrieve a single refund of a transaction:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/transactions/{{transaction_uid}}/refunds/{{refund_uid}} \
-H "Authorization: Bearer {{api_key}}" \
GET https://api-sandbox.onlinebetaalplatform.nl/v1/transactions/{{transaction_uid}}/refunds/{{refund_uid}}
Example response:
{
"uid": "{{refund_uid}}",
"object": "refund",
"created": 1596204264,
"updated": 1596204264,
"paid": null,
"amount": 6750,
"currency": "EUR",
"status": "created",
"message": null,
"internal_reason": null,
"fees": {},
"payout_description": "Refund from Product A"
}
Example request - Retrieve all refunds of a transaction:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/transactions/refunds \
-H "Authorization: Bearer {{api_key}}" \
GET https://api-sandbox.onlinebetaalplatform.nl/v1/transactions/refunds
Example response:
{
"object": "list",
"url": "/v1/transactions/{{transaction_uid}}/refunds",
"has_more": false,
"total_item_count": 1,
"items_per_page": 10,
"current_page": 1,
"last_page": 1,
"data": [
{
"uid": "{{refund_uid}}",
"object": "refund",
"created": 1596204264,
"updated": 1596204264,
"paid": null,
"amount": 6750,
"currency": "EUR",
"status": "created",
"message": null,
"internal_reason": null,
"fees": {},
"payout_description": "Refund from Product A"
}
]
}
You can retrieve an individual refund as well as a list of all refunds. The following filters can be used when retrieving transactions:
Filter name | Description |
Currently, no filters are available for refunds. |
Refund Fees
Example response - Expanding fees:
{
"livemode": false,
"uid": "tra_6af0fb03d44c",
"object": "transaction",
...
"fees": {
"merchant_gateway_fee": 0,
"merchant_transaction_fee": 0,
"merchant_order_fee": 45,
"merchant_payable_amount": 2455,
"gateway_fee": 25,
"transaction_fee": 15,
"order_fee": 0,
"payable_amount": 5
},
...
}
When expanding certain objects, they will appear when requested. Objects that do not have any CRUD functionality, but are either set by OPP or only set when creating the refund can be found here.
Variable | Description |
merchant_gateway_fee integer | Gateway fee that the merchant pays in cents. |
merchant_transaction_fee integer | Transaction fee that the merchant pays in cents. |
merchant_order_fee integer | The partner_fee that you provide in the transaction request. |
merchant_payable_amount integer | Payable amount to the merchant in cents. |
gateway_fee integer | Gateway fee that the partner pays in cents. |
transaction_fee integer | Transaction fee that the partner pays in cents. Defined in the partner contract |
order_fee integer | Order fee that the partner pays in cents. |
payable_amount integer | Payable amount to the partner in cents. (= merchant_order_fee - transaction_fee) |
Update Refund
It is not possible to update a refund. If the refunded amount is bigger than initially agreed upon, a second refund should be made.
Delete Refund
It is not possible to delete a refund.
Payment Reference
Object Definition - Payment Reference
The Payment Reference object contains the following variables.
Variables | Description |
uid string | Payment Reference unique identifier. up to 20 characters |
object string | Value: payment_reference |
created timestamp | Timestamp when payment reference is created. |
updated timestamp | Timestamp when payment reference is updated. |
code alphanumeric | Payment reference code, to be used in the description of the payment. |
currency string | Currency of the payment reference. |
notify_url string | Notification url to receive status updates. up to 255 characters |
payment_details array | Payment details for the transactions. |
|
Notification Example - Payment Reference
Example notification transaction registered:
{
"uid": "{{notification_uid}}",
"type": "payment_reference.transaction.registered",
"created": 1685004021,
"object_uid": "{{transaction_uid}}",
"object_type": "transaction",
"object_url": "https://api-sandbox.onlinebetaalplatform.nl/v1/payment_references/{{payment_reference_uid}}/transactions/{{transaction_uid}}",
"parent_uid": "{{payment_reference_uid}}",
"parent_type": "payment_reference",
"parent_url": "https://api-sandbox.onlinebetaalplatform.nl/v1/payment_references/{{payment_reference_uid}}",
"verification_hash": "{{hash}}"
}
Example notification transaction denied:
{
"uid": "not_646be1218cae",
"type": "payment_reference.transaction.denied",
"created": 1685004121,
"object_uid": "{{payment_reference_uid}}",
"object_type": "payment_reference",
"object_url": null,
"verification_hash": "{{hash}}"
}
Please find a notification example to the right.
Create Payment Reference
Example request - Create Payment Reference:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/payment_references \
-H "Authorization: Bearer {{api_key}}"
-d “merchant_uid={{merchant_uid}} \
-d “code=TEST0001” \
-d “currency=EUR” \
-d “notify_url=https://platform.example.com/notify/”
POST https://api-sandbox.onlinebetaalplatform.nl/v1/payment_references
{
"merchant_uid": "{{merchant_uid}}",
"code": "TEST0001",
"currency": "EUR",
"notify_url": "https://platform.example.com/notify/"
}
Example response:
{
"uid": "{{payment_reference_uid}}",
"object": "payment_reference",
"created": 1624371329,
"updated": 1624371329,
"code": "TEST0001",
"currency": "EUR",
"notify_url": "https://platform.example.com/notify/",
"payment_details": {
"provider_bank_account_name": "Online Payments Foundation",
"provider_bank_account_iban": "NL96INGB0674534352",
"provider_bank_account_bic": "INGBNL2A"
}
}
You can create a payment reference using the Payment Reference API. Below are all payment reference object variables that can be used in the POST request when creating a payment reference.
You may create payment references to register SEPA transfers for your merchants. A payment reference is linked to a merchant’s profile. This allows merchants to register payments for each profile seperately.
Variable | Description |
merchant_uid required | Unique identifier of a merchant. |
profile_uid optional | Unique identifier of a merchants profile. default is: first merchant profile UID |
code optional | min 6, max 10 characters. Random code will be generated if not POSTed. |
currency optional | ISO 4217 currency code. |
virtual_iban_uid optional | The viban UID that should be displayed for this Payment Reference. |
notify_url required | Notification url to receive status updates up to 255 characters |
Retrieve Payment Reference
Example request - Retrieve a single payment reference object:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/payment_references/{{payment_reference_uid}} \
-H "Authorization: Bearer {{api_key}}" \
GET https://api-sandbox.onlinebetaalplatform.nl/v1/payment_references/{{payment_reference_uid}}
Example response:
{
"uid": "{{payment_reference_uid}}",
"object": "payment_reference",
"created": 1624371329,
"updated": 1624371329,
"code": "TEST0001",
"currency": "EUR",
"notify_url": "https://platform.example.com/notify/",
"payment_details": {
"provider_bank_account_name": "Online Payments Foundation",
"provider_bank_account_iban": "NL96INGB0674534352",
"provider_bank_account_bic": "INGBNL2A"
}
}
Example request - Retrieve all payment references:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/payment_references \
-H "Authorization: Bearer {{api_key}}" \
GET https://api-sandbox.onlinebetaalplatform.nl/v1/payment_references
Example response:
{
"object": "list",
"url": "/v1/payment_references",
"has_more": true,
"total_item_count": 12,
"items_per_page": 10,
"current_page": 1,
"last_page": 2,
"data": [
{
"uid": "{{payment_reference_uid}}",
"object": "payment_reference",
"created": 1624371329,
"updated": 1624371329,
"code": "TEST0001",
"currency": "EUR",
"notify_url": "https://platform.example.com/notify/",
"payment_details": {
"provider_bank_account_name": "Online Payments Foundation",
"provider_bank_account_iban": "NL96INGB0674534352",
"provider_bank_account_bic": "INGBNL2A"
}
},
...
]
}
You can retrieve an individual payment reference as well as a list of all payment references. The following filters can be used when retrieving payment references:
Filter name | Description |
code | Shows payment referenes with a specific code. |
merchant | Shows the transactions belonging to a specific merchant. |
profile | Shows the transactions belonging to a specific profile. |
Retrieve Payment Reference transactions
Example request - Retrieve transactions from payment reference object:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/payment_references/{{payment_reference_uid}}/transactions \
-H "Authorization: Bearer {{api_key}}" \
GET https://api-sandbox.onlinebetaalplatform.nl/v1/payment_references/{{payment_reference_uid}}/transactions
Example response:
{
"object": "list",
"url": "/v1/payment_references/{{payment_reference_uid}}/transactions",
"has_more": true,
"total_item_count": 439,
"items_per_page": 10,
"current_page": 1,
"last_page": 44,
"data": [
{
"uid": "{{transaction_uid}}",
"object": "transaction",
"created": 1613741183,
"updated": 1613741183,
"completed": null,
"merchant_uid": "{{merchant_uid}}",
"profile_uid": "{{profile_uid}}",
"buyer_uid": "{{buyer_uid}}",
"has_checkout": false,
"payment_method": null,
"payment_flow": "direct",
"payment_details": [],
"amount": 250,
"return_url": "https://platform.example.com/return/",
"redirect_url": "https://sandbox.onlinebetaalplatform.nl/nl/6bfa1c3e1d1d/betalen/verzendgegevens/{{transaction_uid}}",
"notify_url": "https://platform.example.com/notify/",
"status": "created",
"metadata": [
{
"key": "external_id",
"value": "2015486"
}
],
"statuses": [
{
"uid": "sta_8b03f99bbd54",
"object": "status",
"created": 1613741183,
"updated": 1613741183,
"status": "created"
}
],
"order": [],
"escrow": null,
"fees": {},
"refunds": {}
},
...
]
}
If you want to retrieve all payments that belong to a specific payment reference, you can use the API call at the right.
Update Payment Reference
Currently, it is not possible to update a payment reference.
Delete Payment Reference
Example request - Delete payment reference:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/payment_references/{{payment_reference_uid}} \
-H "Authorization: Bearer {{api_key}}" \
-X DELETE
DELETE https://api-sandbox.onlinebetaalplatform.nl/v1/payment_references/{{payment_reference_uid}}
Example response:
{
"uid": "{{payment_reference_uid}}",
"deleted": true
}
When a payment reference is not needed anymore, you are able to delete it. Please note that if you delete the payment reference after the buyer has already transferred the funds, the funds will automatically bounce back to the buyer.
Sandbox Simulation - Payment Reference
Payment references and transactions may be tested on sandbox by POSTing pre-defined codes. Each test code has a different simulated flow. Do note that the test-code will be altered by us on sandbox to allow multiple tests per code.
Code | Status |
TEST100 | Create Payment Reference and register one single transaction |
TEST200 | Create Payment Reference and register two transactions |
TEST300 | Create Payment Reference and register one single transaction which will be denied to simulate a transaction registered on a ‘revoked’ payment reference. |
Payment Link
Object Definition - Payment Link
The Payment Link object contains the following variables.
Variables | Description | ||||||||||
uid string | Payment Link unique identifier. up to 20 characters |
||||||||||
object string | Value: payment_link |
||||||||||
locale string | Language in which the payment link is shown. | ||||||||||
title string | Title of the payment link. | ||||||||||
total_amount integer | Total sum of the products * prices. | ||||||||||
profile_name string | Name of the profile the payment link was created for. | ||||||||||
status string | Current status of the object. one of: created pending completed failed |
||||||||||
statuses array | Current and previous payment link statuses. | ||||||||||
created timestamp | Timestamp at which the payment link was created. | ||||||||||
payment_url string | The customer should be directed to this url, for making the payment. up to 255 characters |
||||||||||
products array | Products added to the payment page, array of one or more products objects |
||||||||||
|
|||||||||||
currency string | ISO 4217 currency code. | ||||||||||
transactions_count integer | Number of transactions created for this payment link. Attempts until success. | ||||||||||
skip_confirmation_page integer | Whether or not confirmation page is skipped. Either 0 or 1 |
||||||||||
checkout integer | Whether or not checkout is used. Either 0 or 1 |
||||||||||
date_expired datetime | Date and time at which the payment link will expire. | ||||||||||
date_completed datetime | Date and time at which the payment link is completed. Nullable | ||||||||||
date_created datetime | Date and time at which the payment link is created. | ||||||||||
notify_url string | Notification url to receive status updates up to 255 characters . Nullable |
||||||||||
return_url string | The customer is directed to this url, once the payment is completed. up to 255 characters. Nullable |
||||||||||
currency string | Currency of the payment link. | ||||||||||
payment_link_recipients array | Array of recipients. | ||||||||||
trading_names array | Array with one or more trading names. | ||||||||||
|
|||||||||||
metadata array | Set of key / value pairs to store additional data. nullable |
Payment Link Status
The payment link status is a status indication about the payment link in the OPP system. According to this status, you should handle the flow on your platform accordingly.
The possible status flows can be found below:
Status | Explanation |
created | Payment link is created, no action has taken place yet. |
pending | User has opened the redirect_url, OPP is awaiting final state from the issuer. |
completed | Payment link is successfully completed and the transaction will be settled in order to payout. |
expired | The expiration time of the payment link has passed. A new payment link needs to be created. |
failed | The transaction created by the payment link failed to succeed. The link provides the possibility to try again. |
Notification Example - Payment Link
Example notification:
{
"uid": "{{notification_uid}}",
"type": "merchant.module.payment_link.status.changed",
"created": 1695213633,
"object_uid": "{{payment_link_uid}}",
"object_type": "payment_link",
"object_url": "https://api-sandbox.onlinebetaalplatform.nl/v1/modules/payment-links/{{payment_link_uid}}",
"verification_hash": "{{hash}}"
}
Please find a notification example to the right.
Create Payment Link
Example request - Create payment link:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/modules/payment-links/create \
-H "Authorization: Bearer {{api_key}}" \
-d merchant_uid={{merchant_uid}} \
-d "title=WakeUp Light Payment Link" \
-d "products[0][name]=WakeUp Light" \
-d products[0][price]=250 \
-d products[0][quantity]=1 \
-d checkout=false \
-d locale=en \
-d return_url=https://platform.example.com/return/ \
-d notify_url=https://platform.example.com/notify/ \
-d metadata[external_id]=2015486 \
-d currency=EUR
POST https://api-sandbox.onlinebetaalplatform.nl/v1/modules/payment-links/create
{
"merchant_uid": "{{merchant_uid}}",
"title": "WakeUp Light Payment Link",
"products": [
{
"name": "WakeUp Light",
"price": 250,
"quantity": 1
}
],
"return_url": "https://platform.example.com/return/",
"notify_url": "https://platform.example.com/notify/",
"total_price": 250,
"currency": "EUR",
"checkout": false,
"locale": "en",
"metadata":
{
"external_id": "2015486"
}
}
Example response:
{
"livemode": false,
"uid": "{{payment_link_uid}}",
"object": "payment_link",
"locale": "en",
"title": "WakeUp Light Payment Link",
"total_amount": 250,
"currency": "EUR",
"profile_name": "Profile Name",
"status": "created",
"statuses": [
{
"uid": "pls_0684fefc28c4",
"object": "payment_link_status",
"created": 1696513363,
"status": "created"
}
],
"created": 1696513363,
"payment_url": "https://sandbox.onlinebetaalplatform.nl/en/{{hash}}/pay/{{payment_link_uid}}",
"products": [
{
"name": "WakeUp Light",
"price": 250,
"quantity": 1,
"total_amount": 250
}
],
"transactions_count": 0,
"skip_confirmation_page": 0,
"checkout": 0,
"date_expired": "2023-11-05 15:42:43",
"date_completed": null,
"date_created": "2023-10-05 15:42:43",
"notify_url": "https://platform.example.com/notify/",
"return_url": null,
"currency": "EUR",
"payment_link_recipients": [
{
"name": "T Tester",
"type": "email",
"email": "email@domain.com",
"reply_to_email": "reply_to@domain.com",
"date_sent": "2024-03-14 11:17:50"
}
]
}
You can create a payment link using the Payment Links API. Below are all payment link object variables that can be used in the POST request when creating a payment link.
Variable | Description | ||||||
merchant_uid required | Unique identifier of a merchant. | ||||||
profile_uid optional | Unique identifier of a merchants profile. default is: first merchant profile UID |
||||||
title required | Title of the payment link | ||||||
locale required |
Locale used for payment link, one of: nl en fr de |
||||||
checkout required | Whether or not to use the whitelabel checkout flow designed by OPP. This page lets the buyer fill in their
personal data. one of: true false In case checkout is true, an email will be sent to the buyer with an order overview. |
||||||
skip_confirmation_page optional |
Whether or not to skip the confirmation page.
Available when checkout = true Default is: false one of: true false |
||||||
date_expired optional | Payment Link Expiration date. Default is 30 days. | ||||||
products required | Products to be added to the payment page, array of one or more products objects |
||||||
|
|||||||
currency optional | ISO 4217 currency code. | ||||||
return_url optional | The return url the customer is redirected to once the payment is completed. up to 255 characters |
||||||
notify_url optional | Notification url to receive status updates up to 255 characters |
||||||
metadata object with key-value pairs | Additional data that belongs to the transaction object. |
Retrieve Payment Link
Example request - Retrieve a single payment link object:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/modules/payment-links/{{payment_link_uid}} \
-H "Authorization: Bearer {{api_key}}"
GET https://api-sandbox.onlinebetaalplatform.nl/v1/modules/payment-links/{{payment_link_uid}}
Example response:
{
"livemode": false,
"uid": "{{payment_link_uid}}",
"object": "payment_link",
"locale": "en",
"title": "WakeUp Light Payment Link",
"total_amount": 250,
"currency": "EUR",
"profile_name": "Profile Name",
"status": "created",
"statuses": [
{
"uid": "pls_0684fefc28c4",
"object": "payment_link_status",
"created": 1696513363,
"status": "created"
}
],
"created": 1696513363,
"payment_url": "https://sandbox.onlinebetaalplatform.nl/en/{{hash}}/pay/{{payment_link_uid}}",
"products": [
{
"name": "WakeUp Light",
"price": 250,
"quantity": 1,
"total_amount": 250
}
],
"transactions_count": 0,
"skip_confirmation_page": 0,
"checkout": 0,
"date_expired": "2023-11-05 15:42:43",
"date_completed": null,
"date_created": "2023-10-05 15:42:43"
}
Example request - Retrieve all payment links:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/modules/payment-links \
-H "Authorization: Bearer {{api_key}}"
GET https://api-sandbox.onlinebetaalplatform.nl/v1/modules/payment-links
Example response:
{
"object": "list",
"url": "/v1/modules/payment-links",
"has_more": true,
"total_item_count": 439,
"items_per_page": 10,
"current_page": 1,
"last_page": 44,
"data": [
{
"uid": "{{payment_link_uid}}",
"object": "payment_link",
"locale": "en",
"title": "WakeUp Light Payment Link",
"total_amount": 250,
"currency": "EUR",
"profile_name": "Profile Name",
"status": "created",
"statuses": [
{
"uid": "pls_0684fefc28c4",
"object": "payment_link_status",
"created": 1696513363,
"status": "created"
}
],
"created": 1696513363,
"payment_url": "https://sandbox.onlinebetaalplatform.nl/en/{{hash}}/pay/{{payment_link_uid}}",
"products": [
{
"name": "WakeUp Light",
"price": 250,
"quantity": 1,
"total_amount": 250
}
],
"transactions_count": 0,
"skip_confirmation_page": 0,
"checkout": 0,
"date_expired": "2023-11-05 15:42:43",
"date_completed": null,
"date_created": "2023-10-05 15:42:43"
},
...
]
}
You can retrieve an individual payment link as well as a list of all payment links. The following filters can be used when retrieving payment links:
Filter name | Description |
status | Shows payment links with a specific status. |
created | Only in extended filter. Shows the payment links within a specific created date. |
Update Payment Link
Example request - Update payment link:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/modules/payment-links/{{payment_link_uid}} \
-H "Authorization: Bearer {{api_key}}"
-d "title=WakeUp Light Payment Link" \
-d "products[0][name]=WakeUp Light" \
-d products[0][price]=250 \
-d products[0][quantity]=1 \
-d checkout=false \
POST https://api-sandbox.onlinebetaalplatform.nl/v1/modules/payment-links/{{payment_link_uid}}
{
"title": "WakeUp Light Payment Link",
"products": [
{
"name": "WakeUp Light",
"price": 250,
"quantity": 1
}
],
}
Example response:
{
"livemode": false,
"uid": "{{payment_link_uid}}",
"object": "payment_link",
"locale": "en",
"title": "WakeUp Light Payment Link",
"total_amount": 250,
"currency": "EUR",
"profile_name": "Profile Name",
"status": "created",
"statuses": [
{
"uid": "pls_0684fefc28c4",
"object": "payment_link_status",
"created": 1696513363,
"status": "created"
}
],
"created": 1696513363,
"payment_url": "https://sandbox.onlinebetaalplatform.nl/en/{{hash}}/pay/{{payment_link_uid}}",
"products": [
{
"name": "WakeUp Light",
"price": 250,
"quantity": 1,
"total_amount": 250
}
],
"transactions_count": 0,
"skip_confirmation_page": 0,
"checkout": 0,
"date_expired": "2023-11-05 15:42:43",
"date_completed": null,
"date_created": "2023-10-05 15:42:43"
}
You are able to update a payment link by performing a POST on the payment link. You can update one variable at a time, or multiple as you desire.
The following fields can be updated:
Variable | Description | ||||||
merchant_uid string | Unique identifier of a merchant. | ||||||
profile_uid stsring | Unique identifier of a merchants profile. default is: first merchant profile UID |
||||||
locale string |
Locale used for payment link, one of: nl en fr de |
||||||
checkout boolean | Whether or not to use the whitelabel checkout flow designed by OPP. This page lets the buyer fill in their
personal data. one of: true false In case checkout is true, an email will be sent to the buyer with an order overview. |
||||||
skip_confirmation_page boolean |
Whether or not to skip the confirmation page.
Available when checkout = true Default is: false one of: true false |
||||||
date_expired datetime | Payment Link Expiration date. Formatted as YYYY-MM-DD HH:MM:SS . Default is 30 days. |
||||||
products array | Products to be added to the payment page, array of one or more products objects |
||||||
|
|||||||
return_url string | The return url the customer is redirected to once the payment is completed. up to 255 characters |
||||||
notify_url string | Notification url to receive status updates up to 255 characters |
Delete Payment Link
Example request - Delete Payment Link:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/modules/payment-links/{{payment_link_uid}} \
-H "Authorization: Bearer {{api_key}}" \
-X DELETE
DELETE https://api-sandbox.onlinebetaalplatform.nl/v1/modules/payment-links/{{payment_link_uid}}
Example response:
{
"livemode": false,
"uid": "{{payment_link_uid}}",
"deleted": true
}
When a payment link is not needed anymore, you are able to delete it. This is only possible when the payment link has a created
state.
After the payment link is successfully deleted, it will be removed from any API responses.
Payment Methods
Transactions have a standard expiration time of 15 minutes. Depending on the payment method, this can be extended. Please note that not all payment methods are available or suitable for your situation. Together with your Implementation Manager, you decided on a set of payment methods to start with. Any additional payment method that you would like to use, need to be discussed with your Implementation Manager.
Currently OPP provides the following payment methods:
Payment method | Expiration | Needs application |
ideal - iDEAL |
15 minutes, not extendable | Additional application not needed |
bcmc - Bancontact |
15 minutes, not extendable | Additional application not needed |
sepa - SEPA Bank Transfer |
7 days, extendable using date_expired |
Additional application not needed |
pi-single - Payment Initiation (PIS) |
Depending on the issuer, not extendable | Additional application not needed |
paypal-ppcp - PayPal |
15 minutes, not extendable | Additional application needed |
creditcard - Creditcard |
15 minutes, not extendable | Additional application needed |
apple-pay - Apple Pay |
15 minutes, not extendable | Additional application needed |
mybank - MyBank |
15 minutes, not extendable | Additional application needed |
mandate - SEPA Direct Debit |
see Mandates & Direct Debit | Additional application needed |
multi - Multi-split transactions |
see Multi Transactions | Additional application needed |
Payment Details
Example request - SEPA Transaction:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/transactions \
-H "Authorization: Bearer {{api_key}}"
-d merchant_uid={{merchant_uid}} \
-d products[0][name]=Test \
-d products[0][price]=100 \
-d products[0][quantity]=1 \
-d total_price=100 \
-d return_url=https://platform.example.com/return/ \
-d notify_url=https://platform.example.com/notify/ \
-d payment_method=sepa \
-d checkout=false \
-d date_expired=2021-05-01 08:15:00
{
"merchant_uid": "{{merchant_uid}}",
"products": [
{
"name": "Test",
"price": 100,
"quantity": 1
}
],
"return_url": "https://platform.example.com/return/",
"notify_url": "https://platform.example.com/notify/",
"total_price": 100,
"payment_method": "sepa",
"checkout": false,
"date_expired": "2021-05-01 08:15:00",
"metadata":
{
"external_id": "2015486"
}
}
Example response:
{
"uid": "{{transaction_uid}}",
"object": "transaction",
"created": 1554113700,
"updated": 1554113700,
"completed": null,
"merchant_uid": "{{merchant_uid}}",
"has_checkout": false,
"payment_method": "sepa",
"payment_flow": "direct",
"payment_details": {
"provider_bank_account_name": "Online Payments Foundation",
"provider_bank_account_iban": "NL35INGB0653386540",
"provider_bank_account_bic": "INGBNL2A",
"reference": "P4JRGW",
"expired": 1556705700
},
"amount": 100,
"return_url": "https://platform.example.com/return",
"redirect_url": "https://onlinebetaalplatform.nl/nl/
{profile_uid}/transactie/start/{{transaction_uid}}",
"notify_url": "https://platform.example.com/notify/",
"status": "created",
"metadata": [],
"statuses": [ {
"uid": "{{status_uid}}",
"object": "status",
"created": 1554113700,
"updated": 1554113700,
"status": "created"
} ],
"order": [],
"escrow": null,
"fees": {},
"refunds": {}
}
Payment details will become available in a transaction when the user has chosen to pay using SEPA.
To complete a SEPA transaction the payer has to complete a bank transfer with the full amount of the transaction to our third-party funds "Online Payments Foundation".
All details required for this transfer can be found in the payment details object within the transaction object.
It is very important that the payer uses our unique reference
and our reference only for the description of the transfer.
All payments received which cannot be processed due to reasons such as an incorrect description, incorrect amount and/or payments received after the expiration date will be refunded to the payer’s bank account.
The payer can continue trying until the expiration date has passed. Otherwise, a new transaction will need to be created.
Variable | Description |
provider_bank_account_name string | Name of our third party bank account. |
provider_bank_account_iban string | IBAN of our third party bank account. |
provider_bank_account_bic string | BIC of our third party bank account. |
reference string | Reference that needs to be put in the description field of the bank transfer. |
expired timestamp | Timestamp in CE(S)T when the reference, and thus the transactoin is expired. |
For international transfers it might be required for a payer to provide additional company or/and bank information. In these cases the payer can use the following:
Company information | Bank information |
Online Payment Platform B.V. | ING Bank N.V. |
Foreign Operations | |
Kanaalweg 1 | PO Box 1800 |
2628 EB Delft | 1000 BV Amsterdam |
The Netherlands | The Netherlands |
Mandates & Direct Debit
Mandates can be used to let a merchant fulfil a direct debit on someone's bank account. This can either be recurring or once. After creating a mandate, you have the right as a platform to create a direct debit transaction, or mandate transaction. This chapter will provide you all the necessary information about and functionality of a mandate object and its transactions.
We already provided a Postman collection on the Mandate API for you to start with.
Mandate
Object Definition - Mandate
The Mandate object contains the following variables.
Variables | Description |
uid string | Mandate unique identifier. up to 20 characters |
object string | Value: mandate |
token string | The mandate token needed to start mandate transactions. |
created timestamp | Timestamp in CE(S)T when mandate is created. |
updated timestamp | Timestamp in CE(S)T when mandate is updated. |
start timestamp | Timestamp in CE(S)T when mandate is started. Will always be null (DEPRECATED) |
end timestamp | Timestamp in CE(S)T when mandate is ended. Will always be null (DEPRECATED) |
completed timestamp | Timestamp in CE(S)T when mandate is completed. |
expired timestamp | Timestamp in CE(S)T when mandate is expired. |
revoked timestamp | Timestamp in CE(S)T when mandate is revoked. |
amount integer | Mandate amount in cents. |
repeats integer | Number of times mandate transactions are created. !NOTE! All mandates of OPP are continuous, this is only for visualisation purposes. |
interval integer | Interval in days a mandate transaction is created. !NOTE! This is only for visualisation purposes. |
description string | Description of the mandate. |
return_url string | The customer is directed to this url, once the mandate is completed. up to 255 characters |
redirect_url string | The customer is directed to this url, for completing the mandate. up to 255 characters |
notify_url string | Notification url to receive status updates. up to 255 characters |
has_checkoutboolean | One of: true false Whether checkout is used for this mandate. |
skip_confirmationboolean | One of: true false Whether the confirmation page is skipped for this mandate. |
mandate_flow string | Value: direct Shows whether the mandate page is used. |
mandate_repeat string | Defines how often the mandate can be used to create a transaction. One of: once subscription continued |
mandate_type string | Whether the mandate is for a business or a consumer. One of: consumer business |
mandate_method string | The method used for the mandate completion. One of: form payment emandate import |
payment_method string | Value: null unless mandate_method = payment was chosen. |
status string | Current status of the object. one of: createdpendingcompletedcancelledfailedexpiredrevoked |
customer array | The customer that has given the mandate. See Mandate customer. |
order array | The order that has been placed. See Mandate order. |
metadata array | Set of key / value pairs to store additional data. |
statuses array | Current and previous mandate statuses. |
currency string | ISO 4217 currency code. |
Mandate Status
The mandate status is a status indication about the mandate in the OPP system. According to this status, you should handle the flow on your platform.
The possible status flows can be found below:
Status | Explanation |
created | Mandate is created, no action has taken place yet. |
pending | User has opened the redirect_url, OPP is awaiting final state. |
completed | Mandate is successfully completed and ready to be used for transactions. |
cancelled | Mandate was manually cancelled by the user. A new mandate needs to be created. |
expired | The expiration time of the mandate has passed. A new mandate needs to be created. |
failed | The mandate has failed due to an error at the issuer or OPP. A new mandate needs to be created. If you keep receiving status failed, please contact your implementation manager. |
revoked | The mandate has been revoked by the platform, the user or OPP and cannot be used anymore. A new mandate needs to be created. |
Notification Example - Mandate
Example notification profile balance:
{
"uid": "{{notification_uid}}",
"type": "mandate.status.changed",
"created": 1684936993,
"object_uid": "{{mandate_uid}}",
"object_type": "mandate",
"object_url": "https://api-sandbox.onlinebetaalplatform.nl/v1/mandates/{{mandate_uid}}",
"verification_hash": "{{hash}}"
}
Please find a notification example to the right.
Create Mandate
Example request - Create mandate:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/mandates \
-H "Authorization: Bearer {{api_key}}"
-d merchant_uid={{merchant_uid}} \
-d mandate_method=payment \
-d mandate_type=consumer \
-d mandate_repeat=subscription \
-d mandate_amount=100 \
-d "products[0][name]=Test product" \
-d products[0][price]=2525 \
-d products[0][quantity]=1 \
-d total_price=2525 \
-d return_url="https://platform.example.com/return/" \
-d notify_url="https://platform.example.com/notify/"
POST https://api-sandbox.onlinebetaalplatform.nl/v1/mandates
{
"merchant_uid": "{{merchant_uid}}",
"mandate_method": "payment",
"mandate_type": "consumer",
"mandate_repeat": "subscription",
"mandate_amount": 100,
"products": [{
"name": "Test product",
"price": 2525,
"quantity": 1
}],
"total_price": 2525,
"return_url": "https://platform.example.com/return/",
"notify_url": "https://platform.example.com/notify/"
}
Example response:
{
"livemode": false,
"uid": "{{mandate_uid}}",
"object": "mandate",
"token": null,
"created": 1625492691,
"updated": 1625492691,
"start": null,
"end": null,
"completed": null,
"expired": 1625494491,
"revoked": null,
"amount": 100,
"repeats": null,
"interval": null,
"description": null,
"return_url": "https://platform.example.com/return/",
"redirect_url": "https://sandbox.onlinebetaalplatform.nl/nl/6bfa1c3e1d1d/machtiging/verificatie-betaling/start/{{mandate_uid}}",
"notify_url": "https://platform.example.com/notify/",
"has_checkout": true,
"skip_confirmation": false,
"mandate_flow": "direct",
"mandate_repeat": "subscription",
"mandate_type": "consumer",
"mandate_method": "payment",
"payment_method": null,
"status": "created",
"customer": {},
"order": {},
"metadata": [],
"statuses": [],
"currency": "EUR"
}
You can create a mandate using the Mandate API. Below are all mandate object variables that can be used in the POST request when creating a mandate.
Variable | Description | ||||||||||||||||||||||||||||||||||
merchant_uid required | The merchant UID which allows for direct debit payments. In most cases this will be your partner merchant. | ||||||||||||||||||||||||||||||||||
merchant_profile_uid optional | Unique identifier of a merchants profile. default is: first merchant profile UID |
||||||||||||||||||||||||||||||||||
locale optional |
one of: nl dutch en english fr french de german |
||||||||||||||||||||||||||||||||||
checkout optional | Whether or not to use the whitelabel checkout flow designed by OPP. Default is: true one of: true false |
||||||||||||||||||||||||||||||||||
skip_confirmation optional |
Skip the confirmation page after successful mandate creation, one of: Default is: false true false |
||||||||||||||||||||||||||||||||||
mandate_method required |
one of: form authorization by form payment authorization by iDEAL payment emandate authorization by bank import batch import |
||||||||||||||||||||||||||||||||||
mandate_flow required |
one of: direct |
||||||||||||||||||||||||||||||||||
mandate_type required |
one of: business consumer |
||||||||||||||||||||||||||||||||||
mandate_repeat required | Defines how often the mandate can be used to create a transaction. one of: once subscription continued |
||||||||||||||||||||||||||||||||||
mandate_amount required | Amount used for mandate verification transaction in cents. In case this amount is higher than the verification amount (10 cents), this will also count as the first payment to the merchant. Only required when mandate_method = "payment" minimum: 10 cents |
||||||||||||||||||||||||||||||||||
payment_method optional |
one of: ideal bcmc creditcard only required if mandate_method = "payment" |
||||||||||||||||||||||||||||||||||
ideal_issuer optional | The iDEAL issuer of the bank. Use valid BIC here. only required if mandate_method = "ideal" |
||||||||||||||||||||||||||||||||||
issuer optional | The eMandate issuer of the bank. Use valid BIC here. only required if mandate_method = "emandate" |
||||||||||||||||||||||||||||||||||
repeats optional | Number of times a mandate repeats. for instance: 12 (times) !NOTE! This is only for visualisation purposes. |
||||||||||||||||||||||||||||||||||
interval optional | Interval in days a mandate repeats. for instance: 30 (days) !NOTE! This is only for visualisation purposes. |
||||||||||||||||||||||||||||||||||
total_price required | Shows the total price for recurring payment of the merchant on the checkout page in cents. Actual mandate transactions have to be created separately. We advise to fill in the actual recurring amount that will be regularly debited from the consumer or business. minimum: 100, maximum: as agreed with OPP |
||||||||||||||||||||||||||||||||||
shipping_costs optional | Shipping costs in cents. can be: 0 maximum: 99999999 |
||||||||||||||||||||||||||||||||||
customer optional |
Array of customer[key]=value attributes. required if mandate_method = payment or import & checkout = false |
||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||
products optional |
Array of one or more products objects. required when mandate_method = payment or form |
||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||
return_url required | The return url the customer is redirected to, once the mandate is created. | ||||||||||||||||||||||||||||||||||
notify_url required | Notification url to receive status updates. | ||||||||||||||||||||||||||||||||||
metadata optional | Array with name/value pairs to store additional data. nullable |
||||||||||||||||||||||||||||||||||
|
Retrieve Mandate
Example request - Retrieve a mandate object:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/mandates/{{mandate_uid}} \
-H "Authorization: Bearer {{api_key}}" \
GET https://api-sandbox.onlinebetaalplatform.nl/v1/mandates/{{mandate_uid}}
Example response:
{
"livemode": false,
"uid": "{{mandate_uid}}",
"object": "mandate",
"token": "{{token}}",
"created": 1625561886,
"updated": 1625561953,
"start": null,
"end": null,
"completed": 1625561931,
"expired": 1625563686,
"revoked": null,
"amount": 100,
"repeats": null,
"interval": null,
"description": null,
"return_url": "https://platform.example.com/return/",
"redirect_url": "https://sandbox.onlinebetaalplatform.nl/nl/6bfa1c3e1d1d/machtiging/verificatie-betaling/start/{{mandate_uid}}",
"notify_url": "https://platform.example.com/notify/",
"has_checkout": true,
"skip_confirmation": false,
"mandate_flow": "direct",
"mandate_repeat": "subscription",
"mandate_type": "consumer",
"mandate_method": "payment",
"payment_method": "ideal",
"status": "revoked",
"customer": {},
"order": {},
"metadata": [],
"statuses": [
{
"uid": "mst_df7c98c21145",
"object": "mandate_status",
"created": 1625561886,
"updated": 1625561886,
"status": "created"
},
{
"uid": "mst_09a6d4f82849",
"object": "mandate_status",
"created": 1625561890,
"updated": 1625561890,
"status": "pending"
},
{
"uid": "mst_59f65df787ba",
"object": "mandate_status",
"created": 1625561931,
"updated": 1625561931,
"status": "completed"
}
],
"currency": "EUR"
}
Example request - Retrieve all mandates:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/mandates \
-H "Authorization: Bearer {{api_key}}" \
GET https://api-sandbox.onlinebetaalplatform.nl/v1/mandates
Example response:
{
"object": "list",
"url": "/v1/mandates",
"has_more": true,
"total_item_count": 83,
"items_per_page": 10,
"current_page": 1,
"last_page": 9,
"data": [
{
"livemode": false,
"uid": "{{mandate_uid}}",
"object": "mandate",
"token": "{{token}}",
"created": 1625561886,
"updated": 1625561953,
"start": null,
"end": null,
"completed": 1625561931,
"expired": 1625563686,
"revoked": null,
"amount": 100,
"repeats": null,
"interval": null,
"description": null,
"return_url": "https://platform.example.com/return/",
"redirect_url": "https://sandbox.onlinebetaalplatform.nl/nl/6bfa1c3e1d1d/machtiging/verificatie-betaling/start/{{mandate_uid}}",
"notify_url": "https://platform.example.com/notify/",
"has_checkout": true,
"skip_confirmation": false,
"mandate_flow": "direct",
"mandate_repeat": "subscription",
"mandate_type": "consumer",
"mandate_method": "payment",
"payment_method": "ideal",
"status": "revoked",
"customer": {},
"order": {},
"metadata": [],
"statuses": [],
"currency": "EUR"
}
...
]
}
You can retrieve an individual mandate as well as a list of all mandates. The following filters can be used when retrieving mandates:
Filter name | Description |
status | Shows mandates with a specific status. |
merchant | Shows the mandates belonging to a specific merchant_uid. |
mandate_method | Shows the mandates with a specific mandate_method. |
payment_method | Shows the mandates with a specific payment_method. |
transaction_uid | Shows the mandate belonging to a specific transaction_uid. |
mandate_date | Only in extended filter. Shows the mandates within a specific completed date. |
Mandate Customer
Example response - expanding customer:
{
"livemode": false,
"uid": "{{mandate_uid}}",
"object": "mandate",
"token": "{{token}}",
"created": 1625561886,
"updated": 1625561953,
"start": null,
"end": null,
"completed": 1625561931,
...
"status": "revoked",
"customer": {
"uid": "{{mandate_customer_uid}}",
"object": "mandate_consumer",
"created": 1625561886,
"updated": 1625561931,
"gender": "m",
"name_first": "Online Payment",
"name_prefix": null,
"name_last": "Platform",
"street": "Kanaalweg",
"housenumber": "1",
"housenumber_addition": null,
"zipcode": "2628EB",
"city": "Delft",
"state": "Zuid-Holland",
"country": "Netherlands",
"emailaddress": "integrations@onlinepaymentplatform.com",
"phonenumber": "0612345678",
"company": null,
"payment_details": {
"name": "Hr E G H Küppers en/of MW M.J. Küppers-Veeneman",
"iban": "NL53***********370",
"bic": "INGBNL2A"
}
},
"currency": "EUR"
...
}
When expanding certain objects, they will appear when requested. Objects that do not have any CRUD functionality, but are either set by OPP or only set when creating the transaction can be found here.
Customer Variable | Description | ||||||
uid string | Customer unique identifier. up to 20 characters |
||||||
object string | value: mandate_customer |
||||||
created timestamp | Timestamp in CE(S)T when object is created. | ||||||
updated timestamp | Timestamp in CE(S)T when object is updated. | ||||||
gender string, nullable | Gender of the customer. One of: mfother | ||||||
name_first string, nullable | Customer first name. | ||||||
name_prefix string, nullable | Customer name prefix. | ||||||
name_last string, nullable | Customer last name. | ||||||
street string, nullable | Customer street. | ||||||
housenumber string, nullable | Customer housenumber. | ||||||
housenumber_addition string, nullable | Customer housenumber_addition. | ||||||
zipcode string, nullable | Customer zipcode. | ||||||
city string, nullable | Customer city. | ||||||
state string, nullable | Customer state. | ||||||
country string, nullable | Customer country. | ||||||
emailaddress string, nullable | Customer emailaddress. | ||||||
phonenumber string, nullable | Customer phonenumber. | ||||||
company string, nullable | Customer company. | ||||||
payment_details array | Payment details of the customer. | ||||||
|
Mandate Order
Example response - expanding order and order.products:
{
"livemode": false,
"uid": "{{mandate_uid}}",
"object": "mandate",
"token": "{{token}}",
"created": 1625561886,
"updated": 1625561953,
"start": null,
"end": null,
"completed": 1625561931,
...
"status": "revoked",
"customer": {},
"order": {
"uid": "{{mandate_order_uid}}",
"object": "mandate_order",
"created": 1625561886,
"updated": 1625561886,
"shipping_costs": 0,
"total_price": 2525,
"products": [
{
"uid": "{{mandate_product_uid}}",
"object": "mandate_product",
"created": 1625561886,
"updated": 1625561886,
"ean": null,
"code": null,
"name": "Test product",
"price": 2525,
"quantity": 1
}
]
},
"currency": "EUR"
...
}
Order Variable | Description |
uid string | Order unique identifier. up to 20 characters |
object string | value: mandate_order |
created timestamp | Timestamp in CE(S)T when object is created. |
updated timestamp | Timestamp in CE(S)T when object is updated. |
shipping_costs integer | Order shipping costs. |
total_price integer | Total order price. |
products array | Order products, see below. |
Products Variable | Description |
uid string | Product unique identifier. up to 20 characters |
object string | value: mandate_product |
created timestamp | Timestamp in CE(S)T when object is created. |
updated timestamp | Timestamp in CE(S)T when object is updated. |
ean string, nullable | Product EAN. |
code string, nullable | Product code. |
name string | Product name. |
price integer | Product price in cents. |
quantity integer | Product quanity. |
Update Mandate
An active mandate cannot be changed. If mandate information has changed, please revoke the mandate and create a new one. Please note that all mandates OPP uses are continuous, meaning that you can reuse the same mandate as you wish.
Delete Mandate
Example request - Delete mandate:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/mandates/{{mandate_uid}} \
-H "Authorization: Bearer {{api_key}}" \
-X DELETE
DELETE https://api-sandbox.onlinebetaalplatform.nl/v1/mandates/{{mandate_uid}}
Example response:
{
"livemode": false,
"uid": "{{mandate_uid}}",
"object": "mandate",
"token": "{{token}}",
"created": 1625561886,
"updated": 1625561953,
"start": null,
"end": null,
"completed": 1625561931,
"expired": 1625563686,
"revoked": 1625561953,
"amount": 100,
"repeats": null,
"interval": null,
"description": null,
"return_url": "https://platform.example.com/return/",
"redirect_url": "https://sandbox.onlinebetaalplatform.nl/nl/6bfa1c3e1d1d/machtiging/verificatie-betaling/start/{{mandate_uid}}",
"notify_url": "https://platform.example.com/notify/",
"has_checkout": true,
"skip_confirmation": false,
"mandate_flow": "direct",
"mandate_repeat": "subscription",
"mandate_type": "consumer",
"mandate_method": "payment",
"payment_method": "ideal",
"status": "completed",
"customer": {},
"order": {},
"metadata": [],
"statuses": [],
"currency": "EUR"
}
A mandate can be deleted by revoking the mandate. A revoked mandate can no longer be used to create transactions.
Please note that if you revoke a mandate before OPP have received the funds of the last mandate transaction, the transaction might be chargebacked.
Sandbox Simulation - Mandates
Use the following amounts to trigger mandate statuses on sandbox mode. For the simulations to have effect, provide the amounts in the total_price
. You will not need to follow up the mandate using the redirect_url. A direct status will be given on the mandate.
Amount | Status |
101 | created |
201 | pending |
301 | expired |
401 | cancelled |
501 | completed |
701 | failed |
1001 | revoked |
any other amount | created |
Mandate Methods
Mandates have a standard expiration time of 15 minutes, depending on the mandate method. Please note that not all mandate methods are available or suitable for your situation. Together with your Implementation Manager, you decided on a set of mandate methods to start with. Any additional mandate method that you would like to use, need to be discussed with your Implementation Manager.
Each mandate method comes with a different risk level, which could lead to a different set of contractual rules that are applied by our compliance and risk department. You can find the different methods below.
Mandate methods | |
form | Customer enters his IBAN and name on account and signs the mandate form to authorize Online Payments Foundation to send collection instructions to his/her bank to debit his/her account and to authorize his/her bank to debit his/her account once or on a recurrent basis in accordance with the instructions from Online Payments Foundation. Risk level: HIGH |
import | Import allows you to create a mandate by specifying customer IBAN (bank_iban ), BIC (bank_bic ) and Account holder name (bank_name ). When mandate_method is import these fields are required in the customer object. Risk level: HIGH |
payment | Customer completes an iDEAL, Bancontact or Creditcard payment and signs the mandate form to authorize Online Payments Foundation to send collection instructions to his/her bank to debit his/her account and to authorize his/her bank to debit his/her account in accordance with the instructions from Online Payments Foundation. Risk level: MEDIUM |
emandate | Customer authorises Online Payments Foundation to send collection instructions via their bank’s online banking application. !NOTE! emandate is currently only available in The Netherlands. You can find more information here. Risk level: LOW |
Mandate Transaction
Object Definition - Mandate Transaction
The Mandate Transaction object is very similar to the normal Transactions Object and contains the following variables.
Variables | Description |
uid string | Transaction unique identifier. up to 20 characters |
object string | Value: transaction |
created timestamp | Timestamp when transaction is created. |
updated timestamp | Timestamp when transaction is updated. |
completed timestamp | Timestamp when transaction is completed. |
merchant_uid string | Merchant to which the transaction belongs. |
profile_uid string | Merchant Profile to which the transaction belongs. |
has_checkoutboolean | One of: true false Whether checkout is used for this transaction. |
payment_method string | Value: mandate |
payment_flow string | Value: direct |
payment_details array | See Payment details |
amount integer | Transaction amount in cents. |
return_url string | Return url not available for Mandate Transactions. |
redirect_url string | Value: null |
notify_url string | Notification url to receive status updates. up to 255 characters |
status string | Current status of the object. one of: createdpendingplannedcompletedreservedrefundedchargeback |
metadata array | Set of key / value pairs to store additional data. nullable |
statuses array | Current and previous transaction statuses. |
order array | The order that has been placed. Same as Transaction order. See Transaction order. |
escrow array | The specifications of the escrow period. Same as Transaction escrow. See Transaction escrow. |
fees object | The specifications of the fees. Same as Transaction fees. See Transaction fees |
refunds object | The refund that belongs to this transaction, if any. Same as Transaction refunds. See Transaction refunds |
Mandate Transaction Status
The mandate transaction status is a status indication about the transaction in the OPP system. According to this status, you should handle the flow on your platform accordingly.
The possible status flows can be found below:
Status | Explanation |
created | Transaction is created, no action has taken place yet. |
pending | Money is received by OPP, waiting to be processed. |
planned | Money is reserved on the issuer's side, but not claimed by OPP yet. |
reserved | Transaction is successfully completed and put in escrow. |
completed | Transaction is successfully completed and settled in order to payout. |
refunded | The transaction has been initiated for (partial) refund. Once the refund has been initiated, OPP will refund the given amount within 24 hours. Depending on your bank or card supplier, this will be visible at a later period on your account. |
chargeback | The transaction has been initiated for refund, while it was in escrow. Once the refund has been initiated, OPP will refund the total amount within 24 hours. Depending on your bank or card supplier, this will be visible at a later period on your account. |
Create Mandate Transaction
Example request - Create mandate transaction:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/mandates/{{mandate_uid}}/transactions \
-H "Authorization: Bearer {{api_key}}" \
-d merchant_uid={{merchant_uid}} \
-d "reference=ABC1234" \
-d token={{mandate_token}} \
-d total_price=2525 \
-d notify_url=https://platform.example.com/notify/ \
POST https://api-sandbox.onlinebetaalplatform.nl/v1/mandates/{{mandate_uid}}/transactions
{
"merchant_uid": "{{merchant_uid}}",
"reference": "ABC1234",
"token": "{{mandate_token}}",
"total_price": 2525,
"notify_url": "https://platform.example.com/notify/"
}
Example response:
{
"livemode": false,
"uid": "{{transaction_uid}}",
"object": "transaction",
"created": 1625572951,
"updated": 1625572951,
"completed": null,
"merchant_uid": "{{merchant_uid}}",
"profile_uid": "{{profile_uid}}",
"buyer_uid": "{{buyer_uid}}",
"has_checkout": false,
"payment_method": "mandate",
"payment_flow": "direct",
"payment_details": {
"reference": "ABC1234",
"code": null,
"message": null
},
"amount": 2525,
"return_url": "https://platform.example.com/return/",
"redirect_url": null,
"notify_url": "https://platform.com/notify/",
"status": "created",
"metadata": [],
"statuses": [],
"order": [],
"escrow": {},
"fees": {},
"refunds": {}
}
You can create a mandate transaction using the Mandate Transaction API. Below are all transaction object variables that can be used in the POST request when creating a mandate transaction.
Variable | Description | ||||||||||||
merchant_uid required | Unique identifier of a merchant. | ||||||||||||
profile_uid optional | Unique identifier of a merchants profile. default is: first merchant profile UID |
||||||||||||
token required | Mandate token. | ||||||||||||
reference required | Unique reference of the transaction. | ||||||||||||
total_price required | Total price in cents for all products quantities * prices, maximum: 99999999 |
||||||||||||
shipping_costs optional | Shipping costs in cents, maximum: 99999999, default is account setting |
||||||||||||
partner_fee optional | Partner fee in cents. | ||||||||||||
mandate_description optional | Description visible at payment overview payer. Will be appended to the default description: SOB: {{mandate_uid}} if set: SOB: {{mandate_uid}} {{mandate_description}} maximum: 100 characters |
||||||||||||
escrow_period optional | Escrow period in days. Minimum: as agreed with OPP compliance |
||||||||||||
escrow_date optional | Escrow end datetime format: YYYY-MM-DD HH:MM:SS Minimum: as agreed with OPP compliance |
||||||||||||
products optional | Products to be added to the payment page, array of one or more products objects |
||||||||||||
|
|||||||||||||
notify_url required | Notification url to receive status updates up to 255 characters |
||||||||||||
metadata object with key-value pairs | Additional data that belongs to the transaction object. |
Retrieve Mandate Transaction
Example request - Retrieve a single mandate transaction object:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/transactions/{{transaction_uid}} \
-H "Authorization: Bearer {{api_key}}" \
GET https://api-sandbox.onlinebetaalplatform.nl/v1/transactions/{{transaction_uid}}
Example response:
{
"uid": "{{transaction_uid}}",
"object": "transaction",
"created": 1625572951,
"updated": 1625572951,
"completed": null,
"merchant_uid": "{{merchant_uid}}",
"profile_uid": "{{profile_uid}}",
"buyer_uid": "{{buyer_uid}}",
"has_checkout": false,
"payment_method": "mandate",
"payment_flow": "direct",
"payment_details": {
"reference": "ABC383849",
"code": null,
"message": null
},
"amount": 2525,
"return_url": "https://platform.example.com/return/",
"redirect_url": null,
"notify_url": "http://test.com/notify",
"status": "created",
"metadata": [],
"statuses": [
{
"uid": "sta_b25e511f5657",
"object": "status",
"created": 1625572951,
"updated": 1625572951,
"status": "created"
}
],
"order": [],
"escrow": {},
"fees": {},
"refunds": {}
}
Example request - Retrieve all mandate transactions from a specific mandate:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/mandates/{{mandate_uid}}/transactions \
-H "Authorization: Bearer {{api_key}}" \
GET https://api-sandbox.onlinebetaalplatform.nl/v1/mandates/{{mandate_uid}}/transactions
Example response:
{
"object": "list",
"url": "/v1/mandates/man_b785cbea0d6d/transactions",
"has_more": false,
"total_item_count": 2,
"items_per_page": 10,
"current_page": 1,
"last_page": 1,
"data": [
{
"uid": "{{transaction_uid}}",
"object": "transaction",
"created": 1625572951,
"updated": 1625572951,
"completed": null,
"merchant_uid": "{{merchant_uid}}",
"profile_uid": "{{profile_uid}}",
"buyer_uid": "{{buyer_uid}}",
"has_checkout": false,
"payment_method": "mandate",
"payment_flow": "direct",
"payment_details": {
"reference": "ABC383849",
"code": null,
"message": null
},
"amount": 2525,
"return_url": "https://platform.example.com/return/",
"redirect_url": null,
"notify_url": "http://test.com/notify",
"status": "created",
"metadata": [],
"statuses": [
{
"uid": "sta_b25e511f5657",
"object": "status",
"created": 1625572951,
"updated": 1625572951,
"status": "created"
}
],
"order": [],
"escrow": {},
"fees": {},
"refunds": {}
},
...
]
}
You can retrieve an individual transaction as well as a list of all transactions from one mandate. You can always retrieve all transactions using the Transaction API. The following filters can be used when retrieving transactions:
Filter name | Description |
status | Shows transactions with a specific status. |
refund | Shows the transaction belonging to a refund_uid. |
payment_method | Shows the transactions with a specific payment_method. |
merchant | Shows the transactions belonging to a specific merchant. |
date_completed | Only in extended filter. Shows the transactions within a specific completed date. |
When expanding certain objects, they will appear when requested. Objects that do not have any CRUD functionality, but are either set by OPP or only set when creating the transaction can be found in the Transaction API.
Update Mandate Transaction
Example request - Update transaction:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/transactions/{{transaction_uid}} \
-H "Authorization: Bearer {{api_key}}"
-d "notify_url=https://platform.com/notify"
POST https://api-sandbox.onlinebetaalplatform.nl/v1/transactions/{{transaction_uid}}
{
{
"notify_url": "https://platform.com/notify"
}
}
Example response:
{
"uid": "{{transaction_uid}}",
"object": "transaction",
"created": 1613741183,
"updated": 1613741183,
"completed": null,
"merchant_uid": "{{merchant_uid}}",
"profile_uid": "{{profile_uid}}",
"buyer_uid": "{{buyer_uid}}",
"has_checkout": false,
"payment_method": mandate,
"payment_flow": "direct",
"payment_details": [],
"amount": 250,
"return_url": "https://platform.example.com/return/",
"redirect_url": null,
"notify_url": "https://platform.example.com/notify/",
"status": "reserved",
"metadata": [
{
"key": "external_id",
"value": "2015486"
}
],
"statuses": [
{
"uid": "sta_8basda43bd54",
"object": "status",
"created": 1613741183,
"updated": 1613741183,
"status": "created"
},
{
"uid": "sta_f9926sehg5y",
"object": "status",
"created": 1613741183,
"updated": 1613741183,
"status": "pending"
},
{
"uid": "sta_8b03f99bbd54",
"object": "status",
"created": 1613741183,
"updated": 1613741183,
"status": "reserved"
}
],
"order": [],
"escrow": {},
"fees": {},
"refunds": {}
}
You are able to update a mandate transaction by performing a POST on the transaction. You can update one variable at a time, or multiple as you desire.
The following fields can be updated:
Variable | Description |
notify_url string | Notification url to receive status updates up to 255 characters Only possible when transaction has one of the following statuses: created pending planned reserved completed refunded |
escrow_date string | Escrow end datetime format: YYYY-MM-DD HH:MM:SS |
Delete Mandate Transaction
It is not possible to delete a mandate transaction.
Sandbox Simulation - Mandate Transaction
Use the following amounts to trigger transaction statuses on sandbox mode.
Amount | Status |
101 | created |
201 | pending |
301 | expired |
401 | cancelled |
501 | completed |
601 | chargeback |
701 | failed |
801 | refunded |
901 | reserved |
any other amount | created |
Mandate Multi Transaction
Mandate Multi transactions allow you to handle multiple transactions, for different merchants or different cases, in one API call. For example when you would like to combine transactions and let the user pay them at once.
Object Definition - Mandate Multi Transaction
The Mandate Multi Transaction object is very similar to the normal Multi Transactions Object and contains the following variables.
Variables | Description |
uid string | Transaction unique identifier. up to 20 characters |
object string | Value: multi_transaction |
created timestamp | Timestamp when transaction is created. |
updated timestamp | Timestamp when transaction is updated. |
completed timestamp | Timestamp when transaction is completed. |
merchant_uid string | The partner merchant, owner of the multi transaction container. |
payment_method string | Value: mandate |
payment_details array | See Payment details |
description string | Description of the multi-transaction. |
amount integer | Transaction amount in cents. |
return_url string | Return url not available for Mandate Transactions. |
redirect_url string | Value: null |
notify_url string | Notification url to receive status updates. up to 255 characters |
status string | Single-field representation of the last updated status value one of: createdpendingcompleted |
metadata array | Set of key / value pairs to store additional data. nullable |
statuses array | Current and previous transaction statuses. |
fees object | The specifications of the fees. Same as Multi transaction fees. See Multi transaction fees. |
transactions array | The list of transactions that are within the multi transaction. See Mandate Transactions object. |
Mandate Multi Transaction Status
The mandate multi transaction status is a status indication about the multi transaction in the OPP system. According to this status, you should handle the flow on your platform accordingly.
The possible status flows can be found below:
Status | Explanation |
created | Transaction is created, no action has taken place yet. |
pending | User has opened the redirect_url, OPP is awaiting final state from the issuer. |
completed | Transaction is successfully completed and settled in order to payout. |
Create Mandate Multi Transaction
Example request - Create mandate multi transaction:
curl https://api-sandbox.onlinebetaalplatform.nl/v1/mandates/{{mandate_uid}}/multi_transactions \
-H "Authorization: Bearer {{api_key}}"
-d reference=ABC1234 \
-d description=ABC1234 \
-d token={{token}} \
-d total_price=5000 \
-d notify_url=https://platform.example.com/notify/ \
-d transactions[0][merchant_uid]={{merchant_uid}} \
-d transactions[0][total_price]=2500 \
-d transactions[0][partner_fee]=100 \
-d transactions[0][products][0][name]=Product A \
-d transactions[0][products][0][quantity]=1 \
-d transactions[0][products][0][price]=2500 \
-d transactions[0][notify_url]=https://platform.example.com/notify/ \
-d transactions[1][merchant_uid]={{merchant_uid}} \
-d transactions[1][total_price]=2500 \
-d transactions[1][partner_fee]=100 \
-d transactions[1][products][0][name]=Product A \
-d transactions[1][products][0][quantity]=1 \
-d transactions[1][products][0][price]=2500 \
-d transactions[0][notify_url]=https://platform.example.com/notify/
POST https://api-sandbox.onlinebetaalplatform.nl/v1/mandates/{{mandate_uid}}/multi_transactions
{
"reference"
"total_price": 5000,
"transactions": [
{
"merchant_uid": "{{merchant_uid}}",
"total_price": 2500,
"partner_fee": 100,
"products": [
{
"name": "Product A",
"quantity": 1,
"price": 2500
}
],
"notify_url": "https://platform.example.com/notify/"
},
{
"merchant_uid": "{{merchant_uid}}",
"total_price": 2500,
"partner_fee": 100,
"products": [
{
"name": "Product B",
"quantity": 1,
"price": 2500
}
],
"notify_url": "https://platform.example.com/notify/"
}
],
"return_url": "https://platform.example.com/return/",
"notify_url": "https://platform.example.com/notify/"
}
Example response:
{
"livemode": false,
"uid": "{{multi_transaction_uid}}",
"object": "multi_transaction",
"created": 1625662045,
"updated": 1625662045,
"completed": null,
"merchant_uid": "{{merchant_uid}}",
"payment_method": "mandate",
"payment_details": null,
"description": "ABC1234",
"amount": 5000,
"return_url": "https://platform.example.com/return/",
"redirect_url": null,
"notify_url": "https://platform.example.com/notify/",
"status": "created",
"metadata": [],
"statuses": [
{
"uid": "mts_3ed4774457f2",
"object": "status",
"created": 1625662045,
"updated": 1625662045,
"status": "created"
},
{
"uid": "mts_9ec5fb50969e",
"object": "status",
"created": 1625662045,
"updated": 1625662045,
"status": "pending"
},
{
"uid": "mts_f9ed9a84a5cd",
"object": "status",
"created": 1625662046,
"updated": 1625662046,
"status": "completed"
}
],
"fees": {},
"transactions": [
{
"uid": "{{transaction_uid}}",
"object": "transaction",
"created": 1625662045,
"updated": 1625662046,
"completed": 1625662046,
"merchant_uid": "{{merchant_uid}}",
"profile_uid": "{{profile_uid}}",
"buyer_uid": "{{buyer_uid}}",
"has_checkout": false,
"payment_method": "multi",
"payment_flow": "direct",
"payment_details"