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 will contain a Set-Cookie header with a session token which should be present when loading the microsite iFrame. The response body also includes the session token inside the session property. This can be used as the cookie value to make it easier to support situations where it’s necessary to manually create the cookie for the WebView rather than relying on ambient cookies. In this scenario the cookie should be created with following configuration:
Name: session
Path: /
HttpOnly: true
Secure: true
SameSite: None
An additional cookie should be set to support older browsers using the following configuration:
Name: session_legacy
Path: /
HttpOnly: true
Secure: true
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"
}
}
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=="
}
}
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.
- 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 cookie 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.