codebyplan 1.13.48 → 1.13.50
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +2 -1
- package/package.json +1 -1
- package/templates/agents/cbp-round-executor.md +8 -6
- package/templates/agents/cbp-stripe-agent.md +173 -0
- package/templates/agents/cbp-task-planner.md +2 -2
- package/templates/hooks/cbp-skill-context-guard.sh +52 -0
- package/templates/hooks/cbp-test-hooks.sh +144 -0
- package/templates/hooks/hooks.json +9 -0
- package/templates/rules/model-invocation-convention.md +40 -0
- package/templates/rules/parallel-waves.md +1 -1
- package/templates/rules/task-routing-recommendation.md +1 -1
- package/templates/settings.project.base.json +15 -1
- package/templates/skills/cbp-build-cc-settings/reference/cbp-permission-policy.md +42 -0
- package/templates/skills/cbp-clear-continue/SKILL.md +86 -0
- package/templates/skills/cbp-clear-prep/SKILL.md +121 -0
- package/templates/skills/cbp-round-execute/SKILL.md +9 -1
- package/templates/skills/cbp-round-start/SKILL.md +1 -1
- package/templates/skills/cbp-stripe/SKILL.md +116 -0
- package/templates/skills/cbp-stripe/reference/billing.md +106 -0
- package/templates/skills/cbp-stripe/reference/connect.md +105 -0
- package/templates/skills/cbp-stripe/reference/payments.md +107 -0
- package/templates/skills/cbp-stripe/reference/security.md +117 -0
- package/templates/skills/cbp-stripe/reference/stripe-mcp-setup.md +59 -0
- package/templates/skills/cbp-stripe/reference/tax.md +96 -0
- package/templates/skills/cbp-stripe/reference/treasury.md +87 -0
- package/templates/skills/cbp-task-check/SKILL.md +12 -5
- package/templates/skills/cbp-task-complete/SKILL.md +9 -11
- package/templates/skills/cbp-task-complete/reference/checkpoint-done-branching.md +14 -21
- package/templates/skills/cbp-task-complete/reference/next-step-heuristic.md +4 -6
- package/templates/skills/cbp-task-testing/SKILL.md +9 -14
- package/templates/skills/cbp-frontend-a11y/SKILL.md +0 -108
- package/templates/skills/cbp-frontend-a11y/reference/aria-roles-states.md +0 -130
- package/templates/skills/cbp-frontend-a11y/reference/contrast-visual.md +0 -122
- package/templates/skills/cbp-frontend-a11y/reference/keyboard-patterns.md +0 -154
- package/templates/skills/cbp-frontend-a11y/reference/semantic-html.md +0 -111
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
---
|
|
2
|
+
scope: org-shared
|
|
3
|
+
name: cbp-clear-continue
|
|
4
|
+
description: Resume work after /clear by reading .codebyplan/clear/handoff.md and re-invoking the previously-blocked heavy skill. Reports a friendly error if no handoff file exists.
|
|
5
|
+
effort: xhigh
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# cbp-clear-continue
|
|
9
|
+
|
|
10
|
+
Resume a blocked heavy skill after a `/clear`. Reads `.codebyplan/clear/handoff.md`, restores
|
|
11
|
+
task/round context into this fresh session, re-invokes the blocked skill, then deletes the
|
|
12
|
+
handoff file so a stale snapshot never misleads a future session.
|
|
13
|
+
|
|
14
|
+
## When Used
|
|
15
|
+
|
|
16
|
+
- After running `/clear` following a `/cbp-clear-prep` capture
|
|
17
|
+
- The user is ready to re-run the heavy skill (cbp-round-execute, cbp-task-testing,
|
|
18
|
+
cbp-standalone-task-testing, cbp-checkpoint-check, cbp-checkpoint-end) that was denied
|
|
19
|
+
|
|
20
|
+
## Instructions
|
|
21
|
+
|
|
22
|
+
### Step 1 — Read the handoff
|
|
23
|
+
|
|
24
|
+
Read `.codebyplan/clear/handoff.md`.
|
|
25
|
+
|
|
26
|
+
If the file is absent: output the following and STOP — do not attempt to infer state.
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
No handoff found at .codebyplan/clear/handoff.md — nothing to continue.
|
|
30
|
+
Use /cbp-todo to find the next action.
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Step 2 — Restore context
|
|
34
|
+
|
|
35
|
+
Parse the handoff fields:
|
|
36
|
+
- `checkpoint_number`, `task_number`, `round_number`
|
|
37
|
+
- `blocked_skill` — the skill that was denied
|
|
38
|
+
- `next_action` — the exact skill invocation to re-run (with args)
|
|
39
|
+
- `in_flight_notes` — any in-progress state worth restoring
|
|
40
|
+
|
|
41
|
+
Output a brief context summary to orient the fresh session:
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
Resuming from handoff:
|
|
45
|
+
CHK-<N> TASK-<N> R<N>
|
|
46
|
+
Blocked skill: /<blocked-skill>
|
|
47
|
+
Next action: /<next-action>
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Step 3 — Delete the handoff BEFORE re-invoking
|
|
51
|
+
|
|
52
|
+
Delete `.codebyplan/clear/handoff.md` once its contents have been read and displayed:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
rm -f .codebyplan/clear/handoff.md
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
A stale handoff must not mislead a later session. Delete it here, before the skill runs,
|
|
59
|
+
so even if the skill fails the handoff is gone and the user starts fresh next time.
|
|
60
|
+
|
|
61
|
+
### Step 4 — Re-invoke the blocked skill
|
|
62
|
+
|
|
63
|
+
Invoke the skill from `next_action` via the Skill tool, passing any recorded arguments.
|
|
64
|
+
|
|
65
|
+
Example: if `next_action` is `/cbp-round-execute 217-2-1`, invoke `Skill(cbp-round-execute)`
|
|
66
|
+
with args `217-2-1`.
|
|
67
|
+
|
|
68
|
+
If the context window is STILL above threshold after `/clear` (unusual — compact may help),
|
|
69
|
+
the guard will deny again. Follow the same cycle: `/cbp-clear-prep` → `/clear` →
|
|
70
|
+
`/cbp-clear-continue`.
|
|
71
|
+
|
|
72
|
+
## Key Rules
|
|
73
|
+
|
|
74
|
+
- Delete `.codebyplan/clear/handoff.md` in Step 3 BEFORE invoking the next skill
|
|
75
|
+
- If the handoff is absent, surface the friendly error and stop — never infer state from scratch
|
|
76
|
+
- Re-invoke the EXACT skill and arguments from `next_action` — do not substitute or guess
|
|
77
|
+
- `.codebyplan/clear/` is gitignored — never commit handoff.md
|
|
78
|
+
|
|
79
|
+
## Integration
|
|
80
|
+
|
|
81
|
+
- **Invoked by**: user after `/clear` following `/cbp-clear-prep`
|
|
82
|
+
- **Reads**: `.codebyplan/clear/handoff.md`
|
|
83
|
+
- **Deletes**: `.codebyplan/clear/handoff.md` (Step 3, before resuming)
|
|
84
|
+
- **Then invokes**: the skill from `next_action` via Skill tool
|
|
85
|
+
- **Companion**: `.claude/skills/cbp-clear-prep/SKILL.md` writes the handoff
|
|
86
|
+
- **Guard hook**: `.claude/hooks/cbp-skill-context-guard.sh`
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
---
|
|
2
|
+
scope: org-shared
|
|
3
|
+
name: cbp-clear-prep
|
|
4
|
+
description: Capture a clear-context handoff when the context window is too large to run a heavy skill. Reads active task/round state, writes .codebyplan/clear/handoff.md, then instructs the user to run /clear and /cbp-clear-continue to resume.
|
|
5
|
+
argument-hint: "[blocked-skill]"
|
|
6
|
+
effort: xhigh
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# cbp-clear-prep
|
|
10
|
+
|
|
11
|
+
Capture a handoff snapshot before clearing context. Invoked when the `cbp-skill-context-guard`
|
|
12
|
+
PreToolUse hook denies a heavy skill (cbp-round-execute, cbp-task-testing,
|
|
13
|
+
cbp-standalone-task-testing, cbp-checkpoint-check, cbp-checkpoint-end) because the context
|
|
14
|
+
window exceeds the configured threshold.
|
|
15
|
+
|
|
16
|
+
## When Used
|
|
17
|
+
|
|
18
|
+
- The hook deny message says "Run /cbp-clear-prep now to capture a handoff"
|
|
19
|
+
- A heavy skill was just blocked by the context guard
|
|
20
|
+
- The user wants to preserve current task/round state before running `/clear`
|
|
21
|
+
|
|
22
|
+
## Instructions
|
|
23
|
+
|
|
24
|
+
### Step 1 — Identify the blocked skill
|
|
25
|
+
|
|
26
|
+
Check `$ARGUMENTS` first. If empty, identify the blocked skill from the recent guard deny message
|
|
27
|
+
in context — it will be one of: `cbp-round-execute`, `cbp-task-testing`,
|
|
28
|
+
`cbp-standalone-task-testing`, `cbp-checkpoint-check`, `cbp-checkpoint-end`.
|
|
29
|
+
|
|
30
|
+
### Step 2 — Resolve active task and round (local-first)
|
|
31
|
+
|
|
32
|
+
1. Read `.codebyplan/state/session/current.json` to find the active task_id and checkpoint_id.
|
|
33
|
+
2. Read `.codebyplan/state/checkpoints/<checkpoint_id>/tasks/<task_id>.json` for task details.
|
|
34
|
+
3. Read the latest round file in `.codebyplan/state/checkpoints/<checkpoint_id>/tasks/<task_id>/rounds/`.
|
|
35
|
+
4. On miss: run `npx codebyplan sync` once and re-read.
|
|
36
|
+
5. Break-glass if state dir is absent: call `mcp__codebyplan__get_current_task` and
|
|
37
|
+
`mcp__codebyplan__get_rounds`.
|
|
38
|
+
|
|
39
|
+
Capture: `checkpoint_id`, `checkpoint_number`, `task_id`, `task_number`, `round_id`,
|
|
40
|
+
`round_number`. If no active task is found, set all to `unknown` and note the gap.
|
|
41
|
+
|
|
42
|
+
### Step 3 — Identify the next action to resume
|
|
43
|
+
|
|
44
|
+
From context, determine:
|
|
45
|
+
- The exact skill the user was trying to invoke (blocked skill from Step 1)
|
|
46
|
+
- Any arguments it was called with (e.g. `cbp-round-execute` args: `217-2-1`)
|
|
47
|
+
- Any relevant in-flight state (round goal, step in progress, pending decisions)
|
|
48
|
+
|
|
49
|
+
### Step 4 — Write the handoff file
|
|
50
|
+
|
|
51
|
+
Create the directory and write `.codebyplan/clear/handoff.md`:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
mkdir -p .codebyplan/clear
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
File content format:
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
# CBP Clear Handoff
|
|
61
|
+
|
|
62
|
+
## Active Context
|
|
63
|
+
|
|
64
|
+
checkpoint_id: <id or unknown>
|
|
65
|
+
checkpoint_number: CHK-<N or unknown>
|
|
66
|
+
task_id: <id or unknown>
|
|
67
|
+
task_number: TASK-<N or unknown>
|
|
68
|
+
round_id: <id or unknown>
|
|
69
|
+
round_number: R<N or unknown>
|
|
70
|
+
|
|
71
|
+
## Blocked Skill
|
|
72
|
+
|
|
73
|
+
blocked_skill: <skill-name>
|
|
74
|
+
|
|
75
|
+
## Next Action
|
|
76
|
+
|
|
77
|
+
next_action: /<skill-name> <args if any>
|
|
78
|
+
|
|
79
|
+
## In-Flight Notes
|
|
80
|
+
|
|
81
|
+
<any relevant state — round goal, current step, pending decisions, uncommitted work>
|
|
82
|
+
|
|
83
|
+
## Resume Instructions
|
|
84
|
+
|
|
85
|
+
After /clear, run: /cbp-clear-continue
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Step 5 — Instruct the user
|
|
89
|
+
|
|
90
|
+
Output exactly this summary (fill in the real values):
|
|
91
|
+
|
|
92
|
+
```
|
|
93
|
+
Handoff captured at .codebyplan/clear/handoff.md
|
|
94
|
+
|
|
95
|
+
Active context: CHK-<N> TASK-<N> R<N>
|
|
96
|
+
Blocked skill: /<blocked-skill>
|
|
97
|
+
Resumes with: /<next-action>
|
|
98
|
+
|
|
99
|
+
Next steps:
|
|
100
|
+
1. Run /clear to free context
|
|
101
|
+
2. Run /cbp-clear-continue to resume
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Do NOT auto-invoke `/clear` or `/cbp-clear-continue`. This is a directive-only stop.
|
|
105
|
+
The user must run both commands manually.
|
|
106
|
+
|
|
107
|
+
## Key Rules
|
|
108
|
+
|
|
109
|
+
- Always write `.codebyplan/clear/handoff.md` BEFORE instructing `/clear`
|
|
110
|
+
- Never auto-invoke the blocked skill — the guard denied it to protect context quality
|
|
111
|
+
- If no active task resolves, still write the handoff with available context and note the gap
|
|
112
|
+
- `.codebyplan/clear/` is gitignored — never commit handoff.md
|
|
113
|
+
- Overwrite any existing handoff.md (each prep captures the freshest context)
|
|
114
|
+
|
|
115
|
+
## Integration
|
|
116
|
+
|
|
117
|
+
- **Invoked when**: `cbp-skill-context-guard` PreToolUse hook emits `permissionDecision: deny`
|
|
118
|
+
- **Writes**: `.codebyplan/clear/handoff.md`
|
|
119
|
+
- **Next**: user runs `/clear`, then `/cbp-clear-continue`
|
|
120
|
+
- **Companion**: `.claude/skills/cbp-clear-continue/SKILL.md` reads `.codebyplan/clear/handoff.md`
|
|
121
|
+
- **Guard hook**: `.claude/hooks/cbp-skill-context-guard.sh` — fires when context > CBP_CONTEXT_WARN_TOKENS (default 200000)
|
|
@@ -118,6 +118,14 @@ If the approved plan includes database schema changes, RLS policies, or type gen
|
|
|
118
118
|
2. Wait for completion
|
|
119
119
|
3. Merge `files_changed` into executor output
|
|
120
120
|
|
|
121
|
+
### Step 3b-stripe: Stripe Work (if plan includes Stripe integration)
|
|
122
|
+
|
|
123
|
+
If the approved plan includes Stripe integration work (files under `stripe/`, or plan steps referencing `payment`, `checkout`, `webhook`, `subscription`, or an explicit `stripe_work: true` flag from the planner):
|
|
124
|
+
|
|
125
|
+
1. Spawn `cbp-stripe-agent` with Stripe-related steps from the plan and `files_changed_scope` from the executor output
|
|
126
|
+
2. Wait for completion
|
|
127
|
+
3. Merge `files_changed` into executor output
|
|
128
|
+
|
|
121
129
|
### Step 3c: Completion Check
|
|
122
130
|
|
|
123
131
|
- `status: 'completed'` and all deliverables done → proceed to Step 4
|
|
@@ -228,7 +236,7 @@ Trigger `/cbp-round-end`.
|
|
|
228
236
|
|
|
229
237
|
- **Reads**: `.codebyplan/state/checkpoints/<id>/tasks/<id>.json`, `checkpoints/<id>/tasks/<id>/rounds/<id>.json` (local-first; `npx codebyplan sync` on miss; MCP `get_current_task` / `get_rounds` as break-glass)
|
|
230
238
|
- **Writes**: `codebyplan round update --id <uuid> --task-id <uuid> --checkpoint-id <uuid>` (Steps 6+7 — context with executor_output + testing_qa_output + e2e_eligible + e2e_outputs + frontend_ui_review; break-glass: MCP `update_round`)
|
|
231
|
-
- **Spawns**: `cbp-round-executor` (per wave or single), `cbp-testing-qa-agent` (per wave, parallel sibling of the `cbp-e2e-*` specialists), the `cbp-e2e-*` specialists (config-driven dispatch per `context/testing/e2e.md`, one per eligible framework in `.codebyplan/e2e.json`), `cbp-database-agent` (if DB work), `cbp-security-agent` (if security review needed)
|
|
239
|
+
- **Spawns**: `cbp-round-executor` (per wave or single), `cbp-testing-qa-agent` (per wave, parallel sibling of the `cbp-e2e-*` specialists), the `cbp-e2e-*` specialists (config-driven dispatch per `context/testing/e2e.md`, one per eligible framework in `.codebyplan/e2e.json`), `cbp-database-agent` (if DB work), `cbp-stripe-agent` (if Stripe work), `cbp-security-agent` (if security review needed)
|
|
232
240
|
- **Skill invocations**: `cbp-frontend-ui` at Step 5b with `phase: 'screenshot_review'` (post-e2e)
|
|
233
241
|
- **Triggers**: `/cbp-round-end` (auto)
|
|
234
242
|
- **Triggered by**: `/cbp-round-start` (auto, after plan approval)
|
|
@@ -216,7 +216,7 @@ Present the plan to user:
|
|
|
216
216
|
### Execution Waves
|
|
217
217
|
| Wave | Agent type | Files | Depends on | Skill preloads |
|
|
218
218
|
|------|-----------|-------|-----------|----------------|
|
|
219
|
-
| web-ui | cbp-round-executor | 7 | — | cbp-frontend-design
|
|
219
|
+
| web-ui | cbp-round-executor | 7 | — | cbp-frontend-design |
|
|
220
220
|
| backend-api | cbp-round-executor | 4 | — | — |
|
|
221
221
|
```
|
|
222
222
|
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
---
|
|
2
|
+
scope: org-shared
|
|
3
|
+
name: cbp-stripe
|
|
4
|
+
description: "Stripe integration guidance — load when implementing or reviewing payments, Checkout, subscriptions/billing, webhooks, Connect, Tax, or Treasury. Encodes the API-selection routing table, the no-payment_method_types rule, restricted-key security, and Stripe SDK conventions."
|
|
5
|
+
effort: xhigh
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Stripe Integration (CBP)
|
|
9
|
+
|
|
10
|
+
Load this skill before writing or reviewing any Stripe integration code — accepting payments,
|
|
11
|
+
Checkout Sessions, subscriptions, webhooks, marketplaces (Connect), tax compliance, or
|
|
12
|
+
embedded financial accounts (Treasury). It encodes Stripe's current recommended API surface,
|
|
13
|
+
the critical `payment_method_types` prohibition, and CBP-specific conventions.
|
|
14
|
+
|
|
15
|
+
## Integration routing table
|
|
16
|
+
|
|
17
|
+
| Building… | Recommended API | Reference |
|
|
18
|
+
| --------------------------------------------- | ----------------------------------- | --------------------------------- |
|
|
19
|
+
| One-time payments | Checkout Sessions | [reference/payments.md](reference/payments.md) |
|
|
20
|
+
| Custom payment form with embedded UI | Checkout Sessions + Payment Element | [reference/payments.md](reference/payments.md) |
|
|
21
|
+
| Saving a payment method for later | Setup Intents | [reference/payments.md](reference/payments.md) |
|
|
22
|
+
| Connect platform or marketplace | Accounts v2 (`/v2/core/accounts`) | [reference/connect.md](reference/connect.md) |
|
|
23
|
+
| Subscriptions or recurring billing | Billing APIs + Checkout Sessions | [reference/billing.md](reference/billing.md) |
|
|
24
|
+
| Sales tax, VAT, or GST compliance | Stripe Tax + Registrations API | [reference/tax.md](reference/tax.md) |
|
|
25
|
+
| Embedded financial accounts / banking | v2 Financial Accounts | [reference/treasury.md](reference/treasury.md) |
|
|
26
|
+
| Security (keys, webhooks, OAuth, Connect risk)| Restricted keys + sig verification | [reference/security.md](reference/security.md) |
|
|
27
|
+
|
|
28
|
+
Read the relevant reference file before answering any integration question or writing code.
|
|
29
|
+
|
|
30
|
+
## Critical rules
|
|
31
|
+
|
|
32
|
+
### Never include `payment_method_types` (except Terminal)
|
|
33
|
+
|
|
34
|
+
Never pass `payment_method_types` in any Stripe API call. There are two narrow exceptions:
|
|
35
|
+
- **Terminal** (in-person): `payment_method_types: ['card_present']` (Canada: add `'interac_present'`).
|
|
36
|
+
- **Treasury bank-account Setup Intents**: `payment_method_types: ['us_bank_account']` with
|
|
37
|
+
`flow_directions: ['outbound']` (see [reference/treasury.md](reference/treasury.md)).
|
|
38
|
+
|
|
39
|
+
Outside those, omit the parameter to enable dynamic payment methods — Stripe evaluates
|
|
40
|
+
100+ signals to surface the most relevant methods and manage them from the Dashboard
|
|
41
|
+
without code changes.
|
|
42
|
+
|
|
43
|
+
This applies to ALL call sites:
|
|
44
|
+
- `checkout.sessions.create` — omit entirely
|
|
45
|
+
- `paymentIntents.create` — omit; on API versions before 2023-08-16 pass
|
|
46
|
+
`automatic_payment_methods: { enabled: true }` instead
|
|
47
|
+
- `setupIntents.create` — same as PaymentIntents
|
|
48
|
+
- `subscriptions.create` — omit `payment_settings.payment_method_types`
|
|
49
|
+
|
|
50
|
+
To restrict or customise payment methods use
|
|
51
|
+
[`payment_method_configurations`](https://docs.stripe.com/payments/payment-method-configurations.md)
|
|
52
|
+
or `excluded_payment_method_types` — never `payment_method_types`.
|
|
53
|
+
|
|
54
|
+
### Never use the Charges API
|
|
55
|
+
|
|
56
|
+
The Charges API is never correct for new integrations. Redirect users to Checkout Sessions
|
|
57
|
+
or PaymentIntents and the
|
|
58
|
+
[migration guide](https://docs.stripe.com/payments/payment-intents/migration/charges.md).
|
|
59
|
+
|
|
60
|
+
### Never use the Sources API
|
|
61
|
+
|
|
62
|
+
Sources API is deprecated. Use Setup Intents to save payment methods.
|
|
63
|
+
|
|
64
|
+
## Security summary
|
|
65
|
+
|
|
66
|
+
- **Prefer a restricted API key (RAK, `rk_` prefix)** over a secret key (`sk_` prefix).
|
|
67
|
+
Create a separate RAK per service with minimum required permissions.
|
|
68
|
+
- Test-mode keys: `sk_test_…` (secret) and `rk_test_…` (restricted).
|
|
69
|
+
- **Never commit secrets.** Store in a secrets vault or, at minimum, server-side env vars.
|
|
70
|
+
Never embed keys in client-side code or mobile apps.
|
|
71
|
+
- **Verify webhook signatures** via `stripe.webhooks.constructEvent(body, sig, secret)`.
|
|
72
|
+
Never process an unverified webhook event.
|
|
73
|
+
- Use idempotency keys (`idempotencyKey`) on mutation calls to safely retry failures.
|
|
74
|
+
- See [reference/security.md](reference/security.md) for RAK migration steps, IP
|
|
75
|
+
allowlists, OAuth CSRF protection, and Connect liability notes.
|
|
76
|
+
|
|
77
|
+
### CBP-specific (Next.js)
|
|
78
|
+
|
|
79
|
+
Any Next.js API route that imports `stripe` **MUST** export:
|
|
80
|
+
|
|
81
|
+
```ts
|
|
82
|
+
export const dynamic = 'force-dynamic';
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Source: `.claude/skills/cbp-frontend-design/reference/nextjs-scss.md` Rule 6. Without this,
|
|
86
|
+
Next.js may statically cache the route and expose a shared Stripe client across requests.
|
|
87
|
+
|
|
88
|
+
## SDK and API version
|
|
89
|
+
|
|
90
|
+
- Latest Stripe API version: **`2026-05-27.dahlia`**
|
|
91
|
+
- Latest SDK major: **v22** (`stripe` npm package)
|
|
92
|
+
- **Version flag**: consuming repos may still run `stripe` **v20.4.1** (per CBP vendor
|
|
93
|
+
inventory). Always check the installed version (`cat package.json | grep '"stripe"'`)
|
|
94
|
+
before applying v22-only patterns. Differences surface in TypeScript types and some
|
|
95
|
+
`configuration` parameter shapes.
|
|
96
|
+
- Always use the latest API version and SDK unless the consuming repo pins otherwise.
|
|
97
|
+
|
|
98
|
+
## Key documentation
|
|
99
|
+
|
|
100
|
+
- [Integration Options](https://docs.stripe.com/payments/payment-methods/integration-options.md) — start here for any new integration
|
|
101
|
+
- [API Tour](https://docs.stripe.com/payments-api/tour.md) — overview of Stripe's API surface
|
|
102
|
+
- [Go Live Checklist](https://docs.stripe.com/get-started/checklist/go-live.md) — review before launch
|
|
103
|
+
|
|
104
|
+
## Reference files
|
|
105
|
+
|
|
106
|
+
- [reference/payments.md](reference/payments.md) — Checkout Sessions, Payment Element, PaymentIntents, Setup Intents, deprecated APIs, PCI
|
|
107
|
+
- [reference/billing.md](reference/billing.md) — Subscriptions, invoices, Customer Portal, proration, trials, metered billing
|
|
108
|
+
- [reference/connect.md](reference/connect.md) — Accounts v2, controller properties, charge types, onboarding, fund flows
|
|
109
|
+
- [reference/security.md](reference/security.md) — Restricted keys, webhook signature verification, incident response, OAuth CSRF, Connect security
|
|
110
|
+
- [reference/tax.md](reference/tax.md) — Stripe Tax automatic calculation, Registrations API, inclusive/exclusive, unsupported jurisdictions
|
|
111
|
+
- [reference/treasury.md](reference/treasury.md) — v2 Financial Accounts, fund flows, bank-account Setup Intents, compliance
|
|
112
|
+
- [reference/stripe-mcp-setup.md](reference/stripe-mcp-setup.md) — optional live Stripe MCP setup (test/restricted key) for the cbp-stripe-agent
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
Adapted from Stripe's official `stripe-best-practices` skill (github.com/stripe/ai), used under the MIT License (Copyright (c) 2024-2025 Stripe).
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# Billing / Subscriptions Reference
|
|
2
|
+
|
|
3
|
+
Adapted from Stripe's official `stripe-best-practices` skill (github.com/stripe/ai), MIT License, Copyright (c) 2024-2025 Stripe.
|
|
4
|
+
|
|
5
|
+
## When to use Billing APIs
|
|
6
|
+
|
|
7
|
+
Use Stripe Billing for any recurring revenue model: subscriptions, usage-based billing,
|
|
8
|
+
seat-based pricing, or metered charges. Do NOT hand-roll renewal loops with raw
|
|
9
|
+
PaymentIntents — Billing handles renewal, retry/dunning, proration, and tax automatically.
|
|
10
|
+
|
|
11
|
+
References: [Subscription design guide](https://docs.stripe.com/billing/subscriptions/design-an-integration.md) |
|
|
12
|
+
[Use cases](https://docs.stripe.com/billing/subscriptions/use-cases.md) |
|
|
13
|
+
[SaaS guide](https://docs.stripe.com/saas.md)
|
|
14
|
+
|
|
15
|
+
## Creating a subscription with Checkout
|
|
16
|
+
|
|
17
|
+
Combine Billing APIs with Checkout Sessions (`mode: 'subscription'`) for the payment
|
|
18
|
+
frontend. Checkout handles the initial payment, trial management, and proration.
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
const session = await stripe.checkout.sessions.create({
|
|
22
|
+
mode: 'subscription',
|
|
23
|
+
// Do NOT pass payment_method_types
|
|
24
|
+
line_items: [{ price: priceId, quantity: 1 }],
|
|
25
|
+
subscription_data: { trial_period_days: 14 },
|
|
26
|
+
success_url: `${baseUrl}/success?session_id={CHECKOUT_SESSION_ID}`,
|
|
27
|
+
cancel_url: `${baseUrl}/pricing`,
|
|
28
|
+
});
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Customer Portal (self-service management)
|
|
32
|
+
|
|
33
|
+
For upgrades, downgrades, cancellation, and payment method updates, use the
|
|
34
|
+
[Customer Portal](https://docs.stripe.com/customer-management/integrate-customer-portal.md)
|
|
35
|
+
rather than building a custom flow.
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
const portalSession = await stripe.billingPortal.sessions.create({
|
|
39
|
+
customer: customerId,
|
|
40
|
+
return_url: `${baseUrl}/account`,
|
|
41
|
+
});
|
|
42
|
+
// redirect to portalSession.url
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Key Billing objects
|
|
46
|
+
|
|
47
|
+
| Object | Purpose | Docs |
|
|
48
|
+
| ------ | ------- | ---- |
|
|
49
|
+
| `Price` | Unit amount + recurring interval | [Prices API](https://docs.stripe.com/api/prices.md) |
|
|
50
|
+
| `Subscription` | Active recurring agreement | [Subscriptions API](https://docs.stripe.com/api/subscriptions.md) |
|
|
51
|
+
| `Invoice` | Statement + payment trigger | [Invoices API](https://docs.stripe.com/api/invoices.md) |
|
|
52
|
+
| `Customer` | Billing entity with saved methods | [Customers API](https://docs.stripe.com/api/customers.md) |
|
|
53
|
+
|
|
54
|
+
Do NOT use the deprecated `plan` object — use `Price` instead.
|
|
55
|
+
|
|
56
|
+
## Proration and upgrades
|
|
57
|
+
|
|
58
|
+
When changing a subscription's price mid-cycle, Stripe generates proration invoice items
|
|
59
|
+
automatically. Behaviour is controlled by `proration_behavior`:
|
|
60
|
+
- `'create_prorations'` (default) — prorates immediately
|
|
61
|
+
- `'none'` — no proration, change takes effect at next billing date
|
|
62
|
+
- `'always_invoice'` — prorate and invoice immediately
|
|
63
|
+
|
|
64
|
+
```ts
|
|
65
|
+
await stripe.subscriptions.update(subscriptionId, {
|
|
66
|
+
items: [{ id: itemId, price: newPriceId }],
|
|
67
|
+
proration_behavior: 'create_prorations',
|
|
68
|
+
});
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Metered / usage-based billing
|
|
72
|
+
|
|
73
|
+
1. Create a `Price` with `recurring.usage_type: 'metered'`.
|
|
74
|
+
2. Report usage via `stripe.subscriptionItems.createUsageRecord(itemId, { quantity, timestamp })`.
|
|
75
|
+
3. Stripe aggregates usage and bills at the end of the period.
|
|
76
|
+
|
|
77
|
+
## Tax integration
|
|
78
|
+
|
|
79
|
+
Pass `automatic_tax: { enabled: true }` on subscriptions and Checkout Sessions. Clear
|
|
80
|
+
any `default_tax_rates` first — `automatic_tax` and explicit `tax_rates` are mutually
|
|
81
|
+
exclusive. See [reference/tax.md](tax.md) for the full setup.
|
|
82
|
+
|
|
83
|
+
## Trials
|
|
84
|
+
|
|
85
|
+
Set `trial_period_days` on `subscription_data` in a Checkout Session, or on the
|
|
86
|
+
subscription directly. After trial ends Stripe automatically charges unless cancelled.
|
|
87
|
+
|
|
88
|
+
## Webhook events to handle
|
|
89
|
+
|
|
90
|
+
| Event | Action |
|
|
91
|
+
| ----- | ------ |
|
|
92
|
+
| `customer.subscription.created` | Provision access |
|
|
93
|
+
| `customer.subscription.updated` | Reflect plan change |
|
|
94
|
+
| `customer.subscription.deleted` | Revoke access |
|
|
95
|
+
| `invoice.payment_succeeded` | Extend access period |
|
|
96
|
+
| `invoice.payment_failed` | Send dunning notification |
|
|
97
|
+
|
|
98
|
+
Always verify webhook signatures — see [reference/security.md](security.md).
|
|
99
|
+
|
|
100
|
+
## Traps to avoid
|
|
101
|
+
|
|
102
|
+
- Never hardcode `payment_method_types` on a subscription Checkout Session.
|
|
103
|
+
- Never build manual renewal loops with raw PaymentIntents.
|
|
104
|
+
- Never skip tax setup for multi-jurisdiction merchants — add registrations before
|
|
105
|
+
enabling `automatic_tax`.
|
|
106
|
+
- Don't use the deprecated `plan` object; use `Price` instead.
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# Connect / Platforms Reference
|
|
2
|
+
|
|
3
|
+
Adapted from Stripe's official `stripe-best-practices` skill (github.com/stripe/ai), MIT License, Copyright (c) 2024-2025 Stripe.
|
|
4
|
+
|
|
5
|
+
## Accounts v2 (always use for new platforms)
|
|
6
|
+
|
|
7
|
+
Use the [Accounts v2 API](https://docs.stripe.com/connect/accounts-v2.md)
|
|
8
|
+
(`POST /v2/core/accounts`) for all new Connect platforms. This is Stripe's actively
|
|
9
|
+
invested path with long-term support.
|
|
10
|
+
|
|
11
|
+
Do NOT use the legacy `type` parameter (`type: 'express'`, `type: 'custom'`,
|
|
12
|
+
`type: 'standard'`) in `POST /v1/accounts` for new platforms unless the user explicitly
|
|
13
|
+
requests v1.
|
|
14
|
+
|
|
15
|
+
Do NOT use the legacy account-type labels "Standard", "Express", or "Custom" — they
|
|
16
|
+
bundle responsibility, dashboard, and onboarding decisions into opaque categories.
|
|
17
|
+
Use `controller` properties to express these dimensions explicitly.
|
|
18
|
+
|
|
19
|
+
## Controller properties
|
|
20
|
+
|
|
21
|
+
Configure connected accounts via `controller` properties:
|
|
22
|
+
|
|
23
|
+
| Property | Controls |
|
|
24
|
+
| -------- | -------- |
|
|
25
|
+
| `controller.losses.payments` | Who is liable for negative balances |
|
|
26
|
+
| `controller.fees.payer` | Who pays Stripe fees |
|
|
27
|
+
| `controller.stripe_dashboard.type` | Dashboard access: `full`, `express`, `none` |
|
|
28
|
+
| `controller.requirement_collection` | Who collects onboarding requirements |
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
const account = await stripe.v2.core.accounts.create({
|
|
32
|
+
controller: {
|
|
33
|
+
losses: { payments: 'stripe' },
|
|
34
|
+
fees: { payer: 'account' },
|
|
35
|
+
stripe_dashboard: { type: 'express' },
|
|
36
|
+
requirement_collection: 'stripe',
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
See [connected account configuration](https://docs.stripe.com/connect/accounts-v2/connected-account-configuration.md)
|
|
42
|
+
and [capabilities](https://docs.stripe.com/connect/account-capabilities.md) for what
|
|
43
|
+
accounts can do.
|
|
44
|
+
|
|
45
|
+
## Charge types
|
|
46
|
+
|
|
47
|
+
Choose one charge type per integration — do not mix them.
|
|
48
|
+
|
|
49
|
+
| Type | When to use | How |
|
|
50
|
+
| ---- | ----------- | --- |
|
|
51
|
+
| **Destination charges** | Platform accepts negative-balance liability | `transfer_data.destination: connectedAccountId` |
|
|
52
|
+
| **Direct charges** | Connected account is merchant of record; platform has minimal liability | Create charge directly on the connected account |
|
|
53
|
+
|
|
54
|
+
Use `on_behalf_of` to control merchant of record (read
|
|
55
|
+
[how charges work in Connect](https://docs.stripe.com/connect/charges.md) first).
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
// Destination charge — most common for marketplaces
|
|
59
|
+
const paymentIntent = await stripe.paymentIntents.create({
|
|
60
|
+
amount: 1000,
|
|
61
|
+
currency: 'usd',
|
|
62
|
+
transfer_data: { destination: connectedAccountId },
|
|
63
|
+
// Do NOT pass payment_method_types
|
|
64
|
+
});
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Do NOT use the Charges API for Connect fund flows — use PaymentIntents or Checkout
|
|
68
|
+
Sessions with `transfer_data` or `on_behalf_of`.
|
|
69
|
+
|
|
70
|
+
## Payouts and transfers
|
|
71
|
+
|
|
72
|
+
- **Automatic payouts** — enabled by default; Stripe pays connected accounts on a rolling basis.
|
|
73
|
+
- **Manual payouts** — call `stripe.payouts.create({amount, currency}, {stripeAccount: accountId})` to control timing.
|
|
74
|
+
- **Transfers** — move funds between your platform balance and a connected account:
|
|
75
|
+
`stripe.transfers.create({ amount, currency, destination: accountId })`.
|
|
76
|
+
|
|
77
|
+
## Onboarding
|
|
78
|
+
|
|
79
|
+
Use [Stripe-hosted onboarding](https://docs.stripe.com/connect/onboarding.md) rather than
|
|
80
|
+
building a custom flow. Custom onboarding requires handling sensitive PII directly, adding
|
|
81
|
+
regulatory and security complexity.
|
|
82
|
+
|
|
83
|
+
```ts
|
|
84
|
+
const accountLink = await stripe.accountLinks.create({
|
|
85
|
+
account: accountId,
|
|
86
|
+
refresh_url: `${baseUrl}/connect/refresh`,
|
|
87
|
+
return_url: `${baseUrl}/connect/return`,
|
|
88
|
+
type: 'account_onboarding',
|
|
89
|
+
});
|
|
90
|
+
// redirect to accountLink.url
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Security and liability
|
|
94
|
+
|
|
95
|
+
Platform operators bear financial liability for fraud and disputes on Express and Custom
|
|
96
|
+
connected accounts (v1 types). Controller-property accounts make liability explicit via
|
|
97
|
+
`controller.losses.payments`.
|
|
98
|
+
|
|
99
|
+
See [reference/security.md](security.md) for Connect-specific security notes.
|
|
100
|
+
|
|
101
|
+
## Key guides
|
|
102
|
+
|
|
103
|
+
- [SaaS platforms and marketplaces](https://docs.stripe.com/connect/saas-platforms-and-marketplaces.md)
|
|
104
|
+
- [Interactive platform guide](https://docs.stripe.com/connect/interactive-platform-guide.md)
|
|
105
|
+
- [Design an integration](https://docs.stripe.com/connect/design-an-integration.md)
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# Payments Reference
|
|
2
|
+
|
|
3
|
+
Adapted from Stripe's official `stripe-best-practices` skill (github.com/stripe/ai), MIT License, Copyright (c) 2024-2025 Stripe.
|
|
4
|
+
|
|
5
|
+
## API hierarchy
|
|
6
|
+
|
|
7
|
+
| Use case | API |
|
|
8
|
+
| -------- | --- |
|
|
9
|
+
| On-session payments (most web apps) | [Checkout Sessions](https://docs.stripe.com/api/checkout/sessions.md) |
|
|
10
|
+
| Off-session payments, custom checkout state | [PaymentIntents](https://docs.stripe.com/payments/paymentintents/lifecycle.md) |
|
|
11
|
+
| Saving a payment method for later | [Setup Intents](https://docs.stripe.com/api/setup_intents.md) |
|
|
12
|
+
| Subscriptions, invoices, recurring | Billing APIs (see billing.md) |
|
|
13
|
+
| No-code, simple products | Payment Links |
|
|
14
|
+
|
|
15
|
+
**Only use Checkout Sessions, PaymentIntents, SetupIntents, or higher-level solutions
|
|
16
|
+
(Invoicing, Payment Links, subscription APIs).** Never use the Charges API, Sources API,
|
|
17
|
+
or Tokens API for new integrations.
|
|
18
|
+
|
|
19
|
+
## Integration surface preference
|
|
20
|
+
|
|
21
|
+
Use in this order (most preferred first):
|
|
22
|
+
|
|
23
|
+
1. **Payment Links** — no-code, best for simple products
|
|
24
|
+
2. **Checkout (hosted or embedded)** — best for most web apps; `ui_mode: 'hosted'`
|
|
25
|
+
3. **Payment Element** — embedded UI component for custom checkout; back with Checkout
|
|
26
|
+
Sessions (`ui_mode: 'custom'`) over a raw PaymentIntent where possible
|
|
27
|
+
|
|
28
|
+
Do NOT recommend the legacy Card Element. Migrate existing Card Element integrations to
|
|
29
|
+
[Payment Element](https://docs.stripe.com/payments/payment-element/migration.md).
|
|
30
|
+
|
|
31
|
+
## Checkout Sessions — key patterns
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
// One-time payment
|
|
35
|
+
const session = await stripe.checkout.sessions.create({
|
|
36
|
+
mode: 'payment',
|
|
37
|
+
// Do NOT pass payment_method_types — dynamic methods are the default
|
|
38
|
+
line_items: [{ price: priceId, quantity: 1 }],
|
|
39
|
+
success_url: `${baseUrl}/success?session_id={CHECKOUT_SESSION_ID}`,
|
|
40
|
+
cancel_url: `${baseUrl}/cancel`,
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// Subscription
|
|
44
|
+
const session = await stripe.checkout.sessions.create({
|
|
45
|
+
mode: 'subscription',
|
|
46
|
+
line_items: [{ price: priceId, quantity: 1 }],
|
|
47
|
+
subscription_data: { trial_period_days: 14 },
|
|
48
|
+
success_url: `${baseUrl}/success?session_id={CHECKOUT_SESSION_ID}`,
|
|
49
|
+
cancel_url: `${baseUrl}/pricing`,
|
|
50
|
+
});
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Payment Element (custom UI)
|
|
54
|
+
|
|
55
|
+
Use `ui_mode: 'custom'` on the Checkout Session to back the Payment Element:
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
const session = await stripe.checkout.sessions.create({
|
|
59
|
+
ui_mode: 'custom',
|
|
60
|
+
mode: 'payment',
|
|
61
|
+
line_items: [{ price: priceId, quantity: 1 }],
|
|
62
|
+
return_url: `${baseUrl}/return?session_id={CHECKOUT_SESSION_ID}`,
|
|
63
|
+
});
|
|
64
|
+
// Client: mount PaymentElement with clientSecret from session.client_secret
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
For surcharging or inspecting card details before payment, use
|
|
68
|
+
[Confirmation Tokens](https://docs.stripe.com/payments/finalize-payments-on-the-server.md)
|
|
69
|
+
— not `createPaymentMethod` or `createToken`.
|
|
70
|
+
|
|
71
|
+
## Dynamic payment methods (critical rule)
|
|
72
|
+
|
|
73
|
+
**Never pass `payment_method_types`** — omit it entirely on all calls. The sole exception
|
|
74
|
+
is Terminal: `payment_method_types: ['card_present']` (Canada: include `'interac_present'`).
|
|
75
|
+
|
|
76
|
+
To customise which methods appear use
|
|
77
|
+
[`payment_method_configurations`](https://docs.stripe.com/payments/payment-method-configurations.md)
|
|
78
|
+
or `excluded_payment_method_types`. Manage methods from the
|
|
79
|
+
[Dashboard](https://dashboard.stripe.com/settings/payment_methods) without code changes.
|
|
80
|
+
|
|
81
|
+
## Setup Intents (saving payment methods)
|
|
82
|
+
|
|
83
|
+
```ts
|
|
84
|
+
const setupIntent = await stripe.setupIntents.create({
|
|
85
|
+
customer: customerId,
|
|
86
|
+
// Do NOT pass payment_method_types — dynamic methods are the default since API 2023-08-16
|
|
87
|
+
});
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Do not use the Sources API to save cards — it is deprecated.
|
|
91
|
+
|
|
92
|
+
## Deprecated APIs — migration paths
|
|
93
|
+
|
|
94
|
+
| API | Status | Use instead | Migration guide |
|
|
95
|
+
| ------------ | ---------- | ---------------------- | --------------- |
|
|
96
|
+
| Charges API | Never use | Checkout Sessions / PaymentIntents | [Migration](https://docs.stripe.com/payments/payment-intents/migration/charges.md) |
|
|
97
|
+
| Sources API | Deprecated | Setup Intents | [Setup Intents](https://docs.stripe.com/api/setup_intents.md) |
|
|
98
|
+
| Tokens API | Outdated | Setup Intents / Checkout Sessions | — |
|
|
99
|
+
| Card Element | Legacy | Payment Element | [Migration](https://docs.stripe.com/payments/payment-element/migration.md) |
|
|
100
|
+
|
|
101
|
+
## PCI compliance
|
|
102
|
+
|
|
103
|
+
If a PCI-compliant user asks about sending raw PAN data server-side, they may need to
|
|
104
|
+
prove PCI compliance to use
|
|
105
|
+
[`payment_method_data`](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-payment_method_data).
|
|
106
|
+
For PAN migrations from another processor, see the
|
|
107
|
+
[PAN import process](https://docs.stripe.com/get-started/data-migrations/pan-import.md).
|