Skip to main content

Run the payment

With the transaction approved, hand the credentials to the SDK. It fetches the virtual card, fills the merchant's payment form, and submits — all without the card ever being visible.

Hand the credentials to the SDK

session.runPaymentAutomation(
paymentAttemptId = paymentAttemptId,
cardFetchToken = cardFetchToken,
callback = object : AutomationCallback {
override fun onSuccess(flowId: String?) {
// Payment submitted on the merchant page — show your success state
}
override fun onPreconditionFailed(message: String) {
// The merchant page needs a user action first (e.g. a delivery
// slot isn't selected) — show the message and let the user retry
}
override fun onFailure(error: OpenFabricError) {
// Automation failed — the merchant's own payment form is restored
}
},
)
CallbackFired when
onSuccess(flowId)The card was filled and the payment form submitted on the merchant page.
onPreconditionFailed(message)A guard check blocked the flow before any payment step ran — the customer needs to complete something on the merchant page first. See below.
onFailure(error)All payment flows failed; the merchant's own payment form has been restored.
note

runPaymentAutomation requires a prior successful requestOrderDetails in the same session — that call also prepares the payment steps for the current checkout page.

What happens on-device

  1. The SDK calls the Open Fabric Issuer service directly with the card_fetch_token, authenticated by its session token. Card data never passes through the analysis service or your app.
  2. The issuer returns the card number and CVV encrypted with the RSA-2048 public key the SDK generated at session start. Decryption happens on-device with the private key that never left it.
  3. The SDK executes the merchant's payment steps — selecting card payment, filling the card fields (hidden from the customer), and submitting the form.
  4. The result is reported back to Open Fabric for merchant health monitoring, and to your app via the callback.

Handle failures

Precondition blocked — onPreconditionFailed

Some merchants require a step the customer must complete themselves before payment can run — selecting a delivery slot, for example. When such a guard blocks the flow, the SDK fires onPreconditionFailed(message) without attempting payment:

  • message is user-facing — surface it as-is (e.g. a toast) so the customer knows what to fix on the merchant page.
  • Keep your payment surface open. Once the customer completes the missing step, call runPaymentAutomation again with the same paymentAttemptId and cardFetchToken.
  • Overriding onPreconditionFailed is optional — if you don't, it falls through to onFailure. Override it to give customers the retry experience instead of a terminal failure.

Automation failed — onFailure

onFailure means the automation could not complete — typically because the merchant changed their checkout page. The SDK has already restored the merchant's payment form by the time the callback fires:

  • Show a brief, non-blocking notice (e.g. a toast) and let the customer complete the purchase with the merchant's own payment methods. Never dead-end the customer.
  • Failures are reported to Open Fabric automatically and feed the merchant's health monitoring, which triggers configuration repair on our side. No action is needed from you beyond the graceful fallback.
  • If the transaction should not proceed at all, handle the cancellation on your backend against the approved transaction.
PCI posture

The decrypted card exists only transiently in SDK memory during form filling and is cleared afterwards. It is never persisted on the device, never shown to the customer (debug = false), never logged, and never sent to your app or backend.

Where to go from here

onSuccess is not the final payment confirmation

onSuccess(flowId) means the SDK successfully submitted the card on the merchant's checkout page — not that the payment has cleared. Your customer sees the merchant's own order confirmation in the WebView.

The authoritative payment outcome reaches your backend asynchronously, as transaction lifecycle events (charge, reversal) over your notification channels. Update your customer's balance, order status, and ledgers from those events — not from onSuccess alone.

  • Transaction lifecycle events (charge, reversal) reach your backend through your existing notification channels — see Notifications.
  • For end-to-end testing, use the sandbox SDK with sandbox credentials — see Testing and go-live.