Web Content Display

Hybrid & Migration Strategies

If you as a merchant already put effort into the integration of one or even more payment providers, and they are working well, it is natural that you would like to keep using them. Therefore we want to show you the possibilities for a "soft start" with optile where you combine optile functionality with your existing implementation (your "proprietary" solution as we call it in the remainder of this docment). These "hybrid scenarios" can stand on their own, or they can be an intermediary step towards a deeper integration with optile.

There are two main aspects of the checkout process that are typically subject to hybrid setups:

  • Payment Page generation: Which system determines which payment methods should be presented to a new user?
  • Processing: Do the payment requests go through optile or directly to the respective payment provider(s)?

On a general level, both categories can be seen separately, and they can be selected independently from each other in the diagram. But not all theoretical setups make sense as we will explain further down.

Please find a visualization of available options in both categories here:

Interactive Hybrid scenarios diagram (opens in new tab).

An explanation of the visualized scenarios in both categories follows, together with comments on their limitations.

Web Content Display

Payment Page

The following options let you add partial optile logic to your existing payment page.

Method list recommendation: Your system restricts the set of payment methods you have integrated to the set recommended by optile logic for this transaction, based on order and customer attributes. Typically the payment processing takes place through the payment providers directly. Technically your system would only issue a LIST request per transaction to optile and reduce your potential set of payment methods accordingly. As a prerequisite you should configure the payment page (per country, division etc) on optile side to apply the selection logic accordingly.

Method list merge (server-side): Your system has a set of payment methods for the payment page, and on top of that it receives a method list from optile. On the server-side it generates the set union of both. Typically it would also render the optile-originating methods with optile resources (logos and input forms). The processing would typically go either through your system or optile, depending on which method was chosen by the customer. Technically your system would issue a LIST request to optile, compare with the self-generated list, remove duplications and then render the payment page server-side with the resources linked in the LIST response (for optile-originating methods). Typically a payment request would then go from the payment page to your server system, where it would either result ina CHARGE request to optile, or processing to your own payment provider connections. In case card payments should go through optile and you would like to minimize your PCI requirements a fork on the client side should be considered, so that card data goes directly from the payment page to optile through a client-side CHARGE request. If generically implemented this approach is already an "implement once" solution, meaning you could add methods and providers on runtime. Also, a step-by-step migration of your payment methods to optile is easy, because you can remove your system's representation of them on the page and add them to optile instead.

Method list merge (client-side, JS lib.): Similar to the server-side merge also in this approach there will be a mix of your own and optile methods on the payment page. Instead of orchestrating this on your server-side, however, the optile payment page widget will inject the optile methods on client side. Therefore your system should also restrict the LIST result beforehand to make sure there are no duplicate methods. The optile payment page widget will also support the distinction on submit (going to proprietary or optile endpoints). Therefore this setup requires only minimum implementation effort on your side. See the separate chapter on Hybrid payment page widget for a detailed technical documentation. Also in this case we already have an "implement once" solution allowing you to add methods on runtime.

This is a visualization of the client-side merge. Most of the other scenarios also use some of the requests depicted here:

Proprietary scoring logic: Your system relies on optile for generating the payment page, for example using optile's payment page widget. However, it restricts the method list, typically based on a custom scoring logic that excludes or allows certain payment methods based on historical data you have about your customer, the purchased items, or other criteria. Technically your system issues a LIST request to optile with the restriction contained in the preselection.networkCodes parameter and then renders the entire result either on server- or client-side. This is handy if you take advantage of optile's payment page widget, because it can run without any additional logic. The processing typically takes place through CHARGE requests to optile.

Fail-over payment page: You are using optile's full payment page (optionally with the aforementioned own intelligence or scoring), but you keep your proprietary page as a fallback, which you could switch to in case optile was not reachable at some point (which you will hopefully and probably not experience). Technically this is a full optile integration while keeping your proprietary page and processing separately.

