Two-phase confirmation
Every financial operation follows a two-phase confirmation flow that separates data collection from execution authorization.Phase 1 — in-chat composition
The agent collects transaction details through conversation: destination country, amount, recipient, and payout method. It generates a quote via tool functions and presents a complete transaction summary to the sender. The agent then explicitly asks the sender to confirm, modify, or cancel. This confirmation step is mandated in every agent’s system prompt — it is not optional behavior that the model may skip.Phase 2 — out-of-chat authorization
Upon in-chat confirmation, the agent creates a ticket, generates an authenticated link to a web widget, and sends it to the sender as a short link. The sender opens the link in their browser, completes identity verification (CIP) and/or card authorization in the widget, and the widget submits the result to an encrypted callback URL. The backend operation only executes when the widget’s callback is received and validated. The chat layer initiates the flow; execution requires the widget callback.Callback-gated execution
HttpCallbackProvider creates callback URLs with multiple cryptographic and operational protections:
| Protection | Mechanism |
|---|---|
| Confidentiality | AES encryption for the callback payload |
| Integrity | HMAC signing to prevent tampering |
| Replay prevention | Single-use enforcement — each callback can only be invoked once |
| Expiration | 2-hour TTL — abandoned sessions cannot be resumed |
process_send_call_back) only executes when the web widget POSTs to the callback URL with a valid, encrypted payload containing the matching ticket ID. If any validation fails — wrong ticket, expired TTL, replayed callback, invalid signature — the operation is rejected.
Ticket-based authorization
Every financial operation creates a ticket before generating the widget link. The ticket provides a structured authorization boundary for the web widget.Ticket contents
Ticket contents
Each ticket contains:
- Transaction metadata — summary, amounts, destination, recipient details
- Callback URLs — success and failure endpoints, both encrypted and signed
- Allowed actions — a scoped list defining exactly what the widget can do (e.g.,
cip:scan-id,cip:pol-token,card-validation:query-card) - Attempt limits — maximum retries for specific actions (e.g., 3 card validation attempts)
Widget scope enforcement
Widget scope enforcement
The web widget can only perform actions explicitly listed in the ticket’s
allowed_actions. A ticket created for CIP verification cannot be used for card authorization, and vice versa. This prevents the widget from being repurposed for unauthorized operations.Ticket IDs are validated on callback — if the callback’s ticket ID does not match the expected ticket, the operation is rejected.Operation lifecycle
The full lifecycle of a financial operation follows this path:- Chat collects data — the agent converses with the sender to gather transaction details
- Agent generates quote — the
pre_quotetool function returns exchange rates and fees from the backend - Summary displayed — the agent presents the complete transaction summary for sender review
- Sender confirms in chat — the sender explicitly approves the transaction details
- Ticket created — the agent creates a ticket with transaction metadata, allowed actions, and callback URLs
- Short link generated — an authenticated link to the web widget is created and sent to the sender
- Sender opens widget — the sender opens the link in their browser, outside the chat channel
- CIP/card flow completed — the sender completes identity verification and/or card authorization in the widget
- Widget POSTs to callback — the widget submits the encrypted, signed result to the callback URL
- Backend executes operation — the backend validates the callback and executes the remittance
- Confirmation sent to chat — the agent notifies the sender of the operation result
Steps 7 through 10 occur entirely outside the chat channel. The AI agent has no involvement in the authorization phase — it only initiates the flow and reports the result.
Escalation to human agents
Chatwoot integration enables the bank to route conversations to live human agents when they fall outside automated handling:- The bank defines escalation triggers — sender frustration, repeated failures, compliance edge cases, or explicit requests for human assistance
- All conversation history is available to the human agent in Chatwoot for context continuity
- The human agent can view the full middleware-enriched conversation, including authentication status and agent routing decisions
Bank control
The bank retains control over every aspect of the human-in-the-loop architecture:| Mechanism | What the bank configures |
|---|---|
| Agent tool functions | Which agents can initiate financial operations and which tools are available |
| System prompts | Confirmation requirements, language for transaction summaries, and escalation instructions |
| Escalation triggers | When and how conversations route to human agents in Chatwoot |
| Middleware ordering | Authentication and enrichment steps that run before any agent interaction |
| Channel allowlists | Which senders can interact with Lola Send during phased rollouts |
| Ticket allowed actions | The scoped list of operations each widget session can perform |