NAV
cURL json
Questions

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:
  • 25% of the shares or exercising voting rights
  • effective control of the company or organization
  • 25% or more beneficiary rights on the capital
  • special control of 25% or more on the capital
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:

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:

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

Merchant account / profile requirements

Besides the above required functionality, we highly recommend to also implement the following, in order to reduce questions and support load:

Partner backoffice requirements

Transactions requirements

Mandates requirements (if applicable)

Production key

Your production key will be provided to you once the following actions have taken place or files have been delivered:

Production environment

In order to use the production environment successfully, please whitelist the IP's:

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:

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) : Combination of the method and path
  • host : Host value
  • date : Date in standard http request date according to RFC 7231
  • digest : Combination of hash algorithm name and hash of the request body
The message used to create the signature will look like this:
        (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:

  1. Parse the HTTP Signature header and extract the relevant components, including the key ID, signature algorithm, and signature value.
  2. Retrieve the notification secret associated with the key ID from a trusted source, such as a key server or a configuration file.
  3. Calculate the expected signature value for the message using the same signature algorithm and input data as the sender.
  4. Compare the expected signature value with the signature value included in the HTTP Signature header.
  5. 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:

  1. 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.
  2. 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.
  3. 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.

  1. 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.
  2. 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.
  3. 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.

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:

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.

name
string

Trading name.

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.

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 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:

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:

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:

account_iban
string

International bank account number.
nullable,
up to 34 characters

account_name
string

Account holder's name.

Bank object Contains:

bic
string

Bank identifier code.
nullable,
up to 20 characters

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:

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.

emailaddress
email

E-mailaddress details of the contact.

phonenumbers array Array of phonenumbers[#][phonenumber]=value pair.

phonenumber
phonenumber

Phone number details of the contact.

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.
initials string, optional Initials of the contact,
up to 10 characters, nullable
Required if type=representative
first string, optional First name of the contact,
up to 50 characters, nullable
Required if type=representative
last string, optional Last name of the contact,
up to 50 characters, nullable
Required if type=representative
names_given string, optional All given names of the contact,
up to 50 characters, nullable
Required if type=representative
emailaddresses array, optional Array of emailaddresses[#][emailaddress]=value pair.

emailaddress
email

E-mailaddress details of the contact.

phonenumbers array, optional Array of phonenumbers[#][phonenumber]=value pair.

phonenumber
phonenumber

Phone number details of the contact.

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.
name_initials string, optional Initials of the contact,
up to 10 characters, nullable
Required if type=representative
name_first string, optional First name of the contact,
up to 50 characters, nullable
Required if type=representative
name_last string, optional Last name of the contact,
up to 50 characters, nullable
Required if type=representative
names_given string, optional Last name of the contact,
up to 50 characters, nullable
Required if type=representative
emailaddresses array, optional Array of emailaddresses[#][emailaddress]=value pair.

emailaddress
email

E-mailaddress details of the contact.

phonenumbers array, optional Array of phonenumbers[#][phonenumber]=value pair.

phonenumber
phonenumber

Phone number details of the contact.

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:

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:

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:

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.

type
string

The requirement type.

object_uid
string

Unique identifier of the object the requirement applies to.

object_type
string

Object type the requirement applies to.

object_url
string

API resource url of the object the requirement applies to.

object_redirect_url
string

The merchant is directed to this url, to fulfil the required actions.

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:

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:

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.

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.

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.

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.

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

address_line_1
optional

Street name of the buyer.
up to 45 characters

housenumber
optional

House number of the buyer.
up to 10 characters

housenumber_addition
optional

Addition to the house number of the buyer.
up to 10 characters

zipcode
optional

Zip code for the address of the buyer.
between 3 and 9 characters

city
optional

City of the address of the buyer.
up to 45 characters

country
optional

Country code of the address of the buyer,
use ISO 3166-1 alpha-3 country code

products required Products to be added to the payment page,
array of one or more products objects

name
required

Product name,
up to 150 characters

ean
optional

Product EAN code (European Article Number),
up to 13 characters

code
optional

Product code,
up to 50 characters

quantity
required

Number, number of products,
maximum: 65535

price
required

Product price in cents,
minimum: 0 - maximum: 99999999

vat_rate
optional

Value added tax rate.
between 0 and 100 (%)

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}}
- Online Payments Foundation -

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

address_line_1
optional

Street name of the buyer.
up to 45 characters

housenumber
optional

House number of the buyer.
up to 10 characters

housenumber_addition
optional

Addition to the house number of the buyer.
up to 10 characters

zipcode
optional

Zip code for the address of the buyer.
between 3 and 9 characters

city
optional

City of the address of the buyer.
up to 45 characters

country
optional

Country code of the address of the buyer,
use ISO 3166-1 alpha-3 country code

products required Products to be added to the payment page,
array of one or more products objects

name
required

Product name,
up to 150 characters

ean
optional

Product EAN code (European Article Number),
up to 13 characters

code
optional

Product code,
up to 50 characters

quantity
required

Number, number of products,
maximum: 65535

price
required

Product price in cents,
minimum: 0 - maximum: 99999999

vat_rate
optional

Value added tax rate.
between 0 and 100 (%)

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:

  1. Create the Multi Transaction Import. OPP Returns a Multi Transaction Import object.
  2. Processing. OPP will process the Multi Transaction Import in the background (asynchronous).
  3. 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

address_line_1
optional

Street name of the buyer.
up to 45 characters

housenumber
optional

House number of the buyer.
up to 10 characters

housenumber_addition
optional

Addition to the house number of the buyer.
up to 10 characters

zipcode
optional

Zip code for the address of the buyer.
between 3 and 9 characters

city
optional

City of the address of the buyer.
up to 45 characters

country
optional

Country code of the address of the buyer,
use ISO 3166-1 alpha-3 country code

products required Products to be added to the payment page,
array of one or more products objects

name
required

Product name,
up to 150 characters

ean
optional

Product EAN code (European Article Number),
up to 13 characters

code
optional

Product code,
up to 50 characters

quantity
required

Number, number of products,
maximum: 65535

price
required

Product price in cents,
minimum: 0 - maximum: 99999999

vat_rate
optional

Value added tax rate.
between 0 and 100 (%)

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}}
- Online Payments Foundation -

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}}
- Online Payments Foundation -

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.

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.

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.

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

