Back to skills
SKILL.md
Mpp Spt Lifecycle
ASecurityImplement Shared Payment Token (SPT) lifecycle management for MPP — creation, usage, deactivation, webhook events, and reconciliation. Use when building the fiat/card payment flow within MPP using Stripe SPTs.
- 39 stars
- 0 votes
- 0 copies
- 0 views
- Added September 7, 2026
Works with
Security analysis
100/100npx -y skills add OrcaQubits/agentic-commerce-skills-plugins --skill mpp-spt-lifecycle --agent claude-codeAre you the author of Mpp Spt Lifecycle?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/orcaqubits-mpp-spt-lifecycle-agentic-commerce-skills-plugin)---
name: mpp-spt-lifecycle
description: Implement Shared Payment Token (SPT) lifecycle management for MPP — creation, usage, deactivation, webhook events, and reconciliation. Use when building the fiat/card payment flow within MPP using Stripe SPTs.
allowed-tools: Read, Write, Edit, Bash, Grep, Glob, WebSearch, WebFetch
---
# MPP Shared Payment Token (SPT) Lifecycle
## Before writing code
**Fetch live docs**:
1. Fetch `https://docs.stripe.com/agentic-commerce/concepts/shared-payment-tokens` for the canonical SPT documentation
2. Web-search `site:docs.stripe.com shared_payment granted_token API` for SPT API endpoints
3. Web-search `stripe shared payment token webhook events` for SPT event schemas
4. Fetch `https://docs.stripe.com/payments/machine/mpp` for SPT usage within MPP context
## Conceptual Architecture
### What SPTs Are
Shared Payment Tokens are one-time payment tokens scoped to a specific merchant and exact amount. They are the mechanism by which card/fiat payments work within the MPP protocol. The agent never handles raw card data — SPTs abstract away PCI-sensitive information.
### SPT Lifecycle
```
1. Agent → Stripe: Create SPT (scoped to merchant + amount + expiry)
2. Stripe → Agent: Returns spt_... token
3. Agent → Server: Sends SPT as payment credential in 402 flow
4. Server → Stripe: Creates PaymentIntent with SPT
5. Stripe → Server: Payment confirmed
6. Stripe → Agent: Webhook: shared_payment.issued_token.used
7. Stripe → Server: Webhook: shared_payment.granted_token.used
```
### SPT Creation (Agent-Side)
```
POST /v1/test_helpers/shared_payment/granted_tokens
Parameters:
payment_method: pm_card_visa
usage_limits[currency]: usd
usage_limits[max_amount]: 1000 # $10.00 in cents
usage_limits[expires_at]: <unix_ts> # Expiration timestamp
seller_details[network_id]: <seller_id> # Merchant's network ID
seller_details[external_id]: <ext_id> # Optional external reference
```
### SPT Consumption (Server-Side)
```
POST /v1/payment_intents
Parameters:
amount: 500 # $5.00 in cents
currency: usd
shared_payment_granted_token: spt_...
confirm: true
```
When confirmed, Stripe clones the original PaymentMethod and processes the charge.
### SPT Retrieval
```
GET /v1/shared_payment/granted_tokens/{id}
```
Returns limited payment method details (card brand, last four digits) and usage restrictions.
### SPT Webhook Events
| Event | Recipient | Trigger | Key Fields |
|-------|-----------|---------|------------|
| `shared_payment.granted_token.used` | Seller (Server) | SPT successfully consumed | token_id, amount, currency |
| `shared_payment.granted_token.deactivated` | Seller (Server) | SPT revoked or expired | token_id, reason |
| `shared_payment.issued_token.used` | Agent | Seller consumed the SPT | token_id, amount |
| `shared_payment.issued_token.deactivated` | Agent | SPT no longer valid | token_id, reason |
### Webhook Listener (Server-Side)
```typescript
app.post('/webhooks/stripe', async (c) => {
const sig = c.req.header('stripe-signature');
const event = stripe.webhooks.constructEvent(
await c.req.text(),
sig,
process.env.STRIPE_WEBHOOK_SECRET
);
switch (event.type) {
case 'shared_payment.granted_token.used':
// SPT was successfully consumed — update records
break;
case 'shared_payment.granted_token.deactivated':
// SPT expired or was revoked — clean up
break;
}
});
```
### SPT Constraints
| Constraint | Purpose |
|-----------|---------|
| `max_amount` | Transaction cannot exceed this (minor units) |
| `currency` | Token only works in specified currency |
| `expires_at` | Token invalid after this timestamp |
| `network_id` | Only specified merchant can use it |
| `external_id` | Additional merchant scoping |
### Deactivation Reasons
SPTs can be deactivated for:
- **Expiration** — `expires_at` passed
- **Usage** — Successfully consumed (single-use)
- **Revocation** — Agent or platform revoked the token
- **Fraud** — Flagged by Stripe's fraud detection
### Reconciliation
- Match SPT creation events to consumption events
- Track SPT lifecycle (created → used → settled) for accounting
- Monitor deactivation rates (high expiration rate may mean TTL is too short)
- Cross-reference SPT usage with PaymentIntent events
### Best Practices
- Set `max_amount` to the exact payment amount — never higher
- Set short expiration times (minutes, not hours)
- Implement idempotent webhook handlers (same event may be delivered multiple times)
- Verify webhook signatures using `stripe.webhooks.constructEvent()`
- Log SPT lifecycle events for audit trail (token IDs only, not sensitive data)
- Handle race conditions between SPT creation and consumption
- Monitor SPT deactivation webhook for cleanup
Fetch the latest Stripe SPT API documentation for exact endpoint paths, webhook event schemas, and error codes before implementing.
Attribution
Comments
Loading comments…