Skip to main content

Create a shopping session

Every shopping journey starts with a session. Your backend creates it and receives a single-use exchange token; your app hands that token to the SDK, which redeems it for a session-scoped credential and opens the merchant.

Create the session from your backend

info

For security reasons, sessions must be created from your backend (server-to-server) using your OAuth access token. The exchange token is single-use with a 60-second TTL — mint it when the customer opens the merchant, not in advance.

Call the Create in-app shopping session API with the merchant domain:

Sample request

{
"domain": "nike.com/sg",
"tenant_user_ref": "CUST0001"
}

Sample response

{
"session_id": "01927d8a-9c3e-7b7a-9f4e-1d2a3b4c5d6e",
"exchange_token": "8f4a2b1c9d3e7f5a6b8c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a",
"expires_at": "2026-07-08T13:00:00Z",
"merchant": {
"id": "9b2f4e1c-6d8a-4f3b-8c5e-7a1b2c3d4e5f",
"domain": "nike.com/sg",
"name": "Nike",
"automation": {
"checkout_urls": ["https://www.nike.com/**/checkout**"]
}
}
}

Forward session_id, exchange_token, the merchant identity, and automation.checkout_urls to your app. Keep session_id on your backend too — you will need it to create the transaction later.

tip

domain may include a locale path — nike.com/sg and nike.com/jp are distinct merchants.

Attach the SDK to your WebView

Attach the SDK to the WebView that will host the merchant. This registers the callbacks through which the SDK talks to your app:

WebViewHolder.kt
val session: InAppShoppingSession = OfInAppShoppingSdk.attach(
webView = webView,
sessionCallback = object : SessionCallback {
override fun onSuccess() { /* session active — customer can shop */ }
override fun onError(error: OpenFabricError) { /* show error, offer retry */ }
},
checkoutCallback = object : CheckoutCallback {
override fun onCheckoutDetected() { /* show your payment hint */ }
override fun onCheckoutExited() { /* hide the hint */ }
},
onSessionExpiredCallback = object : OnSessionExpiredCallback {
override fun onSessionExpired(sessionId: String) {
// create a fresh session via your backend and restart
}
},
)
CallbackFired when
SessionCallback.onSuccessThe exchange token was redeemed and the session is active.
SessionCallback.onErrorSession start failed (expired/used exchange token, network error).
CheckoutCallback.onCheckoutDetectedThe WebView URL entered a checkout page (matched against checkoutUrls).
CheckoutCallback.onCheckoutExitedThe customer navigated away from checkout.
OnSessionExpiredCallback.onSessionExpiredThe session credential expired mid-flow (see below).

Start the session

Pass the values received from your backend:

session.startSession(
InAppSessionConfiguration(
sessionId = sessionId,
merchantId = merchantId,
merchantName = merchantName,
merchantUrl = "https://www.nike.com/sg",
exchangeToken = exchangeToken,
checkoutUrls = checkoutUrls, // from the merchant.automation response
)
)

Under the hood, the SDK generates an RSA-2048 keypair on the device (the private key never leaves it), redeems the exchange token for a session-scoped token valid for 3 hours, and loads merchantUrl into the WebView. It never mints or holds any other credential.

checkoutUrls are glob-style patterns (** matches any characters including /, * any characters except /). When the WebView URL matches one, onCheckoutDetected fires.

Handle expiry and teardown

  • Expiry: if the session outlives its 3-hour credential, the SDK fires onSessionExpired(sessionId) — either proactively before a call, or on a rejected request. Create a fresh session via your backend and restart the flow; the exchange token cannot be reused.
  • Teardown: call session.close() when the customer dismisses the shopping screen, and destroy the WebView. Only one session can be active per process — close() frees it.

Next: Capture and approve the order.