Blog

Protocol-Neutral Agentic Commerce and Payment Orchestration for ADK-Rust

Introducing adk-payments, a protocol-neutral agentic commerce and payment orchestration for ADK-Rust.

Posted on: 2026-04-07 by AI Assistant


adk-payments is a protocol-neutral agentic commerce and payment orchestration library for ADK-Rust. It provides a canonical commerce kernel and durable transaction journal that can sit behind multiple protocol adapters. This library is designed for scenarios where an agent needs to create, update, authorize, complete, and follow up on real commerce transactions without leaking raw payment artifacts into the normal conversation state.

Overview

Use adk-payments when you need to:

The crate combines:

Which Protocol Should I Use?

Protocol Support

FeatureStatusWhat it enables
acpStable baselineACP 2026-01-30 checkout routes, delegated payment, completion, cancelation, status
acp-experimentalDraft / feature-gatedACP discovery, delegate-authentication, signed webhooks
ap2Alpha baselineAP2 v0.1-alpha mandates, payment execution, receipts, interventions
ap2-a2aAdditiveAP2 A2A-oriented helpers and AgentCard metadata
ap2-mcpAdditiveAP2 MCP-safe continuation, intervention, and receipt views

ACP stable is the conservative production baseline. AP2 support tracks the current alpha research draft. The experimental ACP surface is intentionally feature-gated because the wire format is still moving.

Installation

Choose only the features you need:

[dependencies]
adk-payments = { version = "0.5.0", features = ["acp"] }
[dependencies]
adk-payments = { version = "0.5.0", features = ["ap2", "ap2-a2a", "ap2-mcp"] }
[dependencies]
adk-payments = { version = "0.5.0", features = ["acp", "acp-experimental", "ap2"] }

Core Concepts

Canonical Transaction

ACP sessions, ACP orders, AP2 mandates, and AP2 receipts all correlate to one internal TransactionId. Protocol IDs are preserved in ProtocolRefs; they are not treated as interchangeable.

Durable Journal

The transaction journal stores canonical commerce state in adk-session. Safe, masked transaction summaries are indexed into adk-memory. Raw sensitive payloads live in adk-artifact through the evidence store.

Evidence First

Raw payment credentials, merchant signatures, user authorizations, mandate payloads, and receipt bodies are preserved as immutable evidence artifacts. Only safe summary metadata is kept in transcript-visible and memory-visible surfaces.

Kernel-Mediated Compatibility

ACP and AP2 can share a backend, but adk-payments does not pretend their artifacts are semantically equivalent. When a direct ACP-to-AP2 or AP2-to-ACP conversion would lose provenance or authorization semantics, the kernel returns an explicit unsupported error instead of fabricating a translation.

Typical Architecture

Agent / Tool / Server surface
        |
        v
   ACP router or AP2 adapter
        |
        v
Canonical commerce kernel traits
        |
        +--> transaction journal (adk-session)
        +--> evidence store (adk-artifact)
        +--> masked recall index (adk-memory)
        +--> auth + guardrail enforcement

Quick Start

1. Expose ACP Checkout Routes

use std::sync::Arc;

use adk_payments::domain::{CommerceActor, CommerceActorRole, CommerceMode, MerchantRef, ProtocolExtensions};
use adk_payments::protocol::acp::{AcpContextTemplate, AcpRouterBuilder, AcpVerificationConfig};

let router = AcpRouterBuilder::new(AcpContextTemplate {
    session_identity: Some(identity),
    actor: CommerceActor {
        actor_id: "shopper-agent".to_string(),
        role: CommerceActorRole::AgentSurface,
        display_name: Some("shopper".to_string()),
        tenant_id: Some("tenant-1".to_string()),
        extensions: ProtocolExtensions::default(),
    },
    merchant_of_record: MerchantRef {
        merchant_id: "merchant-123".to_string(),
        legal_name: "Merchant Example LLC".to_string(),
        display_name: Some("Merchant Example".to_string()),
        statement_descriptor: Some("MERCHANT*EXAMPLE".to_string()),
        country_code: Some("US".to_string()),
        website: Some("https://merchant.example".to_string()),
        extensions: ProtocolExtensions::default(),
    },
    payment_processor: None,
    mode: CommerceMode::HumanPresent,
})
.with_merchant_checkout_service(checkout_service)
.with_delegated_payment_service(delegated_payment_service)
.with_verification(AcpVerificationConfig::strict())
.build()?;

Use this route surface when you want HTTP endpoints for checkout session create, update, completion, cancelation, status lookup, and delegated payment.

2. Handle AP2 Mandate Flows

use adk_payments::protocol::ap2::Ap2Adapter;

let adapter = Ap2Adapter::new(
    checkout_service,
    payment_execution_service,
    transaction_store,
    evidence_store,
)
.with_intervention_service(intervention_service);

let record = adapter.submit_cart_mandate(context, cart_mandate).await?;
let payment = adapter.submit_payment_mandate(context, payment_mandate).await?;
let final_record = adapter.apply_payment_receipt(context, payment_receipt).await?;

Use AP2 when your flow is mandate-based and multiple specialized actors participate in authorization and settlement.

3. Register Agent-Facing Payment Tools

use adk_payments::tools::PaymentToolsetBuilder;

let toolset = PaymentToolsetBuilder::new(checkout_service, transaction_store)
    .with_intervention_service(intervention_service)
    .build();

let tools = toolset.tools();

These tools return masked transaction summaries only. Raw card data, signatures, and authorization blobs do not appear in tool outputs.

Primary Journeys

The crate is currently shaped around five first-class journeys:

Security Model

Validation and Examples

The integration tests are the authoritative executable reference path:

cargo test -p adk-payments --features acp --test acp_integration_tests
cargo test -p adk-payments --features ap2,ap2-a2a,ap2-mcp --test ap2_integration_tests
cargo test -p adk-payments --test cross_protocol_correlation_tests
cargo test -p adk-payments --features acp-experimental --test acp_experimental_integration_tests

Use these as the starting point for real implementations: