Sorry, you need to enable JavaScript to visit this website.

Omnikassa Payment flow

The API of Rabo Omnikassa facilitates online payments that are typically initiated from a web shop. In this section we give an overview of the steps a payment normally consists of and to which API calls they relate to. For the technical details of these calls the reader is referred to the API specification. Additional information on these calls that could not be fitted into the specification are provided in separate paragraphs of this document.

Steps

A single payment typically consists of the following steps:

  1. The web shop requests an access token from Rabo Omnikassa given a refresh token (refresh call). Note that this request is not needed if a previous obtained access token is still valid.
  2. The web shop uses the access token to announce an order (order announce call)
  3. The web shop redirects the consumer to Rabo Omnikassa.
  4. The consumer makes the payment.
  5. The consumer is redirected back to the web shop.
  6. Rabo Omnikassa sends the web shop a notification to indicate that an order status update is available (notification call).
  7. The web shop requests from Rabo Omnikassa the latest order statuses (status pull call).

Although not strictly necessary to handle payments, the API also provides the payment brands call to request the payment brands that are available to the web shop (e.g. iDEAL, PayPal, etc.).

In the calls so called JSON Web Tokens (JWT) are used. It is not necessary for the web shop to be able to create or parse these tokens. All are generated by Rabo Omnikassa.

More information on the calls are provided in the remaining subsections of this document.

Refresh call

A web shop must be authorized to initiate online payments. This is achieved using the refresh call where the web shop obtains an access token from Rabo Omnikassa using his refresh token. An access token has a limited validity (a number of hours). If the web shop no longer has a valid access token, the refresh token must be used to retrieve a new access token. This access token can then be used for subsequent order announce calls until it expires. The web shop is expected to keep track of how long an access token is valid, and when a new access token has to be retrieved. The shop must cache the access token in a secure manner as long as it is still valid. It is not the intention that a new access token is collected for every individual payment if this is not necessary

Payment brands call

This call can be performed to check the available payment brands and the corresponding statuses. To perform this call a valid access token is required.

Order announce call

A new payment is initiated by announcing an order. In the call details of the order must be provided. The response of this call consists of a unique ID that Rabo Omnikassa assigned to the order as well as an URL to the payment pages of Rabo Omnikassa where the consumers's browser must be redirected to. On these pages the consumer can choose between different payment brands to complete the payment or the consumer can choose to cancel the payment and return to the webshop.

VAT calculation

If order lines are supplied with VAT information then care must taken to ensure that the total order amount is consistent with the order lines. The order amount (including VAT ) must be equal to the sum over all order items of the piece price (including VAT) multiplied by the quantity.

Depending on how this is calculated rounding errors can occur resulting in differences. We therefore recommend to base the total VAT amount on the VAT of the piece price instead of the total order amount excluding VAT. For example:

Suppose that the piece 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). When a consumer orders 7 copies the order amount (including VAT) to specify in the announcement equals 7 x € 15.71 = € 109.97.

Note: If the order amount is incorrect then

  1. the order items from the order announcement are filtered out, and
  2. AfterPay is not possible as a payment method

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.

Required fields per payment brand

Regardless of the payment brand, at least the current date/time, merchant order ID, the order amount and the return URL must be included in each order. Depending on the payment method, additional information must be included in the order as specified in the table below.

Payment brand Additional information in the order
iDEAL No additional information is required for this payment method.
PayPal Although not mandatory, we also recommend that you include order items in the order for additional security regarding PayPal's payment to the merchant.
Bancontact, Visa, MasterCard, V PAY, Maestro Although not mandatory, we recommend include the delivery address (or, if not known, the billing address) in the order for additional certainty about a successful payment.
AfterPay For AfterPay, the following additional information is required:
  • Order items where for each item the id and description fields are mandatory. Also for each order item the tax amount or the vat category is required.
  • Billing or delivery address (if different then both addresses are required).

In addition, AfterPay requires that the merchantOrderId field is unique and the order amount to be at least 5 euro.

If for a payment brand the mandatory additional information is missing in the order then the consumer cannot use this method to fulfil the payment request. If the payment brand was included in the order using the paymentBrand field then the announcement will be refused by Rabo Omnikassa.

Customer returns to the web shop

When the customer returns to the web shop, parameters are added to the return URL containing information on the status of the order. Unfortunately, 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.

The URL parameters are specified in the table below:

URL Parameter Description Example
order_id The merchant order ID as supplied in the order announce call. order123
status The status of the order, see below for more details. COMPLETED
signature The hexadecimal representation of the signature of the data in the URL, see below for more details. 14bf9e935956546887c7c8fd020a0702cd4462d3dd97b48752f3d4d4c5a9cf0afbd8c60d2b7b0e0c46564b1bfeb0a4f7ffc160005c71a1f7c504ef7ca8bbfb82

