Rabo Smart Pay offers you an all-in-one solution to receive payments on your physical and online locations. It includes a dashboard that puts you in full control of your Rabo Smart Pay and all products included in it:

  • Rabo OnlineKassa,
  • Payment terminals
  • Rabo PinBox
  • Rabo SmartPin
  • Retourpinnen
  • Rabo PinTegoed
  • Rabo Betaalverzoek Plus

 and payment brands such as:

  • Maestro
  • V PAY
  • iDEAL
  • MasterCard
  • Visa
  • PayPal
  • Bancontact

You can integrate your webshop with the Online Payment API using any programming language and platform. You can choose to connect your webshop to the Rabo Smart Pay API in any of following ways:

  • Plugins: There are plugins available for popular webshops like Magento and WooCommerce. These can be installed and configured easily without any coding. See Available Plugins to know more.
  • SDKs: Software development kits (SDKs) are available for PHP, .NET, and Java. These SDKs use our API and simplify the process for programmers. See Available SDKs to know more.
  • Connect your webshop directly to the API.

Visit the Rabo Smart Pay – OnlineKassa page to see an overview of supported plugins and SDKs. For more detailed integration information on the plug-ins and SDK's, read our Rabo Smart Pay manual.

Setup sandbox account

Before your begin, make sure you have a working sandbox account in the Rabobank developer portal. Read Get Started to set up an account.

You require a valid refresh token and a signing key for authentication and security. Here’s how you can obtain them:

  • If you are successfully registered with Rabo Smart and have access to the dashboard: go to Zelf regelen > Webwinkels beheren > Acties to find the refresh token and signing key.
  • If you are not developing for a specific merchant and therefore lack access to the dashboard: Contact our Support Team.

After you have access to the sandbox environment, you can start integrating and testing the API.

Switching from sandbox to live

After successfully integrating in the sandbox environment and ensuring the connections are working properly, you can transition to the live environment by:

  1. Changing the base path of each call from /omnikassa-api-sandbox to /omnikassa-api.
  2. Replacing the sandbox refresh token and signing key with the refresh token and signing key for the live environment.

    These can only be obtained by a registered merchant with the Rabo Smart Pay dashboard.

Payment journey

The Rabo Smart Pay Online Payment API enables online payments for webshops. The following steps outline the payment flow and indicate where your webshop needs to interact with Rabo Smart Pay:

  1. For authorization purposes, your webshop makes a refresh call to the Rabo Smart Pay API to obtain an access token. (If your previously obtained access token is still valid, you can skip this step.)
  2. After receiving an access token, the webshop makes an order announce call to announce an order.
  3. Your webshop then redirects the user to Rabo Smart Pay hosted checkout. The user makes the payment and is redirected back to the webshop.
  4. The Rabo Smart Pay API sends a notification call to notify the webshop of the order status update.
  5. Your webshop makes a status pull call to request the latest order status.
  6. (Optional) The webshop makes a refund by calling the refund endpoint 

To complete an online payment, the webshop needs to perform three calls: the Refresh call, the Order Announce call, and the Status Pull call. These steps are explained below.

Refresh call

The first step in the payment journey is authorizing your webshop to initiate online payments. This is done using a refresh call.

Your webshop makes the refresh call by handing over the refresh token in exchange for an access token from Rabo Smart Pay. 

After receiving the access token, it is valid for a limited time (a number of hours). Your webshop is expected to keep track of the access token's validity period and use the refresh token to retrieve a new access token when necessary.

You are required to cache the access token in a secure manner as long as it is valid.

Refresh call endpoint: GET - https://api.pay.rabobank.nl/omnikassa-api/gatekeeper/refresh

An access token can then be used for subsequent order announce calls till it expires. You should not request an access token for every individual call as long as the previously obtained token is still valid.

Order announce call

The next step in the payment journey is the order announce call, which is used to initiate a payment. The access token received in the previous step (refresh call) is needed to perform the order announcement. Additionally, you should provide order details in the request, the minimal required order details can differ between payment methods:

  • The current date/time, merchant order ID, order amount, and the return URL should be included in every order, regardless of the payment method.
  • Depending on the payment method, additional information should be included in the order.

    If mandatory parameters for specific payment method(s) are missing from the request, the shopper is not able to complete the payment with the selected payment method. However, the shopper can still choose other available payment methods to complete the said payment. 
    An exception occurs if a payment method is forced while still missing information. In this case, the order announcement is refused even if other brands are available

