Checkout.com

Checkout.com

Build production-grade agent payment workflows with Checkout.com

Build production-grade agent payment workflows with Checkout.com

Jun 3, 20268 min readBy Checkout.com Blog

AI agents handling payments in production fail 70–95% of the time due to compounding errors, missing audit trails, and lack of rollback visibility. Checkout.com provides payment orchestration and fraud prevention infrastructure that agents can safely invoke through structured workflows and compliance controls. Agent-driven payment systems require metering, audit logs, and settlement workflows—core features that separate toy agents from enterprise-safe orchestration layers. Building production agents means implementing explicit action tracing, recovery mechanisms, and payment routing that Checkout.com's platform enables.

What this tutorial covers

  • Outcome: You will design a TypeScript agent workflow that processes payments through Checkout.com with audit trails, error recovery, and compliance monitoring built in.
  • Endpoints used:
  • Language: typescript
  • Auth: API key
  • Estimated implementation time: ~18 minutes

Step 1: Define agent payment action schemas for Checkout.com orchestration

Agents must declare payment intents with explicit parameters before invoking Checkout.com. Schema-driven action definitions prevent hallucination and enable audit compliance. Define TypeScript interfaces that represent each payment operation—authorization, capture, refund—so agents can only invoke valid operations with traced parameters.

Payment action schemas

typescript
1// Define schema-driven payment actions for agent workflows
2interface PaymentAuthorizeAction {
3  type: 'authorize';
4  amount: number;
5  currency: string;
6  customerId: string;
7  paymentMethod: string; // Tokenized instrument from Checkout.com
8  metadata: Record<string, unknown>;
9  idempotencyKey: string; // Prevent duplicate processing
10}
11
12interface PaymentCaptureAction {
13  type: 'capture';
14  authorizationId: string;
15  amount?: number; // Partial capture support
16  reason: string; // Audit trail: why this capture
17}
18
19interface PaymentRefundAction {
20  type: 'refund';
21  transactionId: string;
22  amount?: number; // Partial refund
23  reason: string; // Regulatory requirement
24}
25
26type AgentPaymentAction = PaymentAuthorizeAction | PaymentCaptureAction | PaymentRefundAction;
27
28// Agent must select action from this enum only
29enum PaymentActionType {
30  AUTHORIZE = 'authorize',
31  CAPTURE = 'capture',
32  REFUND = 'refund'
33}

Agents now have strongly-typed, auditable payment actions with required fields like idempotencyKey and reason—preventing vague or uncompliant requests.

Step 2: Implement action execution with Checkout.com payment manager

Wrap Checkout.com payment operations in an agent executor that enforces idempotency, logs every call, and implements retry logic with exponential backoff. Production agents must never call payment processors directly; instead, route all operations through a payment manager that tracks state and enables rollback.

Execution layer with audit logging

