Secure agent-led payments with cryptographic trust. Verifiable credentials, autonomous transactions, multi-platform bookings. Credit cards, crypto, bank transfers.
AP2 (Agent Payments Protocol) enables autonomous agents to execute payments securely and reliably. The protocol separates the payment intent (what the agent wants to pay for) from execution (actually processing the payment), allowing for flexible approval workflows.
Agent Intent Mandate Approval Flow Payment Execution
│ │ │ │
├─ Create mandate ──→ [Storage] │ │
│ │ │
├─ Request payment ──────────────────────→ [Check limits] │
│ │ │
│ ┌─ High amount? │
│ │ ├─ Human approval │
│ │ └─ Approved │
│ │ │
└─ Execute ────────────────────────────────→ [Process payment] ──→ Settlement
AP2 integrates with the 6-dimension ontology for complete payment tracking:
AP2 implements multiple security layers:
Mandate {
agentId: string; // Which agent can pay
maxAmount: number; // Total authorized
currency: string; // Currency (USD, EUR, etc)
validFrom: Date; // When mandate starts
validUntil: Date; // When mandate expires
allowedMethods: string[]; // Payment methods allowed
constraints: {
perTransaction: number; // Max per single payment
perDay: number; // Max per day
perMonth: number; // Max per month
requireApprovalAbove: number;
};
allowedMerchants?: string[]; // Optional whitelist
approverSignature: string; // Cryptographic signature
}
AP2 supports multiple payment methods:
AP2 includes built-in risk management:
| Aspect | AP2 | X402 | ACP |
|---|---|---|---|
| Primary Use | Agent payments | Micropayments | Messaging |
| Payment Type | Full payments | Tiny payments | N/A |
| Intent | Explicit mandate | Implicit per-call | N/A |
| Settlement | Minutes to hours | Seconds | N/A |
How this protocol maps to the 6-dimension ontology
Payment intents scoped to groups with spending policies
Agents have payment authority based on roles and mandates
Intent mandates stored as things with cryptographic proofs
Payment relationships track who paid whom for what
Payment events with full audit trail (intent, execution, settlement)
Payment history and agent credibility stored for risk assessment
Cryptographically signed payment intent with W3C standards
Agents can execute payments without human intervention within limits
Credit cards, crypto, bank transfers, digital wallets
Express payment intent (what, amount, purpose) separately from execution
Agent books flights, hotels, and rentals within approved budget
Agents subscribe to services with pre-approved budgets
Agents pay vendors based on pre-approved cost conditions
Small autonomous payments for API calls, data, or services
// Create intent mandate for agent payment authority
const mandate = {
agentId: "agent_travel_planner",
maxAmount: 5000,
currency: "USD",
allowedPaymentMethods: ["credit_card", "bank_transfer"],
validFrom: new Date(),
validUntil: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000), // 30 days
constraints: {
perTransaction: 1000,
perDay: 3000,
requireApprovalAbove: 2000
},
purpose: "Travel booking for employees",
approverSignature: crypto.sign(mandateData)
};
// Store mandate as thing
const mandateId = await ctx.db.insert("things", {
type: "intent_mandate",
name: `Payment Mandate for ${mandate.agentId}`,
groupId: ctx.auth?.getOrganizationId?.(),
properties: {
protocols: {
ap2: {
agentId: mandate.agentId,
maxAmount: mandate.maxAmount,
currency: mandate.currency,
constraints: mandate.constraints,
approverSignature: mandate.approverSignature,
credentialHash: crypto.hash(JSON.stringify(mandate))
}
}
},
status: "active",
createdAt: Date.now(),
updatedAt: Date.now()
});
// Log mandate creation
await ctx.db.insert("events", {
type: "payment_intent_created",
groupId: ctx.auth?.getOrganizationId?.(),
actorId: ctx.auth?.getUserId?.(),
targetId: mandateId,
metadata: {
protocol: "ap2",
mandateId: mandateId,
agentId: mandate.agentId,
maxAmount: mandate.maxAmount
},
timestamp: Date.now()
});
// Agent executes payment within mandate limits
const payment = {
mandateId: "mandate_123",
agentId: "agent_travel_planner",
amount: 899.99,
currency: "USD",
paymentMethod: "credit_card",
merchant: "flightbooking.com",
purpose: "Flight booking for employee_456",
transactionId: "txn_abc123"
};
// Validate against mandate
const mandate = await ctx.db.get(payment.mandateId);
if (!validatePaymentAgainstMandate(payment, mandate.properties.protocols.ap2)) {
throw new Error("Payment violates mandate constraints");
}
// Create transaction thing
const transactionId = await ctx.db.insert("things", {
type: "payment_transaction",
name: `Payment to ${payment.merchant}`,
groupId: ctx.auth?.getOrganizationId?.(),
properties: {
protocols: {
ap2: {
mandateId: payment.mandateId,
amount: payment.amount,
currency: payment.currency,
merchant: payment.merchant,
purpose: payment.purpose,
status: "pending"
}
}
},
status: "active",
createdAt: Date.now(),
updatedAt: Date.now()
});
// Execute payment
const result = await executePaymentWithAP2(payment);
// Update transaction status
await ctx.db.patch(transactionId, {
properties: {
protocols: {
ap2: {
...mandate.properties.protocols.ap2,
status: result.success ? "completed" : "failed",
settlementTime: result.settlementTime,
confirmationId: result.confirmationId
}
}
}
});
// Create payment connection
await ctx.db.insert("connections", {
type: "transacted",
fromId: payment.agentId,
toId: "merchant_" + payment.merchant,
groupId: ctx.auth?.getOrganizationId?.(),
metadata: {
protocol: "ap2",
transactionId: transactionId,
amount: payment.amount,
currency: payment.currency,
purpose: payment.purpose
},
validFrom: Date.now()
});
// Log payment event
await ctx.db.insert("events", {
type: "payment_executed",
groupId: ctx.auth?.getOrganizationId?.(),
actorId: payment.agentId,
targetId: transactionId,
metadata: {
protocol: "ap2",
amount: payment.amount,
merchant: payment.merchant,
status: result.success ? "completed" : "failed"
},
timestamp: Date.now()
});
// Payment that requires human approval
const paymentRequest = {
mandateId: "mandate_123",
amount: 2500, // Above approval threshold
merchant: "premium-vendor.com",
agentId: "agent_purchasing",
requiresApproval: true
};
// Agent initiates but pauses for approval
const approvalId = await ctx.db.insert("things", {
type: "payment_approval",
name: `Approval required for $${paymentRequest.amount} payment`,
groupId: ctx.auth?.getOrganizationId?.(),
properties: {
protocols: {
ap2: {
status: "pending_approval",
payment: paymentRequest,
requestedAt: Date.now(),
requestedBy: paymentRequest.agentId
}
}
},
status: "active",
createdAt: Date.now(),
updatedAt: Date.now()
});
// Human approves
if (await humanApproves(approvalId)) {
// Execute payment
const result = await executePaymentWithAP2(paymentRequest);
console.log(`Payment approved and executed: ${result.confirmationId}`);
}