The table below shows which information should be included per payment brand:

Payment brandAdditional information in order announcement
iDEAL, PayPalNo additional information required
Mastercard, Visa, Maestro, V Pay
Bancontact
Although not mandatory, we recommend you to include the email address and delivery address (or, if not known, the billing address) in the order for additional assurance for a successful payment.

Rabo Smart Pay API responds with a unique ID assigned to the order and a payment page URL to redirect the user. In the order announcement call it is possible to add a User-Agent and a partner reference. This can be done in the X-Api-User-Agent header. The User-Agent should follow the standard string format found here: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent.

Order announce call endpoint v2: POST - https://api.pay.rabobank.nl/omnikassa-api/order/server/api/v2/order
Order announce call endpoint v1 (deprecated): POST - https://api.pay.rabobank.nl/omnikassa-api/order/server/api/order

Payment brand call (optional call)

After receiving a valid access token (during the refresh call), a payment brand call can be performed. The payment brand call retrieves the available payment brands and their corresponding statuses. Only available payment brands are shown to the shopper. You can manage the availability of payment brands in the dashboard.

Payment brand call endpoint: GET - https://api.pay.rabobank.nl/omnikassa-api/order/server/api/payment-brands

VAT calculations (Kill functionality and adjust to section 'Order lines')

If order lines are supplied with VAT information, you should ensure that the total order amount is consistent with the order lines. The order amount (including VAT) must be equal to the sum of all order items' piece prices (including VAT) multiplied by their quantities. Depending on how this is calculated, rounding errors can occur, resulting in differences. If the order amount is incorrect, the order items are filtered out from the order announcement. Therefore, we recommend basing the total VAT amount on the VAT of the item price instead of the total order amount excluding VAT.

Example: A item price of an order item (excluding VAT) is €12.98, and a VAT rate of 21% applies. The piece price including VAT equals €12.98 + 21% = €15.71 (rounded to 2 decimals). If a shopper orders 7 items, the order amount (including VAT) to be specified in the announcement equals 7 x €15.71 = €109.97.

If the order amount is incorrect, the order items from the order announcement are filtered out.

Discounts

A discount can be provided by an order item in the order details with a negative amount and (if applicable) a negative tax amount.

Redirect shopper to checkout page & shopper returns to the webshop

After a successful order announcement, the merchant redirects the shopper to the Rabo Smart Pay checkout page. Here the shopper can complete their payment using any of the available payment brands. 

Example:

When/if the payment is completed, expired, or canceled, the shopper redirects to the webshop. After redirect, the following additional parameters are added to the return URL, providing information about the order status:

URL ParameterDescriptionExample
order_idThe merchant order ID as supplied in the order announce call.order123
statusThe status of the order.COMPLETED
signatureThe hexadecimal representation of the signature of the data in the URL.14bf9e935956546887c7c8fd020a0702cd4462d3dd97b48752f3d4d4c5a9cf0afbd8c60d2b7b0e0c46564b1bfeb0a4f7ffc160005c71a1f7c504ef7ca8bbfb82

The final status of an order is not known in all cases, for example with an iDEAL payment there might be some delay before the final state is known.

Overview order statuses

The order status can have various states. Possible values for the order status include:

  • IN_PROGRESS: The payment has not yet been completed. This can occur if the shopper is still in the checkout process or due to a breakdown or delay in payment processing. This is a possible outcome of an iDEAL or credit card payment.
  • COMPLETED: The payment was successful.
  • EXPIRED: The shopper has not paid within the stipulated time period.
  • CANCELLED: The shopper chose not to pay and actively cancelled the order.

Verify signature

To verify the integrity of the request it is highly recommended that the webshop verifies the signature using the HMAC-SHA512 cryptographic algorithm. This can be done by:

  1. Constructing the payload by concatenating the values of the order_id and the status parameters in a comma-separated string. Make sure that the values are specified in this order without any spaces, otherwise the signature validation fails, e.g.: order123,COMPLETED
  2. Next, initialize a HMAC-SHA512 computation by supplying the (secret) signing key.

