Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion plugins/link/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "link",
"version": "0.7.2",
"version": "0.7.3",
"description": "Authenticate with Link, create spend requests, and retrieve one-time-use card or shared payment token credentials for user-approved purchases.",
"author": {
"name": "Stripe"
Expand Down
2 changes: 1 addition & 1 deletion plugins/link/.codex-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "link",
"version": "0.7.2",
"version": "0.7.3",
"description": "Secure, one-time-use payment credentials from Link",
"author": {
"name": "Stripe",
Expand Down
2 changes: 1 addition & 1 deletion plugins/link/.cursor-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "link",
"displayName": "Stripe Link",
"version": "0.7.2",
"version": "0.7.3",
"description": "Get secure, one-time-use payment credentials from a Link wallet so agents can complete purchases on your behalf.",
"author": {
"name": "Stripe"
Expand Down
43 changes: 39 additions & 4 deletions skills/create-payment-credential/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
version: 0.7.2
version: 0.7.3
name: create-payment-credential
description: |
Gets secure, one-time-use payment credentials (cards, tokens) from a Link wallet so agents can complete purchases on behalf of users. Use when the user says "get me a card", "buy something", "pay for X", "make a purchase", "I need to pay", "complete checkout", or asks to transact on any merchant site. Use when the user asks to connect or log in to or sign up for their Link account.
Expand Down Expand Up @@ -113,14 +113,16 @@ Always check the current authentication status before starting a new login flow
**Determine how the merchant accepts payment:**

1. **Navigate to the merchant page** — browse it, read the page content, and understand how the site accepts payment.
2. **If the page has a credit card form, Stripe Elements, or traditional checkout UI** — use `card`.
3. **If the page describes an API or programmatic payment flow** — make a request to the relevant endpoint. If it returns **HTTP 402** with a `www-authenticate` header, use `shared_payment_token`.
2. **If the checkout page contains a hidden input `input[name="link_pay_token"]`** (typically inside a Stripe iframe) — use the **Link Pay Token flow** (Step 5, "Link Pay Token" section). This is the most seamless path. **Requires browser automation.** If you do not have browser automation available, fall back to the `card` credential flow instead.
3. **If the page has a credit card form without a hidden `link_pay_token` input** — use `card`.
4. **If the page describes an API or programmatic payment flow** — make a request to the relevant endpoint. If it returns **HTTP 402** with a `www-authenticate` header, use `shared_payment_token`.

What you find determines which credential type to use:

| What you see | Credential type | What to request |
|---|---|---|
| Credit card form / Stripe Elements | `card` (default) | Card |
| Hidden `input[name="link_pay_token"]` present on page | (none needed) | Link Pay Token flow |
| Credit card form (no hidden `link_pay_token` input) | `card` (default) | Card |
| HTTP 402 with `method="stripe"` in `www-authenticate` | `shared_payment_token` | Shared payment token (SPT) |
| HTTP 402 without `method="stripe"` in `www-authenticate` | not supported | Do not continue |

Expand Down Expand Up @@ -194,6 +196,39 @@ link-cli mpp pay <url> --spend-request-id <id> [--method POST] [--data '{"amount

`mpp pay` handles the full 402 flow automatically: probes the URL, parses the `www-authenticate` header, builds the `Authorization: Payment` credential using the SPT, and retries.

**Link Pay Token:** When the checkout page contains a hidden `input[name="link_pay_token"]` (typically inside a Stripe iframe), no card numbers are needed for this transaction. This flow requires browser automation.

1. Create a spend request (same as Step 4 -- no `--credential-type` flag needed) and get approval.

2. Retrieve the Link Pay Token:

```bash
link-cli spend-request retrieve <id> --include link_pay_token --format json
```

The response includes `link_pay_token: "eyJ..."`.

3. Open the merchant checkout page in a browser.

4. Find the hidden input `input[name="link_pay_token"]` (it may be inside an iframe) and inject the token using a native input event:

```javascript
const input = document.querySelector('input[name="link_pay_token"]');
Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, 'value')
.set.call(input, token);
input.dispatchEvent(new Event('input', { bubbles: true }));
```

5. Wait for the checkout to transition -- the card form disappears and a saved card appears with the consumer's email in the header. This confirms the token exchange and login succeeded.

6. Click the Pay/Submit button. Payment confirms without CVC or CAPTCHA.

**Important notes for the Link Pay Token flow:**
- The token is short-lived -- complete the flow promptly after retrieval.
- In this flow, card numbers are not needed -- the token authorizes payment directly using the consumer's saved card on file.
- If the browser already has an existing session cookie, the checkout may show a pre-existing session instead of the card form with the hidden input. Use a fresh browser context to ensure the token injection triggers.
- The consumer only sees the card they authorized in the spend request.


## Important

Expand Down
Loading