The White Label Loyalty (WLL) Microsite provides the simplest mechanism to integrate WLL’s loyalty platform into an app or website. It provides all UI and handles all user loyalty interactions internally, meaning that the integrator need not necessarily interact with WLL’s APIs at all. The microsite can be embedded in a website iFrame, app WebView, or the integrator could redirect to it when needed.
By default the Microsite is configured to use an interactive authentication strategy where the user must enter their authentication information to see their account details. However, when embedding in a website or app this behaviour is not usually desirable since it adds an unnecessary step to the user journey when the app/website context already holds the user’s session information. To handle this situation, the Microsite also supports a non-interactive authentication strategy which allows a user’s session to be passed in the background from the app/website context to the microsite, thereby enabling authentication which is transparent to the user. This strategy requires a small amount of additional work as explained in the Authenticating Users section.
Note: all URL examples below use $customer.web.wlloyalty.net as the base domain; you can replace this with your own default domain or custom domain (if configured).
Authenticating Users
To authenticate a user transparently in the background a HTTP request with the user’s details should be sent to https://$customer.web.wlloyalty.net/api/auth. This request dictates which user should be authenticated (via the selector property) and provides the most up-to-date profile information for that user. If no account exists for the specified user, the Microsite will automatically create a new one using the data passed in the profile property of the request. If an account already exists the user’s profile information will be updated to reflect the provided profile data.
The X-Client-ID header should be included in the request to identify the requester.
The selector.authIdentifier property should contain the pre-existing user identifier that is already known in the website or app session context. The emailAddress, givenName, and familyName profile fields are mandatory, the other fields are optional though they should be provided if possible to enable the experience to be better tailored to the user.
Note: this is an upsert method meaning that if a user already exists with the specified identifier, their profile details will be updated with the data passed in the request.
If successful, the response body will contain the user's session token inside the session property. This token should be passed in the request when loading the microsite within an iFrame so that the user views the interface from their logged-in perspective. The session token can be passed to the microsite by one of two ways:
- Creating a cookie
- Passing the token in the URL when first loading the microsite.
Request Example
POST /api/auth HTTP/1.1
Host: $customer.web.wlloyalty.net
Content-Type: application/json
Accept: application/json
X-Client-ID: CLIENT-ID-HERE
{
"selector": {
"authIdentifier": "USER-IDENTIFIER-HERE"
},
"profile": {
"givenName": "Jane",
"familyName": "Doe",
"emailAddress": "jane.doe@example.com",
"gender": "FEMALE",
"birthdate": "1980-01-01",
"country": "GB",
"city": "Leeds",
"postcode": "LS1 5PZ",
"pictureUrl": "https://example.com/pic.jpg",
"streetAddress": "99 Road Street",
"region": "West Yorkshire",
"telephoneNumber": "01437532699"
}
}
Response Example
HTTP/1.1 200 OK
Set-Cookie: session=p%2B6BqjiOhRvKvD0DxX632%2FAEiZExMAAY4AEQR1qt%2Bhr1nRLdoxuTrS01kecZjPsyMwGQ6GoyiaQvxW%2BNLXWnrYdeWoIoemeg0RU2qkEn4A%3D%3D; Max-Age=259200; Domain=customer.web.wlloyalty.net; Secure; SameSite=None
Content-Type: application/json; charset=utf-8
Content-Length: 384
{
"status": "success",
"data": {
"user": {
"externalIdentifier": "5b2257d404e0e30bf729cbf2"
"authIdentifier": "5b2257d404e0e30bf729cbf2",
"isRestricted": false,
"id": "d9d35027-58e3-4167-8e22-a81728f46f62",
"createdAt": "2018-07-20T09:19:54.699Z",
"updatedAt": "2019-08-21T10:22:48.017Z",
"flags": {
"genderProvided": true
}
},
"session": "p+6BqjiOhRvKvD0DxX632/AEiZExMAAY4AEQR1qt+hr1nRLdoxuTrS01kecZjPsyMwGQ6GoyiaQvxW+NLXWnrYdeWoIoemeg0RU2qkEn4A=="
}
}
Passing Session via Cookie
In this scenario a cookie should be created with following configuration and added to the device ambient environment:
Name: session
Domain: rootdomain.com
Path: /
HttpOnly: true
Secure: true
SameSite: None
An additional cookie should be set to support older browsers using the following configuration:
Name: session_legacy
Domain: rootdomain.com
Path: /
HttpOnly: true
Secure: true
Note that the above configuration specifies the cookie domain, this should be set to root/bare domain under which both the microsite and parent website are accessed from. For example, assuming you've configured a custom domain for the microsite to make it accessible at microsite.example.com and the website which is embedding the microsite is accessible at www.example.com then the cookie domain should be set as example.com.
Passing Session via Query Parameter
In this scenario you can append a session query parameter in the microsite URL using the token as the value. Meaning that your iFrame or WebView would load a URL like https://$customer.web.wlloyalty.net/?session=abc123.
Embedding in a website
We've provided an example of embedding the microsite in an iframe: https://github.com/white-label-loyalty/microsite-web-example
Handling authentication
This section is only relevant where non-interactive authentication is required. In this case the steps are as follows:
- Make an HTTP request (as outlined in the previous section) to the microsite authentication endpoint when the user logs in to the parent website. We recommend initiating this request from the server-side context so that the “Client ID” is protected.
- Pass the returned session token in the iFrame request either as a session query param or as a cookie. Details for cookies below:
- Ensure the user’s browser receives the session cookie. If the authentication request is made from the browser context then the endpoint’s response will automatically set this cookie. If the authentication request is made from the server context (more secure) the “Set-Cookie” header should be forwarded in the server’s response to the browser. Alternatively the cookie can be re-constructed as explained in the previous section.
- Ensure the cookie is present in the user’s browser before loading the iFrame.
Configuring the iFrame
A simple iFrame should be added to the website which points to the microsite’s root URL https://$customer.web.wlloyalty.net. By default it will load the English language version of the UI but if the user should be shown a different language, then the relevant language code should be supplied as a ?lang= parameter. For example, the following URL would load the French version: https://$customer.web.wlloyalty.net?lang=fr. The other available language options currently supported are German (de) and Italian (it).
Embedding in an app
The main steps required for configuring the WebView are:
- Ensuring the app has the correct platform permissions.
- Supplying the necessary UI handlers, e.g. confirmation dialogs, file access.
- Ensuring the generated session token is included in the WebView request.
- Loading the relevant URL for the user’s locale.
Some specific platform examples for some of this configuration is provided below.
The root URL to load is https://$customer.web.wlloyalty.net. By default it will load the English language version of the UI but if the user should be shown a different language, then the relevant language code should be supplied as a ?lang= parameter. For example, to load the French version of the this URL should be loaded: https:/$customer.web.wlloyalty.net?lang=fr , the other currently available language options are de (German) and it (Italian). Other locales can be added on request.
iOS Examples
Permissions
Below is the minimal known set of requirements for the app’s Info.plist. The camera and photo permissions are only needed if you will be using the receipt scanning feature.
<dict>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<key>NSCameraUsageDescription</key>
<string>Camera access required to scan receipts.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>We need to verify your location to redeem a voucher.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>Photo library access required to select receipt photos.</string>
</dict>
UI handlers
The view controller containing the WebView should implement the following method of the WKUIDelegate protocol to support native confirmation dialogs:
func webView(_ webView: WKWebView,
runJavaScriptConfirmPanelWithMessage message: String,
initiatedByFrame frame: WKFrameInfo,
completionHandler: @escaping (Bool) -> Void) {
let alertController = UIAlertController(title: message,
message: nil,
preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "OK",
style: .default,
handler: { (action) in
completionHandler(true)
}))
alertController.addAction(UIAlertAction(title: "Cancel",
style: .cancel,
handler: { (action) in
completionHandler(false)
}))
present(alertController, animated: true, completion: nil)
}
Android Examples
Permissions
Below is the minimal known set of requirements for the app’s manifest. The camera and photo permissions are only needed if you will be using the receipt scanning feature.
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
UI Handlers
The Android configuration for the WebView handlers is somewhat more involved, an example configuration can be view in this repository.