The signing key is supplied in a base64 encoded format and must be decoded to the corresponding byte sequence. Subsequently, the UTF-8 byte representation of the payload is presented to the HMAC-SHA512 to arrive at the signature in byte representation. To compare this with the expected value in the signature parameter of the return URL, it must be encoded to (lowercase) hexadecimal string. If the values are equal, then the request to return to the webshop is authentic; otherwise, the request should be rejected by the webshop.

Below are code examples in PHP, Java, and C# to further illustrate the signature computation:


PHP

$payload = 'order123,COMPLETED';
$signingKey = '<signing key as copied from Rabo Smart Pay Dashboard>';
$signingKeyDecoded = base64_decode($signingKey);
$signature = hash_hmac('sha512', $payload, $signingKeyDecoded);

Java

String payload = "order123,COMPLETED";
String signingKey = "<signing key as copied from Rabo Smart Pay Dashboard>";
byte\[\] signingKeyDecoded = Base64.getDecoder().decode(signingKey);
Mac macAlgorithm = Mac.getInstance("HmacSHA512");
Key secretKey = new SecretKeySpec(signingKeyDecoded , "HmacSHA512");
macAlgorithm.init(secretKey);
byte\[\] result = macAlgorithm.doFinal(payload.getBytes(UTF_8));
String signature = Hex.encodeHexString(result);

C#

String payload = "order123,COMPLETED";
String signingKey = "<signing key as copied from Rabo Smart Pay Dashboard>";
byte\[\] signingKeyDecoded = Convert.FromBase64String(signingKey);
string signature = "";
using (var hmacsha512 = new HMACSHA512(signingKeyDecoded))
{
var stream = new MemoryStream(Encoding.UTF8.GetBytes(payload));
foreach (var b in hmacsha512.ComputeHash(stream))
{
signature = signature + $"{b:x2}";
}
}

Notification call

After one or more new orders are processed at Smart Pay, the Rabo Smart Pay API sends a notification message to the webshop. This notification serves as an invitation for the webshop to retrieve the order statuses with a Status Pull call. The webshop can do this immediately (even before an answer has been given to the notification) or at a later time.

The notification contains a token that the webshop must use in the Status Pull call, this token has a limited validity (minutes). If the webshop does not make a status update call, Rabo Smart Pay sends a new notification. Rabo Smart Pay gives up after a number of attempts until a new order is processed.

The body of the notification is a JSON object contains the following fields:

FieldMeaning
authenticationThe token that must be used for the status pull call.
expiryThe validity period of the token, in the ISO-8601 format
eventNameThe type of notification. For the time being this is always: merchant.order.status.changed
poiIdIdentification of the webshop (point of interaction), seen from Rabo Smart Pay. This is relevant if several webshops use the same webhook URL.
signatureThe hexadecimal representation of the signature of the data in the notification.

 Verify signature

The notification is cryptographically signed by Rabo Smart Pay using the same approach as the return URL so that the webshop can verify its integrity, It is highly recommended that your webshop verifies the signature before accepting the notification. If the computed signature is equal to the signature in the notification then the notification can be trusted and further processed, otherwise the notification should be rejected by the webshop.

The signature is then computed by applying HMAC-SHA512 with the base64 decoded signing key and the payload above decoded to a UTF-8 byte sequence.

The fields for the payload are used are in the following order:

  1. authentication
  2. expiry
  3. eventName
  4. poiId

Example:

eyJraWQiOiJOTyIsImFsZyI6IkVTMjU2In0.eyJubyMiOjEyMywibWtpZCI6NSwibm8kIjoibWVyY2hhbnQub3JkZXIuc3RhdHVzLmNoYW5nZWQiLCJjaWQiOiJhYmNkLTEyMzQiLCJleHAiOjE0ODg0NjQ1MDN9.MEUCIHtPFoKmXAc7JNQjj0U5rWpl0zR9RsQvgj_n-ckHBngHAiEAmbtgrxaiy4cS3BTHd0DJ8md3Rn7V13Nv35m5DurY1wI,2016-11-25T09:53:46.765+01:00,merchant.order.status.changed,123