typescript
1import { v4 as uuidv4 } from 'uuid';
2
3interface ExecutionLog {
4  actionId: string;
5  timestamp: number;
6  action: AgentPaymentAction;
7  status: 'pending' | 'success' | 'failed' | 'rolled_back';
8  error?: string;
9  result?: Record<string, unknown>;
10  retries: number;
11}
12
13class CheckoutPaymentExecutor {
14  private logs: ExecutionLog[] = [];
15  private pendingActions = new Map<string, AgentPaymentAction>();
16
17  async executeAction(action: AgentPaymentAction): Promise<ExecutionLog> {
18    const actionId = uuidv4();
19    const log: ExecutionLog = {
20      actionId,
21      timestamp: Date.now(),
22      action,
23      status: 'pending',
24      retries: 0
25    };
26
27    // Check idempotency: if action.idempotencyKey exists in store, return cached result
28    if ('idempotencyKey' in action && this.isIdempotent(action.idempotencyKey)) {
29      log.status = 'success';
30      log.result = { cached: true, message: 'Idempotent request—using previous result' };
31      return log;
32    }
33
34    // Execute with retry logic
35    let lastError: Error | null = null;
36    for (let attempt = 0; attempt < 3; attempt++) {
37      try {
38        log.retries = attempt;
39        const result = await this.invokeCheckoutAPI(action);
40        log.status = 'success';
41        log.result = result;
42        this.logs.push(log);
43        this.pendingActions.set(actionId, action);
44        return log;
45      } catch (error) {
46        lastError = error as Error;
47        if (attempt < 2) {
48          await this.exponentialBackoff(attempt);
49        }
50      }
51    }
52
53    log.status = 'failed';
54    log.error = lastError?.message || 'Unknown error';
55    this.logs.push(log);
56    return log;
57  }
58
59  private isIdempotent(key: string): boolean {
60    return this.logs.some(log => 'idempotencyKey' in log.action && log.action.idempotencyKey === key);
61  }
62
63  private async invokeCheckoutAPI(action: AgentPaymentAction): Promise<Record<string, unknown>> {
64    // In production, integrate with actual Checkout.com SDK or REST API
65    // This is a placeholder for the payment manager layer
66    if (action.type === 'authorize') {
67      return { authorizationId: uuidv4(), status: 'authorized', amount: (action as PaymentAuthorizeAction).amount };
68    } else if (action.type === 'capture') {
69      return { captureId: uuidv4(), status: 'captured', authorizationId: (action as PaymentCaptureAction).authorizationId };
70    } else {
71      return { refundId: uuidv4(), status: 'refunded', transactionId: (action as PaymentRefundAction).transactionId };
72    }
73  }
74
75  private async exponentialBackoff(attempt: number): Promise<void> {
76    const delay = Math.pow(2, attempt) * 1000;
77    return new Promise(resolve => setTimeout(resolve, delay));
78  }
79
80  getAuditLog(): ExecutionLog[] {
81    return [...this.logs];
82  }
83
84  async rollback(actionId: string): Promise<void> {
85    const log = this.logs.find(l => l.actionId === actionId);
86    if (log && log.status === 'success') {
87      // Initiate refund or reverse operation
88      log.status = 'rolled_back';
89    }
90  }
91}

The executor now logs every payment attempt with timestamp, retry count, and outcome, enabling compliance review and failure replay through Checkout.com's orchestration layer.

Step 3: Integrate agent decision loop with Checkout.com fraud prevention

Before executing any payment, agents must consult Checkout.com's fraud signals and risk scoring to decide whether to authorize, challenge, or decline. Production workflows require agents to implement risk-aware routing: high-risk transactions escalate to manual review or trigger 3D Secure, while low-risk transactions proceed automatically.

Risk-aware agent routing

typescript
1interface FraudSignal {
2  riskScore: number; // 0–100
3  flaggedRules: string[];
4  recommendedAction: 'approve' | 'challenge' | 'decline';
5  metadata: Record<string, unknown>;
6}
7
8class AgentPaymentOrchestrator {
9  private executor: CheckoutPaymentExecutor;
10
11  constructor(executor: CheckoutPaymentExecutor) {
12    this.executor = executor;
13  }
14
15  async processPaymentWithRiskAwareness(authorizeAction: PaymentAuthorizeAction, fraudSignal: FraudSignal): Promise<ExecutionLog> {
16    // Agent decision: route based on fraud signal
17    if (fraudSignal.riskScore > 75) {
18      console.log(`[AGENT] High-risk transaction (score: ${fraudSignal.riskScore}). Escalating to manual review.`);
19      // In production, this would queue for manual review in Checkout.com's dashboard
20      return {
21        actionId: uuidv4(),
22        timestamp: Date.now(),
23        action: authorizeAction,
24        status: 'pending',
25        retries: 0,
26        result: { escalationReason: 'high_fraud_risk', fraudSignal }
27      };
28    }
29
30    if (fraudSignal.riskScore > 40) {
31      console.log(`[AGENT] Medium-risk transaction (score: ${fraudSignal.riskScore}). Triggering 3D Secure.`);
32      // Modify action to require 3D Secure authentication
33      authorizeAction.metadata['require_3ds'] = true;
34    }
35
36    // Low-risk: proceed to authorization
37    console.log(`[AGENT] Low-risk transaction (score: ${fraudSignal.riskScore}). Proceeding to authorization.`);
38    return this.executor.executeAction(authorizeAction);
39  }
40
41  evaluateFraudSignal(transactionData: Record<string, unknown>): FraudSignal {
42    // Simulate Checkout.com fraud API response
43    // In production, call Checkout.com's risk/fraud endpoint
44    const riskScore = Math.random() * 100;
45    return {
46      riskScore,
47      flaggedRules: riskScore > 50 ? ['velocity_check', 'geoip_mismatch'] : [],
48      recommendedAction: riskScore > 75 ? 'decline' : riskScore > 40 ? 'challenge' : 'approve',
49      metadata: { checkoutComSignatureVersion: '1.0', timestamp: Date.now() }
50    };
51  }
52}

Agents now integrate fraud prevention into payment decisions: high-risk transactions are escalated, medium-risk transactions require 3D Secure, and low-risk transactions proceed automatically with Checkout.com's controls.

Step 4: Monitor and replay agent workflow failures with settlement reconciliation

Production agents require explicit failure monitoring, workflow replay, and settlement reconciliation to detect compounding errors and enable regulatory audits. Implement a settlement worker that periodically reconciles agent-initiated transactions against Checkout.com's settlement feeds, detecting gaps and triggering recovery workflows.

Settlement monitoring and replay

typescript
1interface SettlementRecord {
2  transactionId: string;
3  checkoutComId: string;
4  amount: number;
5  currency: string;
6  status: 'settled' | 'pending' | 'failed' | 'disputed';
7  settledAt?: number;
8}
9
10class SettlementReconciler {
11  private auditLog: ExecutionLog[] = [];
12  private settlements: Map<string, SettlementRecord> = new Map();
13
14  async reconcileWithCheckout(executor: CheckoutPaymentExecutor): Promise<{ reconciled: number; gaps: ExecutionLog[] }> {
15    const auditLog = executor.getAuditLog();
16    const gaps: ExecutionLog[] = [];
17
18    for (const log of auditLog) {
19      if (log.status === 'success' && log.result?.authorizationId) {
20        // Check if this transaction has a settlement record from Checkout.com
21        const settlement = this.settlements.get(log.result.authorizationId as string);
22        
23        if (!settlement) {
24          gaps.push(log);
25          console.warn(`[RECONCILER] Gap detected: Authorization ${log.result.authorizationId} has no settlement record.`);
26        } else if (settlement.status === 'failed') {
27          gaps.push(log);
28          console.warn(`[RECONCILER] Failed settlement: ${settlement.transactionId}`);
29        }
30      }
31    }
32
33    return { reconciled: auditLog.length - gaps.length, gaps };
34  }
35
36  async replayFailedWorkflow(failedLog: ExecutionLog, executor: CheckoutPaymentExecutor): Promise<ExecutionLog> {
37    console.log(`[REPLAY] Replaying action ${failedLog.actionId} (${failedLog.action.type})`);
38    // Attempt to replay the original action
39    return executor.executeAction(failedLog.action);
40  }
41
42  updateSettlement(transactionId: string, checkoutComId: string, record: Omit<SettlementRecord, 'transactionId' | 'checkoutComId'>): void {
43    this.settlements.set(checkoutComId, {
44      transactionId,
45      checkoutComId,
46      ...record
47    });
48  }
49
50  getSettlementStatus(checkoutComId: string): SettlementRecord | undefined {
51    return this.settlements.get(checkoutComId);
52  }
53}

The reconciler detects failed settlements, identifies gaps between agent actions and Checkout.com settlement records, and enables automated replay of failed workflows for recovery.

Step 5: Deploy agent workflow with metering, compliance controls, and escalation analytics

Enterprise-grade agent workflows require metering (transaction limits, rate limits), compliance controls (KYC checks, AML rules), and escalation analytics to track agent performance. Checkpoint.com's compliance layer integrates with agent orchestration to enforce per-agent limits, audit all decisions, and route high-value or suspicious transactions to human review.

Compliance and metering layer

