Web Content Display

Express Checkout

optile Express Checkout is an abstraction for third-party express checkout providers such as PayPal Express and Amazon Pay. The Express Checkout functionality targets new customers, i.e. those that are unknown to your shop system. With the help of express checkout providers, those users can take advantage of a third-party login (e.g., PayPal, Amazon) to do a payment with an account they have already stored there and at the same time share their shipping and/or billing addresses with your shop. Because they don't have to enter payment or address data into your shop again, this can be seen as a streamlined checkout flow with increased speed and conversion.

The following diagram gives a conceptual overview about the typical user flow and some of the related API calls. It represents a simplified view on the technical part, omitting the interaction with JavaScript libraries and some intermediary API calls. For implementation purposes you should therefore refer to the more detailed diagrams and descriptions further below.

Special attention is required to the frontend side, where a lot of the logic is executed through JavaScript, as explained in the chapters below...

Express Checkout

optile Express Checkout is an abstraction for third-party express checkout providers such as PayPal Express and Amazon Pay. The Express Checkout functionality targets new customers, i.e. those that are unknown to your shop system. With the help of express checkout providers, those users can take advantage of a third-party login (e.g., PayPal, Amazon) to do a payment with an account they have already stored there and at the same time share their shipping and/or billing addresses with your shop. Because they don't have to enter payment or address data into your shop again, this can be seen as a streamlined checkout flow with increased speed and conversion.

The following diagram gives a conceptual overview about the typical user flow and some of the related API calls. It represents a simplified view on the technical part, omitting the interaction with JavaScript libraries and some intermediary API calls. For implementation purposes you should therefore refer to the more detailed diagrams and descriptions further below.

Please sign in to view further details of this article. Login

Web Content Display

JavaScript Express Widget

Express Checkout providers make heavy use of proprietary JavaScript to render their provider-specific Express Checkout buttons. Therefore, optile provides the "Express Widget" JavaScript library that offers a frontend-side abstraction for integrating those into your shop. It is interacting with almost all requests (and responses) to and from proprietary provider scripts (which are loaded dynamically) and the optile OPG regarding the express flow. You can find a comprehensive end-to-end visualization under Merchant Customized Integration.

Integration Modes

When integrating the optile Express Widget you can set the URLs that it should connect to. This way you choose if it should communicate directly with optile's OPG, or if it communicates with your backend first, which in turn would connect to the OPG. Also, you can leave the default implementation of how the widget connects with the given servers, or you can override the corresponding JavaScript hooks to use a different data format or implement other custom logic.

This results in the following 4 integration modes:

Integration Modes matrix

In the following description we reference example HTML files that can be found within the templates folder of our code distributable, which we can provide you with.

  • Pure Frontend Integration: This is the easiest way to integrate Express Checkout and therefore our recommendation. The widget is configured with the default optile URL and thus starts with a request directly to optile's OPG. From there on it will work with the default operation URLs provided in the responses. This means it will continue with a direct communication with the optile backend. For this integration you will need a clientId, please request this from optile. A simple example implementation is shown in client_integration.html.
  • Merchant Backend Integration: In this mode you write your own backend code to forward the requests from the widget to optile's OPG and have some custom backend logic. You would replace the operation URLs with URLs pointing to your own servers, so the optile Express Widget will issue the requests there, in the default data format. Your servers should be able to receive this data and then pass it on to the OPG using the Express Web API. Authentication against optile is therefore done through the usual pair of merchant code and token. A simple example implementation (of the frontend side) is shown in server_integration.html.
  • Custom Backend Integration: If you want to use your own servers with your own data format you can override the JavaScript hook functions of optile's widget (such as expressPreset, expressPresetUpdate) to modify and send the requests in your own way. Note that some data objects that are passed to this JavaScript hooks, such as providerRequest, usually have to be passed on to the OPG without modification. In this scenario they will therefore go through your servers first, which will then connect to the OPG using the Express Web API. This mode of integration requires both, frontend customization and a careful handling of the subsequent operation URLs that will be provided by the OPG responses. A simple example implementation (of the frontend side) is shown in server_overrides_integration.html.
  • Custom Frontend Integration: This would mean you override the JavaScript hooks but in a way that they use exactly optile's data format to connect directly with optile's OPG. This is an uncommon use case. However, you could apply it in order to add different kinds of custom frontend logic around the requests.

Including the Widget

Including the optile Express Widget looks very similar for all integration modes. On the right we show you a generic example and below there is a conceptual explanation of the parameters. Specific examples and hints for the individual integration modes you will find in the corresponding chapters further below.

Please always integrate the library as hosted by optile under the following URL:

https://resources.sandbox.oscato.com/expresscheckout/v1/op-express-widget-v1.min.js

This will always give you the latest version (within the v1 line) which will be backwards-compatible. Because the widget will enable more Express methods and improvements in the future, we do not recommend to host the file yourself.

optile also hosts a related CSS file that you should include in your payment page, which is required for some (for example Amazon Pay) but not all (for example PayPal) Express methods. Please integrate this with:

https://resources.sandbox.oscato.com/expresscheckout/v1/op-express-widget-v1.css

Our recommendation is that you include the hosted version and override the party you may want to customize (the file is not minified for your convenience). This way you will automatically also receive the default CSS for any added Express method.

For both files don't forget to replace the sandbox subdomain with live for future production use.

Configuration

In any integration mode the Express Widget behavior must be configured via the optile object. This object is also found in the example HTML templates. Here is an overview about the available configuration attributes.

  • config.paymentElementSelector: The CSS selector that points to the HTML placeholder element where the Express buttons should be placed into by optile's Express widget.
  • baseUrl: The URL used to get the list of available Express methods. With this attribute you determine if your servers should be involved. For a pure frontend integration let it point to optile's OPG. If your backend should be involved you should have it point to your servers instead.
  • clientId: This is a long string that is only used for a pure frontend integration and authorizes widget access to the OPG. It has to be generated by optile upfront and is associated with a specific merchant configuration on optile's side, including the merchant division and summary, return, cancel, and notification URLs.
  • country: This indicates the country of the current purchase and will be used to access the corresponding configuration on optile's side regarding available providers, methods, etc. If you you work with multiple country-dependent configurations, set this dynamically. However, it's typically not required in a customized integration, because the transaction country would be determined by the merchant backend.

Hook Functions

Under functions you can override the default behavior of various hook functions with your own implementation.

The hooks that trigger Express Checkout operations are described under Custom Backend Integration. You would use those to customize the data and data format sent to your own servers.

The following hooks will be called depending on the result of the final updateExpressPreset, ie after the users have completed their provider interaction:

  • onProceed: (preset) Called when the payment succeeded as expected (Interaction Code PROCEED). optile's default implementation will redirect the user to the redirect URL returned by the OPG, presumably the previously defined summaryUrl leading to a Summary Page on your system.
  • onAbort: (preset, step) Called when the payment has to be aborted due to an unrecoverable error (Interaction Code ABORT). optile's default implementation will redirect the user to the redirect URL returned by the OPG, presumably the previously defined cancelUrl.
  • onReload: (preset, step) Called when the available Express methods should be reloaded because the chosen method is not be available right now, eg due to a provider downtime (Interaction Codes TRY_OTHER_NETWORK or RELOAD). optile's default implementation will not do anything in this unlikely case, but you may want to inform the user that this method is not available and reload the EXPRESS LIST (which makes sense if you have more than one Express method, so that one option may remain).
  • onRetry: (preset, step) Called when the user should retry the payment with a different account, ie provider login (Interaction Codes TRY_OTHER_ACCOUNT or RETRY). optile's default implementation will not do anything in this case, because the user should stay on the current page to proceed with the same or a different Express method again or choose a different way to check out. However, you should display the corresponding error message. The provider popups will close in any case.

These hooks could get invoked during any time of the customer interaction:

  • onClientException: (preset, step) Called when an exception occurred on the frontend side. optile's default implementation will not do anything in this unlikely case, but you may want to inform the user and your developers.
  • onCustomerAbort: (preset) Called when the user cancelled the provider interaction during the payment process, eg by clicking a cancel link. optile's default implementation will not do anything in this case, because the user should stay on the current page to proceed with the same or a different Express method again or choose a different way to check out.

The parameters of the aforementioned hooks are:

  • preset: The Express PRESET data object that was last returned by the OPG. It contains among others the Interaction Codes and potential redirect information.
  • step: The current operation step as a string to give context. It's only provided to hooks where there can be ambiguity. It can have these values:
    • list in the context of getExpressList
    • create in the context of createExpressPreset
    • update in the context of updateExpressPreset
Widget Integration Example
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Express Checkout Demo Page</title>
  <link href="https://resources.sandbox.oscato.com/expresscheckout/v1/op-express-widget-v1.css" rel="stylesheet">
</head>
<body>
<script>

  optile = {
    baseURL: 'https://api.sandbox.oscato.com/pci/v1/express',
    clientId: 'v1.opt-div-app.deafa8c7d85d48f5aa4009a6e7a910be',  // Only for pure frontend integration
    country: "DE",

    createTransactionDetails: function(requestData) {
      // Only required for pure frontend integration
    },

    functions: {
      // Hook implementations for merchant customized integrations go here
    },

    config: {
      watchMutations: false,
      classNameToWatch: "express-checkout",
      paymentElementSelector: '.express-checkout',
      paypalConfig: {
        style: {
          size: 'small',
          color: 'gold',
          shape: 'rect',
          label: 'checkout'
        },
        locale: 'en_US',
      }
    }
  };
</script>

<div id="root"></div>

<div class="express-checkout"></div>

<script type="text/javascript" src="https://resources.sandbox.oscato.com/expresscheckout/v1/op-express-widget-v1.min.js"></script>
</body>
</html>

JavaScript Express Widget

Express Checkout providers make heavy use of proprietary JavaScript to render their provider-specific Express Checkout buttons. Therefore, optile provides the "Express Widget" JavaScript library that offers a frontend-side abstraction for integrating those into your shop. It is interacting with almost all requests (and responses) to and from proprietary provider scripts (which are loaded dynamically) and the optile OPG regarding the express flow. You can find a comprehensive end-to-end visualization under Merchant Customized Integration.

Integration Modes

When integrating the optile Express Widget you can set the URLs that it should connect to. This way you choose if it should communicate directly with optile's OPG, or if it communicates with your backend first, which in turn would connect to the OPG. Also, you can leave the default implementation of how the widget connects with the given servers, or you can override the corresponding JavaScript hooks to use a different data format or implement other custom logic.

This results in the following 4 integration modes:

Integration Modes matrix

In the following description we reference example HTML files that can be found within the templates folder of our code distributable, which we can provide you with.

  • Pure Frontend Integration: This is the easiest way to integrate Express Checkout and therefore our recommendation. The widget is configured with the default optile URL and thus starts with a request directly to optile's OPG. From there on it will work with the default operation URLs provided in the responses. This means it will continue with a direct communication with the optile backend. For this integration you will need a clientId, please request this from optile. A simple example implementation is shown in client_integration.html.
  • Merchant Backend Integration: In this mode you write your own backend code to forward the requests from the widget to optile's OPG and have some custom backend logic. You would replace the operation URLs with URLs pointing to your own servers, so the optile Express Widget will issue the requests there, in the default data format. Your servers should be able to receive this data and then pass it on to the OPG using the Express Web API. Authentication against optile is therefore done through the usual pair of merchant code and token. A simple example implementation (of the frontend side) is shown in server_integration.html.
  • Custom Backend Integration: If you want to use your own servers with your own data format you can override the JavaScript hook functions of optile's widget (such as expressPreset, expressPresetUpdate) to modify and send the requests in your own way. Note that some data objects that are passed to this JavaScript hooks, such as providerRequest, usually have to be passed on to the OPG without modification. In this scenario they will therefore go through your servers first, which will then connect to the OPG using the Express Web API. This mode of integration requires both, frontend customization and a careful handling of the subsequent operation URLs that will be provided by the OPG responses. A simple example implementation (of the frontend side) is shown in server_overrides_integration.html.
  • Custom Frontend Integration: This would mean you override the JavaScript hooks but in a way that they use exactly optile's data format to connect directly with optile's OPG. This is an uncommon use case. However, you could apply it in order to add different kinds of custom frontend logic around the requests.

Please sign in to view further details of this article. Login

Web Content Display

Pure Frontend Integration

Using optile's Express Widget in a "pure frontend" mode requires only little integration effort from your side. By setting a few configuration parameters and integrating the JavaScript library correctly, this library will take care of the rest, including handling of proprietary provider scripts, buttons and all communication with optile's OPG and/or providers' servers.