On successful receipt of the notification, Rabo Smart Pay expects a HTTP status code 200 in return. If another status code is sent in response to the notification, Rabo Smart Pay assumes that the notification could not be processed and does not try to send the notification again until a new order is processed.

 If more than one signing key is active for the webshop, Rabo Smart Pay sends separate notifications to the webshop, each signed with a different key. This is because Rabo Smart Pay does not know which key is actually used within the webshop. The webshop can carry out a successful verification of the signature with one signing key.

Status pull call

After Rabo Smart Pay sends a notification call, your webshop can retrieve the final status for the newly processed order(s) using the Status Pull call. A token should be used in the authentication field of the notification message.

The response of this call is cryptographically signed by Rabo Smart Pay using the same approach as the return URL so that the webshop can verify the integrity. It is recommended that the webshop validates the signature before processing the response.

For example, consider the following response: 

{
"signature": "99ca2487243fbad72bbaa456a3219db7b0d2a19777f436cedb3c045e999b86c05001bb0837b43caa3d1757321d00959ac2a161f473a103af72bf440db5147b4a",
"moreOrderResultsAvailable": false,
 
"orderResults": [
{
"merchantOrderId": "order00001",
"omnikassaOrderId": "1d0a95f4-2589-439b-9562-c50aa19f9caf",
"poiId": "2004",
"orderStatus": "CANCELLED",
"orderStatusDateTime": "2016-11-25T13:20:03.157+01:00",
"errorCode": "",
"paidAmount": {
"currency": "EUR",
"amount": "0"
},
"totalAmount": {
"currency": "EUR",
"amount": "4999"
}
},
{
"merchantOrderId": "order00002",
"omnikassaOrderId": "5a89e364-9800-11e9-bc42-526af7764f64",
"poiId": "2004",
"orderStatus": "COMPLETED",
"orderStatusDateTime": "2016-11-25T13:20:45.654+01:00",
"errorCode": "",
"paidAmount": {
"currency": "EUR",
"amount": "8999"
},
"totalAmount": {
"currency": "EUR",
"amount": "8999"
},
 
"transactions" : [{
"id" : "1",
"paymentBrand" : "IDEAL",
"type" : "PAYMENT",
"status" : "SUCCESS",
"amount" : {
"currency" : "EUR",
"amount" : "8999" },
"confirmedAmount" : {
"currency" : "EUR",
"amount" : "8999" },
"startTime" : "2016-07-28T12:51:15.574+01:00",
"lastUpdateTime" : "2016-07-28T12:51:15.574+01:00" }
]
}
]
}

Status pull call endpoint v2: GET - https://api.pay.rabobank.nl/omnikassa-api/order/server/api/v2/events/results/merchant.order.status.changed
Status pull call endpoint v1 (deprecated): GET - https://api.pay.rabobank.nl/omnikassa-api/order/server/api/events/results/merchant.order.status.changed

The deprecated endpoint - /events/results/merchant.order.status.changed does not return a list of transactions.

Verify signature

To verify the signature, the payload is constructed by concatenating the fields into a comma-separated string in the following order:

  • moreOrderResultsAvailable
  • orderResults

where each element of orderResult is expanded to a comma-separated string in the following order:

  • merchantOrderId
  • omnikassaOrderId
  • poiId
  • orderStatus
  • orderStatusDateTime
  • errorCode
  • paidAmount currency
  • paidAmount amount
  • totalAmount currency
  • totalAmount amount

followed by a list of transactions, each in order:

  • id
  • paymentBrand
  • type
  • status
  • amount currency
  • amount amount
  • confirmedAmount currency
  • confirmedAmount amount
  • startTime
  • lastUpdateTime

The confirmedAmount values is regarded as null values if the confirmedAmount is null.

Below are some examples of the payload for a completed and cancelled order:

Successful order and transaction:

false,order00002,5a89e364-9800-11e9-bc42-526af7764f64,2004,COMPLETED,2016-11-25T13:20:45.654+01:00,,EUR,100,EUR,100,1,IDEAL,PAYMENT,SUCCESS,EUR,100,EUR,100,2016-07-28T12:51:15.574+01:00,2016-07-28T12:51:15.574+01:00,2,IDEAL,PAYMENT,SUCCESS,EUR,200,EUR,200,2016-07-28T12:51:15.574+02:00,2016-07-28T12:51:15.574+02:00

