@funnelsgrove/cli 0.1.246 → 0.1.255

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.
Files changed (29) hide show
  1. package/docs-release-history.json +4 -0
  2. package/funnel-contract-compatibility.json +28 -28
  3. package/legacy-docs-catalog.json +195 -0
  4. package/package.json +4 -4
  5. package/template_docs/.funnelsgrove-docs.json +3 -3
  6. package/template_docs/docs/funnelsgrove/migrations/step-contract-v3.md +1 -1
  7. package/template_docs/funnel-docs.config.json +1 -1
  8. package/template_scaffold/.funnelsgrove-docs.json +3 -3
  9. package/template_scaffold/.funnelsgrove-scaffold.json +25 -45
  10. package/template_scaffold/context/build-context.md +1 -1
  11. package/template_scaffold/docs/funnelsgrove/migrations/step-contract-v3.md +1 -1
  12. package/template_scaffold/funnel-docs.config.json +1 -1
  13. package/template_scaffold/funnel.runtime-capabilities.json +4 -0
  14. package/template_scaffold/package-lock.json +64 -15
  15. package/template_scaffold/package.json +5 -3
  16. package/template_scaffold/src/app/sdk/page.tsx +1 -1
  17. package/template_scaffold/src/components/FunnelFlow.tsx +2 -0
  18. package/template_scaffold/src/components/StripeFraudDetection.tsx +36 -0
  19. package/template_scaffold/src/config/billing.plans.ts +6 -3
  20. package/template_scaffold/src/config/billing.test.plans.ts +3 -3
  21. package/template_scaffold/src/steps/content/step-32-paywall.content.ts +3 -0
  22. package/template_scaffold/src/steps/editor/step-32-paywall.editor.ts +6 -0
  23. package/template_scaffold/src/steps/step-32-paywall.tsx +90 -34
  24. package/template_scaffold/docs/AGENT_FUNNEL_IMPLEMENTATION_SPEC.md +0 -5
  25. package/template_scaffold/docs/ARCHITECTURE.md +0 -5
  26. package/template_scaffold/docs/FLOW_CONFIG_AND_ROUTING.md +0 -5
  27. package/template_scaffold/docs/PAYWALL_AND_PAYMENTS.md +0 -5
  28. package/template_scaffold/docs/README.md +0 -5
  29. package/template_scaffold/docs/references/funnel-sdk-user-answers.md +0 -5
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
- "sourceTreeHash": "189cc920ba1b08307ce189019d59cdeafd3f7ff27aa5e812d2547e283b0bc56d",
3
+ "sourceTreeHash": "c3035a50bb6a37cbe8545129ac71167ceb858d612f5c26d488c520d5924415f0",
4
4
  "stepContractVersion": 3,
