UNPKG

oneie

Version:

Build apps, websites, and AI agents in English. Zero-interaction setup for AI agents (Claude Code, Cursor, Windsurf). Download to your computer, run in the cloud, deploy to the edge. Open source and free forever.

750 lines (647 loc) 22.2 kB
--- title: Acps dimension: connections category: acps.md tags: agent, ai, ontology, protocol related_dimensions: events, people, things scope: global created: 2025-11-03 updated: 2025-11-03 version: 1.0.0 ai_context: | This document is part of the connections dimension in the acps.md category. Location: one/connections/acps.md Purpose: Documents acpayments - agent collaboration payment system Related dimensions: events, people, things For AI agents: Read this to understand acps. --- # ACPayments - Agent Collaboration Payment System **Version:** 2.0.0 **Purpose:** Comprehensive payment and billing system for multi-agent collaboration, combining X402 protocol with Agentic Commerce Protocol (ACP) **Related:** X402.md (HTTP payment protocol), Ontology.md (entity/event types) --- ## Overview **ACPayments** integrates two complementary payment protocols to create a complete payment ecosystem for the ONE platform: 1. **X402 Protocol** - HTTP-native micropayments for API/agent services 2. **ACP (Agentic Commerce Protocol)** - AI agent-initiated product purchases **Key Capabilities:** - ✅ **Agent-to-Agent Payments** - Agents pay each other for services (X402) - ✅ **AI Commerce** - Agents purchase products for users (ACP) - ✅ **Workflow-Based Billing** - Multi-agent orchestration payments - ✅ **Revenue Sharing** - Distribute payments across agents - ✅ **Subscription Models** - Recurring access payments - ✅ **Usage-Based Pricing** - Pay-per-use with automatic tracking - ✅ **Escrow & Settlements** - Hold and release on completion **Built On:** - **X402 Protocol** - Micropayments for services - **ACP (Stripe + OpenAI)** - AI-native product commerce - **Effect.ts** - Type-safe payment services - **Convex** - Real-time payment tracking - **Multi-Chain** - Base, Ethereum, Solana support --- ## Part 1: Agentic Commerce Protocol (ACP) ### What is ACP? **Agentic Commerce Protocol (ACP)** is an open standard developed by Stripe and OpenAI for programmatic commerce flows between buyers, AI agents, and businesses. **License:** Apache 2.0 (open source) **Compatibility:** REST and MCP (Model Context Protocol) **First Implementation:** OpenAI's Instant Checkout in ChatGPT **PSP:** Stripe (first compatible payment service provider) ### ACP Architecture ``` ┌─────────────┐ ┌─────────────┐ ┌──────────────┐ │ AI Agent │ ──────> │ Business │ ──────> │ Stripe │ │ (Buyer Rep) │ <────── │ (Merchant) │ <────── │ (PSP) │ └─────────────┘ └─────────────┘ └──────────────┘ │ │ │ │ 1. Discover Products │ │ │ 2. Initiate Purchase │ │ │ 3. Accept/Decline │ │ 4. Process Payment ───────────> │ │ 5. Confirm ────┘ │ 6. Complete Order │ ``` ### ACP Features **1. Open Standard** - Community-designed protocol - Works with any AI agent or payment processor - No vendor lock-in **2. Merchant Control** - Merchants remain "merchant of record" - Full control over product presentation - Accept/decline transactions per agent or transaction - Support for multiple commerce types: - Physical goods - Digital goods - Subscriptions - Async purchases **3. Security & Compliance** - PCI compliant - Secure payment credential handling - Payment token passing between buyers and businesses ### ACP Ontology Integration #### Entity Types **New Types:** ```typescript | 'product' // Sellable product/service | 'payment_transaction' // ACP transaction record ``` **Product Properties:** ```typescript { type: "product", name: "Course: Web Development", properties: { price: 99.00, currency: "USD", productType: "digital_good", // or "physical_good", "subscription" acpEnabled: true, stripeProductId: "prod_xxx", inventory?: number, fulfillmentMethod: "digital_download" | "shipping" | "email", description: string, images: string[], } } ``` **Payment Transaction Properties:** ```typescript { type: "payment_transaction", name: "ACP Payment via ChatGPT", properties: { protocol: "acp", amount: 99.00, currency: "USD", status: "pending" | "approved" | "declined" | "completed" | "refunded", paymentMethod: "acp", agentPlatform: "chatgpt" | "claude" | "gemini", stripePaymentId: "pi_xxx", merchantId: Id<'entities'>, productId: Id<'entities'>, buyerId: Id<'entities'>, agentId: Id<'entities'>, declineReason?: string, refundReason?: string, completedAt?: number, } } ``` #### Event Types Uses existing event types: ```typescript // ACP purchase initiated { type: 'commerce_event', actorId: agentId, targetId: transactionId, timestamp: Date.now(), metadata: { eventType: 'purchase_initiated', protocol: 'acp', agentPlatform: 'chatgpt', productId: productId, amount: 99.00 } } // Merchant approval decision { type: 'commerce_event', actorId: merchantId, targetId: transactionId, timestamp: Date.now(), metadata: { eventType: 'transaction_decision', protocol: 'acp', approved: true, processingTime: 150 } } // Payment completed { type: 'payment_completed', actorId: stripeEntityId, targetId: transactionId, timestamp: Date.now(), metadata: { protocol: 'acp', stripePaymentId: 'pi_xxx', amount: 99.00, fee: 3.20 } } // Product delivered { type: 'content_changed', actorId: systemId, targetId: productId, timestamp: Date.now(), metadata: { action: 'delivered', protocol: 'acp', buyerId: buyerId, deliveryMethod: 'digital_download', transactionId: transactionId } } ``` ### ACP Service Implementation **File:** `convex/services/acp-payment.ts` ```typescript import { Effect } from 'effect'; import { ConvexDatabase } from './convex-database'; import type { Id } from '../_generated/dataModel'; export class ACPPaymentService extends Effect.Service<ACPPaymentService>()( 'ACPPaymentService', { effect: Effect.gen(function* () { const db = yield* ConvexDatabase; return { /** * Agent initiates product purchase */ initiatePurchase: (args: { agentId: Id<'entities'>; productId: Id<'entities'>; buyerId: Id<'entities'>; agentPlatform: 'chatgpt' | 'claude' | 'gemini'; }) => Effect.gen(function* () { // 1. Validate product is ACP-enabled const product = yield* db.get(args.productId); if (!product.properties.acpEnabled) { yield* Effect.fail( new Error('Product is not enabled for Agentic Commerce') ); } // 2. Create transaction entity const transactionId = yield* db.insert('entities', { type: 'payment_transaction', name: `ACP Transaction ${Date.now()}`, properties: { protocol: 'acp', amount: product.properties.price as number, currency: (product.properties.currency as string) || 'USD', status: 'pending', paymentMethod: 'acp', agentPlatform: args.agentPlatform, productId: args.productId, buyerId: args.buyerId, agentId: args.agentId, merchantId: product.properties.merchantId as Id<'entities'>, }, status: 'active', createdAt: Date.now(), updatedAt: Date.now(), }); // 3. Create connection: agent → transaction yield* db.insert('connections', { fromEntityId: args.agentId, toEntityId: transactionId, relationshipType: 'initiated', metadata: { type: 'purchase_initiation', timestamp: Date.now(), }, createdAt: Date.now(), updatedAt: Date.now(), }); // 4. Log event yield* db.insert('events', { type: 'commerce_event', actorId: args.agentId, targetId: transactionId, timestamp: Date.now(), metadata: { eventType: 'purchase_initiated', protocol: 'acp', agentPlatform: args.agentPlatform, productId: args.productId, amount: product.properties.price, }, }); return { transactionId, status: 'pending' }; }), /** * Merchant approves/declines transaction */ processTransaction: (args: { transactionId: Id<'entities'>; merchantId: Id<'entities'>; approved: boolean; reason?: string; }) => Effect.gen(function* () { const transaction = yield* db.get(args.transactionId); if (transaction.properties.status !== 'pending') { yield* Effect.fail( new Error('Transaction is not in pending state') ); } // Update transaction status yield* db.patch(args.transactionId, { 'properties.status': args.approved ? 'approved' : 'declined', 'properties.declineReason': args.reason, updatedAt: Date.now(), }); // Create approval connection yield* db.insert('connections', { fromEntityId: args.merchantId, toEntityId: args.transactionId, relationshipType: args.approved ? 'approved' : 'rejected', metadata: { reason: args.reason, timestamp: Date.now(), }, createdAt: Date.now(), updatedAt: Date.now(), }); // Log event yield* db.insert('events', { type: 'commerce_event', actorId: args.merchantId, targetId: args.transactionId, timestamp: Date.now(), metadata: { eventType: 'transaction_decision', protocol: 'acp', approved: args.approved, reason: args.reason, }, }); // If approved, process payment if (args.approved) { return yield* processStripePayment({ transactionId: args.transactionId, amount: transaction.properties.amount as number, currency: (transaction.properties.currency as string) || 'USD', }); } return { success: true, status: 'declined' }; }), }; }), dependencies: [ConvexDatabase.Default], } ) {} // Helper: Process Stripe payment const processStripePayment = (args: { transactionId: Id<'entities'>; amount: number; currency: string; }) => Effect.gen(function* () { const db = yield* ConvexDatabase; // Create Stripe payment intent (simplified) const paymentIntentId = `pi_${Date.now()}`; // Update transaction yield* db.patch(args.transactionId, { 'properties.stripePaymentId': paymentIntentId, 'properties.status': 'completed', 'properties.completedAt': Date.now(), updatedAt: Date.now(), }); // Log completion yield* db.insert('events', { type: 'payment_completed', actorId: 'system' as Id<'entities'>, targetId: args.transactionId, timestamp: Date.now(), metadata: { protocol: 'acp', stripePaymentId: paymentIntentId, amount: args.amount, currency: args.currency, }, }); return { success: true, paymentIntentId, status: 'completed', }; }); ``` --- ## Part 2: X402 + Multi-Agent Workflows ### X402 Service Integration See **X402.md** for complete X402 protocol implementation. **Key X402 Features:** - HTTP 402 status code payment flow - Micropayments ($0.001+) - Multi-chain support (Base, Ethereum, Solana) - Instant settlement (~2 seconds) ### Multi-Agent Revenue Sharing **File:** `convex/services/agent-payment.ts` ```typescript import { Effect } from 'effect'; import { ConvexDatabase } from './convex-database'; import { X402PaymentService } from './x402-payment'; import type { Id } from '../_generated/dataModel'; export class AgentPaymentService extends Effect.Service<AgentPaymentService>()( 'AgentPaymentService', { effect: Effect.gen(function* () { const db = yield* ConvexDatabase; const x402 = yield* X402PaymentService; return { /** * Create revenue split for multi-agent workflow */ createRevenueSplit: (args: { workflowId: Id<'entities'>; totalAmount: string; participants: Array<{ agentId: Id<'entities'>; percentage: number; // 0-100 }>; }) => Effect.gen(function* () { // Validate percentages sum to 100 const totalPercentage = args.participants.reduce( (sum, p) => sum + p.percentage, 0 ); if (totalPercentage !== 100) { yield* Effect.fail( new Error(`Revenue split must sum to 100%, got ${totalPercentage}%`) ); } // Create revenue split entity const revenueSplitId = yield* db.insert('entities', { type: 'revenue_split', name: `Revenue Split: ${args.workflowId}`, properties: { workflowId: args.workflowId, totalAmount: args.totalAmount, asset: 'USDC', participants: args.participants, status: 'pending', createdAt: Date.now(), }, status: 'active', createdAt: Date.now(), updatedAt: Date.now(), }); return { revenueSplitId, participants: args.participants }; }), /** * Distribute revenue to participants */ distributeRevenue: (args: { revenueSplitId: Id<'entities'> }) => Effect.gen(function* () { const revenueSplit = yield* db.get(args.revenueSplitId); const { totalAmount, participants } = revenueSplit.properties as { totalAmount: string; participants: Array<{ agentId: Id<'entities'>; percentage: number; }>; }; const total = parseFloat(totalAmount); const distributions = []; // Distribute to each participant for (const participant of participants) { const amount = (total * participant.percentage) / 100; const payment = yield* db.insert('entities', { type: 'payment', name: `Revenue Share: ${participant.percentage}%`, properties: { protocol: 'revenue-split', revenueSplitId: args.revenueSplitId, recipientId: participant.agentId, amount: amount.toFixed(6), asset: 'USDC', percentage: participant.percentage, status: 'completed', completedAt: Date.now(), }, status: 'active', createdAt: Date.now(), updatedAt: Date.now(), }); distributions.push({ agentId: participant.agentId, amount: amount.toFixed(6), paymentId: payment, }); } // Update revenue split status yield* db.patch(args.revenueSplitId, { 'properties.status': 'distributed', 'properties.distributedAt': Date.now(), updatedAt: Date.now(), }); return { distributions, status: 'distributed' }; }), }; }), dependencies: [ConvexDatabase.Default, X402PaymentService.Default], } ) {} ``` --- ## Part 3: Frontend Components ### ACP Checkout Component **File:** `src/components/payment/ACPCheckout.tsx` ```tsx import React, { useState } from 'react'; import { useMutation } from 'convex/react'; import { api } from '@/convex/_generated/api'; import { Button } from '@/components/ui/button'; import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/card'; import { Badge } from '@/components/ui/badge'; import type { Id } from '@/convex/_generated/dataModel'; interface ACPCheckoutProps { productId: Id<'entities'>; agentId: Id<'entities'>; buyerId: Id<'entities'>; agentPlatform: 'chatgpt' | 'claude' | 'gemini'; } export function ACPCheckout({ productId, agentId, buyerId, agentPlatform }: ACPCheckoutProps) { const initiate = useMutation(api.acpPayments.initiatePurchase); const [isProcessing, setIsProcessing] = useState(false); const [error, setError] = useState<string | null>(null); const handlePurchase = async () => { setIsProcessing(true); setError(null); try { const result = await initiate({ productId, agentId, buyerId, agentPlatform, }); console.log('Purchase initiated:', result); } catch (err) { setError(err instanceof Error ? err.message : 'Purchase failed'); } finally { setIsProcessing(false); } }; return ( <Card> <CardHeader> <CardTitle className="flex items-center gap-2"> <Badge variant="secondary">ACP Enabled</Badge> Instant Checkout </CardTitle> </CardHeader> <CardContent className="space-y-4"> {error && ( <div className="rounded-lg border border-destructive bg-destructive/10 p-3 text-sm text-destructive"> {error} </div> )} <Button onClick={handlePurchase} disabled={isProcessing} className="w-full" > {isProcessing ? 'Processing...' : 'Purchase via AI Agent'} </Button> </CardContent> </Card> ); } ``` ### Merchant Approval Dashboard **File:** `src/components/payment/ACPMerchantDashboard.tsx` ```tsx import React from 'react'; import { useMutation, useQuery } from 'convex/react'; import { api } from '@/convex/_generated/api'; import { Button } from '@/components/ui/button'; import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/card'; import { Badge } from '@/components/ui/badge'; import type { Id } from '@/convex/_generated/dataModel'; interface ACPMerchantDashboardProps { merchantId: Id<'entities'>; } export function ACPMerchantDashboard({ merchantId }: ACPMerchantDashboardProps) { const pendingTransactions = useQuery( api.acpPayments.listPendingTransactions, { merchantId } ); const processTransaction = useMutation(api.acpPayments.processTransaction); const handleApprove = async (transactionId: Id<'entities'>) => { await processTransaction({ transactionId, merchantId, approved: true, }); }; const handleDecline = async (transactionId: Id<'entities'>, reason: string) => { await processTransaction({ transactionId, merchantId, approved: false, reason, }); }; if (!pendingTransactions?.length) { return ( <div className="text-center text-muted-foreground"> No pending transactions </div> ); } return ( <div className="space-y-4"> {pendingTransactions.map((tx) => ( <Card key={tx._id}> <CardHeader> <CardTitle className="flex items-center justify-between"> <span> ${tx.properties.amount} {tx.properties.currency} </span> <Badge variant="secondary">{tx.properties.agentPlatform}</Badge> </CardTitle> </CardHeader> <CardContent className="flex gap-2"> <Button onClick={() => handleApprove(tx._id)} className="flex-1"> Approve </Button> <Button variant="destructive" onClick={() => handleDecline(tx._id, 'Manual review required')} className="flex-1" > Decline </Button> </CardContent> </Card> ))} </div> ); } ``` --- ## Summary ### ACPayments Unified System **Protocols:** - **ACP (Agentic Commerce Protocol)** - AI agent product purchases - **X402 Protocol** - HTTP-native API/service micropayments **New Entity Types:** 5 - `product` (ACP) - `payment_transaction` (ACP) - `revenue_split` (multi-agent) - `subscription` (recurring) - `escrow` (workflow payments) **Existing Types Reused:** - `payment` (all payment records) - `conversation` (payment context) - `message` (payment notifications) **Breaking Changes:** ZERO **Key Features:** - AI commerce (ACP with Stripe) - Service micropayments (X402) - Multi-agent revenue sharing - Workflow escrow - Subscription billing - Usage tracking 🎉 **Result:** Complete payment ecosystem for AI-native platform with both product commerce and service micropayments. ## Resources - **ACP Website**: https://www.agenticcommerce.dev/ - **Stripe ACP Docs**: https://stripe.com/docs/agentic-commerce - **X402 Protocol**: https://www.x402.org/ - **X402 GitHub**: https://github.com/coinbase/x402 - **OpenAI Instant Checkout**: https://platform.openai.com/docs/instant-checkout