When an AI agent buys a sweater on your behalf, what exactly is it holding when it talks to the seller? For most of 2025 the honest answer was either "a saved card" or "a brittle bundle of cookies and CSRF tokens." Neither answer is acceptable when the agent is autonomous, the seller is real, and the money is yours.
Stripe Shared Payment Tokens, or SPTs, are the answer Stripe shipped as part of its 2026 Agentic Commerce Suite. An SPT is a payment credential that the user issues to an agent with three guardrails baked in: it can only be used at a specific seller, it caps the total amount the agent can spend, and it expires at a fixed time. Every state change in its life is an event the issuing user, the agent runtime, and the seller can observe.
This post is the long-form explainer. We walk through what an SPT actually is, how it differs from a saved card or a vaulted token, what its lifecycle looks like in practice, and which brands are already routing real shopping through SPTs. Then we build a streaming SQL pipeline in RisingWave that ingests SPT lifecycle events and maintains live views of active tokens, utilization, and anomalies. Every SQL block is verified on RisingWave v2.8.0 with real output included.
What Are Stripe Shared Payment Tokens?
A Shared Payment Token is a payment credential issued by a user to an agent so the agent can pay a specific seller, up to a specific amount, until a specific time. That is the whole concept, and almost every property of an SPT follows from those three constraints.
SPTs are part of Stripe's Agentic Commerce Suite, the same suite that ships the Stripe Agent Toolkit for Python and TypeScript. The toolkit handles the agent-side primitives: requesting tokens, presenting them to sellers, and reacting to lifecycle changes. The suite formalizes a model where the agent never sees the underlying card or bank account; it only ever holds the SPT, which is meaningless outside its narrow scope.
In April 2026, Stripe Link wallet became agent-usable, which closed the last UX loop for SPTs. A user can now approve an SPT directly from their existing Link wallet without re-entering payment information, and Link itself handles the cryptographic binding between user, agent, and seller. The first cohort of brands accepting SPT-driven traffic includes URBN's family of stores (Anthropologie, Free People, Urban Outfitters), Etsy, Coach, Kate Spade, Ashley Furniture, Revolve, Halara, and Abt. These are not hypotheticals. If you ask an agent today to buy a particular Anthropologie bedding set, it can hold an SPT scoped to seller_anthropologie with a $500 cap that expires in two hours.
The key idea is scope. A traditional saved card is a bearer credential: anyone who can present it to Stripe and pass risk checks can charge it. An SPT, by contrast, is non-fungible by design. Stripe rejects any charge attempt against an SPT that is not from the bound seller, that exceeds the remaining amount, or that arrives after expiry. The user does not have to trust the agent to behave; they only have to trust Stripe to enforce the SPT's bounds.
How SPTs Differ From Traditional Payment Tokens
Stripe already had several payment token types before SPTs: PaymentMethods, SetupIntents, and Connect-style indirect charges. So why a new primitive?
The simplest way to see the difference is to compare what each token type controls.
| Property | Saved card / PaymentMethod | Stripe Shared Payment Token |
| Bound to a specific seller | No, usable at any merchant on file | Yes, scoped to one seller_id |
| Spend cap | None beyond the card limit | Hard maximum amount enforced by Stripe |
| Time bound | None, expires with the card | Explicit expiry timestamp, often hours or days |
| Revocable mid-flight | Requires deleting the PaymentMethod | First-class revoke event, instant |
| Lifecycle observability | Charges only | created, authorized, charged, expired, revoked |
| Audience | Any client, including humans | Designed for autonomous agents |
The three properties at the top, seller-scoping, amount-bounding, and time-bounding, are what make SPTs safe to hand to an agent. The bottom two rows are what make them operable. Because every state change is a discrete event, you can build dashboards, alerts, and audit trails from a stream rather than reconstructing them by polling the Stripe API.
There is also a mental model shift. A saved card is a long-lived asset. An SPT is a short-lived contract. Issuing one is closer in spirit to creating an OAuth scope than to vaulting a card. That is what "scoped agentic payments" means: the user is granting an agent a narrow, revocable, time-bounded right to pay, not handing over a wallet.
The SPT Lifecycle
Every SPT moves through the same five-state machine. Stripe emits a webhook event for each transition.
stateDiagram-v2
[*] --> Created: agent calls create_spt()
Created --> Authorized: user approves via Link
Created --> Revoked: user denies before authorizing
Authorized --> Charged: seller captures funds
Charged --> Charged: subsequent capture (within cap)
Authorized --> Revoked: user cancels mid-flight
Charged --> Revoked: user cancels after partial spend
Authorized --> Expired: time bound elapses unused
Charged --> Expired: time bound elapses with funds remaining
Revoked --> [*]
Expired --> [*]
A few things are worth noticing about this diagram.
- Charged is a self-loop. A single SPT can be captured against multiple times, as long as the cumulative amount stays under the cap and the expiry has not passed. This is what makes SPTs useful for multi-step agent flows where a single shopping session produces several discrete charges.
- Revoke is always available. From any state except terminal ones, the user can revoke. This is the escape hatch and is part of why SPTs can be issued generously: the user knows they can always pull the token back.
- Terminal states are revoked and expired. There is no "consumed" state. A fully spent SPT either stays in
chargeduntil expiry, then moves toexpired, or is explicitly revoked.
In practice, your monitoring system will see between three and seven events per SPT. The vast majority of well-behaved tokens emit created, authorized, one or more charged events, and a final expired. The interesting cases, which we want our streaming pipeline to surface, are tokens that get revoked mid-flight, tokens that race toward the cap suspiciously fast, and tokens that hit the cap exactly.
Use Cases: Where SPTs Excel
SPTs are not a replacement for one-click checkout. They are a replacement for "I gave my agent my saved card and crossed my fingers." Three concrete use cases bring this out.
Agent shopping carts
The canonical SPT use case is an agent assembling a cart at a single seller. A user tells their agent "find me a navy linen blazer under $400 from URBN brands." The agent visits Anthropologie, Free People, and Urban Outfitters, evaluates options, and needs to commit to a purchase. Before checkout it requests an SPT scoped to the chosen brand with a $400 cap and a 30-minute expiry. The user approves via Link. The agent completes checkout. Stripe emits charged, the agent confirms the purchase, and the SPT eventually expires unused for any remainder.
This pattern is what URBN, Coach, Kate Spade, and Revolve are using SPTs for today. The seller gets a normal Stripe charge, the user gets the same audit trail they would get for any purchase, and the agent never holds anything reusable.
Recurring agent purchases
Some agentic workflows are not one-shot. A grocery agent that re-orders staples weekly does not want to ask the user for a fresh SPT every Monday. Instead, the agent requests an SPT with a higher cap, say $200, and a 7-day expiry. Each week it captures against the same SPT for the actual basket value. When the SPT nears expiry or runs out of headroom, the agent prompts the user to issue a new one.
This pattern leans on the multi-charge nature of SPTs and on the lifecycle observability. The user can watch utilization climb week by week in their wallet UI and decide whether the agent's spending is still tracking their intent.
Multi-step agent flows with refunds
Furniture purchases, Ashley's domain, are messy. An agent might commit to a sofa, the seller might ship it in two parts and capture twice, and a return might trigger a refund. SPTs handle this gracefully because every capture and every refund flows through the same token. The materialized lifecycle stays consistent, and the user can see in one place that they authorized $2,500, the seller captured $1,800 in two pieces, and $400 was refunded after a return.
The alternative, which is what many agent integrations did before SPTs, was to chain together separate PaymentIntents and reconcile them client-side. SPTs collapse that into a single observable object.
Monitoring SPT Lifecycle with Streaming SQL
The lifecycle observability of SPTs only matters if you can actually consume the events. In production you will almost always pipe Stripe webhook events into a queue (Kafka, Kinesis, or Stripe's own event delivery), and you want a streaming engine to maintain live views over that stream.
The rest of this post builds that pipeline in RisingWave, a streaming database that lets you write standard SQL and get incrementally maintained materialized views. Every SQL block below is verified on RisingWave v2.8.0.
The lifecycle events table
CREATE TABLE aap04_spt_lifecycle (
event_id VARCHAR PRIMARY KEY,
token_id VARCHAR NOT NULL,
agent_id VARCHAR NOT NULL,
user_id VARCHAR NOT NULL,
seller_id VARCHAR NOT NULL,
max_amount DECIMAL,
expiry TIMESTAMPTZ,
event_type VARCHAR NOT NULL,
charged_amount DECIMAL,
event_time TIMESTAMPTZ NOT NULL
);
In production this table would be backed by a Kafka source ingesting Stripe webhook deliveries. The columns mirror the SPT object fields exposed by Stripe's webhook payloads: token identity, agent identity, the bound user and seller, the cap, the expiry, the event type, and an optional charged amount that is only populated for charged events.
Sample lifecycle events
We insert nineteen events covering five SPTs. Each SPT walks through a different lifecycle path: fully spent, partially spent and active, expired unused, revoked mid-flight, and approaching its cap.
INSERT INTO aap04_spt_lifecycle VALUES
-- Token spt_001: Anthropologie (URBN), fully spent
('evt_001', 'spt_001', 'agent_shop_alpha', 'usr_2001', 'seller_anthropologie', 500.00, '2026-04-15 18:00:00+00', 'created', NULL, '2026-04-15 16:00:00+00'),
('evt_002', 'spt_001', 'agent_shop_alpha', 'usr_2001', 'seller_anthropologie', 500.00, '2026-04-15 18:00:00+00', 'authorized', NULL, '2026-04-15 16:00:30+00'),
('evt_003', 'spt_001', 'agent_shop_alpha', 'usr_2001', 'seller_anthropologie', 500.00, '2026-04-15 18:00:00+00', 'charged', 189.50, '2026-04-15 16:05:00+00'),
('evt_004', 'spt_001', 'agent_shop_alpha', 'usr_2001', 'seller_anthropologie', 500.00, '2026-04-15 18:00:00+00', 'charged', 310.50, '2026-04-15 16:10:00+00'),
-- Token spt_002: Etsy, partial spend, still active
('evt_005', 'spt_002', 'agent_shop_beta', 'usr_2002', 'seller_etsy', 250.00, '2026-05-10 12:00:00+00', 'created', NULL, '2026-05-06 09:00:00+00'),
('evt_006', 'spt_002', 'agent_shop_beta', 'usr_2002', 'seller_etsy', 250.00, '2026-05-10 12:00:00+00', 'authorized', NULL, '2026-05-06 09:00:15+00'),
('evt_007', 'spt_002', 'agent_shop_beta', 'usr_2002', 'seller_etsy', 250.00, '2026-05-10 12:00:00+00', 'charged', 45.99, '2026-05-06 09:05:00+00'),
('evt_008', 'spt_002', 'agent_shop_beta', 'usr_2002', 'seller_etsy', 250.00, '2026-05-10 12:00:00+00', 'charged', 67.50, '2026-05-06 09:30:00+00'),
-- Token spt_003: Coach, expired unused
('evt_009', 'spt_003', 'agent_shop_gamma', 'usr_2003', 'seller_coach', 800.00, '2026-04-20 23:00:00+00', 'created', NULL, '2026-04-20 21:00:00+00'),
('evt_010', 'spt_003', 'agent_shop_gamma', 'usr_2003', 'seller_coach', 800.00, '2026-04-20 23:00:00+00', 'authorized', NULL, '2026-04-20 21:01:00+00'),
('evt_011', 'spt_003', 'agent_shop_gamma', 'usr_2003', 'seller_coach', 800.00, '2026-04-20 23:00:00+00', 'expired', NULL, '2026-04-20 23:00:01+00'),
-- Token spt_004: Ashley Furniture, revoked by user mid-flight
('evt_012', 'spt_004', 'agent_shop_delta', 'usr_2004', 'seller_ashley', 2500.00, '2026-04-25 20:00:00+00', 'created', NULL, '2026-04-25 14:00:00+00'),
('evt_013', 'spt_004', 'agent_shop_delta', 'usr_2004', 'seller_ashley', 2500.00, '2026-04-25 20:00:00+00', 'authorized', NULL, '2026-04-25 14:00:30+00'),
('evt_014', 'spt_004', 'agent_shop_delta', 'usr_2004', 'seller_ashley', 2500.00, '2026-04-25 20:00:00+00', 'charged', 899.00, '2026-04-25 14:30:00+00'),
('evt_015', 'spt_004', 'agent_shop_delta', 'usr_2004', 'seller_ashley', 2500.00, '2026-04-25 20:00:00+00', 'revoked', NULL, '2026-04-25 15:00:00+00'),
-- Token spt_005: Revolve, active and approaching limit
('evt_016', 'spt_005', 'agent_shop_epsilon','usr_2005','seller_revolve', 400.00, '2026-05-08 23:59:59+00', 'created', NULL, '2026-05-06 08:00:00+00'),
('evt_017', 'spt_005', 'agent_shop_epsilon','usr_2005','seller_revolve', 400.00, '2026-05-08 23:59:59+00', 'authorized', NULL, '2026-05-06 08:00:10+00'),
('evt_018', 'spt_005', 'agent_shop_epsilon','usr_2005','seller_revolve', 400.00, '2026-05-08 23:59:59+00', 'charged', 155.00, '2026-05-06 08:30:00+00'),
('evt_019', 'spt_005', 'agent_shop_epsilon','usr_2005','seller_revolve', 400.00, '2026-05-08 23:59:59+00', 'charged', 198.75, '2026-05-06 09:45:00+00');
Active tokens view
The first view we need answers a basic operational question: which SPTs are still chargeable right now? An SPT is active if it has been authorized and has not yet been expired or revoked.
CREATE MATERIALIZED VIEW aap04_active_tokens_mv AS
SELECT
token_id,
MAX(agent_id) AS agent_id,
MAX(user_id) AS user_id,
MAX(seller_id) AS seller_id,
MAX(max_amount) AS max_amount,
COALESCE(SUM(charged_amount), 0) AS spent_amount,
MAX(max_amount) - COALESCE(SUM(charged_amount), 0) AS remaining_amount,
MAX(expiry) AS expiry
FROM aap04_spt_lifecycle
GROUP BY token_id
HAVING BOOL_OR(event_type = 'authorized')
AND NOT BOOL_OR(event_type = 'expired')
AND NOT BOOL_OR(event_type = 'revoked');
The BOOL_OR aggregates collapse the lifecycle for each token into a single row, and the HAVING filter applies the state machine rule: authorized at least once, never expired, never revoked. RisingWave maintains this view incrementally; every new lifecycle event for an existing token updates the row in place rather than re-scanning the table. See the materialized view reference for the full semantics.
Verified output
token_id | agent_id | user_id | seller_id | max_amount | spent_amount | remaining_amount | expiry
----------+--------------------+----------+----------------------+------------+--------------+------------------+---------------------------
spt_001 | agent_shop_alpha | usr_2001 | seller_anthropologie | 500.00 | 500.00 | 0.00 | 2026-04-15 18:00:00+00:00
spt_002 | agent_shop_beta | usr_2002 | seller_etsy | 250.00 | 113.49 | 136.51 | 2026-05-10 12:00:00+00:00
spt_005 | agent_shop_epsilon | usr_2005 | seller_revolve | 400.00 | 353.75 | 46.25 | 2026-05-08 23:59:59+00:00
(3 rows)
The view returns three of the five SPTs: spt_003 was filtered out because it has an expired event, and spt_004 was filtered out because it was revoked. spt_001 is still listed even though it has hit its cap, because it never received an expired event and is technically still chargeable up to its remaining amount of zero. We will catch that nuance in the next view.
Token usage view
The second view tracks how much of each SPT's cap has actually been consumed and at what cadence.
CREATE MATERIALIZED VIEW aap04_token_usage_mv AS
SELECT
token_id,
MAX(seller_id) AS seller_id,
MAX(agent_id) AS agent_id,
MAX(max_amount) AS max_amount,
COUNT(*) FILTER (WHERE event_type = 'charged') AS charge_count,
COALESCE(SUM(charged_amount) FILTER (WHERE event_type = 'charged'), 0) AS total_charged,
ROUND(
COALESCE(SUM(charged_amount) FILTER (WHERE event_type = 'charged'), 0)
/ NULLIF(MAX(max_amount), 0) * 100,
2
) AS pct_of_limit_used,
MIN(event_time) FILTER (WHERE event_type = 'charged') AS first_charge_at,
MAX(event_time) FILTER (WHERE event_type = 'charged') AS last_charge_at
FROM aap04_spt_lifecycle
GROUP BY token_id;
This view is unconditional. Every token shows up, including ones that were revoked or never charged, so an analyst can answer questions like "which Coach SPTs went unused?" or "which Ashley SPTs had charges before being revoked?"
Verified output
token_id | seller_id | agent_id | max_amount | charge_count | total_charged | pct_of_limit_used | first_charge_at | last_charge_at
----------+----------------------+--------------------+------------+--------------+---------------+-------------------+---------------------------+---------------------------
spt_001 | seller_anthropologie | agent_shop_alpha | 500.00 | 2 | 500.00 | 100 | 2026-04-15 16:05:00+00:00 | 2026-04-15 16:10:00+00:00
spt_002 | seller_etsy | agent_shop_beta | 250.00 | 2 | 113.49 | 45.40 | 2026-05-06 09:05:00+00:00 | 2026-05-06 09:30:00+00:00
spt_003 | seller_coach | agent_shop_gamma | 800.00 | 0 | 0 | 0 | |
spt_004 | seller_ashley | agent_shop_delta | 2500.00 | 1 | 899.00 | 35.96 | 2026-04-25 14:30:00+00:00 | 2026-04-25 14:30:00+00:00
spt_005 | seller_revolve | agent_shop_epsilon | 400.00 | 2 | 353.75 | 88.44 | 2026-05-06 08:30:00+00:00 | 2026-05-06 09:45:00+00:00
(5 rows)
The output cleanly separates the five lifecycle paths. spt_001 is fully spent at 100 percent. spt_002 is at a healthy 45 percent on Etsy. spt_003 has zero charges, the classic "user authorized but agent never got around to buying" pattern Coach sees on browse-only sessions. spt_004 has one $899 capture before being revoked. spt_005 is at 88 percent on Revolve, which is the one to watch.
Anomalous tokens view
The third view joins the active and usage views to surface SPTs that warrant attention. The two anomaly conditions we care about are tokens that are at or above 70 percent of their cap, and tokens that have charged three or more times.
CREATE MATERIALIZED VIEW aap04_anomalous_tokens_mv AS
SELECT
a.token_id,
a.seller_id,
a.agent_id,
a.max_amount,
a.spent_amount,
a.remaining_amount,
a.expiry,
u.charge_count,
u.pct_of_limit_used,
CASE
WHEN u.pct_of_limit_used >= 70 THEN 'APPROACHING_LIMIT'
WHEN u.charge_count >= 3 THEN 'HIGH_CHARGE_CADENCE'
ELSE 'OTHER'
END AS anomaly_reason
FROM aap04_active_tokens_mv a
JOIN aap04_token_usage_mv u ON a.token_id = u.token_id
WHERE u.pct_of_limit_used >= 70
OR u.charge_count >= 3;
This is a streaming join between two materialized views. RisingWave maintains it through incremental view maintenance: when a new charge event lands, the usage view updates first, the join propagates the change, and the anomaly view reflects the new state without any full refresh.
Verified output
token_id | seller_id | agent_id | max_amount | spent_amount | remaining_amount | expiry | charge_count | pct_of_limit_used | anomaly_reason
----------+----------------------+--------------------+------------+--------------+------------------+---------------------------+--------------+-------------------+-------------------
spt_001 | seller_anthropologie | agent_shop_alpha | 500.00 | 500.00 | 0.00 | 2026-04-15 18:00:00+00:00 | 2 | 100 | APPROACHING_LIMIT
spt_005 | seller_revolve | agent_shop_epsilon | 400.00 | 353.75 | 46.25 | 2026-05-08 23:59:59+00:00 | 2 | 88.44 | APPROACHING_LIMIT
(2 rows)
Two SPTs trip the anomaly threshold: the fully spent Anthropologie token and the 88 percent Revolve token. Note that spt_004 (Ashley) does not appear because it was revoked, so the active-tokens join filters it out. This is exactly the right behavior: a revoked token is no longer chargeable, so its prior utilization is irrelevant for live alerting.
Real-Time Spend-vs-Limit Tracking
The anomaly view is binary: a token either trips the rule or it does not. For dashboards and operations, you usually want a continuous picture of utilization across the entire token portfolio.
The simplest version is a banded view of every token by utilization:
SELECT
token_id,
seller_id,
max_amount,
total_charged,
max_amount - total_charged AS remaining,
pct_of_limit_used,
CASE
WHEN pct_of_limit_used >= 90 THEN 'CRITICAL'
WHEN pct_of_limit_used >= 70 THEN 'WARNING'
WHEN pct_of_limit_used >= 30 THEN 'NORMAL'
ELSE 'LOW'
END AS utilization_band
FROM aap04_token_usage_mv
ORDER BY pct_of_limit_used DESC;
Verified output
token_id | seller_id | max_amount | total_charged | remaining | pct_of_limit_used | utilization_band
----------+----------------------+------------+---------------+-----------+-------------------+------------------
spt_001 | seller_anthropologie | 500.00 | 500.00 | 0.00 | 100 | CRITICAL
spt_005 | seller_revolve | 400.00 | 353.75 | 46.25 | 88.44 | WARNING
spt_002 | seller_etsy | 250.00 | 113.49 | 136.51 | 45.40 | NORMAL
spt_004 | seller_ashley | 2500.00 | 899.00 | 1601.00 | 35.96 | NORMAL
spt_003 | seller_coach | 800.00 | 0 | 800.00 | 0 | LOW
(5 rows)
This is the kind of output you would render directly in an operations dashboard: one row per token, sorted by risk, color-coded by band.
For platform-level reporting, you usually want utilization rolled up by seller. This is a one-line aggregation on top of the same usage view:
SELECT
seller_id,
COUNT(DISTINCT token_id) AS tokens_issued,
SUM(max_amount) AS total_authorized,
SUM(total_charged) AS total_captured,
ROUND(SUM(total_charged) / NULLIF(SUM(max_amount), 0) * 100, 2) AS aggregate_utilization_pct
FROM aap04_token_usage_mv
GROUP BY seller_id
ORDER BY total_authorized DESC;
Verified output
seller_id | tokens_issued | total_authorized | total_captured | aggregate_utilization_pct
----------------------+---------------+------------------+----------------+---------------------------
seller_ashley | 1 | 2500.00 | 899.00 | 35.96
seller_coach | 1 | 800.00 | 0 | 0
seller_anthropologie | 1 | 500.00 | 500.00 | 100
seller_revolve | 1 | 400.00 | 353.75 | 88.44
seller_etsy | 1 | 250.00 | 113.49 | 45.40
(5 rows)
The interesting numbers are the conversion rates. Ashley authorized $2,500 but only captured $899 because the user revoked. Coach authorized $800 and captured nothing because the SPT expired unused. Anthropologie hit 100 percent. These are exactly the funnel metrics product teams want for agentic commerce, and you get them for free from the same lifecycle stream.
In production, you would push this view to a downstream system through a Kafka sink or query it directly via the PostgreSQL-compatible interface. Either way, every dashboard refresh sees state that is at most a few hundred milliseconds behind Stripe's webhook delivery.
FAQ
What is a Stripe Shared Payment Token?
A Stripe Shared Payment Token (SPT) is a scoped, time-bounded, amount-bounded payment credential that a user issues to an AI agent so the agent can transact with a specific seller on the user's behalf. SPTs are part of Stripe's Agentic Commerce Suite, sit on top of the Stripe Agent Toolkit, and are designed to give shoppers narrow, observable spending authority instead of handing an agent a full payment method.
How is a Shared Payment Token different from a regular Stripe payment method?
A regular Stripe payment method is open ended: any merchant integrated with the user's Stripe account can charge it up to the card limits. An SPT is scoped to a single seller, capped at a maximum amount, and expires at a fixed time. Every SPT also exposes lifecycle events including created, authorized, charged, expired, and revoked, so the issuing user, the agent platform, and the seller all see the same state in real time.
What is the lifecycle of a Shared Payment Token?
An SPT moves through five observable states. It is created when the agent requests payment scope. It is authorized when the user (or Stripe Link wallet) approves it. It transitions to charged each time the seller captures funds against it, and the same SPT can be charged multiple times until the cap is reached. It moves to expired when the time bound elapses, and to revoked when the user cancels it before expiry.
How can RisingWave help monitor SPT activity in real time?
RisingWave is a streaming database that ingests SPT lifecycle events from Stripe webhooks or a Kafka topic and maintains incremental materialized views over them. Teams use it to track active tokens, compute spend-versus-limit utilization, surface anomalies such as tokens approaching their cap, and join SPT data with order and fraud signals, all with sub-second freshness and standard SQL.
Conclusion
Shared Payment Tokens are the first payment primitive that was designed for autonomous agents from the ground up. They give users a way to delegate spending without giving up control, give sellers a clean integration point that does not require trusting agent identity, and give platforms a stream of lifecycle events that is straightforward to monitor.
Key takeaways:
- SPTs are scoped contracts, not vaulted credentials. They bind to a single seller, enforce a hard cap, and expire on a fixed clock. Stripe enforces all three constraints server-side, so the agent only ever holds a narrow capability.
- The lifecycle is observable end to end. Every state change emits an event, and a streaming pipeline can maintain live views of which tokens are chargeable, how much has been spent, and which are approaching their cap.
- Materialized views in RisingWave are the natural home for this data. Three small views (active tokens, token usage, anomalous tokens) cover the operational questions that come up day to day, and they update incrementally as new lifecycle events arrive.
- Real brands are running real traffic on SPTs today. URBN, Etsy, Coach, Kate Spade, Ashley Furniture, Revolve, Halara, and Abt are all part of the launch cohort, and the Link wallet integration in April 2026 closed the user-side UX gap.
All SQL in this tutorial runs on RisingWave v2.8.0 and produces the output shown. You can replicate the pipeline on your own instance by following the quickstart guide.
Ready to build real-time SPT monitoring? Try RisingWave Cloud free, no credit card required.
Join our Slack community to connect with other agentic payment developers.

