Hooks
Hooks are passed at init (and again at restore, since they hold code). Each is a suspend lambda.
PurseHeadlessCheckout.init(
widgetData,
hooks = PurseCheckoutHooks(
onBeforeValidate = { splits -> backend.reserveStock(splits) }, // throwing aborts the submit, nothing is sent
onAfterValidate = { backend.notifyValidateDone() }, // errors swallowed, reported to monitoring
onRedirection = { action -> // true = you open it, false = the SDK does
when (action) {
is RedirectAction.Get -> { openInCustomTab(action.url); true }
else -> false
}
},
),
)
| Hook | When | If it throws |
|---|---|---|
onBeforeValidate(splits) | After the item payloads are built, right before POST /validate, including when Google Pay or PayPal self-submit | The submit is aborted before anything is sent: HookFailed with ON_BEFORE_VALIDATE_HOOK_FAILED, split and data untouched, sessionState back to READY |
onAfterValidate() | After /validate answers, before any redirect | Swallowed, reported as a HEADLESS_CHECKOUT_CLIENT_HOOK_ERROR monitoring event |
onRedirection(action) | /validate asked for a redirect. Return true to open it yourself, false to let the SDK open its Activity | Nothing is opened. The payment element reports Failed with a HookFailed (POST_VALIDATE_FAILED). /validate has already answered, so the session is spent: a new submit throws SubmitBlocked. Get the outcome from your backend or start a new client session |
Take a redirect over
RedirectAction is sealed: Get(url) opens a URL, PostForm posts fields to a URL, PostHtml renders a PSP-provided HTML document that submits itself. A Custom Tab can only handle Get; return false for the other two so the SDK's WebView handles them.
When you return true, the payment element receives no ReturnedFromRedirect: detect the shopper's return yourself, and get the final status from your backend, through webhooks or Get a client session.
The SDK's Activity restricts navigation to https, blocks file and content access, and recognizes the app's own return scheme. Take a redirect over only when a PSP page refuses to render in an embedded WebView.