Designing a confirm-and-pay flow an agent can run
The payment path end to end: where the write is intercepted, what the card must show, when a biometric is worth asking for, and why speech is never the credential.
About this article
A payment an agent initiates should stop at a sentinel in your server code, resurface as one confirm card showing the amount, recipient and fee, and execute only on a separate request carrying the approval. Ask for a device biometric on the highest-risk actions only, and never treat the user's voice as an authentication factor.
A payment is the one action where everything ambiguous about an agent becomes concrete. The user said something, a model understood something, and money either moves or does not. Every design decision in between is legible afterwards, in a support ticket or a chargeback.
This post is the payment flow specifically, from the spoken request to the audit row. Two adjacent pieces cover the general shape: the confirm card as a boundary in code rather than a line in a prompt is the architecture, and deciding which actions are worth a biometric is the tiering. This one is what happens on the path where the amount is real.
Intercept the write, do not instruct the model to pause#
The design mistake that produces the worst incidents is putting the confirmation in the prompt. “Always ask the user before transferring money” is a request, and a request is the wrong shape for a control on money movement. Anything that can change what the model reads can change what the model does, which is the whole argument in what prompt injection looks like when the agent can spend.
The structure that holds is a short circuit. Tools that write are registered as action tools, and when the model calls one, your server does not execute it. It returns a sentinel, reads the arguments the model produced, and builds a confirm card from them. The model has named an intention; nothing has happened.
Execution is a second request. It carries the identifier of the approved confirmation, and your server checks that identifier against its own record before touching the payments backend. Approval becomes a row you can query rather than a sentence in a transcript.
One more rule earns its place here. Build exactly one confirm card per turn, in your server, and stop the model from authoring a second details card alongside it. Two cards showing overlapping numbers is how a user approves the wrong one.
What the card has to show#
The confirm card is the legal record of what the user agreed to, so it carries the things that decide the payment: amount and currency written out, the recipient in a form the user recognises, any fee, and when the money arrives. If the agent inferred the recipient from a nickname, the card shows what it resolved to, masked to the last four digits where the identifier is an account number.
It also has to be the card, not a card. Approving on a summary while the real arguments differ is the failure mode that makes the whole pattern worthless, so the card must be generated from the same parsed arguments the execute path will use. Drawing it as a widget from the render spec rather than as text is what makes that guarantee mechanical.
One consequence worth stating for anyone designing a signup path: this is a poor first experience. A write is the wrong thing to meet a new user with, which is why getting somebody to first value usually starts with a read.

