Shared Payment Tokens (SPT)
Shared Payment Tokens enable secure, time-limited payment delegation from agents to merchants using Stripe's Agentic Commerce Protocol.
Overview
SPTs allow an agent to authorize a merchant to charge a specific amount within a defined time window, without sharing the underlying payment method.
Key Features:
- ⏱️ Time-limited (default: 5 minutes)
- Amount-scoped (exact or maximum)
- Single-use tokens
- Merchant-specific
- Full audit trail
How It Works
MERMAID
sequenceDiagram
Agent->>AutopayOS: Create SPT for merchant
AutopayOS->>Stripe: Issue token
Stripe-->>AutopayOS: issued_token
AutopayOS-->>Agent: SPT ID
Agent->>Merchant: Share SPT
Merchant->>Stripe: Create PaymentIntent with SPT
Stripe-->>Merchant: Payment confirmed
Stripe->>AutopayOS: Webhook: token.usedImplementation
Step 1: Create SPT
TypeScript
const spt = await client.spt.create({
merchantDomain: 'shop.example.com',
amount: 49.99,
currency: 'USD',
expiresIn: 300, // 5 minutes
mandate: {
intentId: 'intent_123',
cartId: 'cart_456',
paymentId: 'payment_789',
},
});
console.log(spt.id); // spt_abc123Step 2: Agent Shares Token
The agent provides the SPT ID to the merchant via A2A protocol:
TypeScript
await agent.sendMessage({
to: 'merchant.example.com',
type: 'payment.authorization',
body: {
sptId: spt.id,
amount: 49.99,
orderId: 'order_123',
},
});Step 3: Merchant Charges
Merchant creates a PaymentIntent using the SPT:
TypeScript
// Merchant backend
const payment = await stripe.paymentIntents.create({
amount: 4999,
currency: 'usd',
payment_method_options: {
shared_payment: {
issued_token: spt.id,
},
},
application_fee_amount: 150, // 3% platform fee
});Step 4: Handle Webhooks
AutopayOS receives webhook events from Stripe:
TypeScript
// Webhook: shared_payment.issued_token.used
{
"type": "shared_payment.issued_token.used",
"data": {
"id": "spt_abc123",
"payment_intent": "pi_xyz789"
}
}SPT Lifecycle
- ACTIVE - Token created, ready to use
- USED - Token consumed by merchant
- EXPIRED - Token exceeded time limit
- REVOKED - Token manually canceled
Security Considerations
Do:
- Validate merchant domain before creating SPT
- Set shortest possible expiration time
- Link SPT to AP2 mandates for audit trail
- Monitor webhook events for fraud detection
Don't:
- Reuse SPT IDs
- Share SPTs over insecure channels
- Create SPTs without user consent
- Skip merchant verification
Monitoring
Check SPT status programmatically:
TypeScript
const status = await client.spt.getStatus(sptId);
console.log({
status: status.status, // ACTIVE | USED | EXPIRED | REVOKED
createdAt: status.createdAt,
usedAt: status.usedAt,
expiresAt: status.expiresAt,
});Admin Operations
Support teams can manage SPTs via admin endpoints:
Bash
# List all active SPTs
GET /admin/spt?status=ACTIVE
# Revoke a token
POST /admin/spt/:id/revoke
# Get statistics
GET /admin/spt/stats/overviewBest Practices
- Short Expiration - Use 5 minutes or less
- Exact Amounts - Specify exact amount when possible
- Mandate Linking - Always link to AP2 mandates
- Error Handling - Handle
EXPIREDgracefully - Webhook Verification - Verify Stripe webhook signatures
Troubleshooting
Token expired before merchant could charge:
- Increase expiration time to 10 minutes
- Optimize merchant checkout flow
- Pre-create SPT during cart review
Payment declined:
- Check user has sufficient balance
- Verify payment method is active
- Review policy restrictions
Merchant can't find token:
- Ensure SPT ID transmitted correctly
- Check merchant is using granted_token API
- Verify network connectivity