The following sequence diagram will give you an overview about what will happen if you use optile's Express Widget in a Pure Frontend Integration. Note that it may look complex on the first glance, but most of the complexity is actually taken care of by our JavaScript library. You only have to initialize it with some configuration parameters, implement the createTransactionDetails JavaScript hook function, and manage the simple web API requests for creating the Summary Page and submitting the user's final payment confirmation. We will look at the details further below.

Also the subtle differences between different Express Checkout providers are only modeled in the diagram for the sake of completeness and in case you want to take a really close look, e.g., for debugging. But these differences are completely transparent for your implementation.

For your implementation you need not and you should not differentiate between different providers.

Sequence diagram pure frontend integration

Configuration Attributes

These are the configuration attributes that you will usually need inside the optile object on the frontend where you have included optile's Express Widget:

  • baseURL: Set this to https://api.sandbox.oscato.com/pci/v1/express so that the widget communicates directly with optile OPG and replace sandbox with live in your live systems.
  • clientId: This is a long token string that optile will generate for you on request. It authorizes the widget to issue an Express LIST call directly to the OPG Client API with a predetermined merchant, division and callback URLs (see about Express LIST below).
  • country: This indicates the country of the current purchase and will be used to access the corresponding configuration on optile's side regarding available providers, methods, etc. If you work with multiple country-dependent configurations, set this dynamically (or do the Express LIST through the Server API, see below).
  • config.paymentElementSelector: The CSS selector pointing to the HTML element where the Express buttons should be injected into.

With these parameters configured optile's Express Widget can retrieve the available Express methods from the OPG and place the corresponding proprietary provider buttons on your page.

Express LIST web API Call

Your frontend can make a direct Express LIST call to the OPG, using the Client API, to retrieve the available Express methods (as depicted in the diagram above). However, since the result is rather static in most cases, we also support the option to make the call to your backend first, and calling the OPG from there occasionally (for example once per hour). This way you can cache the result on your infrastructure inbetween and optimize the load times on your end.

In order to do that, issue the Express LIST call from your backend to OPG's Server API and include the parameter integration=DISPLAY_NATIVE. For such a call on the Server API you don't need the clientId. As a result the returned URLs for the follow-up calls will point to the OPG's Client API and you can use them directly from the frontend. Only for Express PRESET you will need the cliendId again.

JavaScript Hook createTransactionDetails

Once the user clicks the button to start an Express checkout journey your (frontend) system has to provide all relevant information about the current purchase. You do so by implementing the JavaScript hook createTransactionDetails(requestData) which should return this information, including an (optional) transactionId given by your system, the country (typically the one from the configuration to avoid inconsistencies), payment information like amount and the shopping cart with all products.

As input parameter the function receives requestData which contains partly provider specific data. This has to be passed on unchanged, wrapped in the providerRequest attribute. This way it will be passed on the the OPG and the provider, if required.

Checkout Validation & Finalization

At this point the provider-specific frontend logic takes over and guides the user through the process of selecting an address and payment account. Once the user has finished this, optile's Express Widget will redirect the user to your Summary Page. For this it will use the summaryUrl that's either configured in advance and associated with the clientId, or given in an Express PRESET call to the Server API.

Starting with the Summary Page your backend system takes over again. It should retrieve all customer and order details with the GET Express PRESET. At this point your backend directly gets is touch with the order for the first time and should validate it (because the transaction was initiated from the frontend in this scenario).

Especially these checks should take place to avoid forgery from the frontend side:

  • Current status code and reason of the Express PRESET object: must be ready for confirmation
  • payment
    • amount: must equal the sum of the shopping cart of this order
    • currency: must be supported by the shop in the order context
  • products (if present)
    • product prices: must correspond to your product catalogue
    • codes and names: must correspond to your product catalogue

After a successful validation your system shows the Summary Page. The user can review and confirm the order, which would result in CONFIRM and CHARGE requests to the OPG.

Frontend Configuration
<script>
  optile = {
    baseURL: 'https://api.sandbox.oscato.com/pci/v1/express',
    clientId: 'v1.opt-div-app.d22345a4863b4c5eb6b74bd3d63ef51b',
    country: "DE",

    createTransactionDetails: function(requestData) {
      return ({
        transactionId: 'tr-' + new Date().getTime(),
        country: this.country,
        providerRequest: requestData,
        payment: {
          amount: 28.90,
          currency: "EUR",
          reference: "Thanks for your order!",
        },
        products: [
          {
            name: "Tron: Legacy (2010) Blu-Ray",
            code: "THX1138",
            quantity: 2,
            amount: 14.45
          }
        ]
      });
    },

    config: {
      watchMutations: false,
      classNameToWatch: "express-checkout",
      paymentElementSelector: '.express-checkout',
      paypalConfig: {
        style: {
          size: 'small',
          color: 'gold',
          shape: 'rect',
          label: 'checkout'
        },
        locale: 'en_US',
      },
      amazonConfig: {
        type: 'PwA',
        color: 'Gold',
        size: 'small',
        language: 'en-GB'
      }
    },
  };
</script>

Pure Frontend Integration

Using optile's Express Widget in a "pure frontend" mode requires only little integration effort from your side. By setting a few configuration parameters and integrating the JavaScript library correctly, this library will take care of the rest, including handling of proprietary provider scripts, buttons and all communication with optile's OPG and/or providers' servers.

Please sign in to view further details of this article. Login

Web Content Display

Merchant Backend Integration

The easiest way to include your own servers into the communication is to change all relevant URLs for widget in a way that they point to the desired endpoints of your system. This means that the widget will send the Express Checkout requests in the default format (as in the Pure Frontend Integration) but to your backend. There your system can execute custom logic and/or add request data before passing on the call to the optile OPG.

The communication flow therefore resembles the one of the Pure Frontend Integration, with the only difference that all Express Checkout requests go from the client-side widget to your backend first and from there to optile OPG. Then the response goes back to your backend, and from there back to the widget.

These Express Checkout requests are:

Express LIST and URL Replacement

To direct the first request, Express LIST, from your frontend to your backend systems, you replace the baseURL in the optile widget configuration object so that it points to the corresponding endpoint of your backend.