The spoken channel and the drawn channel do different jobs#
Speech is poor at numbers the user must verify. It arrives once, cannot be re-read, and an amount misheard by a factor of ten sounds almost identical to the correct one.
So the division is fixed. The agent says enough to orient the user and ask for a decision. The card holds every figure that matters. After settlement the agent says the payment went through and leaves the reference on screen, because nobody transcribes a reference number from audio correctly.
The second prohibition is less obvious and worth keeping. The agent should not say “confirm with Face ID”. The device decides which gate it can offer, that decision can change between sessions, and an agent that announces a method the device then does not present has told the user their phone is broken.
When the biometric is worth asking for#
Not on everything. A confirmation tax applied uniformly trains people to approve without reading, which removes the value of the confirmation you are paying for.
Tier it by what the action can cost if it is wrong. In our own Paymob configuration, every money-moving tool is confirm-gated and exactly one of them escalates to a device biometric: instant settlement, which moves a merchant’s own balance out on request. Creating a payment link is tap-to-confirm, because the worst case is a link nobody uses.
Android documents the mechanism for the top tier plainly. Biometric authenticators are classed as BIOMETRIC_STRONG or BIOMETRIC_WEAK, a CryptoObject binds the prompt to a cryptographic operation, and the platform notes that auth-per-use keys “can be useful for high-value transactions, such as making a large payment or updating a person’s health records” (Android developer documentation). Binding matters: a prompt that only returns a boolean can be satisfied by anything that can set a boolean, while a key that will not perform its operation without the authentication is a different kind of guarantee.
There is an accessibility argument here that usually goes unmade. WCAG 2.2 success criterion 3.3.8 requires that a cognitive function test, such as remembering a password or solving a puzzle, is not required for any authentication step unless an alternative exists, and it treats biometrics as not being cognitive function tests (W3C, Understanding SC 3.3.8). Replacing a re-entered password with a biometric confirmation improves accessibility as well as security, and the accessibility half of that is rarely part of the pitch.
What the platform standards do and do not give you#
WebAuthn Level 3 became a W3C Recommendation on 25 August 2026 and defines the authorization gesture as a physical interaction that may involve either user verification or a simple test of user presence. Those are different guarantees: presence says somebody is there, verification says the authenticator checked who.
What the specification does not define is confirmation of the details of a specific transaction. Its use cases mention authorising a single transaction such as a payment, and the mechanics of showing an amount and binding an approval to it are not in the document. That gap is your application’s job, and it is the reason the confirm card exists as a server-generated artefact rather than as a property of the authenticator.
Payment regulation in several markets imposes its own requirements on authentication and on linking an authorisation to a specific amount and payee. Those rules vary by jurisdiction and change, so check the current text with someone qualified rather than a blog post, including this one.
Speech is not a credential#
Voice biometrics as an authentication factor for payments is the one idea in this area to reject outright.
The evidence for rejecting it is a decade of a well-run challenge series. ASVspoof 5 evaluated submissions from 53 teams against a crowdsourced database whose attacks were generated with 32 different algorithms, and the authors report that “while many solutions perform well, performance degrades under adversarial attacks and the application of neural encoding/compression schemes” (Wang et al., 7 January 2026). Adversarial conditions and codec compression are the attacker’s choice and the telephone network’s default.
The practical posture follows. Treat the microphone as an input channel with no trust attached. Anyone who can reach it can state any intention, and the design assumption should be that they will. What stops the attack is that the request has to resurface as a card on the enrolled device, in the hands of whoever holds it, and clear a gate bound to hardware.
The flow in a banking or merchant app#
The same skeleton holds wherever money moves, and the wider set of decisions a financial app faces sits around it.
Read tools stay open. Balances, transactions and payment status are answers, and gating them makes the agent useless while protecting nothing that the app’s own screens do not already show.
Write tools are all gated, and only some escalate. Publish the tiering as configuration rather than burying it in code, so a compliance reviewer can read which actions require what without reading a codebase.
Failures need a path. A declined biometric, an abandoned card and a timed-out confirmation are three different states and all three need to leave the system in a clean one. The commonest bug in this area is a confirmation that expires while the execute request is already in flight.
Every gate writes a row. Who asked, what the parsed arguments were, which gate was applied, what the user did and what the backend returned. That row is what answers the question a disputed payment eventually raises, which is not “did the model behave” but “what exactly did this person approve”.
Common questions#
How should an agent confirm a payment? By stopping the write in server code, resurfacing the parsed arguments as one confirm card, and executing on a separate request that carries the approval identifier. The confirmation must be a branch in your code, never an instruction in the prompt.
Should the agent read the amount out loud? It should say enough to ask for a decision and leave the figures on the card. Speech arrives once and cannot be re-read, and a misheard amount sounds like a correct one.
When is a biometric worth requiring? On the actions whose worst case is irreversible or large. Applying it everywhere trains people to approve without reading. Android documents auth-per-use keys for high-value transactions, which is the right tier for it.
Can voice recognition authenticate the payer? No. ASVspoof 5 found spoofing detection degrading under adversarial attacks and neural compression across 53 teams’ submissions. Treat speech as an untrusted input and put the trust in the device gate.
Does WebAuthn confirm what the user is approving? It defines the authorization gesture and the distinction between user presence and user verification. Confirming the details of a specific transaction is not defined in the specification, so showing the amount and binding approval to it remains your application’s responsibility.
Sources#
- Android Developers, Show a biometric authentication dialog. Accessed 12 September 2026.
- W3C, Understanding SC 3.3.8: Accessible Authentication (Minimum), WCAG 2.2. Accessed 12 September 2026.
- W3C, Web Authentication: An API for accessing Public Key Credentials, Level 3, Recommendation, 25 August 2026. Accessed 12 September 2026.
- Wang et al., ASVspoof 5: Evaluation of Spoofing, Deepfake, and Adversarial Attack Detection Using Crowdsourced Speech, 7 January 2026. Accessed 12 September 2026.
Next
How an action is gated, what the confirm step guarantees, and what leaves the device.
Read how the security model is wiredThe rest of Safety
Open the clusterConfirm-first actions, biometric tiering, scoped tokens and the audit trail you need before an agent touches money.
- Confirm cards: letting an agent act without losing controlIf the confirmation lives in the prompt it is a suggestion. Make it a branch in your server code, and decide the tier per tool rather than per sentence.12 min
- An agent in a banking app, and the gate before money movesHow to let an agent act inside a fintech app: which actions get a confirm card, which get a biometric, and why the gate lives in code.8 min
- Security and privacy for an agent that can act on your dataThe threat model for an in-app agent is its tool set, not its microphone. The OWASP entries that apply, the injection path, and the controls worth building first.9 min
- Does your agent work eight times out of eight?Average accuracy is the wrong number for a product. Run the same task eight times and count how often it worked every single time.11 min
- Prompt injection when the agent can spend moneyIn a consumer app the untrusted text is your own user's data and the tools move their money, which makes filtering useless and structure the only real defence.10 min
- Which agent actions deserve Face ID, and which do notBiometric-gating everything trains users to approve without reading. Tier agent actions by what they can destroy, and let the platform decide how.10 min
Elsewhere on the map
- An agent in a healthcare app: booking, refills, and the stop lineThe three patient-facing tasks an in-app agent does well, the escalation line that belongs in code, and the compliance question to settle before any of it.Business9 min
- An in-app agent is an accessibility feature, narrowlyAn agent that completes a task is an alternative input path, and one WCAG 2.2 criterion turns the biometric confirm into an accessibility win rather than a tax.Voice10 min
- A catalogue beats free-form generation, and the objections say whyEvery serious objection to generative UI is an objection to free-form generation. A fixed catalogue answers all four without giving up the idea.Render spec10 min