Except for the first scenario please keep in mind that in addition to the frontend you should have a listener for Status Notifications and other backend processes in place too.

Web Content Display

Hybrid AJAX Page

The idea is that you keep your existing method list, submit button, and logic. With the help of the Orchestration Platform's AJAX library you append the Orchestration Platform's methods to your payment method list (visually). For Orchestration Platform's methods you use the Orchestration Platform's submit logic (also through the AJAX library) which is technically triggered by a separate submit button. However both, your legacy submit button and the Orchestration Platform's submit button have exactly the same look and they get interchanged automatically and without user's notice, depending on which payment method is selected. If you prefer, you can also extend your existing submit button instead of having two that interchange. See the variation below step 4 for that option.

In any case you can keep your existing methods and logic. The addition of the Orchestration Platform methods will only require one small change in your HTML (step 1), one server-side initialization call against OPG (step 2), and one JavaScript callback function from your side (step 3). Step 4 depends on which buttons you want to use. The rest will be taken care of by the Orchestration Platform's AJAX library.

Step-by-Step Guide

1. Integrate our payment method list (through its AJAX library)

Integrate the Orchestration Platform's AJAX library into your payment page as described in AJAX Library Integration. The placeholder for the Orchestration Platform's methods (the paymentNetworks div) should go directly below (or above) your existing method list. Adjust the CSS in a way that the the Orchestration Platform method list appears in the same visual style as your legacy list. Hide the radio buttons, add borders, add highlight styling for selected entries using CSS selectors, adjust sizes or whatever else is necessary. In the initialization call to the library add the deselectLegacyMethods function (see step 3.2). The payButton ID identifies the button that should be used for the Orchestration Platform methods, not your legacy button (see step 4 how you can spare this and extend your own button instead).

2. Integrate the Orchestration Platform's LIST request

In order to initialize the Orchestration Platform's payment method list your system first needs to make an (authenticated) LIST request from your server-side to the OPG. This should happen when the user navigates to the payment page. As integration parameter you can use SELECTIVE_NATIVE or DISPLAY_NATIVE.

The resulting LIST ID should then be used to initialize the AJAX library on the payment page. The library will in turn fetch the payment methods available through the Orchestration Platform's logic and the corresponding resources, and will render the list into the placeholder from step 1.

3. Combine the lists

Currently we have two lists which both can have one payment method selected. Now we need some logic that makes sure that in total only one method can be selected. This means when the user selects a method in one list, any potential selection in the other list has to be removed.

Let's look at the two cases:

3.1. If the user selects any method from the legacy list make your system call this function in the Orchestration Platform's AJAX library: deselectDynamicMethods() - This will remove any existing selection in the Orchestration Platform list. Also it will hide the Orchestration Platform's submit button, if it was given in the initialization. Make sure you show your legacy button in this case.

3.2. If the user selects any method from the Orchestration Platform list, the AJAX library will detect this and invoke the deselectLegacyMethods callback function that you indicated in the init call. You should implement this function in a way that is deselects all methods in your legacy list and, if applicable, hides your legacy button. The Orchestration Platform's AJAX library will automatically show the Orchestration Platformbutton, if it was given in the init call.

4. The submit button

If you go with the two button option you have a very clear separation of the submit flows. Make sure both buttons look exactly the same and hide the correct one on page load. Detect when the user selects a legacy method, show your legacy button and invoke the Orchestration Platform's JavaScript function from 3.1. which will also hide the Orchestration Platform button. Your callback function from 3.2. should in turn hide your legacy button while the Orchestration Platform's AJAX library will show the Orchestration Platform button, if given in the init call.

As a result, a click on the currently visible button will either trigger your existing logic, or it will be the Orchestration Platform submit to OPG.

Variation: Extend your submit button

In case you already have a listener to your submit button you could also extend its logic instead of having a separate Orchestration Platform button.