Your backend should now use the URL for the server-to-server call of Express LIST on OPG side. Set the integration parameter to PURE_NATIVE  to also operate the follow-up requests on the Server API (see Express LIST section).

The response will contain an operation URL for each Express method that was found, and this will point to the corresponding OPG API again. If you don't interfere then the widget would just take these URLs to make the next request. If you chose the Server API that means the request would go directly to the OPG again and fail, because it's not authenticated.

In order to route the follow-up request to your system instead of the OPG, your backend should replace the operation URLs before returning them to the widget.

As a consequence the widget will make the next request to the replacement URL. When your backend receives that it should, however, make the corresponding OPG request (to forward the payload) to the original URL that was returned by OPG last time. It can do so by storing the original values in between, or by finding a consistent mapping between own URLs and OPG URLs.

For example, OPG's URL to an Express object (with the Server Payment API)...

https://api.live.oscato.com/api/presets/5b2b7105b438167111ffcca6egjppvgn0ahvkf297lndqe0ll5

... could be mapped to your URL...

https://yourdomain.com/express/presets/5b2b7105b438167111ffcca6egjppvgn0ahvkf297lndqe0ll5

This principle applies to both, the transition...

Your servers make authenticated requests, therefore you don't need the clientId in this integration mode. Also you typically don't implement the createTransactionDetails JavaScript hook, but add the transaction details on your server side. Other than that the configuration attributes are as in the Pure Frontend Integration.

Merchant Backend Integration

The easiest way to include your own servers into the communication is to change all relevant URLs for widget in a way that they point to the desired endpoints of your system. This means that the widget will send the Express Checkout requests in the default format (as in the Pure Frontend Integration) but to your backend. There your system can execute custom logic and/or add request data before passing on the call to the optile OPG.

Please sign in to view further details of this article. Login

Web Content Display

Custom Backend Integration

You have the possibility to fully or partially customize both the frontend logic and backend logic by overriding all or some of the JavaScript hook functions and implementing server-side logic to make the actual connection to the OPG. Since this adds to the integration complexity, we recommend to only do this if it is required for your use cases. Otherwise just use the optile Express widget's default implementation of the hook functions and maybe don't even route the requests through your own servers.

The following diagram gives an end-to-end overview about a typical customized integration of a merchant backend, including the most relevant JavaScript hooks and the backend API calls.

The subtle differences between different Express Checkout providers are only modeled in the diagram for the sake of completeness and in case you want to take a really close look, e.g., for debugging. But these differences are completely transparent for your implementation.

For your implementation you need not and you should not differentiate between different providers.

Sequence diagram merchant customized integration

A simple example of a customized implementation, overriding the JavaScript hooks, is provided in our example template server_overrides_integration.html.

These are the important configuration attributes for this integration mode:

  • baseUrl: The URL used to get the list of available Express methods. Point this to your servers if they should be involved.
  • country: Typically not required in a customized integration, because the transaction country would be determined by the merchant backend, but it will serve as input parameter for expressList if defined, see below.
  • functions: Hook functions used to trigger Express Checkout operations. These functions should be overriden by you, if you want custom server communication.

A full custom implementation also requires that you have a backend capable of routing frontend requests to API calls as defined by the Web API. In this scenario, the hook functions will call a specific backend route defined by you, so that the backend services can translate them into requests to be fired against the optile OPG, process the responses and send them back to the frontend.