Cancelled order and transaction:

false,order00003,5a89e364-9800-11e9-bc42-526af7764f65,2004,CANCELLED,2016-11-25T13:20:45.654+01:00,,EUR,0,EUR,100,1,IDEAL,PAYMENT,CANCELLED,EUR,100,,,2016-07-28T12:51:15.574+01:00,2016-07-28T12:51:15.574+01:00,2,IDEAL,PAYMENT,CANCELLED,EUR,200,,,2016-07-28T12:51:15.574+02:00,2016-07-28T12:51:15.574+02:00

The signature is then computed by applying HMAC-SHA512 with the base64 decoded signing key. The payload above is decoded to a UTF-8 byte sequence. If the computed signature equals the value of the signature field, then the response is authentic and further processing can continue, if not, then the response should be rejected. 

Alternative to status pull call

Similar to the status pull call, the order status also allows for retrieving status information about an order. Order statuses are guaranteed to remain available for 24 hours after the order reaches a final status.

Order status endpoint: GET - https://api.pay.rabobank.nl/v2/orders/{orderId}

This API endpoint should only be used in rare cases where a webhook notification has not been received. For monitoring status changes, it is mandatory to use the provided webhook mechanism (see Status Pull call). 

Polling this endpoint for status updates is explicitly prohibited. Rabo Smart Pay reserves the right to rate limit or disable this endpoint entirely if it is used inconsistently with its intended purpose. 

This endpoint is currently unavailable in the Sandbox environment.

Refund

After a transaction is successful, it is possible to initiate a refund. Refunds can be initiated using the Rabo Smart Pay dashboard or Rabo Smart Pay app. Next to these, it is possible to initiate refunds via the refund endpoint. For more functional documentation about refunds see the Rabo Smart Pay manual.

The API contains three endpoints for refunds:

The webhook mechanism exposes a transaction ID in the merchant.order.status.changed version 2 endpoint.  This transaction ID must be used to initiate or request the status of a refund.

Refund on the sandbox environment

On the sandbox environment, it is possible to simulate different scenarios based on the refund amount provided when initiating a refund. Additionally, setting a specific transaction ID or refund ID can also trigger one of the following scenarios.

Initiate refund request

Amounts:

  • Amount equal or below 50 euro: successful refund creation
  • Amount above 50 euro: MAXIMUM_REFUNDABLE_AMOUNT_EXCEEDED

Transaction ID:

  • 6a07e870-8b11-11ec-a6a1-a7d4188ce7f8: UNKNOWN API EXCEPTION
  • 83d4788c-8b1a-11ec-a720-074492bc17bb: NON EXISTING TRANSACTION

Any other transaction ID triggers a successful refund.

Retrieve refund details

Depending on the amount of the initiate refund request, we simulate different behaviours when the status of the refund is requested:

  • The default is to simulate a successful refund.
  • When the amount is 4,00 euro then we simulate a pending refund.
  • When the amount is 5,00 euro then we simulate a failed refund.
  • When the amount is 6,00 euro then we simulate an unknown status.

Refund ID:

  • 4762858c-8b11-11ec-92d1-0fb764705fe6: REFUND NOT FOUND EXCEPTION

Any other refund ID triggers one of the scenarios described above, depending on the amount.

Transaction ID:

  • 6a07e870-8b11-11ec-a6a1-a7d4188ce7f8: UNKNOWN API EXCEPTION
  • 83d4788c-8b1a-11ec-a720-074492bc17bb: NON EXISTING REFUND

Any other transaction ID triggers one of the scenarios described above.

Retrieve refundable details

The following transaction IDs can be used to retrieve a refundable details response:

  • 6a07e870-8b11-11ec-a6a1-a7d4188ce7f8: UNKNOWN API EXCEPTION
  • 83d4788c-8b1a-11ec-a720-074492bc17bb: NON EXISTING REFUND

Any other transaction ID returns a refundable amount of 50,00 euro.