![]() |
温柔的桔子 · 启动dolphinScheduler时出现一 ...· 3 月前 · |
![]() |
温文尔雅的领带 · [3D动画]同人动漫 松本乱菊 媚黑侍奉 ...· 4 月前 · |
![]() |
大气的梨子 · 购买 Live、Push、Max for ...· 4 月前 · |
![]() |
纯真的饭卡 · hivesql ...· 4 月前 · |
![]() |
才高八斗的酱肘子 · Elliptic curve ...· 6 月前 · |
Online Payment Platform (OPP) is an end-to-end payment solution with a set of flexible API's designed to support platforms and marketplaces. Allowing a platform to seamlessly onboard new business and consumer merchants enabling them to accept payments on the platform while processing the money in flexible ways to sellers and service providers.
Usecases:This guides consist of the following chapters:
Before we start, have a look at our terminology , to make sure you understand every word we say.
For each receiver of the money, the partner (platform) is required to create a merchant within OPP. A merchant can be a business or a consumer. Depending on the type of merchant, these have to go through different verifications before they can receive money. It is important to note that transactions can be initiated for a merchant before they are required to finalize any verifications, but it is up to you whether you want to provide this possibility.
These verifications are required for processing payments because as a Payment Service Provider we are obliged to know to whom payments are made. For example to prevent money laundering and the financing of terrorism.
Merchants can be created using our Seamless Merchant onboarding. Seamless onboarding allows you to onboard merchants (business or consumer) seamlessly from within your platform environment through API onboarding.
As a partner you can simply create an underlying merchant using the minimal requirements: their
emailaddress
and
phonenumber
.
Once a new merchant has been created you will receive a Merchant UID which is the unique identifier for this user. You will need to save the Merchant UID and use it to, amongst other things, create transactions for this merchant.
After creating a merchant, it is immediately possible to start a transaction. Transactions can be created and successfully paid to a merchant of whom only the e-mail address has been verified. However funds cannot be paid out to the merchant until they have successfully finished the onboarding process and its compliance requirements.
Every user who sells a product or service and is earning money while doing this, needs to be onboarded as a merchant. This can either be a business, or consumer. We will seperate both flows, because a business merchant requires more additional information than a consumer merchant does. Creating and onboarding merchants can be done using our Merchant API .
For onboarding a consumer merchant we offer a tiered verification process (Low KYC and High KYC). Low KYC means that only a verified bank account is needed in order to be able to receive payouts. The standard thresholds for Low KYC merchants are € 250,- in one transaction or € 1.500,- in lifetime volume. If one of these thresholds is reached the consumer is required to identify him- or herself before payouts can be reactivated. The threshold can be adjusted based on the risk profile and assessment of the platform or marketplace.
As soon as a merchant is created, you can start doing transactions. As a partner, you are in charge of when the merchant fulfills the verification requirements. In many cases the partner wants the merchant to perform the least number of actions as possible in the beginning, but in some cases the partner may wish to force the consumer to perform all KYC steps before transactions can be started. Both options are possible, and completely up to you.
The four steps of consumer merchant creation are:
bank_account
.
The example request allows you to create a consumer merchant.
The minimal required fields are:
country
,
emailaddress
,
phone
and
notify_url
.
The emailaddress is our unique identifier. You cannot create multiple merchants with the same email address.
Please note that the
phonenumber
is not required by the API. You are free to leave this out when creating the merchant, but the merchant will need to provide the phonenumber in a later stage. See
5. Fulfill other requirements.
The
notify_url
is the webhook URL used by OPP for notifications of status changes.
As a partner you will receive the Merchant Object with
compliance.level
100
as a response.
Please note, in case you decided together with your Implementation manager on a different compliance level when creating merchants, this might differ for you.
The merchant object contains three fields that you will need to save in your database:
merchant_uid
- The Merchant UID, this is the unique identifier of the created merchant.
status
- The merchant account status.
compliance.status
- The compliance status of the merchant. This status will define whether the merchant will be able to receive payouts.
Ofcourse, other values can be saved in your database as well, if that is preferred by you. However, these three values are important for the flows in your platform.
After the creation of the merchant, it is immediately possible as a partner to create transactions for this merchant. The funds of the paid transactions cannot (yet) be paid out because the merchant does not yet have a linked bank account.
With this request you can create an 'empty' bank account for the merchant.
This 'empty' bank account serves as a container that needs to be filled with verified bank account information.
The bank account is created with a status of
new
and needs to be verified by the merchant.
As soon as a bank account has been created for the merchant, the
compliance.level
of the merchant will immediately be increased to
200
.
You will receive the
merchant.compliance_level.changed
notification of this change on the merchant's specified
notify_url
.
Because the level has been increased, you can now also find the
bank_acount.verification.required
within the
compliance.requirements
. The
verification_url
that can be found in the response of the
bank_account
object is the same URL that is detailed in the compliance requirement.
Redirect the merchant to the
verification_url
.
Optionally, you can save the UID and
verification_url
in your database.
In the previous step we created an 'empty' bank account for the consumer merchant. To verify the bank account, we can follow five routes:
In all cases OPP will send a notification right after the verification took place. The compliance requirement
bank_account.verification.required
and the bank
account status will be
pending
until OPP has performed a compliance check.
You can find the overview_url in the merchant compliance object. Find the overview_url in the compliance object within the merchant and redirect the user to this url.
"uid": "{{merchant_uid}}", "object": "merchant", "compliance": { "level": 200, "status": "unverified", "overview_url": "https://sandbox.onlinebetaalplatform.nl/en/{{partner_slug}}/{{merchant_uid}}/15c0bdb17283475ec5f274cad0a2a0245dda11ff/overview", "requirements": [ "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/{{partner_name}}/merchants/{{merchant_uid}}/verificatie/bankgegevens/{{bank_account_uid}}/7a8d3c308b0739ef96320720017d070533912548"An example of this url can be found below.
You can find the
verification_url
in two places: the
bank_account
object, and the merchant
compliance.requirements
.
Find the verification_url and redirect the merchant to this link to verify the bank account.
"uid": "{{bank_account_uid}}", "object": "bank_account", "created": 1554200096, "updated": 1554200096, "verified": null "verification_url": "https://onlinebetaalplatform.nl/nl/{{partner_name}}/merchants/{{merchant_uid}}/verificatie/bankgegevens/{{bank_account_uid}}/7a8d3c308b0739ef96320720017d070533912548", "status": "new",Find the requirement with type bank_account.verification.required and redirect the merchant to the object_redirect_url .
"uid": "{{merchant_uid}}", "object": "merchant", "compliance": { "level": 200, "status": "unverified", "overview_url": "https://sandbox.onlinebetaalplatform.nl/en/{{partner_slug}}/{{merchant_uid}}/15c0bdb17283475ec5f274cad0a2a0245dda11ff/overview", "requirements": [ 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/{{partner_name}}/merchants/{{merchant_uid}}/verificatie/bankgegevens/{{bank_account_uid}}/7a8d3c308b0739ef96320720017d070533912548"An example of this url can be found below.
In case of Belgium and The Netherlands, we provide a direct link with Bancontact and iDEAL, providing a seamless integration, so that merchants do not see our bank verification screen.
To do this, first find the
verification_url
by using one of the methods in 3.2.
After that, append additional parameters to the url. Then redirect the user to the new url.
If you wish to create a seamless and smoother user experience while making sure the merchants upload their files without you having to process any sensitive data, then you can rely on the Files API to send us all documents necessary to do the KYC. This consists out of two steps.
Please note that using the Files API requires configuration on the side of OPP, and will not function correctly without. Always notify your Implementation Manager when you want to use the Files API. Please also note that the bank_account status will only update to
pending
when both the file and the account data have been filled.
Make sure that you provide
account_name
,
account_iban
and
account_bic
when you
create a bank account
You first need to send a POST request to the Files upload endpoint and specify in the parameters the purpose of the file, ‘bank_account_bank_statement’ and provide the UID for which the upload is to be used.
POST https://files-sandbox.onlinebetaalplatform.nl/v1/uploads "purpose": "bank_account_bank_statement", "merchant_uid": "{{merchant_uid}}", "object_uid": "{{bank_account_uid}}"That leads to the following 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}}"
In order to finish the operation, you need to send the file via a POST request to the endpoint https://api-sandbox.onlinebetaalplatform.nl/v1/{{file_uid}}.
In the headers of this request, you need to provide the token you previously stored in the field
x-opp-files-token
and the file in a FILE parameter.
OPP also supports the ability to verify a merchant's bank account when the merchant itself completes a transaction to another merchant.
This can for example be used to perform buyer onboarding, when the buyer will be a seller at the platform as well. Another case is when you as a platform want to have a dynamic onboarding fee, that differs per merchant. In that case, the
{{seller_merchant_uid}}
will be your platform merchant.
If the merchant does not yet exist,
create a merchant
and an
'empty' bank account
for this merchant first. This allows you to set the right
notify_url
and other details. Do note that you do not have to redirect merchant to the bank_account
verification_url
. You may pass this new merchant's uid as a parameter to the
Create Transaction API
call using parameter
verification_merchant_uid
to verify the bank account via this transaction.
The bank account will stay in a
new
state if this transaction is not successfully completed and will change to state
pending
if transaction is successfully completed, just like the regular bank account verification flow.
The compliance team of OPP checks all new or updated verifications within 24 hours on working days and will either approve or disapprove the verification. Notifications are sent as soon as OPP has approved or disapproved the bank account.
"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}}" "uid": "{{notification_uid}}", "type": "bank_account.status.changed", "created": 1619182670, "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}}" The bank account information has been approved and has received the status
approved
. The compliance requirement
bank_account.verification.required
has received the status
verified
and will no longer be visible within the
merchant.compliance.requirements
.
If the merchant has no other
unverified
or
pending
compliance.requirements
, then merchant's
compliance.status
shall be updated from
pending
to
verified
. This change in status will also be sent by the
following notification
merchant.compliance_status.changed
.
disapproved
. The compliance requirement
bank_account.verification.required
has received the status
unverified
.
Merchant is required to verify its bank details again, see step 3.1.
If the merchant's
compliance.status
was
pending
, this will be changed to
unverified
. This change in status will also be sent
by the following notification
merchant.compliance_status.changed
.
Retrieve the new status after the notification was sent, and adjust this status in your database.
As a partner, you are free to decide at what moment in time you would like your merchants to complete their identity verification. We distinguish two different paths to do this:
In both cases, identification provided must contain the same name as the bank account holder name.
As long as the merchant has not yet reached a compliance level of 400, the identity verification is not obliged by OPP.
In case you would want to already fulfill the contact verification, you can do so by using the
verification_url
in the
merchant.contact
object.
After verification, the merchant will be updated, and the platform will receive the notifications that go with these updates. The compliance level will raise to 400 only when the ID verification gets verified. When you upload the ID card, and the contact status is pending, the compliance level will remain 200. Also when we disapprove the ID verification, the compliance level will remain 200.
An example of the verification url can be found below.
Once the compliance.level of the merchant has reached 400, identity verification is required. There are four ways to provide OPP this identity. You can
verification_url
as used in 4.1.
object_redirect_url
.
You can find the
overview_url
in the merchant
compliance
object. Find the
overview_url
in the compliance object within the merchant and redirect the user to this url.
OPP will send a notification immediately after the identification took place. The
compliance.requirement
contact.verification.required
and the contact status will be
pending
until OPP performed a compliance check.
An example of this url can be found below.
Within the Merchant Object you will find the compliance requirement
contact.verification.required
.
Find the
object_redirect_url
and redirect the merchant to this url to identify him/herself.
Note that this is the same url as the
verification_url
of 4.1.
OPP will send a notification immediately after the identification took place. The
compliance.requirement
contact.verification.required
and the contact status will be
pending
until OPP performed a compliance check.
You can skip the whitelabel screens and immediately redirect the user to a local identification method if this is available in your country. Doing this requires three steps:
object_redirect_url
or
verification_url
as mentioned earlier.
If you wish to create a seamless and smoother user experience while making sure the merchants upload their files without you having to process any sensitive data, then you can rely on the Files API to send us all documents necessary to do the KYC. This consists out of two steps.
Please note that using the Files API requires configuration on the side of OPP, and will not function correctly without. Always notify your Implementation Manager when you want to use the Files API.You first need to send a POST request to the Files upload endpoint and specify in the parameters the purpose of the file, ‘representative_passport’ and provide the UID for which the upload is to be used.
POST https://files-sandbox.onlinebetaalplatform.nl/v1/uploads "purpose": "representative_passport", "merchant_uid": "{{merchant_uid}}", "object_uid": "{{contact_uid}}"That leads to the following response: "uid": "{{file_uid}}", "created": "1606003200", "updated": "1606003200", "expired": "1606004100", "merchant_uid": "{{merchant_uid}}", "object_uid": "{{contact_uid}}", "purpose": "representative_passport", "token": "{{token}}", "url": "https://files-sandbox.onlinebetaalplatform.nl/v1/uploads/{{file_uid}}"
In order to finish the operation, you need to send the file via a POST request to the endpoint https://api-sandbox.onlinebetaalplatform.nl/v1/{{file_uid}}.
In the headers of this request, you need to provide the token you previously stored in the field
x-opp-files-token
and the file in a FILE parameter.
OPP will send a notification immediately after the identification took place. The
compliance.requirement
contact.verification.required
and the contact status will be
pending
until OPP performed a compliance check.
The compliance team of OPP checks all new or updated verifications within 24 hours on working days and will either approve or disapprove the verification. Notifications are sent as soon as OPP has approved or disapproved the identification.
Approved: The identification has been approved and has received the status
verified
. The compliance requirement
contact.verification.required
has been updated with the status
verified
and is no longer visible within the
merchant.compliance.requirements
.
If the merchant has no other
unverified
or
pending
compliance.requirements
, merchant's
compliance.status
will be updated from
pending
to
verified
. This change in status will
also be sent by the following notification
merchant.compliance_status.changed
.
unverified
. The compliance requirement
contact.verification.required
has been updated with the status
unverified
. The merchant is required to identify itself again, see step 1.
If the merchant's
compliance.status
was
pending
, this will be updated to
unverified
. This change in status will also be sent by the
following notification
merchant.compliance_status.changed
.
A business merchant might have several other compliance requirements to fulfill:
Once the merchant is created, you will find the
contact.phonenumber.required
requirement. OPP needs to have a phonenumber that belongs to the merchant. We are legally bound to have a verified phonenumber and email address from 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.
For phone number verification, OPP provides the choice to do it yourself, or let us do the phonenumber verification.
If you prefer to do verification yourself, you can choose to do this at the very beginning, before creating a merchant at our side, or when the merchant already exists. In the compliance requirements, find the object_redirect_url and redirect the representative of the business to this url. If you would prefer a seamless solution, you can do this by performing a POST on the contact object as can be seen on the right. Once the phonenumber is filled in, the merchant will be updated and the notifications will be send.
POST https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/contacts/{{contact_uid}} \ "phonenumbers": [ "phonenumber": "0612345678"
In case you want OPP to do the verification, 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 phonenumber to be verified.
A text message will be send to the phonenumber, which needs to be filled in to verify the phonenumber.
The requirement will then disappear.
As a partner you can create a business merchant using the 5 steps described below. A business merchant must always complete the High KYC.
As soon as a merchant is created, you can start doing transactions. As a partner, you are in charge of when the merchant fulfills the verification requirements. In many cases the partner wants the merchant to perform the least number of actions as possible in the beginning, but in some cases the partner may wish to force the business to perform all KYC steps before transactions can be started. Both options are possible, and completely up to you.
The five steps of business merchant creation are:
bank_account
.
With the example request shown below you can create a business merchant. As a partner you will receive the Merchant Object with
compliance.level
400
as a response.
The minimal required fields are:
coc_nr
,
type
,
country
,
emailaddress
,
phone
and
notify_url
.
The emailaddress is our unique identifier. You cannot create multiple merchants with the same email address.
Please note that the
phonenumber
is not required by the API. You are free to leave this out when creating the merchant, but the merchant will need to provide the phonenumber in a later stage. See
5. Fulfill other requirements.
The
notify_url
is the webhook URL used by OPP for notifications of status changes.
Within the Merchant Object you will also find the Merchant UID, this is the unique identifier of the created merchant and as a partner you will need to save the Merchant UID and use it to, amongst other things, create transactions for this merchant. It is therefore required to store the Merchant UID within your own application.
The merchant object contains three fields that you will need to save in your database:
merchant_uid
- The Merchant UID, this is the unique identifier of the created merchant.
status
- The merchant account status.
compliance.status
- The compliance status of the merchant. This status will define whether the merchant will be able to receive payouts.
Ofcourse, other values can be saved in your database as well, if that is preferred by you. These three values are important for the flows in your platform.
After the creation of the merchant, it is immediately possible as a partner to create transactions for this merchant. The funds of the paid transactions cannot (yet) be paid out because the merchant still has outstanding compliance requirements.
Initializing a merchant will trigger some initial notifications from out the system.
There is no necessaty to follow up these notifications, but it does allow you to send an initial email towards the merchant about their outstanding compliance requirements.
With this request you can create an 'empty' bank account for the merchant.
This 'empty' bank account serves as a container that needs to be filled with verified bank account information.
The bank account is created with a status of
new
and needs to be verified by the merchant.
Now that the required bank account has been created, you will receive a notification with type
merchant.compliance_requirement.status.changed
.
The compliance requirement
bank_account.required
is set to verified, and is being replaced by
bank_account.verification.required
The
verification_url
that can be found in the response of the
bank_account
object is the same URL that is detailed in the compliance requirement.
Redirect the merchant to the
verification_url
.
Optionally, you can save the UID and
verification_url
in your database.
In the previous step we created an 'empty' bank account for the business merchant. To verify the bank account, we can follow four routes:
In all cases OPP will send a notification right after the verification took place. The compliance requirement
bank_account.verification.required
and the bank
account status will be
pending
until OPP has performed a compliance check.
You can find the overview_url in the merchant compliance object. Find the overview_url in the compliance object within the merchant and redirect the user to this url.
"uid": "{{merchant_uid}}", "object": "merchant", "compliance": { "level": 400, "status": "unverified", "overview_url": "https://sandbox.onlinebetaalplatform.nl/en/{{partner_slug}}/{{merchant_uid}}/15c0bdb17283475ec5f274cad0a2a0245dda11ff/overview", "requirements": [ "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/{{partner_name}}/merchants/{{merchant_uid}}/verificatie/bankgegevens/{{bank_account_uid}}/7a8d3c308b0739ef96320720017d070533912548"An example of this url can be found below.
You can find the
verification_url
in two places: the
bank_account
object, and the merchant
compliance.requirements
.
Find the verification_url and redirect the merchant to this link to verify the bank account.
"uid": "{{bank_account_uid}}", "object": "bank_account", "created": 1554200096, "updated": 1554200096, "verified": null "verification_url": "https://onlinebetaalplatform.nl/nl/{{partner_name}}/merchants/{{merchant_uid}}/verificatie/bankgegevens/{{bank_account_uid}}/7a8d3c308b0739ef96320720017d070533912548", "status": "new",Find the requirement with type bank_account.verification.required and redirect the merchant to the object_redirect_url .
"uid": "{{merchant_uid}}", "object": "merchant", "compliance": { "level": 200, "status": "unverified", "overview_url": "https://sandbox.onlinebetaalplatform.nl/en/{{partner_slug}}/{{merchant_uid}}/15c0bdb17283475ec5f274cad0a2a0245dda11ff/overview", "requirements": [ 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/{{partner_name}}/merchants/{{merchant_uid}}/verificatie/bankgegevens/{{bank_account_uid}}/7a8d3c308b0739ef96320720017d070533912548"An example of this url can be found below.
In case of Belgium and The Netherlands, we provide a direct link with Bancontact and iDEAL, providing a seamless integration, so that merchants do not see our bank verification screen.
To do this, first find the
verification_url
by using on of the methods in 3.1.
After that, append additional parameters to the url. Then redirect the user to the new url.
If you wish to create a seamless and smoother user experience while making sure the merchants upload their files without you having to process any sensitive data, then you can rely on the Files API to send us all documents necessary to do the KYC. This consists out of two steps.
Please note that using the Files API requires configuration on the side of OPP, and will not function correctly without. Always notify your Implementation Manager when you want to use the Files API. Please also note that the bank_account status will only update to
pending
when both the file and the account data have been filled.
Make sure that you provide
account_name
,
account_iban
and
account_bic
when you
create a bank account
You first need to send a POST request to the Files upload endpoint and specify in the parameters the purpose of the file, ‘bank_account_bank_statement’ and provide the UID for which the upload is to be used.
POST https://files-sandbox.onlinebetaalplatform.nl/v1/uploads "purpose": "bank_account_bank_statement", "merchant_uid": "{{merchant_uid}}", "object_uid": "{{bank_account_uid}}"That leads to the following 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}}"
In order to finish the operation, you need to send the file via a POST request to the endpoint https://api-sandbox.onlinebetaalplatform.nl/v1/{{file_uid}}.
In the headers of this request, you need to provide the token you previously stored in the field
x-opp-files-token
and the file in a FILE parameter.
OPP also supports the ability to verify a merchant's bank account when the merchant itself completes a transaction to another merchant.
This can for example be used to perform buyer onboarding, when the buyer will be a seller at the platform as well. Another case is when you as a platform want to have a dynamic onboarding fee, that differs per merchant. In that case, the
{{seller_merchant_uid}}
will be your platform merchant.
If the merchant does not yet exist,
create a merchant
and an
'empty' bank account
for this merchant first. This allows you to set the right
notify_url
and other details. Do note that you do not have to redirect merchant to the bank_account
verification_url
. You may pass this new merchant's uid as a parameter to the
Create Transaction API
call using parameter
verification_merchant_uid
to verify the bank account via this transaction.
The bank account will stay in a
new
state if this transaction is not successfully completed and will change to state
pending
if transaction is successfully completed, just like the regular bank account verification flow.
The compliance team of OPP checks all new or updated verifications within 24 hours on working days and will either approve or disapprove the verification. Notifications are sent as soon as OPP has approved or disapproved the bank account.
Approved: The bank account information has been approved and has received the status
approved
. The compliance requirement
bank_account.verification.required
has received the status
verified
and will no longer be visible within the
merchant.compliance.requirements
.
If the merchant has no other
unverified
or
pending
compliance.requirements
, then merchant's
compliance.status
shall be updated from
pending
to
verified
. This change in status will also be sent by the
following notification
merchant.compliance_status.changed
.
disapproved
. The compliance requirement
bank_account.verification.required
has received the status
unverified
.
Merchant is required to verify its bank details again, see step 3.1.
If the merchant's
compliance.status
was
pending
, this will be changed to
unverified
. This change in status will also be sent
by the following notification
merchant.compliance_status.changed
.
Within the Merchant Object you will find the compliance requirement contact.verification.required . The representative of the business is required to identify him or herself.
There are three ways to provide OPP this identity. You can
verification_url
.
object_redirect_url
.
In case you would want to fulfill the contact verification using the contact object, you can do so by using the
verification_url
in the
merchant.contact
object.
After verification, the merchant will be updated, and the platform will receive the notifications that go with these updates.
An example of the verification url can be found below.
You can find the
overview_url
in the merchant
compliance
object. Find the
overview_url
in the compliance object within the merchant and redirect the user to this url.
OPP will send a notification immediately after the identification took place. The
compliance.requirement
contact.verification.required
and the contact status will be
pending
until OPP performed a compliance check.
An example of this url can be found below.
Within the Merchant Object you will find the compliance requirement
contact.verification.required
.
Find the
object_redirect_url
and redirect the merchant to this url to identify him/herself.
Note that this is the same url as the
verification_url
of 4.1.
OPP will send a notification immediately after the identification took place. The
compliance.requirement
contact.verification.required
and the contact status will be
pending
until OPP performed a compliance check.
You can skip the whitelabel screens and immediately redirect the user to a local identification method if this is available in your country. Doing this requires three steps:
object_redirect_url
or
verification_url
as mentioned earlier.
If you wish to create a seamless and smoother user experience while making sure the merchants upload their files without you having to process any sensitive data, then you can rely on the Files API to send us all documents necessary to do the KYC. This consists out of two steps.
Please note that using the Files API requires configuration on the side of OPP, and will not function correctly without. Always notify your Implementation Manager when you want to use the Files API.You first need to send a POST request to the Files upload endpoint and specify in the parameters the purpose of the file, ‘representative_passport’ and provide the UID for which the upload is to be used.
POST https://files-sandbox.onlinebetaalplatform.nl/v1/uploads "purpose": "representative_passport", "merchant_uid": "{{merchant_uid}}", "object_uid": "{{contact_uid}}"That leads to the following response: "uid": "{{file_uid}}", "created": "1606003200", "updated": "1606003200", "expired": "1606004100", "merchant_uid": "{{merchant_uid}}", "object_uid": "{{contact_uid}}", "purpose": "representative_passport", "token": "{{token}}", "url": "https://files-sandbox.onlinebetaalplatform.nl/v1/uploads/{{file_uid}}"
In order to finish the operation, you need to send the file via a POST request to the endpoint https://api-sandbox.onlinebetaalplatform.nl/v1/{{file_uid}}.
In the headers of this request, you need to provide the token you previously stored in the field
x-opp-files-token
and the file in a FILE parameter.
OPP will send a notification immediately after the identification took place. The
compliance.requirement
contact.verification.required
and the contact status will be
pending
until OPP performed a compliance check.
The compliance team of OPP checks all new or updated verifications within 24 hours on working days and will either approve or disapprove the verification. Notifications are sent as soon as OPP has approved or disapproved the identification.
Approved: The identification has been approved and has received the status
verified
. The compliance requirement
contact.verification.required
has been updated with the status
verified
and is no longer visible within the
merchant.compliance.requirements
.
If the merchant has no other
unverified
or
pending
compliance.requirements
, merchant's
compliance.status
will be updated from
pending
to
verified
. This change in status will
also be sent by the following notification
merchant.compliance_status.changed
.
unverified
. The compliance requirement
contact.verification.required
has been updated with the status
unverified
. The merchant is required to identify itself again, see step 1.
If the merchant's
compliance.status
was
pending
, this will be updated to
unverified
. This change in status will also be sent by the
following notification
merchant.compliance_status.changed
.
A business merchant might have several other compliance requirements to fulfill:
Once the business merchant is created, you will find the
contact.phonenumber.required
requirement. OPP needs to have a phonenumber that belongs to the representative who verified in step 4. We are legally bound to have a verified phonenumber and email address from 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.
For phone number verification, OPP provides the choice to do it yourself, or let us do the phonenumber verification.
If you prefer to do verification yourself, you can choose to do this at the very beginning, before creating a merchant at our side, or when the merchant already exists. In the compliance requirements, find the object_redirect_url and redirect the representative of the business to this url. If you would prefer a seamless solution, you can do this by performing a POST on the contact object as can be seen on the right. Once the phonenumber is filled in, the merchant will be updated and the notifications will be send.
POST https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/contacts/{{contact_uid}} \ "phonenumbers": [ "phonenumber": "0612345678"
In case you want OPP to do the verification, 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 phonenumber to be verified.
A text message will be send to the phonenumber, which needs to be filled in to verify the phonenumber.
The requirement will then disappear.
OPP is obliged to trace all Ultimate Beneficial Owners (UBO) of a business entity. Legal business entities such as a B.V., GmbH or BVBA may have more than one UBO. When checking the business verifications, OPP determines whether the UBO verification is required. This verification is therefore never directly required when creating the merchant.
As a partner, you can either choose to already provide us with the UBO information, or wait for the requirement to arrive. If our compliance department finds an UBO that has not registered yet, the compliance requirement
ubo.required
will be triggered.
You can then choose to seamlessly provide the UBO information as described in the
documentation
, or redirect the merchant to the
object_redirect_url
to fulfill the requirement.
An example of the redirect url can be found below:
Now that the required UBO has been created, you will receive a notification with type
merchant.compliance_requirement.status.changed
.
The compliance requirement
ubo.required
is set to verified, and is being replaced by
ubo.verification.required
, which has status
pending
as all information has just been provided.
OPP will send the following notifications when the UBO verification is required:
The compliance team of OPP checks all new or updated verifications within 72 hours on working days and will either approve or disapprove the verification. Notifications are sent as soon as OPP has approved or disapproved the identification.
In case our compliance department is unable to retrieve the chamber of commerce extract from our registers, you might be required to deliver this to us.
In that case, you will find the
coc_extract.required
type of requirement in your compliance requirements.
There are three ways to fulfill this requirement:
Redirect the merchant to the
object_redirect_url
to fulfill this requirement.
An example of the url can be found below:
The chamber of commerce extract can also be uploaded using our Files API as follows. If you wish to create a seamless and smoother user experience while making sure the merchants upload their files without you having to process any sensitive data, then you can rely on the Files API to send us all documents necessary to do the KYC. This consists out of two steps.
Please note that using the Files API requires configuration on the side of OPP, and will not function correctly without. Always notify your Implementation Manager when you want to use the Files API.You first need to send a POST request to the Files upload endpoint and specify in the parameters the purpose of the file, ‘coc_extract’ and provide the UID for which the upload is to be used.
POST https://files-sandbox.onlinebetaalplatform.nl/v1/uploads "purpose": "coc_extract", "merchant_uid": "{{merchant_uid}}", "object_uid": "{{merchant_uid}}"That leads to the following response: "uid": "{{file_uid}}", "created": "1606003200", "updated": "1606003200", "expired": "1606004100", "merchant_uid": "{{merchant_uid}}", "object_uid": "{{merchant_uid}}", "purpose": "coc_extract", "token": "{{token}}", "url": "https://files-sandbox.onlinebetaalplatform.nl/v1/uploads/{{file_uid}}"
In order to finish the operation, you need to send the file via a POST request to the endpoint https://api-sandbox.onlinebetaalplatform.nl/v1/{{file_uid}}.
In the headers of this request, you need to provide the token you previously stored in the field
x-opp-files-token
and the file in a FILE parameter.
In case our compliance department is unable to create an organization structure, e.g. because parts are unknown by the Chamber of Commerce, you might be required to deliver this to us.
In that case, you will find the
organization_structure.required
type of requirement in your compliance requirements.
There are three ways to fulfill this requirement:
object_redirect_url
to fulfill this requirement.
"uid": "{{merchant_uid}}",
"object": "merchant",
"compliance": {
"level": 400,
"status": "unverified",
"requirements": [
"type": "organization_structure.required",
"status": "unverified",
"object_type": null,
"object_uid": null,
"object_url": null,
"object_redirect_url": "https://sandbox.onlinebetaalplatform.nl/en/{{partner_name}}/merchants/{{merchant_uid}}/verifications/organization-structure/feabfd98b2a9d246a6e33742f92af061059b9f81"
An example of the url can be found below:
The organization structure can also be uploaded using our Files API as follows. If you wish to create a seamless and smoother user experience while making sure the merchants upload their files without you having to process any sensitive data, then you can rely on the Files API to send us all documents necessary to do the KYC. This consists out of two steps.
Please note that using the Files API requires configuration on the side of OPP, and will not function correctly without. Always notify your Implementation Manager when you want to use the Files API.You first need to send a POST request to the Files upload endpoint and specify in the parameters the purpose of the file, ‘coc_extract’ and provide the UID for which the upload is to be used.
POST https://files-sandbox.onlinebetaalplatform.nl/v1/uploads "purpose": "organization_structure", "merchant_uid": "{{merchant_uid}}", "object_uid": "{{merchant_uid}}"That leads to the following response: "uid": "{{file_uid}}", "created": "1606003200", "updated": "1606003200", "expired": "1606004100", "merchant_uid": "{{merchant_uid}}", "object_uid": "{{merchant_uid}}", "purpose": "organization_structure", "token": "{{token}}", "url": "https://files-sandbox.onlinebetaalplatform.nl/v1/uploads/{{file_uid}}"
In order to finish the operation, you need to send the file via a POST request to the endpoint https://api-sandbox.onlinebetaalplatform.nl/v1/{{file_uid}}.
In the headers of this request, you need to provide the token you previously stored in the field
x-opp-files-token
and the file in a FILE parameter.
Occasionally, merchants would like to change their IBAN for payouts, because of many reasons. Research has shown us that many partners get these questions, and forward them to the OPP support team. You can create a button to change the IBAN account for payouts as follows.
Please note that whenever a new bank_account is created, the old bank_account cannot be used for payouts anymore. In case the merchant has second thoughts, and does want the first bank_account for payouts, (s)he will have to verify it again.
Step 1: Check whether the merchant has a bank_account with status
new
First, we must find out whether the merchant already has a bank_account that can be filled. This is an important step, to keep your, and our database free of noise. Besides that, every time a new bank_account is created, the old bank_account will not be used for payouts anymore. This means that eventually, the merchant could not have a connected IBAN at all, if we do not keep track.
Find the merchant bank_accounts, and filter the status
new
by using the following call:
Step 2.1: Merchant already has an outstanding bank_account
Get the bank_account with status
new
, and redirect the user to the
verification_url
.
After the merchant has gone through the process, you will receive a notification with type
bank_account.status.changed
. The status is now
pending
.
After our compliance department has checked the new bank_account, you will again receive a notification with type
bank_account.status.changed
.
This can either be
approved
, or
disapproved
. When approved, the bank_account will be used for payouts.
Step 2.2: Merchant has no outstanding bank_account
Create a new bank_account, as described
in the Docs
. Then redirect the user to the
verification_url
.
After the merchant has gone through the process, you will receive a notification with type
bank_account.status.changed
. The status is now
pending
.
After our compliance department has checked the new bank_account, you will again receive a notification with type
bank_account.status.changed
.
This can either be
approved
, or
disapproved
. When approved, the bank_account will be used for payouts.
A merchant can be a consumer or a business entity and each has its own set of KYC (Know Your Customer) compliance requirements. OPP is obliged to do this KYC check, to see if the consumer or business has been in touch with illegal activities, like money laundering or finance of terrorism, or other frauds.
The merchant object contains the ‘compliance’ object. This object contains details on the merchant's current compliance level (1) , compliance status (2) and lists the compliance requirements (3) the merchant should meet to get a verified compliance status. An unverified compliance status results in not being able to receive payouts.
Receive the merchant object using this call:
GET https://api.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}
The compliance levels determine which compliance requirements the merchant should meet.
Once the partner creates a bank account object for the merchant, the compliance level of the merchant is updated to 200. OPP will review the bank account information provided and once approved the merchant can receive payouts of the money on the bank account. Thresholds: the standard thresholds for Level 200 merchants are € 250,- in one transaction or € 1.500,- in lifetime volume. After which the merchant is required to identify itself before payouts can be reactivated. This threshold can be adjusted based on the risk profile and assessment of the platform or marketplace. If the merchant passes the threshold the compliance level is updated to 400 and is obliged to confirm his or her identity. The merchant can do this by uploading an identity document or by performing a local identification method (such as iDIN or itsme). 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. OPP is currently reviewing the merchant's updated ‘compliance requirements’. Verified Merchant compliance status is verified and the merchant is able to receive payouts.The flow below illustrates how the Merchant status and the Merchant Compliance Status change over the course of the onboarding process. It additionally shows when you as a Partner need to take action as a consequence of the merchant providing insufficient documents and when the merchant will need to take action.
Each compliance requirement states the compliance requirement type and details of the related object. A merchant can be redirect to object_redirect_url in order to get to the whitelabel OPP page where the required actions will be explained and can be finalized. It is also possible to provide your own redirect URL and seamlessly integrate these compliance requirement steps.
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 No verified phonenumber available, while at least one is required. 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! ) Compliance found that an UBO is required, and will trigger the option to verify. ubo.verification.required ( BUSINESS ONLY! ) The merchant has to fill / verify all UBO’s.When certain thresholds are met or transaction monitoring raises a flag, our compliance team can trigger a source of funds requirement. The source of funds requirement allows us to do research to where the amount of money came from. Most often, this will be used in Donation or Crowdfunding solutions.
When this is triggered, you will see the
source_of_funds.required
requirement in the merchant compliance object.
To verify the source of funds, we can follow three routes:
In all cases OPP will send a notification right after the verification took place.
The compliance requirement
source_of_funds.required
status will be
pending
until OPP has performed a compliance check.
You can find the overview_url in the merchant compliance object. Find the overview_url in the compliance object within the merchant and redirect the user to this url.
"uid": "{{merchant_uid}}", "object": "merchant", "compliance": { "level": 400, "status": "unverified", "overview_url": "https://sandbox.onlinebetaalplatform.nl/en/{{partner_slug}}/{{merchant_uid}}/15c0bdb17283475ec5f274cad0a2a0245dda11ff/overview", "requirements": [ "type": "source_of_funds.required", "status": "unverified", "object_type": "source_of_fund", "object_uid": "{{sof_uid}}", "object_url": null, "object_redirect_url": "https://sandbox.onlinebetaalplatform.nl/en/{{partner_slug}}/merchants/{{merchant_uid}}/verifications/source-of-funds/{{sof_uid}}/5fa9a435b8b66267aaddb2db48dfe9a74b7e544f"An example of this url can be found below.
You can find the
object_redirect_url
in the merchant
compliance.requirements
.
Find the requirement with type
source_of_funds.required
and redirect the merchant to the
object_redirect_url
.
An example of this url can be found below.
If you wish to create a seamless and smoother user experience while making sure the merchants upload their files without you having to process any sensitive data, then you can rely on the Files API to send us all documents necessary to do the KYC. This consists out of two steps.
The source of funds can have several purposes. Decide which one you are using before uploading the file.
You first need to send a POST request to the Files upload endpoint and specify in the parameters the purpose of the file and provide the UID for which the upload is to be used.
POST https://files-sandbox.onlinebetaalplatform.nl/v1/uploads "purpose": "source_of_fund_savings", "merchant_uid": "{{merchant_uid}}", "object_uid": "{{merchant_uid}}"That leads to the following response: "uid": "{{file_uid}}", "created": "1606003200", "updated": "1606003200", "expired": "1606004100", "merchant_uid": "{{merchant_uid}}", "object_uid": "{{merchant_uid}}", "purpose": "source_of_fund_savings", "token": "{{token}}", "url": "https://files-sandbox.onlinebetaalplatform.nl/v1/uploads/{{file_uid}}"
In order to finish the operation, you need to send the file via a POST request to the endpoint https://api-sandbox.onlinebetaalplatform.nl/v1/{{file_uid}}.
In the headers of this request, you need to provide the token you previously stored in the field
x-opp-files-token
and the file in a FILE parameter.
A transaction needs to be created whenever a service or product is sold. Transactions are created using the Transaction API . Transactions can be created as soon as a merchant_uid is known.
OPP provides a few different types of flows. You can choose between having a direct payment or email transaction flow, using the OPP whitelabel pages or use the seamless integration with the issuer. These different flows and using different payment methods are explained below with example requests and responses.
As soon as a merchant is created, you can start doing transactions.
Please note that payouts of transactions only take place when the merchant's
compliance.status
=
verified
and the
merchant.status
=
live
.
Creating a transaction consists of three steps
There are two possible flows here:
1.1. Use the payment screen of OPP.
You do not need to provide any additional fields in your request in order to use our payment screen.
The
redirect_url
will show you an overview of the payment methods available for your platform, except for direct debit transactions.
1.2. Redirect the user to the acquirer.
You can redirect the user directly to the acquirer if preferred. In that case, the user will not reach to the OPP screen. The
redirect_url
will immediately forward the user to the page of the acquirer.
In order to do so, you will need to add the following fields to the request:
payment_method
- One of the possible payment methods for your platform. See
Payment Methods
Some payment methods need more information before redirecting to the acquirer. In that case the user will first be redirected to the pages of OPP to provide that information. All other payment methods, except the given payment method, will not be visible.
The minimal required fields to create a transaction are:
merchant_uid
,
products
,
total_price
,
return_url
and
notify_url
.
The
notify_url
is the webhook URL used by OPP for notifications of status changes.
The
return_url
is the URL to which the user will be redirected after the payment. We suggest to use the same page in all cases and handle the result as a listener on that page.
To create a single transaction, you can use the following example.
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"
After creating the transaction you will receive a response containing the
transaction_uid
. The status of the transaction is now
created
.
The transaction object contains two fields that you will need to save in your database:
transaction_uid
- The Transaction UID, this is the unique identifier of the created transaction.
status
- The transaction status.
Ofcourse, other values can be saved in your database as well, if that is preferred by you. These two values are important for the flows in your platform.
Now that you have created the transaction, you need to redirect the user in order to pay the transaction.
Make sure to do this as soon as possible, as each transaction has an expiration time of 15 minutes.
If the user has not finished the payment within this time, the transaction will expire. The transaction status will then be
expired
, and you will receive a
transaction.status.changed
notification.
After this, a new transaction needs to be created.
After creating a transaction, the user needs to be redirected to the
redirect_url
.
An example of the OPP
redirect_url
can be found below.
Once the user clicks the
redirect_url
and is redirected to either our pages or that of the acquirer, the status of the transaction will become
pending
.
As soon as the user is redirected to the
redirect_url
, you will receive a
transaction.status.changed
notification.
If the user has not finished the payment within this time, the transaction will expire and a new transaction needs to be created.
The transaction status will then be
expired
, and you will again receive a
transaction.status.changed
notification.
After a (un)successful payment, or cancellation, the user will always be redirected to the
return_url
.
pending
state for 15 minutes.
Now that the user has been redirected to the payment page, we need to handle the result.
In all cases, the user will always be redirected back to the
return_url
.
We suggest to use the same page in all cases and handle the result as a listener on that page.
Best practise is to use a screen which shows a loader and a text like:
You're payment is being processed.
As soon as we have a result from the issuer, we will send a
transaction.status.changed
notification to your
notify_url
. According to the status that you retrieve afterwards, you should show the user a page with the correct status.
There are a couple of statuses possible in this scenario:
cancelled
- The user has manually cancelled the payment, perhaps because the chosen payment method was not desired. You should ask the user to try again, and create a new transaction.
failed
- The payment has failed, for example because the user did not enter correct issuer credentials, there was not enough funds, or there was a technical error during the payment. You should ask the user to try again, and create a new transaction.
expired
- The user has not managed to complete the payment within the set time. You should ask the user to try again, and create a new transaction.
completed
- The user has succesfully paid the order. You should show a success page and lead the user further on in the process of your platform.
For all statuses, please have a look at our documentation.
transaction_uid
and the bank statement. Our finance department will then refund the transaction to the user.
OPP provides the option to put money in escrow. By doing this, you can somewhat give a guaranteed feeling to buyer and seller and in the meantime have more control over when the money is released to the 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.
1.1. Use the payment screen of OPP.
You do not need to provide any additional fields in your request in order to use our payment screen.
The
redirect_url
will show you an overview of the payment methods available for your platform, except for direct debit transactions.
1.2. Redirect the user to the acquirer.
You can redirect the user directly to the acquirer if preferred. In that case, the user will not reach to the OPP screen. The
redirect_url
will immediately forward the user to the page of the acquirer.
In order to do so, you will need to add the following fields to the request:
payment_method
- One of the possible payment methods for your platform. See
Payment Methods
Some payment methods need more information before redirecting to the acquirer. In that case the user will first be redirected to the pages of OPP to provide that information. All other payment methods, except the given payment method, will not be visible.
The minimal required fields to create a transaction are:
merchant_uid
,
products
,
total_price
,
return_url
and
notify_url
.
The
notify_url
is the webhook URL used by OPP for notifications of status changes.
The
return_url
is the URL to which the user will be redirected after the payment. We suggest to use the same page in all cases and handle the result as a listener on that page.
Now, to actually use the escrow, you can choose to use one out of two options:
escrow = true
combined with
escrow_period
escrow = true
combined with
escrow_date
To create a single transaction with esvrow, you can use the following example.
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, "escrow: true", "escrow_period: 14", "metadata": "external_id": "2015486"
After creating the transaction you will receive a response containing the
transaction_uid
. The status of the transaction is now
created
.
The transaction object contains two fields that you will need to save in your database:
transaction_uid
- The Transaction UID, this is the unique identifier of the created transaction.
status
- The transaction status.
Ofcourse, other values can be saved in your database as well, if that is preferred by you. These two values are important for the flows in your platform.
Now that you have created the transaction, you need to redirect the user in order to pay the transaction.
Make sure to do this as soon as possible, as each transaction has an expiration time of 15 minutes.
If the user has not finished the payment within this time, the transaction will expire. The transaction status will then be
expired
, and you will receive a
transaction.status.changed
notification.
After this, a new transaction needs to be created.
After creating a transaction, the user needs to be redirected to the
redirect_url
.
An example of the OPP
redirect_url
can be found below.
Once the user clicks the
redirect_url
and is redirected to either our pages or that of the acquirer, the status of the transaction will become
pending
.
As soon as the user is redirected to the
redirect_url
, you will receive a
transaction.status.changed
notification.
If the user has not finished the payment within this time, the transaction will expire and a new transaction needs to be created.
The transaction status will then be
expired
, and you will again receive a
transaction.status.changed
notification.
After a (un)successful payment, or cancellation, the user will always be redirected to the
return_url
.
pending
state for 15 minutes.
Now that the user has been redirected to the payment page, we need to handle the result.
In all cases, the user will always be redirected back to the
return_url
.
We suggest to use the same page in all cases and handle the result as a listener on that page.
Best practise is to use a screen which shows a loader and a text like:
You're payment is being processed.
As soon as we have a result from the issuer, we will send a
transaction.status.changed
notification to your
notify_url
. According to the status that you retrieve afterwards, you should show the user a page with the correct status.
There are a couple of statuses possible in this scenario:
cancelled
- The user has manually cancelled the payment, perhaps because the chosen payment method was not desired. You should ask the user to try again, and create a new transaction.
failed
- The payment has failed, for example because the user did not enter correct issuer credentials, there was not enough funds, or there was a technical error during the payment. You should ask the user to try again, and create a new transaction.
expired
- The user has not managed to complete the payment within the set time. You should ask the user to try again, and create a new transaction.
planned
/
reserved
- The user has succesfully paid the order. You should show a success page and lead the user further on in the process of your platform.
For all statuses, please have a look at our documentation.
transaction_uid
and the bank statement. Our finance department will then refund the transaction to the user.
Normally, the funds are automatically released when the
escrow_period
or
escrow_date
ends.
In case you want to manually end the escrow, for example when the product was delivered to and accepted by the buyer, you can do so by updating the
escrow_date
to any time between the creation date and now.
You will receive a notification
transaction.status.changed
. The transaction will now have status completed, and be settled on the settlement of the merchant.
Once the transaction is out of escrow, the
partner_fee
will become available and the transaction costs for this transaction will be charged.
In case you want to extend the current escrow period, because for example a dispute is created, you can do so by updating the
escrow_date
to any time in the future that suites your needs. Our advise would be to extend it no longer then three months.
Please note that the standard maximum escrow period is 365 days. In case you need a longer period of time, please contact your Implementation Manager.
As soon as a merchant is created, you can start doing transactions.
Please note that payouts of transactions only take place when the merchant's
compliance.status
=
verified
and the
merchant.status
=
live
.
The minimal required fields to create a transaction are:
merchant_uid
,
products
,
total_price
,
return_url
and
notify_url
.
When using SEPA bank transfer as your payment method, make sure to add this to your request.
payment_method
=
sepa
The
notify_url
is the webhook URL used by OPP for notifications of status changes.
The
return_url
is the URL to which the user will be redirected after the payment. We suggest to use the same page in all cases and handle the result as a listener on that page.
To create a single transaction, you can use the following example.
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, "payment_method": "sepa", "metadata": "external_id": "2015486"
After creating the transaction you will receive a response containing the
transaction_uid
. The status of the transaction is now
created
.
The transaction object contains two fields that you will need to save in your database:
transaction_uid
- The Transaction UID, this is the unique identifier of the created transaction.
status
- The transaction status.
Ofcourse, other values can be saved in your database as well, if that is preferred by you. These two values are important for the flows in your platform.
Now that you have created the transaction, you can either redirect the user in order to show the transaction details, or show them on your platform.
Keep in mind that the user needs to pay before the transaction expires. SEPA transactions expire after 7 days by default, but this can be extanded using
date_expired
in the request.
If the user has not finished the payment within this time, the transaction will expire. The transaction status will then be
expired
, and you will receive a
transaction.status.changed
notification.
After this, a new transaction needs to be created.
After creating a transaction, you can choose two flows:
redirect_url
of OPP to see the payment details.
An example of the OPP
redirect_url
can be found below.
When clicking either "Cancel transaction" or "To {{partner}}" , the user will always be redirected to the
return_url
.
In the response of the the transaction, you will find the payment_details . This shows the details that need to be used in order to do the bank transfer.
"livemode": false, "uid": "{{transaction_uid}}", "object": "transaction", "created": 1625233235, "updated": 1625233235, "completed": null, "merchant_uid": "{{merchant_uid}}", "profile_uid": "{{profile_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": "QBF5ND", "expired": 1625349599 "amount": 250, "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": "created",Show these details to the user on your platform.
Now that the user has done the payment, we need to handle the result.
As soon as we received the funds, we will send a
transaction.status.changed
notification to your
notify_url
. According to the status that you retrieve afterwards, you should update the user and merchant accordingly.
There are a couple of statuses possible in this scenario:
expired
- The user has not managed to complete the payment within the set time. You should ask the user to try again, and create a new transaction.
completed
or
reserved
- The user has succesfully paid the order.
For all statuses, please have a look at our documentation.
In case a specific merchant is receiving funds in a periodic way, a fixed payment reference might come in handy.
Please note that payouts of transactions only take place when the merchant's
compliance.status
=
verified
and the
merchant.status
=
live
.
The minimal required fields to create a SEPA payment reference are:
merchant_uid
,
reference
and
notify_url
.
The
notify_url
is the webhook URL used by OPP for notifications of status changes.
To create a sepa payment reference, you can use the following example.
POST https://api-sandbox.onlinebetaalplatform.nl/v1/payment_references "merchant_uid": "{{merchant_uid}}", "code": "TEST0001", "notify_url": "https://platform.example.com/notify/"From this moment onwards, anyone can transfer funds towards the correct IBAN, using the payment reference created.
Now that the user has done the payment, we need to handle the result.
As soon as we received funds, we will send a
payment_reference.transaction.registered
notification to your
notify_url
. According to the that notification, you should update your database, and continue the flow towards the user and merchant.
Please note that OPP does not check whether the funds that were received actually are correct. It is up to the platform to check whether the amount is correct.
The transaction object has been created automatically from the registered funds. You can see the information of the transaction directly by performing a GET request towards the
object_url
.
The transaction object contains two fields that you will need to save in your database:
transaction_uid
- The Transaction UID, this is the unique identifier of the created transaction.
status
- The transaction status.
Ofcourse, other values can be saved in your database as well, if that is preferred by you. These two values are important for the flows in your platform.
Within OPP we define two types of refunds. Chargebacks, and refunds. A chargeback is a full refund that is being refunded before the money was settled towards the seller. A refund can either be partial or full and might already been paid out to the seller.
You can only create a refund for a transaction that has either status
planned
,
reserved
or
completed
.
You will need the
transaction_uid
that you saved in your database in order to perform the refund.
The minimal required fields to create a refund are:
amount
.
We always suggest to use a
payout_description
, to make sure the buyer knows what this refund belongs to.
To create a refund, you can use the following example.
POST https://api-sandbox.onlinebetaalplatform.nl/v1/transactions/{{transaction_uid}}/refunds "amount": 6750, "payout_description": "Invoice 2021012 not satisfied"
After creating the refund you will receive a response containing the
refund_uid
. The status of the refund is now
created
.
The refund object contains one field that you will need to save in your database:
refund_uid
- The Refund UID, this is the unique identifier of the created refund.
Ofcourse, other values can be saved in your database as well, if that is preferred by you. These two values are important for the flows in your platform.
Now that the refund is created, the transaction that you created this refund for, will get a status change.
"uid": "{{notification_uid}}", "type": "transaction.status.changed", "created": 1621944238, "object_uid": "{{transaction_uid}}", "object_type": "transaction", "object_url": "https://api-sandbox.onlinebetaalplatform.nl/v1/transactions/{{transaction_uid}}", "verification_hash": "f81fed5c48918d81aac3aaa07ac34c99e126685ff7e77b9fedca244c50255091"
The status will now either be
refunded
or
chargeback
.
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.
We currently have no specific notifications on the refund itself. We pay out refunds on a daily base. The moment the buyer has its money back depends on two variables:
Before you are able to create recurring payments, you will need to create a mandate. A mandate allows us as OPP to create a SEPA Direct Debits payment. Mandates are created using the Mandates API . Mandate transactions are created using the Mandate Transaction API . Mandates and transactions can be created as soon as a merchant_uid is known.
Recurring payments might be used for your subscription model in your platform. Please note that the use of recurring payments using SEPA Direct Debits is not without financial risk. Therefore, we will always ask you the following questions if you are willing to use this in your platform. Our compliance department will then review your application and see whether a deposit is needed to cover the risk.
As soon as a merchant is created, you can start doing transactions.
Please note that payouts of transactions only take place when the merchant's
compliance.status
=
verified
and the
merchant.status
=
live
.
First of all, you need to create a mandate. A mandate allows us as OPP to create a SEPA direct debit payment in name of the platform, and forward this towards either the platform or a merchant on your platform.
Creating a mandate consists of three steps
There are different mandate types, and mandate methods available. Below you will find an explanation, including their risk level.
Available Mandate Methods eMandate - Allow mandate by logging into your bank account (The Netherlands only)1.1. Use eMandate as mandate method
You can redirect the user directly to the acquirer if preferred. In that case, the user will not reach the OPP screen. The
redirect_url
will immediately forward the user to the page of the acquirer.
In order to do so, you will need to add the following fields to the request:
issuer
- Optional when the mandate method is emandate. If the issuer is left out, the user will first be redirected to the pages of OPP to select the issuer.
1.2. Use payment as mandate method
You can redirect the user directly to the acquirer if preferred. In that case, the user will not reach to the OPP screen. The
redirect_url
will immediately forward the user to the page of the acquirer.
In order to do so, you will need to add the following fields to the request:
payment_method
- One of the possible mandate payment methods for your platform. See
Mandate payment_method
mandate_amount
- Amount used for mandate verification transaction in cents. In case this amount is higher then the verification amount (10 cents), this will also count as the first payment to the merchant.
Some payment methods need more information before redirecting to the acquirer. In that case the user will first be redirected to the pages of OPP to provide that information. All other payment methods, except the given payment method, will not be visible.
1.3. Use form as mandate method
You do not need to provide any additional fields in your request in order to use our form screen.
1.2. Use import as mandate method
You will need to deliver the bank details to your request:
bank_iban
- Account holder's IBAN.
bank_bic
- Account holder's BIC.
bank_name
- Account holder's name.
The minimal required fields to create a mandate are:
merchant_uid
,
mandate_method
,
mandate_type
,
mandate_repeat
,
products
,
total_price
,
return_url
and
notify_url
.
The
notify_url
is the webhook URL used by OPP for notifications of status changes.
The
return_url
is the URL to which the user will be redirected after the mandate has completed or failed. We suggest to use the same page in all cases and handle the result as a listener on that page.
To create a mandate, you can use the following example.
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/"
After creating the mandate you will receive a response containing the
mandate_uid
. The status of the mandate is now
created
.
The mandate object contains three fields that you will need to save in your database:
mandate_uid
- The Mandate UID, this is the unique identifier of the created mandate.
token
- The Mandate token, this is the unique token belonging to this mandate and will become available on completing the mandate.
status
- The mandate status.
Ofcourse, other values can be saved in your database as well, if that is preferred by you. These three values are important for the flows in your platform.
Now that you have created the mandate, you need to redirect the user in order to complete the flow.
Make sure to do this as soon as possible, as each mandate has an expiration time of 30 minutes.
If the user has not finished the flow within this time, the mandate will expire. The mandate status will then be
expired
, and you will receive a
mandate.status.changed
notification.
After this, a new mandate needs to be created.
After creating a mandate, the user needs to be redirected to the
redirect_url
.
An example of the OPP
redirect_url
flow can be found below.
Once the user clicks the
redirect_url
and is redirected to either our pages or that of the acquirer, the status of the mandate will become
pending
.
As soon as the user is redirected to the
redirect_url
, you will receive a
mandate.status.changed
notification.
If the user has not finished the mandate flow within this time, the mandate will expire and a new mandate needs to be created.
The mandate status will then be
expired
, and you will again receive a
mandate.status.changed
notification.
After a (un)successful mandate flow, or cancellation, the user will always be redirected to the
return_url
.
pending
state for 30 minutes.
Now that the user has been redirected to the mandate page, we need to handle the result.
In all cases, the user will always be redirected back to the
return_url
.
We suggest to use the same page in all cases and handle the result as a listener on that page.
Best practise is to use a screen which shows a loader and a text like:
You're mandate is being processed.
As soon as we have a result from the acquirer or we know the flow was successful, we will send a
mandate.status.changed
notification to your
notify_url
. According to the status that you retrieve afterwards, you should show the user a page with the correct status.
There are a couple of statuses possible in this scenario:
cancelled
- The user has manually cancelled the flow, perhaps because the chosen payment method was not desired. You should ask the user to try again, and create a new mandate.
failed
- The mandate flow has failed, for example because the user did not enter correct issuer credentials, or there was a technical error during the flo. You should ask the user to try again, and create a new mandate.
expired
- The user has not managed to complete the flow within the set time. You should ask the user to try again, and create a new mandate.
completed
- The user has succesfully completed the mandate flow. You should show a success page and lead the user further on in the process of your platform.
NOTE:
The
token
has now become available. If you retrieve the mandate, don't forget to save the
token
as well.
For all statuses, please have a look at our documentation.
As soon as a mandate is completed, you can start doing transactions.
Creating a mandate transaction consists of three steps
The minimal required fields to create a mandate are:
merchant_uid
,
token
,
reference
,
total_price
and
notify_url
.
The
notify_url
is the webhook URL used by OPP for notifications of status changes.
The
reference
is the unique reference that belongs to this transaction. This reference should make sure that you never create a transaction for the same invoice twice.
To create a mandate, you can use the following example.
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/"
After creating the mandate transaction you will receive a response containing the
transaction_uid
. The status of the mandate transaction is now
created
.
The mandate transaction object contains two fields that you will need to save in your database:
transaction_uid
- The Transaction UID, this is the unique identifier of the created transaction.
status
- The transaction status.
Ofcourse, other values can be saved in your database as well, if that is preferred by you. These three values are important for the flows in your platform.
Now that you have created the mandate transaction, you will need to wait for OPP to process the mandate transaction and for the funds to arrive. Every mandate transaction somewhat follows the same timelines:
reserved
.
chargeback
.
reserved
until the agreed escrow period ends.
As soon as we have a result from the bank, we will send a
transaction.status.changed
notification to your
notify_url
. According to the status that you retrieve afterwards, you should show inform the user about this.
There are a couple of statuses possible in this scenario:
reserved
- The funds have been received by OPP. The escrow period that was agreed upon has started.
completed
- The escrow period ended and the funds have settled towards the settlement of the merchant.
chargeback
- The funds have been chargebacked by the bank within the escrow period. A reason code will be available in the transaction object.
refunded
- The funds have been chargebacked by the bank outside of the escrow period. A reason code will be available in the transaction object.
NOTE:
In case the funds were already paid out towards the merchant, we will subtract the funds from your deposit.
For all statuses, please have a look at our documentation.
In all cases, it is possible that chargebacks occur. Either by a payer not having enough funds available or due to one of the other reasons. Find all possible chargeback reasons here .
When a chargeback occurs, you as a platform will receive a
transaction.status.changed
notification to your
notify_url
.
You will then need to handle the result depending on the status:
If you receive a
chargeback
status, this means that the funds were refunded to the payer, while the money was still in escrow.
The funds will be refunded towards the payer without any concequences for the merchant or your platform deposit. You will however, need to create a new transaction to let the user pay again.
You can create a direct payment as a fallback method, using the Create Transaction .
If you receive a
refunded
status, this means that the funds were refunded to the payer, while the money was not in escrow and might already have been paid out towards the merchant.
The funds will be refunded towards the payer and you will need to create a new transaction to let the user pay again.
First, you will need to find out whether the funds where already paid out towards the merchant or not. You can find out whether it was already paid out, by looping through the current settlement and see if the transaction is in there.
GET https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/settlements?filter[status]=current&expand[]=specificationsIf that is the case, you will need to create the new transaction to top-up your deposit, otherwise, you can provide the receiver's merchant_uid.
You can create a direct payment as a fallback method, using the Create Transaction .
If however, you use recurring payments to facilitate your own platform subscriptions, you can skip this fallback method. In that case, you will receive less funds during your next payout.
OPP always puts money received by mandate transactions in escrow. By default, this is set to a value that was agreed upon with OPP Compliance department. As a partner, you are able to influence the escrow date or period by extending or shortening the date or period. By doing this, you can somewhat give a guaranteed feeling to buyer and seller and in the meantime have more control over when the money is released to the 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.
Creating a mandate transaction with escrow consists of three steps
The minimal required fields to create a mandate are:
merchant_uid
,
token
,
reference
,
total_price
and
notify_url
.
The
notify_url
is the webhook URL used by OPP for notifications of status changes.
The
reference
is the unique reference that belongs to this transaction. This reference should make sure that you never create a transaction for the same invoice twice.
To create a mandate, you can use the following example.
POST https://api-sandbox.onlinebetaalplatform.nl/v1/mandates/{{mandate_uid}}/transactions "merchant_uid": "{{merchant_uid}}", "reference": "ABC1234", "token": "{{mandate_token}}", "total_price": 2525, "escrow_period: 60", "notify_url": "https://platform.example.com/notify/"
After creating the mandate transaction you will receive a response containing the
transaction_uid
. The status of the mandate transaction is now
created
.
The mandate transaction object contains two fields that you will need to save in your database:
transaction_uid
- The Transaction UID, this is the unique identifier of the created transaction.
status
- The transaction status.
Ofcourse, other values can be saved in your database as well, if that is preferred by you. These three values are important for the flows in your platform.
Now that you have created the mandate transaction, you will need to wait for OPP to process the mandate transaction and for the funds to arrive. Every mandate transaction somewhat follows the same timelines:
reserved
.
chargeback
.
reserved
until the agreed escrow period ends.
As soon as we have a result from the bank, we will send a
transaction.status.changed
notification to your
notify_url
. According to the status that you retrieve afterwards, you should show inform the user about this.
There are a couple of statuses possible in this scenario:
reserved
- The funds have been received by OPP. The escrow period that was agreed upon has started.
completed
- The escrow period ended and the funds have settled towards the settlement of the merchant.
chargeback
- The funds have been chargebacked by the bank within the escrow period. A reason code will be available in the transaction object.
refunded
- The funds have been chargebacked by the bank outside of the escrow period. A reason code will be available in the transaction object.
NOTE:
In case the funds were already paid out towards the merchant, we will subtract the funds from your deposit.
For all statuses, please have a look at our documentation.
In all cases, it is possible that chargebacks occur. Either by a payer not having enough funds available or due to one of the other reasons. Find all possible chargeback reasons here .
When a chargeback occurs, you as a platform will receive a
transaction.status.changed
notification to your
notify_url
.
You will then need to handle the result depending on the status:
If you receive a
chargeback
status, this means that the funds were refunded to the payer, while the money was still in escrow.
The funds will be refunded towards the payer without any concequences for the merchant or your platform deposit. You will however, need to create a new transaction to let the user pay again.
You can create a direct payment as a fallback method, using the Create Transaction .
If you receive a
refunded
status, this means that the funds were refunded to the payer, while the money was not in escrow and might already have been paid out towards the merchant.
The funds will be refunded towards the payer and you will need to create a new transaction to let the user pay again.
First, you will need to find out whether the funds where already paid out towards the merchant or not. You can find out whether it was already paid out, by looping through the current settlement and see if the transaction is in there.
GET https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/settlements?filter[status]=current&expand[]=specificationsIf that is the case, you will need to create the new transaction to top-up your deposit, otherwise, you can provide the receiver's merchant_uid.
You can create a direct payment as a fallback method, using the Create Transaction .
If however, you use recurring payments to facilitate your own platform subscriptions, you can skip this fallback method. In that case, you will receive less funds during your next payout.
Normally, the funds are automatically released when the
escrow_period
or
escrow_date
ends.
In case you want to manually end the escrow, for example when the product was delivered to and accepted by the buyer, you can do so by updating the
escrow_date
to any time between the agreed minimum period and now.
You will receive a notification
transaction.status.changed
. The transaction will now have status completed, and be settled on the settlement of the merchant.
Once the transaction is out of escrow, the
partner_fee
will become available and the transaction costs for this transaction will be charged.
In case you want to extend the current escrow period, because for example a dispute is created, you can do so by updating the
escrow_date
to any time in the future that suites your needs. Our advise would be to extend it no longer then three months.
Please note that the standard maximum escrow period is 365 days. In case you need a longer period of time, please contact your Implementation Manager.
Every partner has their own wishes and demands of what a correct dashboard looks like and which information it should contain. Because of this reason, we always advise our partners to build an own dashboard for merchants and for yourself. This has two great benefits:
OPP always provides the possibility to use the dashboard created by OPP for you and your merchants, but experience teaches us that partners like the benefits and freedom of their own dashboard. The dashboard created by OPP is also built on our own APIs. Therefore, anything found in the dashboards of OPP can be retrieved via our APIs.
We distinguish three differences:
Besides all the information that your platform whishes to show on a profile page (like avatar, nickname, password management, etc), we advise you to take several of the OPP flows into consideration. We advise you to show the following on the merchant profile:
Merchant status
You can retrieve the merchant status of the merchant using the following call.
GET https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}The status that can be found in the response is the merchant account status. Different meanings of the merchant status can be found here. Please note that you should have saved the merchant status in your database , so a GET request should not be necessary every time a merchant reaches his/her profile page.
"uid": "{{merchant_uid}}", "object": "merchant", "created": 1554113700, "updated": 1554113700, "status": "live", "compliance": { "level": 400, "status": "unverified", "overview_url": "https://sandbox.onlinebetaalplatform.nl/en/{{partner_slug}}/{{merchant_uid}}/{{hash}}/overview", "requirements": [ "type": "contact.phonenumber.required", "status": "unverified", "object_type": "contact_phonenumber", "object_uid": null, "object_url": null, "object_redirect_url": "https://sandbox.onlinebetaalplatform.nl/en/{{partner_slug}}/merchants/{{merchant_uid}}/verifications/phonenumber-form/{{contact_uid}}/{{hash}}" "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/en/{{partner_slug}}/merchants/{{merchant_uid}}/verifications/contact-details/{{contact_uid}}/{{hash}}"Merchant Compliance
You can retrieve the merchant compliance status of the merchant by retrieving the merchant object.
The
compliance
object withing the merchant object contains a
status
. This is the merchant compliance status, and shows whether the merchant is compliant and allowed to receive payouts.
Different meanings of the merchant compliance status can be found
here.
Please note that you should have
saved the merchant compliance status in your database
, so a GET request should not be necessary every time a merchant reaches his/her profile page.
Merchant Compliance Requirements
In case the Merchant Compliance status is not
verified
, you should show the outstanding compliance requirements.
Retrieve the merchant object, and find the
compliance
object. Within this object, you will find the
requirements
array. All possible requirements can be found
here.
Once you have retrieved the merchant object, the merchant can then choose to fulfill outstanding using his/her
overview_url
, or by using the
object_redirect_url
in the outstanding requirement.
Current IBAN We strongly advise you to show the current IBAN that is used for payouts, so that merchants always see what bank account of theirs is connected to our platform. You can find the currently connected IBAN by retrieving the merchant's profile. Unless the merchant is a company that has multiple affiliates which need seperated payouts, a merchant will only have one profile.
Find the profile's bank_account, using
GET https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}?expand[]=profiles.bank_account
In the
profiles
object, find the first profile and find the
bank_account
object.
Within this object, you will find the
account
, which shows a masked
account_iban
and
account_name
.
These values are the current bank account details that are used for the merchant's payouts.
Change IBAN
Occasionally, merchants would like to change their IBAN for payouts, because of many reasons. Research has shown us that many partners get these questions, and forward them to the OPP support team. You can create a button to change the IBAN account for payouts as follows.
Please note that whenever a new bank_account is created, the old bank_account cannot be used for payouts anymore. In case the merchant has second thoughts, and does want the first bank_account for payouts, (s)he will have to verify it again.
Step 1: Check whether the merchant has a bank_account with status
new
First, we must find out whether the merchant already has a bank_account that can be filled. This is an important step, to keep your, and our database free of noise. Besides that, every time a new bank_account is created, the old bank_account will not be used for payouts anymore. This means that eventually, the merchant could not have a connected IBAN at all, if we do not keep track.
Find the merchant bank_accounts, and filter the status
new
by using the following call:
Step 2.1: Merchant already has an outstanding bank_account
Get the bank_account with status
new
, and redirect the user to the
verification_url
.
After the merchant has gone through the process, you will receive a notification with type
bank_account.status.changed
. The status is now
pending
.
After our compliance department has checked the new bank_account, you will again receive a notification with type
bank_account.status.changed
.
This can either be
approved
, or
disapproved
. When approved, the bank_account will be used for payouts.
Step 2.2: Merchant has no outstanding bank_account
Create a new bank_account, as described
in the Docs
. Then redirect the user to the
verification_url
.
After the merchant has gone through the process, you will receive a notification with type
bank_account.status.changed
. The status is now
pending
.
After our compliance department has checked the new bank_account, you will again receive a notification with type
bank_account.status.changed
.
This can either be
approved
, or
disapproved
. When approved, the bank_account will be used for payouts.
When providing payments on your platform, merchants would like to know what happens to their orders and payments, and what funds are available for payouts. In this chapter, we will guide you through providing all information that is required to build your own dashboard for the merchant. This dashboard consists of two parts:
In this guide, we assume that you have registered all
refund_uid’s
and
transaction_uid’s
in your database, in order to relate them to the correct bookings and other related data.
A settlement is the (current) balance of a merchant over a specific period of time. Settlement periods can be daily, weekly, or monthly. Every settlement has a specification for every profile a merchant has. Unless the merchant is a company with multiple affiliates which need seperated payouts, a merchant will only have one profile and thus one specification.
The current settlement can be found using: GET https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/settlements?filter[status]=current&expand[]=specifications
If the merchant has no current settlement, the server will respond with an empty list.
Every specification has its own
specification_uid
. The specification is build up the same way as a settlement is. In case you want to specify the dashboard per profile, it is important to look at the different specifications, instead of the complete settlement.
Important in this response is:
A response might look like this:
"object": "list", "url": "/v1/merchants/{{merchant_uid}}/settlements", "has_more": false, "total_item_count": 1, "items_per_page": 10, "current_page": 1, "last_page": 1, "data": [ "uid": "{{settlement_uid}}", "object": "settlement", "created": 1606307019, "updated": 1606307020, "status": "current", "paid": null, "period_start": 1606258800, "period_end": 1606345199, "total_number_of_transactions": 2, "number_of_transactions": 1, "number_of_refunds": 1, "number_of_withdrawals": 0, "number_of_mandates": 0, "number_of_internal_transfers": 0, "number_of_multi_transactions": 0, "total_volume": 80, "transaction_volume": 100, "refund_volume": -20, "withdrawal_volume": 0, "mandate_volume": 0, "internal_transfer_volume": 0, "multi_transaction_volume": 0, "total_transaction_costs": 0, "transaction_costs": 0, "refund_costs": 0, "withdrawal_costs": 0, "mandate_costs": 0, "internal_transfer_costs": 0, "multi_transaction_costs": 0, "total_order_fees": 0, "total_refund_fees": 0, "total_gateway_fees": 0, "total_amount": 80, "amount_paid": 0, "amount_payable": 80, "payout_type": "collective", "po_number": null, "specifications": [ "uid": "{{specification_uid}}", "object": "specification", "created": 1606307019, "updated": 1606307020, "source": {}, "status": "current", "paid": null, "period_start": 1606258800, "period_end": 1606345199, "total_number_of_transactions": 2, "number_of_transactions": 1, "number_of_refunds": 1, "number_of_withdrawals": 0, "number_of_mandates": 0, "number_of_internal_transfers": 0, "number_of_multi_transactions": 0, "total_volume": 80, "transaction_volume": 100, "refund_volume": -20, "withdrawal_volume": 0, "mandate_volume": 0, "internal_transfer_volume": 0, "multi_transaction_volume": 0, "total_transaction_costs": 0, "transaction_costs": 0, "refund_costs": 0, "withdrawal_costs": 0, "mandate_costs": 0, "internal_transfer_costs": 0, "multi_transaction_costs": 0, "total_order_fees": 0, "total_refund_fees": 0, "total_gateway_fees": 0, "total_amount": 80, "amount_paid": 0, "amount_payable": 80, "po_number": nullAll previous settlements can be found using the following call: GET https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/settlements?expand[]=specifications&order[]=-period
With
&order[]=-period
we order the response to view the settlement with the most recent
period_end
to be the first result.
Aside from the above information, merchants would like to know what their payouts consist of, so that they can process this in their accountancy. Unless you have contractually decided to provide individual payouts, every payout contains the following text on the bank statement:
Betaling settlement {{specification_uid}} {{merchant_name}} periode 01-12-2019 - 01-12-2019
On request, OPP can change this text. Keep in mind that this payout text is for all merchants on your platform. The following tags can be used in the settlement payout description:
We would advise you to create an export of the necessary information for merchants to be able to download.
Having the
settlement_uid
and
specification_uid
we can retrieve an overview of every event within the specification with the following call:
The response shows al settlement specification rows. Important in this row is:
transaction
,
refund
,
chargeback
,
mandate
total_merchant_fee
is the fee of the event that is paid to the partner.
total_partner_fee
is the fee of the event that is paid by the partner to OPP.
In case a
"type": "refund"
is found, which does not match with a transaction in the same specification, you can find the transaction to which this refund belongs by the following call:
If you want to show a merchant all transactions that have been done, you can use the following call. This example shows all transactions of a merchant that have status
completed
or
reserved
. If desired, the filter can be expanded with other statuses to show for example, pending statuses.
If you want to show all completed and reserved transactions within a certain period of time, you can expand the filter to also filter on a date.
GET https://api-sandbox.onlinebetaalplatform.nl/v1/merchants/{{merchant_uid}}/transactions?filter[0][name]=status&filter[0][operand]=in&filter[0][value]=completed,reserved&filter[1][name]=date_completed&filter[1][operand]=between&filter[1][value]=2020-11-01 00:00:00, 2020-11-30 23:59:59A transaction can contain one or more refunds. Refunds belonging to a transaction can be found as follows: GET https://api-sandbox.onlinebetaalplatform.nl/v1/transactions/{{transaction_uid}}/refunds
Do note that we expect you to save all
transaction_uid
s and
refund_uid
s that belong to an order, so filtering and ordering could also be done on your own data.
When providing payments on your platform, you would like to know what happens to their orders and payments. Besides that, it is wise for you to know what happens to your fee and how much you pay for transactions, refunds, mandates, etc.
In this chapter, we will guide you through providing all information that is required to build your own dashboard.
In this guide, we assume that you have registered all
refund_uid’s
and
transaction_uid’s
in your database, in order to relate them to the correct bookings and other related data.
Al your monthly fee is combined into a settlement. A settlement is the (current) balance over a specific period of time. Every settlement has a specification for every merchant your platform has. This way you can see exactly how much you earn from specific merchants.
The current settlement can be found using: GET https://api-sandbox.onlinebetaalplatform.nl/v1/settlements?filter[status]=current&expand[]=specifications
If you do not have a current settlement, the server will respond with an empty list.
Every specification has its own
specification_uid
. The specification is build up the same way as a settlement is. In case you want to specify the dashboard per merchant, it is important to look at the different specifications, instead of the complete settlement.
Important in this response is:
A response might look like this:
"object": "list", "url": "/v1/settlements", "has_more": false, "total_item_count": 1, "items_per_page": 10, "current_page": 1, "last_page": 1, "data": [ "uid": "{{settlement_uid}}", "object": "settlement", "created": 1606307019, "updated": 1606307020, "status": "current", "paid": null, "period_start": 1606258800, "period_end": 1606345199, "total_number_of_transactions": 72, "number_of_transactions": 47, "number_of_refunds": 3, "number_of_withdrawals": 0, "number_of_mandates": 20, "number_of_internal_transfers": 0, "number_of_multi_transactions": 2, "total_volume": 685188, "transaction_volume": 686218, "refund_volume": -1030, "withdrawal_volume": 0, "mandate_volume": 0, "internal_transfer_volume": 0, "multi_transaction_volume": 0, "total_transaction_costs": -4285, "transaction_costs": -435, "refund_costs": 0, "withdrawal_costs": 0, "mandate_costs": -3850, "internal_transfer_costs": 0, "multi_transaction_costs": 0, "total_order_fees": 0, "total_refund_fees": 0, "total_gateway_fees": 0, "total_amount": 80, "amount_paid": 0, "amount_payable": -4442, "payout_type": "collective", "po_number": null, "specifications": [ "uid": "set_8751fc4fb25f", "object": "specification", "created": 1606386063, "updated": 1606386064, "source": {}, "status": "current", "paid": null, "period_start": 1604358000, "period_end": 1606777199, "total_number_of_transactions": 35, "number_of_transactions": 12, "number_of_refunds": 1, "number_of_withdrawals": 0, "number_of_mandates": 20, "number_of_internal_transfers": 0, "number_of_multi_transactions": 2, "total_volume": 33078, "transaction_volume": 34078, "refund_volume": -1000, "withdrawal_volume": 0, "mandate_volume": 0, "internal_transfer_volume": 0, "multi_transaction_volume": 0, "total_transaction_costs": -3910, "transaction_costs": -60, "refund_costs": 0, "withdrawal_costs": 0, "mandate_costs": -3850, "internal_transfer_costs": 0, "multi_transaction_costs": 0, "total_order_fees": 398, "total_refund_fees": -100, "total_gateway_fees": -650, "total_amount": 188, "amount_paid": 0, "amount_payable": -4262, "po_number": nullAll previous settlements can be found using the following call: GET https://api-sandbox.onlinebetaalplatform.nl/v1/settlements?expand[]=specifications&order[]=-period
With
&order[]=-period
we order the response to view the settlement with the most recent
period_end
to be the first result.
The
set_xxx
code, is also visible on your bank statement of that specific period. Your bank statement will look something like this:
Betaling settlement {{settlement_uid}} {{partner_name}} periode 01-12-2019 - 31-12-2019
Aside from the above information, you might want to know what your payouts consist of, so that you can process this in your accountancy. Every payout contains the following text on the bank statement:
We would advise you to create an export of the necessary information for you to be able to download.
Having the
settlement_uid
and
specification_uid
you can retrieve an overview of every event within the specification with the following call:
The response shows al settlement specification rows. Important in this row is:
transaction
,
refund
,
chargeback
,
mandate
The sum of all
amount_payable
in the specifications adds up to the
amount_payable
of the settlement, and is the amount that you will receive on your bank account.
In case a
"type": "refund"
is found, which does not match with a transaction in the same specification, you can find the transaction to which this refund belongs by the following call: