Code Examples
Code Examples
Complete code implementations based on official ACP protocol examples, covering core functionality of agentic checkout and delegated payment.
🚀 Node.js Implementation
Agentic Checkout Implementation
const express = require('express');
const crypto = require('crypto');
const app = express();
app.use(express.json());
// Validate API version and authentication
const validateRequest = (req, res, next) => {
const apiVersion = req.headers['api-version'];
const authorization = req.headers.authorization;
if (apiVersion !== '2025-09-29') {
return res.status(400).json({
type: 'invalid_request',
code: 'unsupported_version',
message: `Unsupported API version: ${apiVersion}`
});
}
if (!authorization || !authorization.startsWith('Bearer ')) {
return res.status(401).json({
type: 'invalid_request',
code: 'missing_authorization',
message: 'Missing Authorization header'
});
}
next();
};
// Create checkout session
app.post('/checkout_sessions', validateRequest, async (req, res) => {
try {
const { items, buyer, fulfillment_address } = req.body;
const idempotencyKey = req.headers['idempotency-key'];
// Validate required fields
if (!items || !Array.isArray(items) || items.length === 0) {
return res.status(400).json({
type: 'invalid_request',
code: 'missing_field',
message: 'Missing required field items',
param: '$.items'
});
}
// Check idempotency
if (idempotencyKey) {
const existingSession = await checkIdempotency(idempotencyKey, req.body);
if (existingSession) {
return res.status(201).json(existingSession);
}
}
// Calculate item totals
const lineItems = await calculateLineItems(items);
const fulfillmentOptions = await getFulfillmentOptions(fulfillment_address);
const selectedOption = fulfillmentOptions[0];
const totals = calculateTotals(lineItems, selectedOption);
const session = {
id: `checkout_session_${Date.now()}`,
payment_provider: {
provider: 'stripe',
supported_payment_methods: ['card']
},
status: fulfillment_address ? 'ready_for_payment' : 'not_ready_for_payment',
currency: 'usd',
line_items: lineItems,
fulfillment_address,
fulfillment_options: fulfillmentOptions,
fulfillment_option_id: selectedOption.id,
totals,
messages: [],
links: [
{
type: 'terms_of_use',
url: 'https://acplib.com/legal/terms'
},
{
type: 'privacy_policy',
url: 'https://acplib.com/legal/privacy'
}
]
};
// Save session
await saveSession(session, idempotencyKey);
res.status(201).json(session);
} catch (error) {
console.error('Create session error:', error);
res.status(500).json({
type: 'processing_error',
code: 'internal_error',
message: 'Internal server error'
});
}
});
// Update checkout session
app.post('/checkout_sessions/:id', validateRequest, async (req, res) => {
try {
const sessionId = req.params.id;
const updates = req.body;
const session = await getSession(sessionId);
if (!session) {
return res.status(404).json({
type: 'invalid_request',
code: 'session_not_found',
message: 'Session not found'
});
}
if (session.status === 'completed' || session.status === 'canceled') {
return res.status(405).json({
type: 'invalid_request',
code: 'session_not_modifiable',
message: 'Session is completed or canceled and cannot be modified'
});
}
// Apply updates
if (updates.items) {
session.line_items = await calculateLineItems(updates.items);
}
if (updates.fulfillment_address) {
session.fulfillment_address = updates.fulfillment_address;
session.fulfillment_options = await getFulfillmentOptions(updates.fulfillment_address);
session.fulfillment_option_id = session.fulfillment_options[0].id;
}
if (updates.fulfillment_option_id) {
const option = session.fulfillment_options.find(o => o.id === updates.fulfillment_option_id);
if (!option) {
return res.status(400).json({
type: 'invalid_request',
code: 'invalid_fulfillment_option',
message: 'Invalid fulfillment option ID'
});
}
session.fulfillment_option_id = updates.fulfillment_option_id;
}
// Recalculate totals
const selectedOption = session.fulfillment_options.find(o => o.id === session.fulfillment_option_id);
session.totals = calculateTotals(session.line_items, selectedOption);
session.status = 'ready_for_payment';
await saveSession(session);
res.json(session);
} catch (error) {
console.error('Update session error:', error);
res.status(500).json({
type: 'processing_error',
code: 'internal_error',
message: 'Internal server error'
});
}
});
// Complete checkout session
app.post('/checkout_sessions/:id/complete', validateRequest, async (req, res) => {
try {
const sessionId = req.params.id;
const { payment_data, buyer } = req.body;
const session = await getSession(sessionId);
if (!session) {
return res.status(404).json({
type: 'invalid_request',
code: 'session_not_found',
message: 'Session not found'
});
}
if (session.status !== 'ready_for_payment') {
return res.status(400).json({
type: 'invalid_request',
code: 'session_not_ready',
message: 'Session is not ready for payment'
});
}
// Validate payment token
const paymentToken = await validatePaymentToken(payment_data.token);
if (!paymentToken) {
return res.status(400).json({
type: 'processing_error',
code: 'payment_declined',
message: 'Payment token is invalid or expired'
});
}
// Process payment
const totalAmount = session.totals.find(t => t.type === 'total').amount;
const paymentResult = await processPayment(paymentToken, totalAmount, session.currency);
if (!paymentResult.success) {
return res.status(400).json({
type: 'processing_error',
code: 'payment_declined',
message: paymentResult.error
});
}
// Create order
const order = await createOrder(session, buyer, paymentResult);
session.status = 'completed';
session.buyer = buyer;
session.order = {
id: order.id,
checkout_session_id: sessionId,
permalink_url: `https://acplib.com/orders/${order.id}`
};
await saveSession(session);
// Send webhook event
await sendWebhook('order_created', {
order_id: order.id,
checkout_session_id: sessionId,
status: 'confirmed'
});
res.json(session);
} catch (error) {
console.error('Complete session error:', error);
res.status(500).json({
type: 'processing_error',
code: 'internal_error',
message: 'Internal server error'
});
}
});
// Helper functions
async function calculateLineItems(items) {
return Promise.all(items.map(async (item) => {
const product = await getProduct(item.id);
const baseAmount = product.price * item.quantity;
const discount = calculateDiscount(product, item.quantity);
const subtotal = baseAmount - discount;
const tax = calculateTax(subtotal);
return {
id: `line_item_${item.id}_${Date.now()}`,
item: {
id: item.id,
quantity: item.quantity
},
base_amount: baseAmount,
discount,
subtotal,
tax,
total: subtotal + tax
};
}));
}
async function getFulfillmentOptions(address) {
if (!address) return [];
return [
{
type: 'shipping',
id: 'standard_shipping',
title: 'Standard Shipping',
subtitle: '3-5 business days',
carrier: 'USPS',
earliest_delivery_time: new Date(Date.now() + 3 * 24 * 60 * 60 * 1000).toISOString(),
latest_delivery_time: new Date(Date.now() + 5 * 24 * 60 * 60 * 1000).toISOString(),
subtotal: 1500,
tax: 0,
total: 1500
},
{
type: 'shipping',
id: 'express_shipping',
title: 'Express Shipping',
subtitle: '1-2 business days',
carrier: 'FedEx',
earliest_delivery_time: new Date(Date.now() + 1 * 24 * 60 * 60 * 1000).toISOString(),
latest_delivery_time: new Date(Date.now() + 2 * 24 * 60 * 60 * 1000).toISOString(),
subtotal: 3000,
tax: 0,
total: 3000
}
];
}
function calculateTotals(lineItems, fulfillmentOption) {
const itemsBaseAmount = lineItems.reduce((sum, item) => sum + item.base_amount, 0);
const itemsDiscount = lineItems.reduce((sum, item) => sum + item.discount, 0);
const subtotal = lineItems.reduce((sum, item) => sum + item.subtotal, 0);
const tax = lineItems.reduce((sum, item) => sum + item.tax, 0);
const fulfillmentAmount = fulfillmentOption ? fulfillmentOption.total : 0;
const total = subtotal + tax + fulfillmentAmount;
return [
{
type: 'items_base_amount',
display_text: 'Items total',
amount: itemsBaseAmount
},
{
type: 'items_discount',
display_text: 'Discount',
amount: -itemsDiscount
},
{
type: 'subtotal',
display_text: 'Subtotal',
amount: subtotal
},
{
type: 'fulfillment',
display_text: 'Shipping',
amount: fulfillmentAmount
},
{
type: 'tax',
display_text: 'Tax',
amount: tax
},
{
type: 'total',
display_text: 'Total',
amount: total
}
];
}
module.exports = app;Delegated Payment Implementation
const crypto = require('crypto');
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
// Create delegated payment token
app.post('/agentic_commerce/delegate_payment', validateRequest, async (req, res) => {
try {
const { payment_method, allowance, billing_address, risk_signals, metadata } = req.body;
const idempotencyKey = req.headers['idempotency-key'];
// Verify request signature (optional but recommended)
if (req.headers.signature && req.headers.timestamp) {
const isValidSignature = verifySignature(req.body, req.headers.signature, req.headers.timestamp);
if (!isValidSignature) {
return res.status(401).json({
type: 'invalid_request',
code: 'invalid_signature',
message: 'Request signature verification failed'
});
}
}
// Validate payment method
if (payment_method.type !== 'card') {
return res.status(400).json({
type: 'invalid_request',
code: 'unsupported_payment_method',
message: 'Only card payment method is supported'
});
}
// Validate allowance
if (allowance.reason !== 'one_time') {
return res.status(400).json({
type: 'invalid_request',
code: 'unsupported_allowance_reason',
message: 'Only one_time allowance reason is supported'
});
}
// Check idempotency
if (idempotencyKey) {
const existingToken = await checkPaymentIdempotency(idempotencyKey, req.body);
if (existingToken) {
return res.status(201).json(existingToken);
}
}
// Create Stripe payment method
const stripePaymentMethod = await stripe.paymentMethods.create({
type: 'card',
card: {
number: payment_method.number,
exp_month: parseInt(payment_method.exp_month),
exp_year: parseInt(payment_method.exp_year),
cvc: payment_method.cvc
},
billing_details: {
name: payment_method.name,
address: billing_address ? {
line1: billing_address.line_one,
line2: billing_address.line_two,
city: billing_address.city,
state: billing_address.state,
country: billing_address.country,
postal_code: billing_address.postal_code
} : undefined
}
});
// Create delegated token record
const delegatedToken = {
id: `vt_${generateId()}`,
created: new Date().toISOString(),
stripe_payment_method_id: stripePaymentMethod.id,
allowance,
risk_signals,
metadata: {
...metadata,
source: 'agent_checkout',
merchant_id: allowance.merchant_id,
idempotency_key: idempotencyKey
}
};
// Save token
await saveDelegatedToken(delegatedToken, idempotencyKey);
// Return response (without sensitive information)
res.status(201).json({
id: delegatedToken.id,
created: delegatedToken.created,
metadata: delegatedToken.metadata
});
} catch (error) {
console.error('Create delegated payment error:', error);
if (error.type === 'StripeCardError') {
return res.status(400).json({
type: 'invalid_request',
code: 'invalid_card',
message: error.message,
param: 'payment_method.number'
});
}
res.status(500).json({
type: 'processing_error',
code: 'internal_error',
message: 'Internal server error'
});
}
});
// Verify request signature
function verifySignature(payload, signature, timestamp) {
try {
const canonicalPayload = JSON.stringify(payload);
const expectedSignature = crypto
.createHmac('sha256', process.env.SIGNING_SECRET)
.update(canonicalPayload + timestamp)
.digest('base64url');
return crypto.timingSafeEqual(
Buffer.from(signature, 'base64url'),
Buffer.from(expectedSignature, 'base64url')
);
} catch (error) {
return false;
}
}
// Process payment
async function processPayment(paymentToken, amount, currency) {
try {
const token = await getDelegatedToken(paymentToken.id);
if (!token) {
return { success: false, error: 'Payment token not found' };
}
// Validate allowance
if (token.allowance.max_amount < amount) {
return { success: false, error: 'Payment amount exceeds allowance' };
}
if (new Date() > new Date(token.allowance.expires_at)) {
return { success: false, error: 'Payment token has expired' };
}
// Process payment using Stripe
const paymentIntent = await stripe.paymentIntents.create({
amount,
currency,
payment_method: token.stripe_payment_method_id,
confirm: true,
metadata: {
checkout_session_id: token.allowance.checkout_session_id,
merchant_id: token.allowance.merchant_id,
delegated_token_id: token.id
}
});
return {
success: paymentIntent.status === 'succeeded',
payment_intent_id: paymentIntent.id,
error: paymentIntent.status !== 'succeeded' ? 'Payment processing failed' : null
};
} catch (error) {
console.error('Payment processing error:', error);
return { success: false, error: error.message };
}
}🐍 Python Implementation
Flask Application Example
from flask import Flask, request, jsonify
import json
import hashlib
import hmac
import time
from datetime import datetime, timedelta
import stripe
import uuid
app = Flask(__name__)
stripe.api_key = os.environ.get('STRIPE_SECRET_KEY')
class ACPError(Exception):
def __init__(self, error_type, code, message, param=None):
self.error_type = error_type
self.code = code
self.message = message
self.param = param
def validate_request():
"""Validate API version and authentication"""
api_version = request.headers.get('API-Version')
authorization = request.headers.get('Authorization')
if api_version != '2025-09-29':
raise ACPError('invalid_request', 'unsupported_version',
f'Unsupported API version: {api_version}')
if not authorization or not authorization.startswith('Bearer '):
raise ACPError('invalid_request', 'missing_authorization',
'Missing Authorization header')
@app.route('/checkout_sessions', methods=['POST'])
def create_checkout_session():
try:
validate_request()
data = request.get_json()
# Validate required fields
if not data.get('items') or not isinstance(data['items'], list):
raise ACPError('invalid_request', 'missing_field',
'Missing required field items', '$.items')
# Calculate order details
line_items = calculate_line_items(data['items'])
fulfillment_options = get_fulfillment_options(data.get('fulfillment_address'))
selected_option = fulfillment_options[0] if fulfillment_options else None
totals = calculate_totals(line_items, selected_option)
session = {
'id': f'checkout_session_{int(time.time())}',
'payment_provider': {
'provider': 'stripe',
'supported_payment_methods': ['card']
},
'status': 'ready_for_payment' if data.get('fulfillment_address') else 'not_ready_for_payment',
'currency': 'usd',
'line_items': line_items,
'fulfillment_address': data.get('fulfillment_address'),
'fulfillment_options': fulfillment_options,
'fulfillment_option_id': selected_option['id'] if selected_option else None,
'totals': totals,
'messages': [],
'links': [
{
'type': 'terms_of_use',
'url': 'https://acplib.com/legal/terms'
}
]
}
# Save session
save_session(session)
return jsonify(session), 201
except ACPError as e:
return jsonify({
'type': e.error_type,
'code': e.code,
'message': e.message,
'param': e.param
}), 400
except Exception as e:
return jsonify({
'type': 'processing_error',
'code': 'internal_error',
'message': 'Internal server error'
}), 500
@app.route('/agentic_commerce/delegate_payment', methods=['POST'])
def create_delegate_payment():
try:
validate_request()
data = request.get_json()
payment_method = data.get('payment_method', {})
allowance = data.get('allowance', {})
# Validate payment method
if payment_method.get('type') != 'card':
raise ACPError('invalid_request', 'unsupported_payment_method',
'Only card payment method is supported')
# Create Stripe payment method
stripe_pm = stripe.PaymentMethod.create(
type='card',
card={
'number': payment_method['number'],
'exp_month': int(payment_method['exp_month']),
'exp_year': int(payment_method['exp_year']),
'cvc': payment_method['cvc']
}
)
# Create delegated token
token = {
'id': f'vt_{uuid.uuid4().hex[:16]}',
'created': datetime.utcnow().isoformat() + 'Z',
'stripe_payment_method_id': stripe_pm.id,
'allowance': allowance,
'metadata': {
'source': 'agent_checkout',
'merchant_id': allowance.get('merchant_id'),
'idempotency_key': request.headers.get('Idempotency-Key')
}
}
save_delegated_token(token)
return jsonify({
'id': token['id'],
'created': token['created'],
'metadata': token['metadata']
}), 201
except stripe.error.CardError as e:
return jsonify({
'type': 'invalid_request',
'code': 'invalid_card',
'message': str(e),
'param': 'payment_method.number'
}), 400
except Exception as e:
return jsonify({
'type': 'processing_error',
'code': 'internal_error',
'message': 'Internal server error'
}), 500
def calculate_line_items(items):
"""Calculate order line items"""
line_items = []
for item in items:
product = get_product(item['id'])
base_amount = product['price'] * item['quantity']
discount = calculate_discount(product, item['quantity'])
subtotal = base_amount - discount
tax = calculate_tax(subtotal)
line_items.append({
'id': f'line_item_{item["id"]}_{int(time.time())}',
'item': {
'id': item['id'],
'quantity': item['quantity']
},
'base_amount': base_amount,
'discount': discount,
'subtotal': subtotal,
'tax': tax,
'total': subtotal + tax
})
return line_items
if __name__ == '__main__':
app.run(debug=True)🔧 PHP Implementation
Laravel Controller Example
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Stripe\Stripe;
use Stripe\PaymentMethod;
use Stripe\PaymentIntent;
class ACPController extends Controller
{
public function __construct()
{
Stripe::setApiKey(config('services.stripe.secret'));
}
public function createCheckoutSession(Request $request): JsonResponse
{
try {
$this->validateRequest($request);
$validator = validator($request->all(), [
'items' => 'required|array|min:1',
'items.*.id' => 'required|string',
'items.*.quantity' => 'required|integer|min:1',
'buyer.email' => 'sometimes|email',
'fulfillment_address.name' => 'sometimes|string|max:256',
]);
if ($validator->fails()) {
return response()->json([
'type' => 'invalid_request',
'code' => 'validation_failed',
'message' => $validator->errors()->first(),
'param' => '$.' . $validator->errors()->keys()[0]
], 400);
}
$lineItems = $this->calculateLineItems($request->input('items'));
$fulfillmentOptions = $this->getFulfillmentOptions(
$request->input('fulfillment_address')
);
$selectedOption = $fulfillmentOptions[0] ?? null;
$totals = $this->calculateTotals($lineItems, $selectedOption);
$session = [
'id' => 'checkout_session_' . time(),
'payment_provider' => [
'provider' => 'stripe',
'supported_payment_methods' => ['card']
],
'status' => $request->has('fulfillment_address') ? 'ready_for_payment' : 'not_ready_for_payment',
'currency' => 'usd',
'line_items' => $lineItems,
'fulfillment_address' => $request->input('fulfillment_address'),
'fulfillment_options' => $fulfillmentOptions,
'fulfillment_option_id' => $selectedOption['id'] ?? null,
'totals' => $totals,
'messages' => [],
'links' => [
[
'type' => 'terms_of_use',
'url' => 'https://acplib.com/legal/terms'
]
]
];
$this->saveSession($session);
return response()->json($session, 201);
} catch (\Exception $e) {
return response()->json([
'type' => 'processing_error',
'code' => 'internal_error',
'message' => 'Internal server error'
], 500);
}
}
public function createDelegatePayment(Request $request): JsonResponse
{
try {
$this->validateRequest($request);
$paymentMethod = $request->input('payment_method');
$allowance = $request->input('allowance');
if ($paymentMethod['type'] !== 'card') {
return response()->json([
'type' => 'invalid_request',
'code' => 'unsupported_payment_method',
'message' => 'Only card payment method is supported'
], 400);
}
// Create Stripe payment method
$stripePaymentMethod = PaymentMethod::create([
'type' => 'card',
'card' => [
'number' => $paymentMethod['number'],
'exp_month' => (int)$paymentMethod['exp_month'],
'exp_year' => (int)$paymentMethod['exp_year'],
'cvc' => $paymentMethod['cvc']
]
]);
$token = [
'id' => 'vt_' . bin2hex(random_bytes(8)),
'created' => now()->toISOString(),
'stripe_payment_method_id' => $stripePaymentMethod->id,
'allowance' => $allowance,
'metadata' => [
'source' => 'agent_checkout',
'merchant_id' => $allowance['merchant_id'] ?? null,
'idempotency_key' => $request->header('Idempotency-Key')
]
];
$this->saveDelegatedToken($token);
return response()->json([
'id' => $token['id'],
'created' => $token['created'],
'metadata' => $token['metadata']
], 201);
} catch (\Stripe\Exception\CardException $e) {
return response()->json([
'type' => 'invalid_request',
'code' => 'invalid_card',
'message' => $e->getMessage(),
'param' => 'payment_method.number'
], 400);
} catch (\Exception $e) {
return response()->json([
'type' => 'processing_error',
'code' => 'internal_error',
'message' => 'Internal server error'
], 500);
}
}
private function validateRequest(Request $request): void
{
$apiVersion = $request->header('API-Version');
$authorization = $request->header('Authorization');
if ($apiVersion !== '2025-09-29') {
throw new \Exception("Unsupported API version: {$apiVersion}");
}
if (!$authorization || !str_starts_with($authorization, 'Bearer ')) {
throw new \Exception('Missing Authorization header');
}
}
private function calculateLineItems(array $items): array
{
$lineItems = [];
foreach ($items as $item) {
$product = $this->getProduct($item['id']);
$baseAmount = $product['price'] * $item['quantity'];
$discount = $this->calculateDiscount($product, $item['quantity']);
$subtotal = $baseAmount - $discount;
$tax = $this->calculateTax($subtotal);
$lineItems[] = [
'id' => 'line_item_' . $item['id'] . '_' . time(),
'item' => [
'id' => $item['id'],
'quantity' => $item['quantity']
],
'base_amount' => $baseAmount,
'discount' => $discount,
'subtotal' => $subtotal,
'tax' => $tax,
'total' => $subtotal + $tax
];
}
return $lineItems;
}
}📱 Frontend Integration Example
JavaScript/TypeScript Client
interface ACPClient {
createCheckoutSession(data: CreateSessionRequest): Promise<CheckoutSession>;
updateCheckoutSession(id: string, data: UpdateSessionRequest): Promise<CheckoutSession>;
completeCheckoutSession(id: string, data: CompleteSessionRequest): Promise<CheckoutSession>;
createDelegatePayment(data: DelegatePaymentRequest): Promise<DelegatePaymentResponse>;
}
class ACPClientImpl implements ACPClient {
private baseUrl: string;
private apiKey: string;
constructor(baseUrl: string, apiKey: string) {
this.baseUrl = baseUrl;
this.apiKey = apiKey;
}
private async request<T>(
method: string,
path: string,
data?: any,
options: RequestInit = {}
): Promise<T> {
const url = `${this.baseUrl}${path}`;
const headers = {
'Authorization': `Bearer ${this.apiKey}`,
'API-Version': '2025-09-29',
'Content-Type': 'application/json',
'Idempotency-Key': this.generateIdempotencyKey(),
...options.headers
};
const response = await fetch(url, {
method,
headers,
body: data ? JSON.stringify(data) : undefined,
...options
});
if (!response.ok) {
const error = await response.json();
throw new ACPError(error.type, error.code, error.message, error.param);
}
return response.json();
}
async createCheckoutSession(data: CreateSessionRequest): Promise<CheckoutSession> {
return this.request<CheckoutSession>('POST', '/checkout_sessions', data);
}
async updateCheckoutSession(id: string, data: UpdateSessionRequest): Promise<CheckoutSession> {
return this.request<CheckoutSession>('POST', `/checkout_sessions/${id}`, data);
}
async completeCheckoutSession(id: string, data: CompleteSessionRequest): Promise<CheckoutSession> {
return this.request<CheckoutSession>('POST', `/checkout_sessions/${id}/complete`, data);
}
async createDelegatePayment(data: DelegatePaymentRequest): Promise<DelegatePaymentResponse> {
const signature = await this.signRequest(data);
const timestamp = new Date().toISOString();
return this.request<DelegatePaymentResponse>(
'POST',
'/agentic_commerce/delegate_payment',
data,
{
headers: {
'Signature': signature,
'Timestamp': timestamp
}
}
);
}
private generateIdempotencyKey(): string {
return `idem_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
}
private async signRequest(data: any): Promise<string> {
const payload = JSON.stringify(data);
const encoder = new TextEncoder();
const keyData = encoder.encode(this.apiKey);
const messageData = encoder.encode(payload);
const cryptoKey = await crypto.subtle.importKey(
'raw',
keyData,
{ name: 'HMAC', hash: 'SHA-256' },
false,
['sign']
);
const signature = await crypto.subtle.sign('HMAC', cryptoKey, messageData);
return btoa(String.fromCharCode(...new Uint8Array(signature)));
}
}
// Usage example
const client = new ACPClientImpl('https://api.acplib.com', 'your-api-key');
// Create checkout session
const session = await client.createCheckoutSession({
items: [
{ id: 'prod_12345', quantity: 2 }
],
buyer: {
first_name: 'John',
last_name: 'Smith',
email: '[email protected]'
},
fulfillment_address: {
name: 'John Smith',
line_one: '1234 Chat Road',
city: 'San Francisco',
state: 'CA',
country: 'US',
postal_code: '94102'
}
});
console.log('Session created:', session.id);Through these complete code examples, you can quickly implement the core functionality of ACP protocol to provide users with seamless AI-driven shopping experiences.