name
string

Product name,
up to 150 characters

quantity
integer

Number of products,
maximum: 65535

price
integer

Product price in cents,
minimum: 0 - maximum: 99999999

total_amount
integer

Sum of product price * product quantity, in cents,
minimum: 0 - maximum: 99999999

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.

name
string

Recipient name.

type
string

Way of receiving the payment link.

email
string

Recipient email.

reply_to_email
string

Reply to email address.

date_sent
datetime

Date and time payment link email was sent.

metadata array Set of key / value pairs to store additional data.
nullable

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.

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.

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

name
required

Product name,
up to 150 characters

quantity
required

Number, number of products,
maximum: 65535

price
required

Product price in cents,
minimum: 0 - maximum: 99999999

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.

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.

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

name
string

Product name,
up to 150 characters

quantity
integer

Number, number of products,
maximum: 65535

price
integer

Product price in cents,
minimum: 0 - maximum: 99999999

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

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

emailaddress
optional

E-mail address of the customer.
up to 100 characters

phonenumber
optional

Phone number of the customer.
up to 20 characters

gender
optional

Gender, one of:
mmale
ffemale
otherother

name_first
optional

First name of the customer.
up to 45 characters

name_prefix
optional

Prefix in front of last name of the customer.
up to 45 characters

name_last
optional

Last name of the customer.
up to 45 characters

street
optional

Street name for the address of the customer.
up to 100 characters

housenumber
optional

House number for the address of the customer.
numeric

housenumber_addition
optional

Addition to the house number of the customer.
up to 10 characters

zipcode
optional

Zip code for the address of the customer.
up to 10 characters

city
optional

City of the address of the customer.
up to 100 characters

state
optional

State of the address of the customer.
up to 45 characters

country
optional

Country code of the customer.
use ISO 3166-1 alpha-3 country code

company_name
optional

Name of the company.
up to 100 characters

bank_iban
optional

Account holder's IBAN. Required if mandate_method = import,
only available when creating a new mandate.

bank_bic
optional

Account holder's BIC. Required if mandate_method = import,
only available when creating a new mandate.

bank_name
optional

Account holder's name. Required if mandate_method = import,
only available when creating a new mandate.

products optional Array of one or more products objects.
required when mandate_method = payment or form

name
conditional

Product name.
Required if mandate_method = payment
up to 150 characters

ean
optional

Product EAN code (European Article Number).
up to 13 characters

code
optional

Product code.
up to 50 characters

price
conditional

Product price in cents.
Required if mandate_method = payment
maximum: 99999999

quantity
conditional

Number of products.
Required if mandate_method = payment
maximum: 65535

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

key
required

Unique key within metadata object.
up to 255 characters

key
required

Corresponding value.
up to 65535 characters

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.
name string Customer's account holder name
iban string IBAN of the customer
bic string BIC code of the customer's issuer

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

name
required

Product name,
up to 150 characters

ean
optional

Product EAN code (European Article Number),
up to 13 characters

code
optional

Product code,
up to 50 characters

quantity
required

Number, number of products,
maximum: 65535

price
required

Product price in cents,
minimum: 0 - maximum: 99999999

vat_rate
optional

Value added tax rate.
between 0 and 100 (%)

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"