5
- "docsBundleVersion": "2.0.238",
5
+ "docsBundleVersion": "2.0.248",
6
6
  "files": [
7
7
  {
8
8
  "path": ".env.example",
@@ -16,7 +16,7 @@
16
16
  },
17
17
  {
18
18
  "path": ".funnelsgrove-docs.json",
19
- "sha256": "c52035e47a492d8ff1bcb204e894c4b5e3ea02e5fb2847aa14273e3a1c82c0e3",
19
+ "sha256": "21e4af4b5c474d7d4ec3574da7d34fce72b9d854478de61ea84610fe76231f50",
20
20
  "mode": "100644"
21
21
  },
22
22
  {
@@ -41,32 +41,7 @@
41
41
  },
42
42
  {
43
43
  "path": "context/build-context.md",
44
- "sha256": "281c094cc80423c4abdf206a67be6025103beac1c7becfad157d135846189f87",
45
- "mode": "100644"
46
- },
47
- {
48
- "path": "docs/AGENT_FUNNEL_IMPLEMENTATION_SPEC.md",
49
- "sha256": "eaf3de420195260ee86b0bfc6ab6eedb42c5b0b6ea5e32f35111bac24ef583f8",
50
- "mode": "100644"
51
- },
52
- {
53
- "path": "docs/ARCHITECTURE.md",
54
- "sha256": "9cb05a5ccbae96fd18bc4d397d89bf1638184941ad896aa584b3a65b932ecdcb",
55
- "mode": "100644"
56
- },
57
- {
58
- "path": "docs/FLOW_CONFIG_AND_ROUTING.md",
59
- "sha256": "8a1c6266c69a1d1c775c5966e7a895f3bcc792dc6bfdc18540b856cca8841c08",
60
- "mode": "100644"
61
- },
62
- {
63
- "path": "docs/PAYWALL_AND_PAYMENTS.md",
64
- "sha256": "b599ec24cb642a26856861c8c813067b9471a2b1b4f36f6989ca14a3419dd796",
65
- "mode": "100644"
66
- },
67
- {
68
- "path": "docs/README.md",
69
- "sha256": "5ef5bb43dfc33d6159ef5c83ce72352284a22836bb4efd38c2dd40487485acd9",
44
+ "sha256": "030a3db1689991e04ab6d60a8b6a0e304a5ef45092625aa895bbabc694ed383e",
70
45
  "mode": "100644"
71
46
  },
72
47
  {
@@ -101,7 +76,7 @@
101
76
  },
102
77
  {
103
78
  "path": "docs/funnelsgrove/migrations/step-contract-v3.md",
104
- "sha256": "4bc62e599ad4eda8c666aadc82e521ab87132b19b905d1ac18d7eefe7094a117",
79
+ "sha256": "19ea25028aebc54e553c223385ed1bf704a4f2bdef817250e01e566866034673",
105
80
  "mode": "100644"
106
81
  },
107
82
  {
@@ -224,11 +199,6 @@
224
199
  "sha256": "9c62b5c908ffade3dc478b95f67b574817af98d4e8c9359d7db20cccd5eca2b7",
225
200
  "mode": "100644"
226
201
  },
227
- {
228
- "path": "docs/references/funnel-sdk-user-answers.md",
229
- "sha256": "5f947eb479da461f533f2e8971c813a74bf4adbab7b723a1f736a27c2467cb15",
230
- "mode": "100644"
231
- },
232
202
  {
233
203
  "path": "eslint.config.mjs",
234
204
  "sha256": "059cab3c5d3244a3695879763e6ca845e862850598b6c23a3c7a62a30b085954",
@@ -236,7 +206,7 @@
236
206
  },
237
207
  {
238
208
  "path": "funnel-docs.config.json",
239
- "sha256": "d338125ed0a8785013323045c54b427bfd542fd0dd3b573b241b3cbc73b185ab",
209
+ "sha256": "07db87377a3d12b6bcf119d01bebffbbbb4702bb3cf83b8059132adbd2486a21",
240
210
  "mode": "100644"
241
211
  },
242
212
  {
@@ -244,6 +214,11 @@
244
214
  "sha256": "6b5f7891fa9ef74e63d6b06f19a20c3aa3184a61541b76e18da4ce366e5faed8",
245
215
  "mode": "100644"
246
216
  },
217
+ {
218
+ "path": "funnel.runtime-capabilities.json",
219
+ "sha256": "3d74683170fced7afa9badfdf837706aac9c3d554690708b3ba31b009028a069",
220
+ "mode": "100644"
221
+ },
247
222
  {
248
223
  "path": "gitignore.template",
249
224
  "sha256": "3a92bf7904de32466cfc5521796fe60bcde1301b88f88e1417709060041e2aec",
@@ -261,12 +236,12 @@
261
236
  },
262
237
  {
263
238
  "path": "package-lock.json",
264
- "sha256": "1a2be5a5642efecb5ac4a37b9bfb27d9bb57eb62434d1d55396ea8cbd7c0c840",
239
+ "sha256": "cd9436fe9d8f31d32377ecf74254c8db0779eac12f23e41f5466dc9a8d85c91e",
265
240
  "mode": "100644"
266
241
  },
267
242
  {
268
243
  "path": "package.json",
269
- "sha256": "e5a2862caeb8e58234129bd55743fba93d6a414e60fc7360679b7d24c103c289",
244
+ "sha256": "2e2f22b65bba762d82f76993fd318098756c2191a6455760fb044395f2a43d34",
270
245
  "mode": "100644"
271
246
  },
272
247
  {
@@ -306,7 +281,7 @@
306
281
  },
307
282
  {
308
283
  "path": "src/app/sdk/page.tsx",
309
- "sha256": "1fc38384167d661d915fe217c4b0799ded2a1e158494eab6120b67406e5ce17e",
284
+ "sha256": "40faecab967f54c23fa9ac751d97773f6f77585a0a5fca0afad76757d3ba7b18",
310
285
  "mode": "100644"
311
286
  },
312
287
  {
@@ -321,7 +296,12 @@
321
296
  },
322
297
  {
323
298
  "path": "src/components/FunnelFlow.tsx",
324
- "sha256": "64424cf80a192ccec542ed1a188ab143a2bb33261a8717b8daa50726c848f0d3",
299
+ "sha256": "d85147018449917e0770fc00d479305b4f805323b1754a5ee1d0ea4a2e780840",
300
+ "mode": "100644"
301
+ },
302
+ {
303
+ "path": "src/components/StripeFraudDetection.tsx",
304
+ "sha256": "caad37065e53a6907dca8a556a08573d24736dccaf7c54d61aa2a74694883536",
325
305
  "mode": "100644"
326
306
  },
327
307
  {
@@ -341,12 +321,12 @@
341
321
  },
342
322
  {
343
323
  "path": "src/config/billing.plans.ts",
344
- "sha256": "71a268bbefd624b58f5d63a66a4f35c36973931ddac4f3f49d38f03576dbe36a",
324
+ "sha256": "a6cc4720de70f47a2c0ffe85be1fc47b53b85eb85d5bb2e750aefe970fbede31",
345
325
  "mode": "100644"
346
326
  },
347
327
  {
348
328
  "path": "src/config/billing.test.plans.ts",
349
- "sha256": "921f3c2e523606f292091762501f256b87479461fbf4e6327cd8fc0c8fb10a68",
329
+ "sha256": "d4adecf2de68970886cc6df4d34d26f0db299965e6005ce32a6215a3b48e5f84",
350
330
  "mode": "100644"
351
331
  },
352
332
  {
@@ -501,7 +481,7 @@
501
481
  },
502
482
  {
503
483
  "path": "src/steps/content/step-32-paywall.content.ts",
504
- "sha256": "1a763425633ad6b8ece3d8f800f4272a72e7dc93cf845d379e9f23faee0d4cd5",
484
+ "sha256": "82d7ddca72c40d29a8509e856fb4a05b96faaab7befecb89c410f8ee43a95e12",
505
485
  "mode": "100644"
506
486
  },
507
487
  {
@@ -526,7 +506,7 @@
526
506
  },
527
507
  {
528
508
  "path": "src/steps/editor/step-32-paywall.editor.ts",
529
- "sha256": "9f6d5d126b456dc59ffe6f9f374b7e3325dd43f80edf8906b6715bb97eae3744",
509
+ "sha256": "e544665b1e0ae7b121630fab9c1de33b88dfd8f3835bf3f12ac2438f7cbd220a",
530
510
  "mode": "100644"
531
511
  },
532
512
  {
@@ -571,7 +551,7 @@
571
551
  },
572
552
  {
573
553
  "path": "src/steps/step-32-paywall.tsx",
574
- "sha256": "46d1a44a37b71f4e73fe5dd7d6ff4d3956929943364b1d285caa9e6846d213a9",
554
+ "sha256": "bebf58e628bf55a7b90d326dbde2b767b2b7054635d4354dc4b6202f96825219",
575
555
  "mode": "100644"
576
556
  },
577
557
  {
@@ -20,7 +20,7 @@
20
20
  - `src/runtime/use-funnel-flow-controller.ts` (flow orchestration, tracking, and runtime mode)
21
21
  - `src/components/FunnelFlow.tsx` (shell render)
22
22
  - `src/components/FunnelEditorPanel.tsx` (editor controls)
23
- - `docs/references/funnel-sdk-user-answers.md` (typed user answers + analytics usage)
23
+ - `docs/funnelsgrove/contracts/content-answers.md` (typed user answers + analytics usage)
24
24
 
25
25
  ## Onboarding Artifacts
26
26
  - `PRODUCT_SENSE.md`: required
@@ -17,7 +17,7 @@ Supported read versions: `1`, `2`, `3`. Authoring and publish target version `3`
17
17
 
18
18
  ### Package release order
19
19
 
20
- Release `@funnelsgrove/sdk` `0.4.0` first, then `@funnelsgrove/runtime` `0.20.1`, then `@funnelsgrove/analytics` `0.3.0`, then `@funnelsgrove/payments` `0.22.4`. The production deploy verifies the zero-traffic API candidate, publishes and verifies `@funnelsgrove/cli` `0.1.246`, and only then promotes the candidate to production traffic. The serving API must never advertise an unpublished preferred CLI. Publishing packages and deploying production remain separately approved operational actions.
20
+ Release `@funnelsgrove/sdk` `0.4.0` first, then `@funnelsgrove/runtime` `0.21.1`, then `@funnelsgrove/analytics` `0.4.1`, then `@funnelsgrove/payments` `0.23.2`. The production deploy verifies the zero-traffic API candidate, publishes and verifies `@funnelsgrove/cli` `0.1.255`, and only then promotes the candidate to production traffic. The serving API must never advertise an unpublished preferred CLI. Publishing packages and deploying production remain separately approved operational actions.
21
21
  <!-- funnelsgrove:generated:end contract-v3/migration/step-contract-v3 -->
22
22
 
23
23
  ## Version-last policy
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
- "bundleVersion": "2.0.238",
3
+ "bundleVersion": "2.0.248",
4
4
  "contractSource": "funnelsgrove-repository://apps/funnel-runtime/contracts/step-contract-v2.json",
5
5
  "fullyGenerated": [
6
6
  ".funnelsgrove-docs.json",
@@ -0,0 +1,4 @@
1
+ {
2
+ "moneyContractVersion": 1,
3
+ "localeContractVersion": 1
4
+ }
@@ -8,9 +8,9 @@
8
8
  "name": "funnel-template",
9
9
  "version": "0.1.0",
10
10
  "dependencies": {
11
- "@funnelsgrove/analytics": "^0.2.0",
12
- "@funnelsgrove/payments": "^0.22.1",
13
- "@funnelsgrove/runtime": "^0.19.1",
11
+ "@funnelsgrove/analytics": "^0.4.1",
12
+ "@funnelsgrove/payments": "^0.23.2",
13
+ "@funnelsgrove/runtime": "^0.21.1",
14
14
  "@stripe/react-stripe-js": "^5.6.0",
15
15
  "@stripe/stripe-js": "^8.7.0",
16
16
  "lucide-react": "^0.553.0",
@@ -24,8 +24,10 @@
24
24
  "@types/node": "^20",
25
25
  "@types/react": "^19",
26
26
  "@types/react-dom": "^19",
27
+ "esbuild": "0.28.1",
27
28
  "eslint": "^9",
28
29
  "eslint-config-next": "16.1.6",
30
+ "playwright": "1.58.2",
29
31
  "typescript": "^5",
30
32
  "vite-node": "3.2.4",
31
33
  "vitest": "^3.2.4"
@@ -938,17 +940,17 @@
938
940
  }
939
941
  },
940
942
  "node_modules/@funnelsgrove/analytics": {
941
- "version": "0.2.0",
942
- "resolved": "https://registry.npmjs.org/@funnelsgrove/analytics/-/analytics-0.2.0.tgz",
943
- "integrity": "sha512-7YFNAOPsw8BCL0RIqDmFM7JSI3ftYhP8BV+++/5u/ryNCdlZ46QpkQO94yXumUSoyKgRpg1zIgdeiaYJd0WWYA==",
943
+ "version": "0.4.1",
944
+ "resolved": "https://registry.npmjs.org/@funnelsgrove/analytics/-/analytics-0.4.1.tgz",
945
+ "integrity": "sha512-9bj0d6fcmGoBlWmCGBqfi3o4jJFHT6TgufquyMPwpichVylhqzgGpSaJ8PPa6MCglHzyQbQfjvDAOhxrl4dZaw==",
944
946
  "peerDependencies": {
945
- "@funnelsgrove/runtime": "^0.19.1"
947
+ "@funnelsgrove/runtime": "^0.21.1"
946
948
  }
947
949
  },
948
950
  "node_modules/@funnelsgrove/payments": {
949
- "version": "0.22.1",
950
- "resolved": "https://registry.npmjs.org/@funnelsgrove/payments/-/payments-0.22.1.tgz",
951
- "integrity": "sha512-WIaOC833Ff5vYp+35ierfVCI9bxAQSXJ2vXVEHIV9RFMTmUD41jAfaE48lhZ/oW0h68Iod8rL9EfUyc0McWZQA==",
951
+ "version": "0.23.2",
952
+ "resolved": "https://registry.npmjs.org/@funnelsgrove/payments/-/payments-0.23.2.tgz",
953
+ "integrity": "sha512-p+tjqo5Bl7g3bR02GOn5CCvFg/FGJwzZkbNUhHGLZjNQnSvBVQr8OluNEMCOvNmIC9B6OeutCZjcLvyoBnjltQ==",
952
954
  "dependencies": {
953
955
  "@solidgate/react-sdk": "1.34.0",
954
956
  "@stripe/react-stripe-js": "^5.6.0",
@@ -958,14 +960,14 @@
958
960
  "stripe": "^20.3.1"
959
961
  },
960
962
  "peerDependencies": {
961
- "@funnelsgrove/analytics": "^0.1.111 || ^0.2.0",
962
- "@funnelsgrove/runtime": "^0.19.1"
963
+ "@funnelsgrove/analytics": "^0.4.1",
964
+ "@funnelsgrove/runtime": "^0.21.1"
963
965
  }
964
966
  },
965
967
  "node_modules/@funnelsgrove/runtime": {
966
- "version": "0.19.1",
967
- "resolved": "https://registry.npmjs.org/@funnelsgrove/runtime/-/runtime-0.19.1.tgz",
968
- "integrity": "sha512-4TTdhU4V2m2hViMd1mdo3vcRjaVvgORK5vcgu9UTGuAhjmUfMXjGTNkzHvgJ2LHLdr2NvFv+d+C0unj7fo5ouw==",
968
+ "version": "0.21.1",
969
+ "resolved": "https://registry.npmjs.org/@funnelsgrove/runtime/-/runtime-0.21.1.tgz",
970
+ "integrity": "sha512-RsPBT8rf0Ms7oU6dJehAY7cCYt7tCw1IjziiaVatguqt9Yusn3Mo2X7DyfIM1N0It6Klg/nlo1o7vwopRT28rg==",
969
971
  "dependencies": {
970
972
  "@funnelsgrove/sdk": "0.4.0",
971
973
  "posthog-js": "^1.369.2",
@@ -6177,6 +6179,53 @@
6177
6179
  "url": "https://github.com/sponsors/jonschlinkert"
6178
6180
  }
6179
6181
  },
6182
+ "node_modules/playwright": {
6183
+ "version": "1.58.2",
6184
+ "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.58.2.tgz",
6185
+ "integrity": "sha512-vA30H8Nvkq/cPBnNw4Q8TWz1EJyqgpuinBcHET0YVJVFldr8JDNiU9LaWAE1KqSkRYazuaBhTpB5ZzShOezQ6A==",
6186
+ "dev": true,
6187
+ "license": "Apache-2.0",
6188
+ "dependencies": {
6189
+ "playwright-core": "1.58.2"
6190
+ },
6191
+ "bin": {
6192
+ "playwright": "cli.js"
6193
+ },
6194
+ "engines": {
6195
+ "node": ">=18"
6196
+ },
6197
+ "optionalDependencies": {
6198
+ "fsevents": "2.3.2"
6199
+ }
6200
+ },
6201
+ "node_modules/playwright-core": {
6202
+ "version": "1.58.2",
6203
+ "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.58.2.tgz",
6204
+ "integrity": "sha512-yZkEtftgwS8CsfYo7nm0KE8jsvm6i/PTgVtB8DL726wNf6H2IMsDuxCpJj59KDaxCtSnrWan2AeDqM7JBaultg==",
6205
+ "dev": true,
6206
+ "license": "Apache-2.0",
6207
+ "bin": {
6208
+ "playwright-core": "cli.js"
6209
+ },
6210
+ "engines": {
6211
+ "node": ">=18"
6212
+ }
6213
+ },
6214
+ "node_modules/playwright/node_modules/fsevents": {
6215
+ "version": "2.3.2",
6216
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
6217
+ "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
6218
+ "dev": true,
6219
+ "hasInstallScript": true,
6220
+ "license": "MIT",
6221
+ "optional": true,
6222
+ "os": [
6223
+ "darwin"
6224
+ ],
6225
+ "engines": {
6226
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
6227
+ }
6228
+ },
6180
6229
  "node_modules/possible-typed-array-names": {
6181
6230
  "version": "1.1.0",
6182
6231
  "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz",
@@ -12,9 +12,9 @@
12
12
  "validate:funnel": "vite-node --config src/contract/funnel-validator.vite.config.ts src/contract/validate-funnel.cli.ts"
13
13
  },
14
14
  "dependencies": {
15
- "@funnelsgrove/analytics": "^0.2.0",
16
- "@funnelsgrove/payments": "^0.22.1",
17
- "@funnelsgrove/runtime": "^0.19.1",
15
+ "@funnelsgrove/analytics": "^0.4.1",
16
+ "@funnelsgrove/payments": "^0.23.2",
17
+ "@funnelsgrove/runtime": "^0.21.1",
18
18
  "@stripe/react-stripe-js": "^5.6.0",
19
19
  "@stripe/stripe-js": "^8.7.0",
20
20
  "lucide-react": "^0.553.0",
@@ -28,8 +28,10 @@
28
28
  "@types/node": "^20",
29
29
  "@types/react": "^19",
30
30
  "@types/react-dom": "^19",
31
+ "esbuild": "0.28.1",
31
32
  "eslint": "^9",
32
33
  "eslint-config-next": "16.1.6",
34
+ "playwright": "1.58.2",
33
35
  "typescript": "^5",
34
36
  "vite-node": "3.2.4",
35
37
  "vitest": "^3.2.4"
@@ -353,7 +353,7 @@ export default function SdkDocsPage() {
353
353
  <h2>User Object (Start Here)</h2>
354
354
  <p>
355
355
  This is the canonical runtime answer payload available as `useFunnel().answers`.
356
- Keep this aligned with `@funnelsgrove/runtime` and `docs/references/funnel-sdk-user-answers.md`.
356
+ Keep this aligned with `@funnelsgrove/runtime` and `docs/funnelsgrove/contracts/content-answers.md`.
357
357
  </p>
358
358
  <pre>
359
359
  <code>{userObjectExample}</code>
@@ -11,6 +11,7 @@ import {
11
11
  usePreviewDefinitionOverrideRevision,
12
12
  usePreviewStepLocalizedContent,
13
13
  } from '@funnelsgrove/runtime';
14
+ import { StripeFraudDetection } from './StripeFraudDetection';
14
15
  import { FunnelEditorPanel, FunnelEditorPanelStyles } from './FunnelEditorPanel';
15
16
  import { runtimeContent } from '@/steps/content/runtime.content';
16
17
  import { getStepContentLocale } from '@/runtime/step-content-context';
@@ -112,6 +113,7 @@ function FunnelFlowRuntime({
112
113
 
113
114
  return (
114
115
  <FunnelProvider value={controller.contextValue}>
116
+ <StripeFraudDetection featureFlags={controller.contextValue.featureFlags} />
115
117
  <section
116
118
  className="funnel-shell"
117
119
  suppressHydrationWarning
@@ -0,0 +1,36 @@
1
+ 'use client';
2
+
3
+ import { useEffect } from 'react';
4
+ import {
5
+ resolvePublishedOfferSetSelection,
6
+ resolvePublishedRuntimeExperiments,
7
+ useBrowserLocationSearch,
8
+ useFunnelRuntimeConfig,
9
+ useRuntimeMode,
10
+ } from '@funnelsgrove/runtime';
11
+
12
+ /** Mount once in the funnel shell so lazy checkout screens still collect risk signals. */
13
+ export function StripeFraudDetection({ featureFlags }: {
14
+ featureFlags: Readonly<Record<string, string>>;
15
+ }) {
16
+ const { config } = useFunnelRuntimeConfig();
17
+ const [mode] = useRuntimeMode();
18
+ const search = useBrowserLocationSearch();
19
+ const { paymentProvidersByMode } = resolvePublishedOfferSetSelection({
20
+ offerSets: config?.offerSets ?? [],
21
+ pricingExperiments: resolvePublishedRuntimeExperiments(config).pricingExperiments,
22
+ featureFlags,
23
+ search,
24
+ defaultOfferSetId: config?.defaultOfferSetId ?? undefined,
25
+ });
26
+ const isStripe = paymentProvidersByMode[mode] === 'stripe';
27
+
28
+ useEffect(() => {
29
+ if (!isStripe) return;
30
+ // The official side-effect import loads Stripe.js with advanced signals enabled.
31
+ // Collection must never gate the quiz; checkout retains its own error handling.
32
+ void import('@stripe/stripe-js').catch(() => {});
33
+ }, [isStripe]);
34
+
35
+ return null;
36
+ }
@@ -21,7 +21,7 @@ const starterLivePlans = {
21
21
  offerSetKey: STARTER_OFFER_SET_KEY,
22
22
  projectPlanId: '32b31f69-5907-4736-89c7-76d3acb38813',
23
23
  title: stepPaywallContent.locales.en.catalogLabels["1-Week Plan"],
24
- providerPlanId: 'price_1T9WL2PPRN41Ty94g2NNOgif',
24
+ providerPlanId: 'price_REPLACE_WITH_YOUR_STRIPE_LIVE_WEEKLY',
25
25
  priceLabel: stepPaywallContent.locales.en.catalogLabels["$7.99/week"],
26
26
  perDayAmount: '$1.14',
27
27
  amountCents: 799,
@@ -32,7 +32,7 @@ const starterLivePlans = {
32
32
  offerSetKey: STARTER_OFFER_SET_KEY,
33
33
  projectPlanId: 'ce0a0022-7bf0-41f2-a707-edc5e6113a07',
34
34
  title: stepPaywallContent.locales.en.catalogLabels["1-Month Plan"],
35
- providerPlanId: 'price_1TP0IIPPRN41Ty94npkzVeDR',
35
+ providerPlanId: 'price_REPLACE_WITH_YOUR_STRIPE_LIVE_MONTHLY',
36
36
  featuredTag: stepPaywallContent.locales.en.catalogLabels["🔥 Most Popular Choice"],
37
37
  priceLabel: stepPaywallContent.locales.en.catalogLabels["$29.99/month"],
38
38
  perDayAmount: '$1.00',
@@ -45,7 +45,7 @@ const starterLivePlans = {
45
45
  offerSetKey: STARTER_OFFER_SET_KEY,
46
46
  projectPlanId: 'fb623ebc-c2fd-4e6a-8eb6-b8ed92db1b21',
47
47
  title: stepPaywallContent.locales.en.catalogLabels["1-Year Plan"],
48
- providerPlanId: 'price_1T06AEPPRN41Ty94zvVt5xrk',
48
+ providerPlanId: 'price_REPLACE_WITH_YOUR_STRIPE_LIVE_YEARLY',
49
49
  priceLabel: stepPaywallContent.locales.en.catalogLabels["$59.99/year"],
50
50
  perDayAmount: '$0.16',
51
51
  amountCents: 5999,
@@ -79,6 +79,7 @@ export const starterDefaultOfferSet = {
79
79
  id: STARTER_OFFER_SET_ID,
80
80
  key: STARTER_OFFER_SET_KEY,
81
81
  isActive: true,
82
+ locales: null,
82
83
  metadata: {
83
84
  discounts: starterDiscounts.map((discount, position) => ({
84
85
  key: discount.stage,
@@ -105,7 +106,9 @@ export const starterBillingRuntimeFallback = {
105
106
  sourceDeploymentId: 'starter-template',
106
107
  sourceVersionId: 'starter-template',
107
108
  publishedAt: '1970-01-01T00:00:00.000Z',
109
+ localeContractVersion: 1,
108
110
  sessionReplay: { enabled: false, sampleRate: 10 },
111
+ defaultOfferSetId: starterDefaultOfferSet.id,
109
112
  offerSets: [starterDefaultOfferSet],
110
113
  experiments: [],
111
114
  } satisfies ResolvedFunnelRuntimeConfig;
@@ -5,7 +5,7 @@ export const billingTestPlans = {
5
5
  primary: {
6
6
  projectPlanId: '32b31f69-5907-4736-89c7-76d3acb38813',
7
7
  title: stepPaywallContent.locales.en.catalogLabels["1-Week Plan"],
8
- providerPlanId: 'price_1TOQ2fPEfkEVo5khumapOSsI',
8
+ providerPlanId: 'price_REPLACE_WITH_YOUR_STRIPE_TEST_WEEKLY',
9
9
  priceLabel: stepPaywallContent.locales.en.catalogLabels["$9.99/week"],
10
10
  perDayAmount: '$1.43',
11
11
  amountCents: 999,
@@ -14,7 +14,7 @@ export const billingTestPlans = {
14
14
  secondary: {
15
15
  projectPlanId: 'ce0a0022-7bf0-41f2-a707-edc5e6113a07',
16
16
  title: stepPaywallContent.locales.en.catalogLabels["1-Month Plan"],
17
- providerPlanId: 'price_1TSgPZPEfkEVo5khMbtAlqsG',
17
+ providerPlanId: 'price_REPLACE_WITH_YOUR_STRIPE_TEST_MONTHLY',
18
18
  featuredTag: stepPaywallContent.locales.en.catalogLabels["🔥 Most Popular Choice"],
19
19
  priceLabel: stepPaywallContent.locales.en.catalogLabels["$29.99/month"],
20
20
  perDayAmount: '$1.00',
@@ -24,7 +24,7 @@ export const billingTestPlans = {
24
24
  tertiary: {
25
25
  projectPlanId: 'fb623ebc-c2fd-4e6a-8eb6-b8ed92db1b21',
26
26
  title: stepPaywallContent.locales.en.catalogLabels["1-Year Plan"],
27
- providerPlanId: 'price_1TBgcaPEfkEVo5khbGnGhrBA',
27
+ providerPlanId: 'price_REPLACE_WITH_YOUR_STRIPE_TEST_YEARLY',
28
28
  priceLabel: stepPaywallContent.locales.en.catalogLabels["$59.99/year"],
29
29
  perDayAmount: '$0.16',
30
30
  amountCents: 5999,
@@ -34,6 +34,7 @@ export type StepPaywallLocaleContent = {
34
34
  cardButtonLabel: string;
35
35
  metaLabels: readonly string[];
36
36
  stripeUnavailableNote: string;
37
+ plansUnavailableNote: string;
37
38
  perDayLabel: string;
38
39
  };
39
40
  checkout: {
@@ -157,6 +158,8 @@ export const stepPaywallContent = {
157
158
  metaLabels: ['Money-back guarantee', 'Cancel anytime'],
158
159
  stripeUnavailableNote:
159
160
  'Stripe publishable key is not available in this app runtime. Update the project payment environment variables or make sure your SDK publishable key maps to a funnel with Stripe settings.',
161
+ plansUnavailableNote:
162
+ 'Plans are unavailable right now. Please try again in a moment or contact support.',
160
163
  },
161
164
  checkout: {
162
165
  title: 'Checkout',
@@ -125,6 +125,12 @@ export const stepPaywallEditor: readonly StepEditorSection[] = [
125
125
  kind: 'textarea',
126
126
  path: 'plans.stripeUnavailableNote',
127
127
  },
128
+ {
129
+ id: 'plans.plansUnavailableNote',
130
+ label: 'Plans unavailable note',
131
+ kind: 'textarea',
132
+ path: 'plans.plansUnavailableNote',
133
+ },
128
134
  ],
129
135
  },
130
136
  {