In this variation you don't have a separate Orchestration Platform button on your payment page, and therefore you don't pass the payButton ID to the AJAX libraries' init call. As a consequence the JavaScript functions from 3.1. and 3.2. would still run as described, making sure only one entry in both payment method lists is selected, but now they don't show or hide submit buttons any more. Reflect this in your implementation of the callback function from 3.2.

The listener on your button, however, now needs to check before data submission, if a legacy or an Orchestration Platform method is selected. In case of a legacy method it can just proceed as before. In case of an Orchestration Platform method it should invoke the AJAX libraries' function: optilePaymentAction()

This will perform a validation first, and on success execute the transaction with OPG. If you want to skip the validation step, you can also call optileOperationAction() instead (which we don't recommend in general).

As a result, there is one button which invokes a different submission logic, depending on the selected method.

This functionality of the AJAX library will be provided within a few weeks after requested by a customer. Please contact us when interested.
AJAX library Initialization call example

  baseUrl: "https://api.sandbox.oscato.com/pci/v1/",
  listId: someVariable,
  deselectLegacyMethods: yourCallbackFunctionName

Web Content Display


The following options are a way to include optile' processing and routing logic partially into your system.

Routing recommendation: In this scenario your system receives a routing recommendation from optile which it can follow when issuing the payment requests, which would typically happen through your own provider connections. Technically your system does a LIST request with the Open Routing option and evaluate the ordered routes per method. This is a helpful option, if you want to outsource the routing logic, but not necessarily your payment provier connections. As a prerequisite you need to model your routing preferences on the optile-side configuration.

Provider tokenization through optile: You use optile as a tokenization service that connects to all required payment providers and creates provider-specific payment account tokens for you, instead of processing the whole payment. This token could then be used by your existing system with the existing provider connections to execute the actual payments with the received tokens.This is helpful if you want to minimize changes in your existing processes for the initial payment and all potential subsequent backend processes (such as refunds). Only the first step, the token generation, will be covered by optile.

Internal PSP: Your system uses optile, typically for the payment page generation and processing, with the goal to also abstract some of the payment methods that are currently handeled by parts of your own system landscape. A typical example would be SEPA transactions that may be handled by an internal accounting system already. However, to decouple this infrastructure from your shop system these transactions could go through optile first, which in this scenario has a custom adapter to talk to the respective payment processing component on your side. This is helpful to create a full abstraction for future extensibility without replacing your existing and working payment processing components right away.

Open routing (route ordering): This is basically a native optile integration, with payments going through your server-side, but with the possibility for your system to override optile's suggested routing. Technically you would use the Open Routing option which gives you a full disclosue of optile's calculated route preferences for each payment method in the LIST response. But when issuing the CHARGE request your system can calculate its own routing preferences and override the route ordering proposed by optile. This is helpful if you have a custom routing logic on your side which cannot be modeled by optile, while you still want to take advantage of all provider connections of optile.

Web Content Display

Open Routing

LIST Request

A LIST request (POST, GET or PUT) with the additional view=routes query parameter will trigger Open Routing information for each applicable or registered network in the LIST response.

For example, a LIST request (POST) could look like: https://api.sandbox.oscato.com/api/lists?view=routes

The following rules must be respected when using routes with the view parameter:

  • If routes is present, the route information is returned in the LIST response.
  • If there are conflicting or unknown arguments like view=routes,-routes or view=abc, the request will fail as invalid. Note that open routing can be combined with other features, such as JSON Forms.
  • If there is any query parameter present other than view, it will be ignored.

The LIST response orders routes by priority according to the currently configures routing strategy. This means the first route is the one that would be tried first if a normal CHARGE was executed. Every route in this context contains the data as given in the example in the right pane, namely:

  • Contract identification, including adapter and provider codes;
  • Cost information as defined via configuration in the contracts app in the merchant portal.
Example LIST Response
"networks": {
  "applicable": [{
    "code": "MASTERCARD",
    "routing": {
      "strategy": "LEAST_COST",
      "routes": [
	"contract": {
	  "id": "5a55e5780d9c031b6c5c6f5a",
	  "providerCode": "EMERCHANTPAY",
	  "adapterCode": "EMERCHANTPAY"
	"costs": {
	  "normalized": 0.1,
	  "original": {
	  "amount": 0.1,
	  "currency": "EUR"

CHARGE Request

During CHARGE a merchant can specify the routes to be used. Additionally to the usually required parameters, one or more routes found in the LIST response should be added as seen in the example in the right pane.

Since this not something to be manipulated by the end customer, a corresponding CHARGE needs to come from a merchant server system, therefore a Pure Native integration scenario (with or without Client Side Encryption) is required.

This is how the OPG will behave when using Open Routing during a CHARGE operation:

  • If no routing list is passed, or it is null, then the routing priority from the OPG will be used.
  • If the list is empty, then no processing will take place, and the response Interaction Code will be: ABORT - INVALID_REQUEST
  • Only the listed routes will be considered for processing, in the order in which they were given.
  • Routes are identified by contract.id, like is shown in the example. If the contract.id doesn't exist at OPG, there will be an error with interaction codes ABORT - INVALID_REQUEST.
  • adapterCode and providerCode are optional inside the contract object. If any of them is passed, they need to match the configured contract. Otherwise there will be an error (and no route fallback) with interaction codes: ABORT - INVALID_REQUEST.
  • The costs data within a route can be optionally given, but it will be ignored.
Example of CHARGE body:
"account": {
  "holderName": "John Doe",
  "number": "42551111111114444",
  "verificationCode": "123",
  "expiryMonth": "12",
  "expiryYear": "2019"
"autoRegistration": true,
"routes": [{
    "contract": {
      "id": "33f4b0d039272d1825ec38a0",
      "adapterCode": "ADYEN-JSON",
      "providerCode": "ADYEN"
    "costs": {
      "normalized": 0.06,
      "original": {
        "amount": 0.07,
        "curency": "GBP"
    "contract": {
      "id": "54f9b03ce4b0d039272d1825"

Web Content Display

Standalone CHARGE

The request is an authenticated POST in analogy to a LIST Request, issued to: /api/charges (e.g.: https://api.sandbox.oscato.com/api/charges)

In the request body it allows the union set of parameters of a LIST and consecutive CHARGE Request, except for the following attributes, which are not allowed: integration, updateOnly, presetFirst, extraElements.

It allows and requires exactly one network code in the preselection.networkCodes array, e.g. VISA, MASTERCARD, SEPADD, PAYPAL, ... , and it requires all parameters that are mandatory for a LIST Request. There are no mandatory parameters for a normal CHARGE Request. However, for all non-redirect methods you have to supply the account structure and all attributes inside that are needed for the used payment method. Potential registration flags go next to the account structure. See a code example to the right.

The processing, including routing, is the same as with a normal CHARGE Request. Also the response format will be the same.

Standalone CHARGEs do count into OPX KPIs, but due to the missing LIST session they do not influence the so called Conversion KPIs.

To use registered Accounts the LIST Request should be used again to retrieve the registered payment accounts that available for payment for that customer.

Example Standalone CHARGE Request
  "transactionId": "tr101",
  "country": "DE",
  "customer": {
      "number": "42",
      "email": "john.doe@example.com"
  "payment": {
      "amount": 189.98,
      "currency": "EUR",
      "reference": "Shop 101/20-03-2017"
  "callback": {
      "returnUrl": "https://dev.oscato.com/shop/success.html",
      "cancelUrl": "https://dev.oscato.com/shop/cancel.html",
  "preselection": {
    "networkCodes": ["MASTERCARD"]
  "account": {
      "holderName": "John Doe",
      "number": "5500000000000004",
      "verificationCode": "123",
      "expiryMonth": "12",
      "expiryYear": "2022"