Documentation

1General Idea of Web Apps

With a web app an external system can request access to specific spaces via the web service API. The user can grant access to other systems in an automated way. The OAuth 2.0 flow specifies this concept in detail.

In general, the OAuth specification provides some room for adaptations to this concrete use case.

2OAuth 2.0 Flow

The integration generally follows the OAuth specification. The flow involves the following actors:

  • User: The user can grant the web app access to a Space. The user is usually the merchant that is granting access to your app.

  • Client: The client invokes the web service API to access the data within the Space. This is your app. Your app might run on a web server too.

  • Server: We use in this documentation the term server for our system. As in the client-server pattern our system represents the server.

To keep this documentation simple we reuse the terminology from the OAuth specification.

OAuth Flow
Figure 1. The OAuth 2.0 flow with the different actors.

The above figure shows the following steps:

  1. The user requests the installation of the web app.

  2. The web app (client) returns the authorization URL to which the user grants access to the web app. The authorization URL requires that a redirect_uri is present.

  3. When the user invokes the authorization URL, the server will in turn request the user to confirm the requested permission on the space. As a result the server will return the redirect_uri to the browser.

  4. The browser invokes the redirect_uri which points to a URL controlled by the web app. The redirect_uri contains a code parameter with which the web app can request the installation of the app.

The following sections cover the above steps in further detail.

2.1Create the web app configuration

As a first step you have to set up a web app and retrieve the client_id and client_secret.

2.2Trigger the installation

There are two ways as how the user can start the installation. In both cases the web app has to forward the user to the authorization URL. See Ask for permission on how to do that.

  • Option 1: The user triggers the installation from within our application. In this case we forward the user to the Installation Redirect URL as defined in the web app configuration. In this case the user will invoke the Installation Redirect URL as a GET HTTP request. We ensure that the request contains the following parameters:

    • space_id: The app is installed into the space resolved by the space ID.

    • timestamp: The timestamp in seconds since 1970. This allows to check for replay attacks. It is recommended to deny requests that are older than a few hours.

    • hmac: A HMAC is calculated based on the space_id and timestamp request parameters. This allows the verification of a request is really originating from us. See HMAC Calculation.

  • Option 2: The user is triggering the installation from within the web app. In this case the web app has to ask for the space ID or use another approach to retrieve it.

2.3Ask for permission

To ask the user for the permission the user has to be forwarded to: https://app-wallee.com/oauth/authorize

The request must contain the following request parameters:

  • space_id: The app is installed into the space resolved by the space ID.

  • redirect_uri: The URI to which the user is forwarded back after the user has authorized the access. The web app configuration must contain this URL as redirection endpoint, otherwise it will be rejected.

  • scope: The scope parameter contains a space separated list of permission IDs which are requested. The permission list provides the full list of all permissions that can be requested.

  • state: A randomly generated value provided by your app (client) that is unique for each authorization request. When the user returns to the redirect_uri we include this value again. It is important that you check this value as the security can be compromised. We recommended that you ensure that the state cannot be used for replay attacks (e.g. include a timestamp and reject requests that are too old).

  • client_id: The client ID that identifies your app. The client ID can be retrieved in the web app configuration.

If you request permissions in the parameter scope that require specific features which are not available to the space we either try to activate those features or return a reduced set of permission at the installation confirmation. So we remove the permissions that we cannot grant.

Example request:

https://app-wallee.com/oauth/v2/authorize?space_id=15023&client_id=14141&redirect_uri=https%3A%2F%2Fexample.com%2Fconfirm%2Finstall&state=1609445756&scope=1432736711150%201432736711152
Note
In case you want to alter the permissions to the web app at some point, you can execute the same steps as if you would install the app from scratch. You can forward the user to the https://app-wallee.com/oauth/v2/authorize with the adapted scope parameter. All the following steps remain the same.

2.4Confirm the app installation

When the user returns to the redirect_uri the web app has to confirm the installation and retrieve the access_token according to the OAuth specification.

Along the redirect_uri the following parameters will be sent:

  • state: The state parameter contains the value as passed to the authorization URL. Verify that this value is identical to the value you have passed.

  • space_id: The ID of the space the user has granted access to.

  • timestamp: The time when the user granted access. The time is in seconds since 1970 (Unix timestamp). Check this that the grant is not too old. A feasible time here is about 10 minutes. This prevents replay attacks.

  • code: The code identifies the grant created in the previous step. You need this code for confirming the installation. See below how to do that.

  • hmac: The HMAC allows to verify that the request has not been tampered. See HMAC Calculation for how you can do that.

Example request:

https://example.com/confirm/install?state=1609445756&space_id=14141&timestamp=1609449756&code=AdF7812311414312312387483&hmac=8jAYtV4R7FFTjl3UqWpkmBy78PVQdDygJ1NbM7v_-1AcAMWMhv45PPJA-nYkNT4gCNZ2XECYF3-N5W29ZXGJ6Q