Possible values for the status parameter are:

  • COMPLETED: The payment was successful.
  • EXPIRED: The consumer has not paid within the stipulated period.
  • IN_PROGRESS: The payment has not yet been completed. This can occur as a result of a breakdown or delay in the hinterland of payment processing. This is a possible outcome of an iDEAL or credit card payment.
  • CANCELLED: The consumer chose not to pay and cancelled the order.

To verify the integrity of the request it is highly recommended that the web shop verifies the signature using the HMAC-SHA512 cryptographic algorithm. This can be done as follows.

First the payload must be constructed by concatenating the values of the order_id and the status parameters to a comma-separated string, e.g.:

order123,COMPLETED

Note that the values must be specified in this order without any whitespace in between, otherwise the signature validation will fail.

Next initialize a HMAC-SHA512 computation by supplying the (secret) signing key. Note that since this signing key is supplied in base64 encoded form it must first 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 first be encoded to (lowercase) hexadecimal string. If the values are equal then the request to return to the web shop is authentic, otherwise the request should be rejected by the web shop.

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 Omnikassa Dashboard>';
$signingKeyDecoded = base64_decode($signingKey);

$signature = hash_hmac('sha512', $payload, $signingKeyDecoded);

Java

String payload = "order123,COMPLETED";
String signingKey = "<signing key as copied from Rabo Omnikassa 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 Omnikassa 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

A notification is a message from Rabo Omnikassa sent to the webhook of the web shop to announce that one or more new orders have been processed. The notification is an invitation to the web shop to retrieve the statuses of these orders (status pull call). The web shop is free to do this immediately (even before an answer has been given to the notification) or at a later time. The notification contains a token that must be used in the status pull call, and this token has a limited validity (minutes). If the web shop does not make a status update call, Rabo Omnikassa will send a new notification later. However, Rabo Omnikassa will give up after a number of hours until the next order is processed.

The notification is cryptographically signed by Rabo Omnikassa using the same approach as the return URL so that the web shop can verify the integrity. It is highly recommended that the web shop first verifies the signature before accepting the notification. If more than one signing key is active for the web shop, Rabo Omnikassa will send separate notifications to the web shop each signed with a different key. The reason for this is that Rabo Omnikassa does not have any knowledge on which key is actually used within the web shop. The web shop can carry out a successful verification of the signature with exactly one signing key.

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

Field Meaning Example
authentication The token that must be used for the status pull call. eyJraWQiOiJOTyIsImFsZyI6IkVTMjU2In0.eyJubyMiOjEyMywibWtpZCI6NSwibm8kIjoibWVyY2hhbnQub3JkZXIuc3RhdHVzLmNoYW5nZWQiLCJjaWQiOiJhYmNkLTEyMzQiLCJleHAiOjE0ODg0NjQ1MDN9.MEUCIHtPFoKmXAc7JNQjj0U5rWpl0zR9RsQvgj_n-ckHBngHAiEAmbtgrxaiy4cS3BTHd0DJ8md3Rn7V13Nv35m5DurY1wI
expiry The validity period of the token, in the ISO-8601 format 2016-11-25T09:53:46.765+01:00
eventName The type of notification. For the time being this is always: merchant.order.status.changed merchant.order.status.changed
poiId Identification of the webshop (point of interaction), seen from ROK. This is relevant if several webshops use the same webhook URL. 123
signature The hexadecimal representation of the signature of the data in the notification, see below for more details.  

The signature of the notification message is calculated in a similar way as the signature of the return URL (See previous chapter). The fields for the payload are used are in the following order:

  • authentication
  • expiry
  • eventName
  • poiId

For example:

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

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. For code examples that demonstrate the use of HMAC-SHA512 please check Customer returns to the web shop.

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 web shop.

Upon successful receipt of the notification Rabo Omnikassa expects HTTP status code 200 in return. If another status code is sent in response to the notification, Rabo Omnikassa will assume that the notification could not be processed and will not try to send the notification again until a new order is processed.

Status pull call

With this call, the web store retrieves the final statuses from newly processed orders using the token in the authentication field of the notification message. The response of this call is cryptographically signed by Rabo Omnikassa using the same approach as the return URL so that the web shop can verify the integrity. It is highly recommended that the web shop 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"
      }
    }    
  ]
}

To verify the signature first 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

For the example above the resulting payload looks like this:

false,order00001,1d0a95f4-2589-439b-9562-c50aa19f9caf,2004,CANCELLED,2016-11-25T13:20:03.157+01:00,,EUR,0,EUR,4999,order00002,5a89e364-9800-11e9-bc42-526af7764f64,2004,COMPLETED,2016-11-25T13:20:45.654+01:00,,EUR,8999,EUR,8999

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. If the computed signature equals the value of the signature field then the response is authentic and further processing can continue. Otherwise the response should be rejected. For code examples that demonstrate the use of HMAC-SHA512 please check Customer returns to the web shop.