The important JavaScript hooks which you can (but don't have to) override are:

  • getExpressList: (url, country) hook (deprecated name expressList): Returns the list of available Express methods. It will automatically be called upon loading of the widget.
    • The parameters come directly from the optile configuration object in the frontend (baseUrl will be given as url).
    • optile's default implementation of the hook makes a request to that url together with the country parameter.
    • If you override the hook, you can also (but don't have to) use the url parameter to make a request to (your own) servers. Your servers then should request the method list from the OPG by adding the country parameter themselves (which is then not relevant on the frontend side anymore). Since the operationUrl returned by the OPG will be given to the following createExpressPreset hook (see below) we recommend that your server overrides it to point to your servers before giving it back. Just note that you would also need to keep the original value to make the following Express PRESET request to the OPG later. In any case, ultimately the hook should return the whole OPG response with the method list back to the optile widget, wrapped into a data object (see example implementations). On your server side we highly recommend caching the list to minimize load times, or you even cache it into the frontend.
  • createExpressPreset: async (url, transaction, network) hook (deprectaed name expressPreset): Triggers the initialization of the provider's payment session. Called when the user clicks the provider's Express button.
    • The parameter url is the operationUrl returned from the previous getExpressList. As mentioned above you need to be aware whether you have already overriden it on your backend previously (so that it points to your servers), or if your JavaScript needs to generate a custom URL instead here. The transaction contains the relevant payload data, which can be partly provider specific, within the providerRequest structure. It is essential for further processing. The network could be used to add some method specific logic, although this is in general not recommended.
    • optile's default implementation of the hook basically sends the transaction data unchanged to the url and returns the response.
    • If you override the hook, make sure to pass at least the providerRequest object unchanged. Then you may add the transaction details on your server side before sending them to the OPG. The destination endpoint (at the OPG) was given in the previous Express LIST response from the OPG. The OPG will now initialize the payment session with the provider and create the Express PRESET object which has a distingushed URL for future access. As a response your system will now receive an Express PRESET object containing links (including one pointing to self) and a providerResponse among others from the OPG. Again your server could override the links.self URL so that the next request goes to your servers again. Ultimately the Express PRESET object should be wrapped by your JavaScript implementation into the expected format (data attribute) and returned by the hook (see example implementations).
  • updateExpressPreset: async (url, transaction, network) hook (required instead of expressPresetActivate from v1.3 onwards, deprecated name expressPresetUpdate): Signals to the provider that the user changed or finalized their selection of address and/or payment account. It is triggered multiple times for some providers (e.g., Amazon Pay) or only once when the user clicks the button to continue after the selection process for others (e.g. PayPal). The logic applied here is almost identical to the one from createExpressPreset above.
    • The parameter url is the operationUrl returned by the previous createExpressPreset. transaction contains a providerRequest object again which needs to be passed on without changes.
    • optile's default implementation of the hook again sends the transaction data unchanged to the url.
    • If you override the hook, make sure again to forward at least the providerRequest object unchanged to the server. As a result from the OPG your server will get again an Express PRESET object containing the transaction identification and status, and this time also including a redirect object. The hook should just return that object back to optile's Express widget again.
  • onProceed: (preset) hook (replaces onActivationSuccess and onUpdateSuccess from v1.3 onwards): Can perform any action after the user finished the selection process on the provider side. It will be called immediately after updateExpressPreset returned successfully on the final user interaction. For this and similar event hooks see also the general description of the Express Widget.
    • The parameter preset is the response from updateExpressPreset.
    • optile's default implementation of the hook redirects the user to the URL given in the redirect structure, together with all parameters. Usually this is the summaryUrl (as given in either the Express PRESET call or associated with the clientId).
    • If you override this hook you can suppress or alter that redirection in case you don't want to show a separate Summary Page.

To show a summary to the user your server can fetch the Express PRESET object from the OPG again to access the chosen payment method and customer and order details. Now the user can review and confirm the purchase with one final click.

Upon the user's confirmation your backend system should issue CONFIRM and CHARGE requests to the URLs given in the links attribute of the Express PRESET object, which will finalize the payment session and debit the funds. The OPG's response to CHARGE will again be a redirect structure that would point to the successUrl given earlier in the Express PRESET call to the OPG. When redirecting the user there they should typically see a "Thank You" page indicating that the purchase is now complete.

Widget Configuration
<script>
  optile = {
    baseURL: "https://www.myserverurl.com/mypath",

    functions: {
      expressList: (url, country) => {
        console.log("Local expressList function called");

        return {
          response: {
            ok: true
          },
          data: {
            // This should come from the OPG's response.
            // It's hard coded here only for illustration.
            resultInfo: "1 applicable networks are found",
            interaction: {
              code: "PROCEED",
              reason: "OK"
            },
            networks: {
              applicable: [
                {
                  code: "PAYPAL",
                  label: "PayPal",
                  method: "WALLET",
                  grouping: "WALLET",
                  registration: "OPTIONAL",
                  recurrence: "NONE",
                  redirect: true,
                  links: {
                    operation: "http://localhost:4000/express/PAYPAL/preset"
                  },
                  button: "button.preset.label",
                  selected: false,
                  contractData: {
                    PAGE_ENVIRONMENT: "sandbox",
                    JAVASCRIPT_INTEGRATION: "false",
                    PAGE_BUTTON_LOCALE: "de_DE"
                  }
                }
              ]
            }
          }
        }
      },

      expressPreset: async (url, transaction, network) => {
        console.log("Local expressPreset function called");

        const postData = (url, bodyObj) => fetch(url, {
          method: 'POST',
          mode: 'cors',
          cache: 'default',
          redirect: 'follow',
          headers: {
            'Content-Type': 'application/json',
            'Accept': 'application/json',
          },
          body: JSON.stringify(bodyObj),
        });
        const resultRaw = await postData(url, transaction,);
        const { links, providerResponse } = await resultRaw.json();

        return {
          response: {
            ok: true
          },
          data: {
            "links": links,
            "resultInfo": "Pending, you have to check the status later",
            "interaction": {
              "code": "PROCEED",
              "reason": "PENDING"
            },
            "network": "PAYPAL",
            "providerResponse": providerResponse
          }
        }
      },

      expressPresetUpdate: async (url, transaction, network) => {
        console.log("Local expressPresetUpdate function called");

        const postData = (url, bodyObj) => fetch(url, {
          method: 'POST',
          mode: 'cors',
          cache: 'default',
          redirect: 'follow',
          headers: {
            'Content-Type': 'application/json',
            'Accept': 'application/json',
          },
          body: JSON.stringify(bodyObj),
        });
        const resultRaw = await postData(url, transaction,);
        const result = await resultRaw.json();

        return {
          response: {
            ok: true
          },
          data: result
        }
      },

      // onUpdateSuccess: preset => console.log(preset),
      // onCancel: () => console.log('Canceled by user'),
      // onError: (error, network, step) => console.log(error, network, step) // step => init, update
    },

    config: {
      watchMutations: false,
      classNameToWatch: "express-checkout",
      paymentElementSelector: '.express-checkout',
      paypalConfig: {
        style: {
          size: 'small',
          color: 'gold',
          shape: 'rect',
          label: 'checkout'
        },
        locale: 'en_US',
      }
    },
  };
</script>

Custom Backend Integration

You have the possibility to fully or partially customize both the frontend logic and backend logic by overriding all or some of the JavaScript hook functions and implementing server-side logic to make the actual connection to the OPG. Since this adds to the integration complexity, we recommend to only do this if it is required for your use cases. Otherwise just use the optile Express widget's default implementation of the hook functions and maybe don't even route the requests through your own servers.

Please sign in to view further details of this article. Login

Web Content Display

Express Web API

In case you don't want to use the Pure Frontend Integration and therefore connect either your client implementation or your server systems directly with the OPG, here we give you the details about the Express Web API calls.

For most calls there is a difference in URL and/or content if you call them from the client side (Client API) or the server side (Server API, requires HTTP authentication).

You will find specific examples below where applicable.

Express Web API

In case you don't want to use the Pure Frontend Integration and therefore connect either your client implementation or your server systems directly with the OPG, here we give you the details about the Express Web API calls.

For most calls there is a difference in URL and/or content if you call them from the client side (Client API) or the server side (Server API, requires HTTP authentication).

You will find specific examples below where applicable.

Please sign in to view further details of this article. Login

Web Content Display

Express LIST

The first (and optional) step is a call to the OPG to get the current Express Checkout possibilities. As a result your system will receive a list of available Express Checkout methods to include into the corresponding page.

In contrast to the classic LIST this request is lightweight, as it does not constitute a session and has no routing or other advanced decision logic behind it. This is based on the assumption that there is no real routing flexibility for Express Checkout providers (i.e. PayPal Express is only offered by PayPal), while at the same time this checkout option will be presented more often to users than the classic payment page (e.g., on the shopping cart or even product page).

As a consequence, this request is represented by a GET against the OPG and takes only query parameters into account.

As in the regular LIST request, this express call has also a client and a server version, and they will require different query parameters when executed.

Client API Express LIST request:

GET: https://api.sandbox.oscato.com/pci/v1/express?country=DE&
clientId=v1.opt-div-app.1a7b8289133e47a9ac17cd026fabc123

The clientId parameter is a (mandatory) public key that allows the frontend to interact directly with the express checkout operations (described in the next subsections). It already determines the merchant, division, and callback URLs, see also our API Reference (Client Payment API). Other requests do not work with this parameter for security reasons.

Server API Express LIST request:

GET: https://api.sandbox.oscato.com/api/express?country=DE&
division=brandshop&integration=DISPLAY_NATIVE|PURE_NATIVE

  • Authorization: Basic ABC1234567.... (user name: merchant code, password: payment token)

The server-side request requires regular HTTP Basic authentication (merchant code and payment token) as already used in other server requests with the Payment API.

  • The division parameter lets your system access a division other than Default, if required.
  • With integration you determine which kinds of operation URLs the express checkout session should return back:
    • PURE_NATIVE will return URL(s) for calls from your server-side (Server API).
    • DISPLAY_NATIVE (default) will return URL(s) for calls directly from the client-side (Client API). Note that this is the default even if your system made the Express LIST as a server-to-server call.

Response

The response (see example to the right) should be used by your system to enrich your customer facing page with a (localized) button of the available Express Checkout possibilities.

links.operation tells your system to which URL a POST should be made for the next step when the customer selects this method, which in this case is an Express PRESET.

The result of the Express LIST call is rather static, therefore we highly recommend caching on your side to reduce loading times and traffic.
Express LIST response
{
"resultInfo": "2 applicable networks are found",		
"interaction": {
  "code": "PROCEED",
  "reason": "OK"
},
"networks": {
  "applicable": [{
    "code": "PAYPAL",
	"label": "PayPal",
	"method": "WALLET",
	"grouping": "WALLET",
	"registration": "NONE",
	"recurrence": "NONE",
	"redirect": true,
	"links": {
	  "operation": "https://api.sandbox.oscato.com/pci/v1/express/PAYPAL/preset"
	},
	"button": "button.preset.label",
	"selected": false,
	"contractData": {
	  "PAGE_ENVIRONMENT": "sandbox",
	  "JAVASCRIPT_INTEGRATION": "false",
	  "PAGE_BUTTON_LOCALE": "de_DE"
	}
  },
  {
	"code": "AMAZONPAY",
	"label": "Amazon Pay",
	"method": "WALLET",
	"grouping": "WALLET",
	"registration": "NONE",
	"recurrence": "NONE",
    "redirect": false,
	"links": {
	  "operation": "https://api.sandbox.oscato.com/pci/v1/express/AMAZONPAY/preset"
    },
	"button": "button.preset.label",
	"selected": false,
	"contractData": {
      "clientId": "amzn1.application-oa2-client.11c24bdec...",
      "sellerId": "A145XEGZ..."
	}
  }]		
}		
}

Express LIST

The first (and optional) step is a call to the OPG to get the current Express Checkout possibilities. As a result your system will receive a list of available Express Checkout methods to include into the corresponding page.

Please sign in to view further details of this article. Login

Web Content Display

Express PRESET

This call initializes the session for the selected Express Checkout provider with given parameters passed in a JSON body. It must contain a payment object, and optionally a list of products to represent the shopping cart.

Again, this request has client and server versions, which are shown below. The provider is specified in the URL, in this examples PAYPAL. However, the URL should come from the previous LIST response.

Client API Express PRESET request:

POST: https://api.sandbox.oscato.com/pci/v1/express/PAYPAL/preset?
clientId=v1.opt-div-app.1a7b8289133e47a9ac17cd026fabc123

The clientId is mandatory when using the Client API version of this call.

The side pane contains examples of complete calls.

Note that there is also a parameter type in the items of the products list, which can assume the following values:

  • PHYSICAL
  • DIGITAL
  • SERVICE
  • OTHER
A merchant must not stipulate the item category as DIGITAL unless specifically agreed with a PayPal Sales Engineer

 

Express PRESET request (Client API)
{
  "transactionId": "order-00134",
  "country": "DE",
  "payment": {
    "amount": 19.95,
    "currency": "EUR",
    "reference": "Payment #1"
  },
  "products": [
    {
      "name": "Product #1",
      "amount": 19.95,
      "type": "PHYSICAL"
    }
  ],
  "providerRequest": providerRequestObject
}

Express PRESET response (to client)
{
  "links": {
    "self": "https://api.sandbox.oscato.com/pci/v1/presets/5b2a0f2bb43816126fbc8c45epenavjgddia1ulnlifgubt871",
  },
  "resultInfo": "Pending, you have to check the status later",
  "interaction": {
    "code": "PROCEED",
    "reason": "PENDING"
  },
  "network": "PAYPAL",
  "providerResponse": {...}
}

Server API Express PRESET request

The URL is taken from the preceding LIST response. It could, for example, be:

POST: https://api.sandbox.oscato.com/api/express/PAYPAL/preset

  • Authentication: Merchant code and token
Express PRESET request (Server API)
{
  "transactionId": "order-00134",
  "country": "DE",
  "callback": {
    "returnUrl": "https://example.com/shop/from-app/success.html",
    "cancelUrl": "https://example.com/shop/from-app/failed.html",
    "summaryUrl": "https://example.com/shop/from-app/summary.html",
    "notificationUrl": "https://example.com/shop/from-app/notify"
  },
  "payment": {
    "amount": 19.95,
    "currency": "EUR",
    "reference": "Payment #1"
  },
  "products": [
    {
      "name": "Product #1",
      "amount": 19.95
    }
  ],
  "providerRequest": providerRequestObject
}
Response:
{
    "links": {
        "self": "https://api.sandbox.oscato.com/api/presets/5b2b7105b438167111ffcca6egjppvgn0ahvkf297lndqe0ll5"
    },
    "timestamp": "2018-06-21T09:33:59.380+0000",
    "operation": "EXPRESSPRESET",
    "resultCode": "00001.PAYPAL.000",
    "resultInfo": "Pending, you have to check the status later",
    "pspCode": "PAYPAL",
    "returnCode": {
        "name": "OK_PENDING",
        "source": "PSP"
    },
    "status": {
        "code": "pending",
        "reason": "preset_requested"
    },
    "interaction": {
        "code": "PROCEED",
        "reason": "PENDING"
    },
    "identification": {
        "longId": "5b2b7105b438167111ffcca6egjppvgn0ahvkf297lndqe0ll5",
        "shortId": "13057-30337",
        "transactionId": "order-00134",
        "pspId": "EC-4C690326198184123"
    },
    "network": "PAYPAL",
    "payment": {
        "reference": "Payment #1",
        "amount": 19.95,
        "currency": "EUR"
    },
    "products": [
        {
            "name": "Product #1",
            "amount": 19.95
        }
    ],
    "providerResponse": {...}
}

Express PRESET

This call initializes the session for the selected Express Checkout provider with given parameters passed in a JSON body. It must contain a payment object, and optionally a list of products to represent the shopping cart.

Please sign in to view further details of this article. Login

Web Content Display

Express UPDATE

The UPDATE of an Express PRESET object is triggered by the provider specific JavaScript libraries. It delivers essential provider-specific data in the providerRequest object to the Provider, therefore it will be executed at least once.

Depending on the provider it can be a continuous update of the user's address and payment selection, such as in Amazon Pay. Or only a one-time delivery such as in PayPal Express.

If your customers makes changes in the shopping cart after they saw the Summary Page, we recommend to accumulate all updates on your side and deliver them once with the final CONFIRM call.

Client API Express UPDATE example call:

PUT https://api.sandbox.oscato.com/pci/v1/presets/5ac38dc32d221135dfda2452e4566els2p1keb6stu2fmfe199

Express UPDATE request (Client API)
{
  "providerRequest": providerRequestObject
}

Response:
{
  "links": {
    "self": "https://api.sandbox.oscato.com/pci/v1/presets/5ac38dc32d221135dfda2452e4566els2p1keb6stu2fmfe199",
    "confirm": "https://api.sandbox.oscato.com/pci/v1/presets/5ac38dc32d221135dfda2452e4566els2p1keb6stu2fmfe199/confirm"
  },
  "resultInfo": "Payment session is successfully updated",
  "interaction": {
    "code": "PROCEED",
    "reason": "PENDING"
  },
  "providerResponse": {...}
}

Server API Express UPDATE example call

PUT https://api.sandbox.oscato.com/api/presets/5ac38dc32d221135dfda2452e4566els2p1keb6stu2fmfe199

  • Authorization: Basic ABC1234567.... (user name: merchant code, password: payment token)
Express UPDATE request (Server API)
{
  "providerRequest": providerRequestObject
}

Response:
{
  "links": {
    "self": "https://api.sandbox.oscato.com/api/presets/5ac38dc32d221135dfda2452e4566els2p1keb6stu2fmfe199"
  },
  "timestamp": "2018-06-21T09:33:59.380+0000",
  "operation": "EXPRESSPRESET",
  "resultCode": "00001.AMAZON.Draft",
  "resultInfo": "Payment session is successfully updated",
  "pspCode": "AMAZON",
  "returnCode": {
    "name": "OK_PENDING",
    "source": "PSP"
  },
  "status": {
    "code": "pending",
    "reason": "preset_requested"
  },
  "interaction": {
    "code": "PROCEED",
    "reason": "PENDING"
  },
  "identification": {
    "longId": "5b2b7105b438167111ffcca6egjppvgn0ahvkf297lndqe0ll5",
    "shortId": "13057-30337",
    "transactionId": "order-00134",
    "pspId": "S02-9944847-9141915"
  },
  "network": "AMAZONPAY",
  "payment": {
    "reference": "Payment #1",
    "amount": 19.95,
    "currency": "EUR"
  },
  "products": [
    {
      "name": "Product #1",
      "amount": 19.95
    }
  ],
  "customerCollectedDetails": {
    "email": "test_payer_amazon@optile.net",
    "name": {
      "firstName": "Test",
      "lastName": "Optiler"
    },
    "addresses": {
      "shipping": {
        "street": "Am Edelweißweg 8675 A",
        "zip": "79117",
        "city": "Freiburg",
        "country": "DE",
        "name": {
          "firstName": "Elise",
          "lastName": "Schmidt"
        }
      },
      "billing": {
        "street": " Meininger Strasse",
        "houseNumber": "58",
        "zip": "66538",
        "city": "Neunkirchen",
        "country": "DE",
        "name": {
          "firstName": "Liam",
          "lastName": "Barker"
        }
      }
    },
    "verified": true,
    "messageToMerchant": "Thank you for your purchase"
  },
  "providerResponse": {...}
}

Express UPDATE

The UPDATE of an Express PRESET object is triggered by the provider specific JavaScript libraries. It delivers essential provider-specific data in the providerRequest object to the Provider, therefore it will be executed at least once.

Please sign in to view further details of this article. Login

Web Content Display

GET Express PRESET

On the Summary Page your system should display the selected payment method and especially address data of the customer for confirmation. This is the data that was shared by the Express Checkout provider. You can retrieve it with the following call (through the Server API only).

You can also use this information to complement a potential registration of the customer on your systems.

To retrieve this data your server system does an (authenticated) GET request on the PRESET object.

GET Express PRESET example call (Server API only):

GET https://api.sandbox.oscato.com/api/presets/5ac38dc32d221135dfda2452e4566els2p1keb6stu2fmfe199

  • Authorization: Basic ABC1234567.... (user name: merchant code, password: payment token)
GET Response:
{
    "links": {
        "self": "https://api.sandbox.oscato.com/api/presets/5b2a0f2bb43816126fbc8c45epenavjgddia1ulnlifgubt871",
        "confirm": "https://api.sandbox.oscato.com/api/presets/5b2a0f2bb43816126fbc8c45epenavjgddia1ulnlifgubt871/confirm"
    },
    "timestamp": "2018-06-20T08:27:47.003+0000",
    "operation": "EXPRESSPRESET",
    "resultCode": "00000.PAYPAL.000",
    "resultInfo": "The payment is pending because it is part of an order that has been authorized but not settled",
    "pspCode": "PAYPAL",
    "returnCode": {
        "name": "OK_MERCHANT_ACTION_REQUIRED",
        "source": "PSP"
    },
    "status": {
        "code": "pending",
        "reason": "confirmation_requested"
    },
    "interaction": {
        "code": "PROCEED",
        "reason": "TAKE_ACTION"
    },
    "identification": {
        "longId": "5b2a0f2bb43816126fbc8c45epenavjgddia1ulnlifgubt871",
        "shortId": "06952-59863",
        "transactionId": "order-00134",
        "pspId": "EC-76K226716U766243M"
    },
    "customerCollectedDetails": {
        "number": "V59NSS56H39BY",
        "email": "paypal_test_account@optile.net",
        "verified": true,
        "name": {
            "firstName": "Tester",
            "lastName": "Optile"
        },
        "addresses": {
            "shipping": {
                "street": "Schlossstraße 26",
                "zip": "12163",
                "city": "Berlin",
                "country": "DE",
                "name": {
                    "firstName": "Markus",
                    "lastName": "Mustermann"
                }
            }
        }
    },
    "network": "PAYPAL",
    "payment": {
        "reference": "Payment #1",
        "amount": 19.95,
        "currency": "EUR"
    },
    "products": [
        {
            "name": "Product #1",
            "amount": 19.95,
            "currency": "EUR"
        }
    ]
}

GET Express PRESET

On the Summary Page your system should display the selected payment method and especially address data of the customer for confirmation. This is the data that was shared by the Express Checkout provider. You can retrieve it with the following call (through the Server API only).

You can also use this information to complement a potential registration of the customer on your systems.

Please sign in to view further details of this article. Login

Web Content Display

Express CONFIRM & CHARGE

The CONFIRM call on an Express PRESET object should be triggered by your system when the user confirms the purchase on the Summary Page. It only exists as a server-to-server version.

This call signals to the Express Provider that the users have given  their final confirmation on the purchase. However, in contrast to a regular payment flow, this one call does not execute the payment yet, therefore we modeled it as a CONFIRM call that is separate from the consecutive CHARGE.

This separation gives you the full flexibility on when to issue the CHARGE after the CONFIRM. Some providers allow up to 3 months of time between the two, which can be an interesting opportunity for some business cases.

Also it allows a differentiated result handling: Since both steps represent two different technical concepts on the provider side (the session and the actual payment) you can react to the results accordingly. Specifically, unsuccessful CONFIRM often indicates an incomplete selection of address and/or payment entries of the customer, so in this case the customer would rather be routed back to complete the selection. A denied CHARGE, however, could be repeated without customer interaction, because it is not related to the selection session anymore.

In any case the CONFIRM call is the last step where the amount could be increased substantially. After this step you may still decrease or adjust the amount for shipping, depending on the providers, see CHARGE below.

CONFIRM Express PRESET example call (Server API only):

POST https://api.sandbox.oscato.com/api/presets/5ac38dc32d221135dfda2452e4566els2p1keb6stu2fmfe199/confirm

  • Authorization: Basic ABC1234567.... (user name: merchant code, password: payment token)
CONFIRM Express PRESET request (Server API):
{
    "payment": {
        "reference": "Payment #1",
        "amount": 29.90,
        "currency": "EUR"
    },
    "products": [
        {
            "name": "Product #1",
            "amount": 19.95,
            "currency": "EUR"
        },
        {
            "name": "Added Product #2",
            "amount": 9.95,
            "currency": "EUR"
        }
    ]
}

Response:
{
    "links": {
        "self": "https://api.sandbox.oscato.com/api/presets/5b2a0f2bb43816126fbc8c45epenavjgddia1ulnlifgubt871",
        "charge": "https://api.sandbox.oscato.com/api/presets/5b2a0f2bb43816126fbc8c45epenavjgddia1ulnlifgubt871/charge"
    },
    "timestamp": "2018-06-20T08:27:47.003+0000",
    "operation": "EXPRESSPRESET",
    "resultCode": "00000.PAYPAL.000",
    "resultInfo": "The payment is pending because it is part of an order that has been authorized but not settled",
    "pspCode": "PAYPAL",
    "returnCode": {
        "name": "OK",
        "source": "PSP"
    },
    "status": {
        "code": "preset",
        "reason": "preset"
    },
    "interaction": {
        "code": "PROCEED",
        "reason": "OK"
    },
    "identification": {
        "longId": "5b2a0f2bb43816126fbc8c45epenavjgddia1ulnlifgubt871",
        "shortId": "06952-59863",
        "transactionId": "order-00134",
        "pspId": "EC-76K226716U766243M"
    },
    "customerCollectedDetails": {
        "number": "V59NSS56H39BY",
        "email": "paypal_test_account@optile.net",
        "verified": true,
        "name": {
            "firstName": "Tester",
            "lastName": "Optile"
        },
        "addresses": {
            "shipping": {
                "street": "Schlossstraße 26",
                "zip": "12163",
                "city": "Berlin",
                "country": "DE",
                "name": {
                    "firstName": "Markus",
                    "lastName": "Mustermann"
                }
            }
        }
    },
    "network": "PAYPAL",
    "payment": {
        "reference": "Payment #1",
        "amount": 29.90,
        "currency": "EUR"
    },
    "products": [
        {
            "name": "Product #1",
            "amount": 19.95,
            "currency": "EUR"
        },
        {
            "name": "Added Product #2",
            "amount": 9.95,
            "currency": "EUR"
        }
    ]
}

CHARGE Express PRESET (Server API only)

To execute the payment your server system does an (authenticated) POST request to the URL given as links.charge in the PRESET object, for example:

https://api.sandbox.oscato.com/api/presets/5b2a0f2bb43816126fbc8c45epenavjgddia1ulnlifgubt871/charge

It typically happens immediately after the CHARGE and has an empty body {}, because all data was already given previously. Substantial increases of the payment amount or ordered products are not possible at this stage anymore. However, there is some allowance to cover shipping costs or similar. Therefore you can pass a payment and products structure in this call also.

The following are the constraints for widely-used providers at the time of writing. Please always consult with your account manager on the provider side to get your specific and most up-to-date conditions.

PayPal Express

Amazon Pay

Express CONFIRM & CHARGE

Please sign in to view further details of this article. Login

Web Content Display

Status Model

The following diagram gives you an overview about the common status transitions and the corresponding Interaction Codes of an Express PRESET object in an Express Checkout flow. Please note that in corner cases also other transitions and/or codes could occur, so your system should be robust against that. Also, related objects such as CHARGE will have different states which you can find in the general code reference.
State Diagram

Status Model

The following diagram gives you an overview about the common status transitions and the corresponding Interaction Codes of an Express PRESET object in an Express Checkout flow. Please note that in corner cases also other transitions and/or codes could occur, so your system should be robust against that. Also, related objects such as CHARGE will have different states which you can find in the general code reference.

Please sign in to view further details of this article. Login