To confirm the installation you have to send an API call. You have to send the following POST message to the URL https://app-wallee.com/api/web-app/confirm. See also in the web service documentation. As this is a regular web service endpoint:

{
   "code": "AdF7812311414312312387483"
}

As this is a regular web service endpoint you have to provide the authentication credentials in the header of the HTTP request. For this purpose use the client_id as the user ID and for the client_secret the secret.

The response looks similar the following example:

{
    "access_token": "dummy-value",
    "token_type": "web-service-hmac",
    "state": "1609445756",
    "scope": "1432736711150 1432736711152",
    "space": {
      "id": 14141,
      "name": "Test",
      "postalAddress": {
         "city": "Winterthur",
         "country": "CH",
         "dependentLocality": null,
         "emailAddress": "test@test.com",
         "familyName": null,
         "givenName": null,
         "organizationName": "Muster AG",
         "postalState": null,
         "postcode": "8400",
         "postCode": "8400",
         "salesTaxNumber": null,
         "salutation": null,
         "sortingCode": null,
         "street": "General-Guisan-Strasse 47"
      },
      "primaryCurrency": "CHF",
      "state": "ACTIVE",
      "technicalContactAddresses": [],
      "timeZone": "Europe/Zurich",
      [...]
   }
}

In this step you should check whether the returned scope list correspond to what you have requested and if the returned set does fulfill your requirements. As indicated before not in all situations all requested permissions can be granted.

The next step covers how to actually invoke the web service API.

2.5Access the web service API

Once the app has been successfully installed in the space, the client_id and client_secret can be used to access the web service API for the given space. On the web service API you have to use the client_id as the user ID and the client_secret as the secret. The invocation of the API is the same as if you would create an application user and use their credentials to invoke the API.

3Notifications

To keep your web app in sync with the installation state within the different spaces we recommend to set up a notification URL. Any change to the installation of the web app within a space will be reported on that URL.

We send a HTTP POST message with the following body:

{
	"space_id": 15023,
	"client_id": "14141",
}

Whether the app has been installed or deinstalled is not part of the message. Use the web service API to find out what was the trigger that we send out this message.

The above behavior is intentionally. It solves the following issues:

  • It may occur that a notification is sent out with a delay because we were having difficulties reaching your system. In that case you still read the installation state from one single source that holds the correct state.

  • There are no security risks as no critical information within the HTTP request are included. The message is just a trigger that you fetch the correct information through the web service API.

  • In some cases the web app and our system might get out of sync due to temporary outages. With the above approach you can decide to retrieve the current installation state at any point.

Note
Be aware that an outage of your system might prevent us from sending notifications to your system. In that case we send an email if specified in your web app configuration.

4HMAC Calculation

To verify the requests are originating from our system we append an HMAC with SHA-512. It guarantees that the parameters are not modified during the transmission. This is similar to a normal hash but in a secure way. Most programming languages provide an implementation for the HMAC calculation.

Generally we have to construct a string first and secure it later with the client_secret. To do so we take all the parameters, order them alphabetically, and concatenate them with an | (pipe).

See the following PHP example with the parameters: space_id, timestamp, client_id and scope

<?php

$client_secret = "OWOMg2gnaSx1nukAM6SN2vxedfY1yLPONvcTKbhDv7I";

$requestParameters = array();
$requestParameters['client_id'] = "14141";
$requestParameters['state'] = "87ggfr456zghjui876tgvbji";
$requestParameters['space_id'] = 15023;
$requestParameters['scope'] = "1432736711150 1432736711152";

// We sort the array elements by the element's key
ksort($requestParameters);


$parametersToSecure = array();

foreach ($requestParameters as $key => $value) {
	$parametersToSecure[] = $key . "=" . $value;
}

$toSecure = implode('|', $parametersToSecure);

$decodedSecret = base64_decode($client_secret);
$hmacValue = base64_encode(hash_hmac("sha512", $toSecure, $decodedSecret, true));

// Replacing "+" with "-" and "/" with "_"
$cleanedMac = $url = strtr($hmacValue, '+/', '-_');

// Remove padding
$cleanedMac = rtrim($cleanedMac, '=');

echo $cleanedMac;

Remarks:

  • We do not URL encode the parameters when we calculate the HMAC.

  • The client_secret provided in the web app configuration page is encoded as Base64 string. We first need to convert it into a binary.

  • The parameters that need to be secured depend on the use case. We are using the HMAC in multiple situations so please adapt the parameters accordingly. We only include the parameters that are explicitly listed. We never include all parameters. So if the request contains further parameters, ignore them.

  • The HMAC included in the request is always Base64 encoded. When you compare the calculated HMAC with the passed HMAC, please compare them in the binary format or make sure you unify the different Base64 formats first. Due to the fact that we are passing the HMAC as an URL parameter we have to use a URL safe implementation without padding. See RFC 4648