typescript
1interface AgentMetrics {
2  agentId: string;
3  transactionsProcessed: number;
4  totalVolumeProcessed: number;
5  failureRate: number;
6  lastActivity: number;
7}
8
9interface CompliancePolicy {
10  agentId: string;
11  maxTransactionAmount: number;
12  maxDailyVolume: number;
13  maxTransactionsPerHour: number;
14  requiresManualReviewAbove: number;
15  amlCheckRequired: boolean;
16}
17
18class ComplianceController {
19  private policies: Map<string, CompliancePolicy> = new Map();
20  private metrics: Map<string, AgentMetrics> = new Map();
21  private escalations: Array<{ agentId: string; reason: string; timestamp: number }> = [];
22
23  canAgentProceed(agentId: string, action: AgentPaymentAction): { allowed: boolean; reason?: string } {
24    const policy = this.policies.get(agentId);
25    const metrics = this.metrics.get(agentId) || { agentId, transactionsProcessed: 0, totalVolumeProcessed: 0, failureRate: 0, lastActivity: 0 };
26
27    if (!policy) {
28      return { allowed: false, reason: 'Agent not registered' };
29    }
30
31    // Check transaction amount limit
32    if ('amount' in action && action.amount > policy.maxTransactionAmount) {
33      this.escalations.push({ agentId, reason: `Transaction exceeds max: ${action.amount} > ${policy.maxTransactionAmount}`, timestamp: Date.now() });
34      return { allowed: false, reason: 'Transaction amount exceeds policy limit' };
35    }
36
37    // Check daily volume
38    if (metrics.totalVolumeProcessed + ('amount' in action ? action.amount : 0) > policy.maxDailyVolume) {
39      this.escalations.push({ agentId, reason: `Daily volume limit exceeded`, timestamp: Date.now() });
40      return { allowed: false, reason: 'Daily volume limit reached' };
41    }
42
43    // Check failure rate
44    if (metrics.failureRate > 0.1) {
45      this.escalations.push({ agentId, reason: `High failure rate: ${(metrics.failureRate * 100).toFixed(2)}%`, timestamp: Date.now() });
46      return { allowed: false, reason: 'Agent failure rate too high—escalate to manual review' };
47    }
48
49    return { allowed: true };
50  }
51
52  registerPolicy(policy: CompliancePolicy): void {
53    this.policies.set(policy.agentId, policy);
54  }
55
56  updateMetrics(agentId: string, action: AgentPaymentAction, success: boolean): void {
57    const current = this.metrics.get(agentId) || { agentId, transactionsProcessed: 0, totalVolumeProcessed: 0, failureRate: 0, lastActivity: 0 };
58    current.transactionsProcessed++;
59    if ('amount' in action) current.totalVolumeProcessed += action.amount;
60    current.lastActivity = Date.now();
61    // Update failure rate (simple moving average)
62    current.failureRate = (current.failureRate * (current.transactionsProcessed - 1) + (success ? 0 : 1)) / current.transactionsProcessed;
63    this.metrics.set(agentId, current);
64  }
65
66  getEscalationAnalytics(): Array<{ agentId: string; reason: string; timestamp: number }> {
67    return [...this.escalations];
68  }
69}

Agents now operate under compliance guardrails: transaction limits, daily volume caps, and failure-rate monitoring automatically escalate risky agents to manual review, keeping Checkout.com payments compliant and auditable.

Common pitfalls when using Checkout.com

  • Calling Checkout.com APIs directly without payment manager intermediation. Agents that invoke payment processors directly lose audit context, idempotency guarantees, and rollback capability. Always route through a payment manager layer that logs every call and implements recovery strategies.
  • Missing idempotency keys and duplicate payment processing. Agent retries without idempotent request tracking cause duplicate charges. Enforce idempotencyKey on every authorize action and check payment manager state before re-executing failed actions.
  • No fraud risk integration before payment authorization. Agents that skip fraud signal consultation and 3D Secure routing increase chargebacks and regulatory exposure. Always evaluate Checkout.com fraud signals and route medium/high-risk transactions through challenge or manual review workflows.
  • Lack of settlement reconciliation and failure replay capability. Gaps between agent-initiated transactions and Checkout.com settlement records go undetected without periodic reconciliation. Implement a settlement worker that compares audit logs to settlement feeds and replays failed workflows automatically.

Ready to harden your payment agents for production? Start with Checkout.com's payment orchestration platform and integrate metering, audit trails, and fraud prevention into your agent workflows.

Ready to elevate your payment experience now?

Join leading brands using Checkout.com to increase acceptance rates, cut costs, and deliver frictionless payments every time.

Read More Blog Posts

Checkout.comCheckout.com

Payment strategies for tomorrow’s digital businesses.

© 2026 Checkout.com. All rights reserved.