@siglume/direct-request-payment 0.4.17 → 0.4.19

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 (35) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/README.md +60 -4
  3. package/bin/siglume-sdrp.mjs +267 -0
  4. package/dist/index.cjs +3 -3
  5. package/dist/index.cjs.map +1 -1
  6. package/dist/index.d.cts +3 -3
  7. package/dist/index.d.ts +3 -3
  8. package/dist/index.js +3 -3
  9. package/dist/index.js.map +1 -1
  10. package/docs/announcement-ja.md +5 -3
  11. package/docs/api-reference.md +34 -1
  12. package/docs/merchant-quickstart.md +19 -2
  13. package/docs/payment-lifecycle.md +85 -0
  14. package/docs/pricing.md +6 -6
  15. package/docs/quickstart-10-minutes.md +145 -0
  16. package/docs/troubleshooting.md +70 -0
  17. package/examples/express-checkout.ts +14 -0
  18. package/examples/hosted-checkout-python/.env.example +5 -0
  19. package/examples/hosted-checkout-python/README.md +21 -0
  20. package/examples/hosted-checkout-python/app.py +124 -0
  21. package/examples/hosted-checkout-python/order_store.py +42 -0
  22. package/examples/hosted-checkout-python/pyproject.toml +9 -0
  23. package/examples/hosted-checkout-typescript/.env.example +5 -0
  24. package/examples/hosted-checkout-typescript/README.md +21 -0
  25. package/examples/hosted-checkout-typescript/package.json +20 -0
  26. package/examples/hosted-checkout-typescript/src/order-store.ts +52 -0
  27. package/examples/hosted-checkout-typescript/src/server.ts +139 -0
  28. package/examples/hosted-checkout-typescript/tsconfig.json +13 -0
  29. package/package.json +12 -1
  30. package/templates/express/README.md +22 -0
  31. package/templates/express/siglume-order-store.example.ts +53 -0
  32. package/templates/express/siglume-sdrp-routes.ts +157 -0
  33. package/templates/fastapi/README.md +22 -0
  34. package/templates/fastapi/siglume_order_store_example.py +54 -0
  35. package/templates/fastapi/siglume_sdrp_routes.py +107 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,45 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.4.19 - 2026-06-20
4
+
5
+ Make the 10-minute integration path a real product-integration path instead of
6
+ a separate demo.
7
+
8
+ - Added npm and PyPI CLI bins `siglume-sdrp` and `siglume-check`.
9
+ - Added `siglume-check readiness` to validate merchant token, merchant key,
10
+ HTTPS origin/webhook configuration, Standard-band probe amount, merchant
11
+ account/billing readiness, and Hosted Checkout availability through an unpaid
12
+ checkout-session probe.
13
+ - Added `siglume-sdrp init express` for npm and `siglume-sdrp init fastapi` for
14
+ npm/PyPI to copy framework-specific checkout/webhook route files into an
15
+ existing product.
16
+ - Added Express and FastAPI integration templates with order-store adapter
17
+ interfaces so teams can wire SDRP into their real order database instead of
18
+ starting from an isolated sample app.
19
+ - Reframed the 10-minute guide around existing-product integration and moved
20
+ the readiness check before any coding.
21
+
22
+ ## 0.4.18 - 2026-06-19
23
+
24
+ Developer-onboarding cleanup for the v0.4.17 public review.
25
+
26
+ - Added a scoped 10-minute first-test guide for one Standard Payment Hosted
27
+ Checkout flow, with explicit prerequisites and non-goals.
28
+ - Added payment lifecycle and troubleshooting docs covering Hosted Checkout
29
+ readiness, webhook failure handling, retries, support references, and refund
30
+ escalation boundaries.
31
+ - Added README glossary and use-case fit tables so merchant / provider /
32
+ publisher / payee wording and 10-minute claims are less ambiguous.
33
+ - Added minimal Hosted Checkout TypeScript and Python starter directories with
34
+ `.env.example`, seeded test order, checkout start route, and webhook handler.
35
+ - Replaced "Stripe Checkout equivalent" wording with Siglume wallet hosted
36
+ checkout wording in public docs and SDK comments.
37
+ - Exported Python `TypedDict` response names for Hosted Checkout, Micro / Nano
38
+ summaries, settlement batches, webhook verification, and confirmation
39
+ classification.
40
+ - Marked the existing Express checkout example as demo-only and not
41
+ production-safe.
42
+
3
43
  ## 0.4.17 - 2026-06-19
4
44
 
5
45
  Public-surface cleanup for the v0.4.15 external review.
package/README.md CHANGED
@@ -56,7 +56,7 @@ buyer**.
56
56
  redirect them to the returned `checkout_url`. They sign into Siglume (passkey
57
57
  or email code — the login *is* the wallet), review the amount, approve once,
58
58
  and pay from their own wallet, then return to your `success_url`. This is the
59
- Stripe-Checkout-equivalent path.
59
+ Siglume wallet hosted checkout path.
60
60
 
61
61
  2. **AI agent / agent-to-agent (AtoA) → direct API / tools.** An autonomous
62
62
  buyer agent pays through `DirectRequestPaymentClient` (your app holds the
@@ -78,6 +78,53 @@ Honest framing: the part that integrates quickly is the **merchant plumbing**
78
78
  shopper to have — or create — a Siglume wallet and pay from it; it is not a
79
79
  card-style "instant" checkout for first-time buyers.
80
80
 
81
+ ## Fast Path
82
+
83
+ Use [10-Minute Product Integration](./docs/quickstart-10-minutes.md) to add
84
+ Hosted Checkout routes to an existing Express or FastAPI product. The path is
85
+ CLI-first:
86
+
87
+ ```bash
88
+ npm install @siglume/direct-request-payment
89
+ npx siglume-check readiness
90
+ npx siglume-sdrp init express --target src/siglume
91
+ ```
92
+
93
+ or:
94
+
95
+ ```bash
96
+ pip install siglume-direct-request-payment
97
+ siglume-sdrp init fastapi --target app/siglume
98
+ ```
99
+
100
+ The readiness command checks account, billing, origin, webhook, and Hosted
101
+ Checkout availability before you write checkout code.
102
+
103
+ Before implementation, confirm Hosted Checkout readiness in
104
+ [Troubleshooting](./docs/troubleshooting.md#hosted-checkout-readiness). For
105
+ state handling, read [Payment lifecycle](./docs/payment-lifecycle.md) before
106
+ fulfilling orders.
107
+
108
+ ## Who Is Who
109
+
110
+ | Term | Meaning for public integrations |
111
+ | --- | --- |
112
+ | Buyer | The Siglume wallet user who pays. The merchant SDK does not log this user in. |
113
+ | Merchant | The external product or store that starts checkout, owns the order, and verifies webhooks. |
114
+ | Provider | The revenue recipient in Micro / Nano statements. In a simple EC integration this is usually the same business as the merchant. |
115
+ | Publisher / listing owner | Marketplace-facing owner of a listing or capability. Most Hosted Checkout merchants do not need to handle this term directly. |
116
+ | Payee | Internal settlement-grouping language. Public integration guides avoid this term unless a statement API field includes it. |
117
+
118
+ ## Use-Case Fit
119
+
120
+ | Use case | Recommended path | 10-minute integration path? | Production work still required |
121
+ | --- | --- | --- | --- |
122
+ | EC one-time Standard payment | Hosted Checkout | Yes, with `siglume-check readiness` and `siglume-sdrp init` | Refund/support process and monitoring |
123
+ | Game consumables | Hosted Checkout or agent/API | Conditional | Idempotent entitlement grants, disconnect recovery, Micro / Nano unsettled-risk handling |
124
+ | Paid API / AtoA | Direct API or Siglume marketplace tool | Conditional | Request idempotency, buyer auth context, reconciliation |
125
+ | SaaS subscription | Recurring challenge plus raw API | No | Renewal, cancellation, failed renewal, plan-change lifecycle |
126
+ | Scheduled autopay | Recurring challenge plus schedule token | No | Scheduler, token custody, budget failure handling |
127
+
81
128
  ## Hosted Checkout (Human Web Shoppers)
82
129
 
83
130
  **Beta / server rollout:** Hosted Checkout is rolling out account by account.
@@ -86,6 +133,8 @@ case `createCheckoutSession(...)` / `getCheckoutSession(...)` raises
86
133
  `HostedCheckoutNotAvailableError` instead of exposing the raw rollout 404/409.
87
134
  Keep the signed `direct_payment.confirmed` webhook as the durable signal, and
88
135
  inspect its settlement machine fields before marking any order paid.
136
+ Check readiness before you build the flow; see
137
+ [Hosted Checkout readiness](./docs/troubleshooting.md#hosted-checkout-readiness).
89
138
 
90
139
  Hosted Checkout is a Siglume-hosted page that turns a "Pay with Siglume" button
91
140
  into a completed wallet payment, then returns the shopper to your store. It
@@ -286,8 +335,8 @@ the flat amounts differ.
286
335
  | Public one-time payment amount | Applied automatically | What you select | Fee | Settlement |
287
336
  | --- | --- | --- | --- | --- |
288
337
  | JPY 501+ / USD 3.01+ | Standard Payment | Select one Standard plan: Launch, Starter, Growth, or Pro | Launch: JPY 0 / USD 0 monthly, 1.8%; Starter: JPY 980 / USD 6 monthly, 1.0%; Growth: JPY 2,980 / USD 18 monthly, 0.7%; Pro: JPY 9,800 / USD 60 monthly, 0.5%. Minimum JPY 30 / USD 0.20 per payment. | Settled on-chain immediately after the payment confirms |
289
- | JPY 50-500 / USD 0.31-3.00 | Micro Payment | Applied automatically by amount | JPY 2 / USD 0.01 per SDRP Tx | Weekly settlement, or earlier at JPY 10,000 / USD 100.00 - see [Settlement schedule](./docs/pricing.md#settlement-schedule) |
290
- | JPY 1-49 / USD 0.01-0.30 | Nano Payment | Applied automatically by amount | JPY 0.2 / USD 0.001 per SDRP Tx | Monthly settlement, or earlier at JPY 10,000 / USD 100.00 - see [Settlement schedule](./docs/pricing.md#settlement-schedule) |
338
+ | JPY 50-500 / USD 0.31-3.00 | Micro Payment | Applied automatically by amount | JPY 2 / USD 0.01 per SDRP Tx | Closes weekly, or earlier when provider gross reaches JPY 10,000 / USD 100.00. See [Settlement schedule](./docs/pricing.md#settlement-schedule). |
339
+ | JPY 1-49 / USD 0.01-0.30 | Nano Payment | Applied automatically by amount | JPY 0.2 / USD 0.001 per SDRP Tx | Closes monthly, or earlier when provider gross reaches JPY 10,000 / USD 100.00. See [Settlement schedule](./docs/pricing.md#settlement-schedule). |
291
340
 
292
341
  In this table, `Tx` means one accepted SDRP payment, not an on-chain settlement
293
342
  transaction.
@@ -641,7 +690,9 @@ an order paid from the event type alone.
641
690
  - Do not treat Direct Request Payment as stored value, prepaid points, escrow, or
642
691
  a platform balance.
643
692
 
644
- Read [docs/security.md](./docs/security.md) before going live.
693
+ Read [docs/security.md](./docs/security.md) before going live. Use
694
+ [docs/troubleshooting.md](./docs/troubleshooting.md) for operational error
695
+ handling and support escalation.
645
696
 
646
697
  ## Go-Live Checklist
647
698
 
@@ -670,12 +721,17 @@ Read [docs/security.md](./docs/security.md) before going live.
670
721
  ## Documentation
671
722
 
672
723
  - [Merchant quickstart](./docs/merchant-quickstart.md)
724
+ - [10-minute product integration](./docs/quickstart-10-minutes.md)
725
+ - [Payment lifecycle](./docs/payment-lifecycle.md)
726
+ - [Troubleshooting](./docs/troubleshooting.md)
673
727
  - [API reference](./docs/api-reference.md)
674
728
  - [Pricing](./docs/pricing.md)
675
729
  - [Micro / Nano statements and notices](./docs/metered-statements.md)
676
730
  - [Security guide](./docs/security.md)
677
731
  - [Merchant setup example](./examples/setup-merchant.ts)
678
732
  - [Express checkout example](./examples/express-checkout.ts)
733
+ - [Hosted Checkout TypeScript starter](./examples/hosted-checkout-typescript)
734
+ - [Hosted Checkout Python starter](./examples/hosted-checkout-python)
679
735
  - [Japanese launch announcement draft](./docs/announcement-ja.md)
680
736
  - [Changelog](./CHANGELOG.md)
681
737
 
@@ -0,0 +1,267 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { readFileSync } from "node:fs";
4
+ import { mkdir, readFile, readdir, stat, writeFile } from "node:fs/promises";
5
+ import { dirname, join, resolve } from "node:path";
6
+ import { fileURLToPath } from "node:url";
7
+
8
+ import {
9
+ DirectRequestPaymentMerchantClient,
10
+ HostedCheckoutNotAvailableError,
11
+ SiglumeApiError,
12
+ } from "../dist/index.js";
13
+
14
+ const rootDir = resolve(dirname(fileURLToPath(import.meta.url)), "..");
15
+
16
+ main().catch((error) => {
17
+ console.error(`siglume-sdrp: ${error instanceof Error ? error.message : String(error)}`);
18
+ process.exitCode = 1;
19
+ });
20
+
21
+ async function main() {
22
+ loadDotEnv();
23
+ const [command = "help", ...args] = process.argv.slice(2);
24
+ if (command === "help" || command === "--help" || command === "-h") {
25
+ printHelp();
26
+ return;
27
+ }
28
+ if (command === "readiness" || command === "doctor") {
29
+ await readiness(parseArgs(args));
30
+ return;
31
+ }
32
+ if (command === "init") {
33
+ await init(args);
34
+ return;
35
+ }
36
+ throw new Error(`Unknown command: ${command}`);
37
+ }
38
+
39
+ function printHelp() {
40
+ console.log(`Siglume SDRP integration CLI
41
+
42
+ Usage:
43
+ siglume-check readiness --merchant <key> --origin <https://shop.example> --webhook-url <https://api.example/siglume/webhook>
44
+ siglume-sdrp init express --target src/siglume
45
+ siglume-sdrp init fastapi --target app/siglume
46
+
47
+ Readiness options:
48
+ --merchant <key> Merchant key. Defaults to SIGLUME_DIRECT_PAYMENT_MERCHANT.
49
+ --origin <origin> Public shop origin. Defaults to SHOP_PUBLIC_ORIGIN.
50
+ --webhook-url <url> Public webhook URL. Defaults to SHOP_WEBHOOK_URL.
51
+ --currency <JPY|USD> Probe currency. Defaults to SIGLUME_DIRECT_PAYMENT_TEST_CURRENCY or JPY.
52
+ --amount-minor <amount> Standard-band probe amount. Defaults to 501 for JPY, 301 for USD.
53
+ --base-url <url> Siglume API base URL. Defaults to SIGLUME_API_BASE or production.
54
+ --no-api Validate local config only; do not call Siglume.
55
+ --no-probe Call getMerchant only; do not create an unpaid checkout session.
56
+ --json Print machine-readable JSON.
57
+ `);
58
+ }
59
+
60
+ function parseArgs(args) {
61
+ const out = { api: true, probe: true, json: false };
62
+ for (let i = 0; i < args.length; i += 1) {
63
+ const arg = args[i];
64
+ if (arg === "--no-api") {
65
+ out.api = false;
66
+ } else if (arg === "--no-probe") {
67
+ out.probe = false;
68
+ } else if (arg === "--json") {
69
+ out.json = true;
70
+ } else if (arg === "--force") {
71
+ out.force = true;
72
+ } else if (arg.startsWith("--")) {
73
+ const key = arg.slice(2).replace(/-([a-z])/g, (_, c) => c.toUpperCase());
74
+ const value = args[i + 1];
75
+ if (!value || value.startsWith("--")) {
76
+ throw new Error(`${arg} requires a value.`);
77
+ }
78
+ out[key] = value;
79
+ i += 1;
80
+ } else {
81
+ throw new Error(`Unexpected argument: ${arg}`);
82
+ }
83
+ }
84
+ return out;
85
+ }
86
+
87
+ async function readiness(options) {
88
+ const checks = [];
89
+ const merchant = options.merchant || process.env.SIGLUME_DIRECT_PAYMENT_MERCHANT || "";
90
+ const origin = options.origin || process.env.SHOP_PUBLIC_ORIGIN || "";
91
+ const webhookUrl = options.webhookUrl || process.env.SHOP_WEBHOOK_URL || "";
92
+ const token = process.env.SIGLUME_MERCHANT_AUTH_TOKEN || process.env.SIGLUME_AUTH_TOKEN || "";
93
+ const currency = normalizeCurrency(options.currency || process.env.SIGLUME_DIRECT_PAYMENT_TEST_CURRENCY || "JPY");
94
+ const amountMinor = Number(options.amountMinor || process.env.SIGLUME_DIRECT_PAYMENT_TEST_AMOUNT_MINOR || (currency === "USD" ? 301 : 501));
95
+
96
+ check(checks, "merchant_key", Boolean(merchant), "Set SIGLUME_DIRECT_PAYMENT_MERCHANT or pass --merchant.");
97
+ check(checks, "merchant_token", Boolean(token) && !token.startsWith("cli_"), "Set SIGLUME_MERCHANT_AUTH_TOKEN to a merchant Siglume bearer token, not a cli_ key.");
98
+ check(checks, "shop_origin", isHttpsOrigin(origin), "Set SHOP_PUBLIC_ORIGIN to an https origin, for example https://www.example.com.");
99
+ check(checks, "webhook_url", isHttpsUrl(webhookUrl), "Set SHOP_WEBHOOK_URL to a public https webhook URL.");
100
+ check(checks, "standard_probe_amount", isStandardAmount(currency, amountMinor), "Use a Standard-band probe amount: JPY 501+ or USD 301+ minor units.");
101
+
102
+ if (options.api && !hasFailures(checks)) {
103
+ const merchantClient = new DirectRequestPaymentMerchantClient({
104
+ auth_token: token,
105
+ base_url: options.baseUrl || process.env.SIGLUME_API_BASE,
106
+ });
107
+ try {
108
+ const merchantResponse = await merchantClient.getMerchant(merchant);
109
+ const account = merchantResponse.merchant_account || {};
110
+ check(checks, "merchant_exists", Boolean(account.merchant), "Run merchant setup before checkout.");
111
+ check(checks, "billing_mandate", Boolean(account.billing_mandate_id) || activeLike(account.billing_status), "Complete the merchant billing mandate wallet approval.");
112
+ warnIf(checks, "merchant_status", account.status && !activeLike(account.status), `Merchant status is ${account.status}; confirm it is allowed to accept payments.`);
113
+ warnIf(checks, "billing_status", account.billing_status && !activeLike(account.billing_status), `Billing status is ${account.billing_status}; confirm it is active before accepting payments.`);
114
+ } catch (error) {
115
+ check(checks, "merchant_api", false, apiErrorMessage(error, "Could not read the merchant account."));
116
+ }
117
+
118
+ if (options.probe && !hasFailures(checks)) {
119
+ try {
120
+ const session = await merchantClient.createCheckoutSession({
121
+ merchant,
122
+ amount_minor: amountMinor,
123
+ currency,
124
+ nonce: `sdrp-readiness-${Date.now()}`,
125
+ success_url: `${origin}/siglume-readiness/success`,
126
+ cancel_url: `${origin}/siglume-readiness/cancel`,
127
+ metadata: { source: "siglume-sdrp-readiness" },
128
+ });
129
+ check(checks, "hosted_checkout", Boolean(session.checkout_url && session.challenge_hash), "Hosted Checkout did not return a checkout_url.");
130
+ } catch (error) {
131
+ const message = error instanceof HostedCheckoutNotAvailableError
132
+ ? "Hosted Checkout is not enabled for this merchant account. Ask Siglume to enable it before coding the human checkout path."
133
+ : apiErrorMessage(error, "Hosted Checkout probe failed. Check checkout_allowed_origins, currency, amount, and billing mandate.");
134
+ check(checks, "hosted_checkout", false, message);
135
+ }
136
+ }
137
+ }
138
+
139
+ const ok = !hasFailures(checks);
140
+ if (options.json) {
141
+ console.log(JSON.stringify({ ok, checks }, null, 2));
142
+ } else {
143
+ for (const item of checks) {
144
+ const mark = item.status === "pass" ? "OK" : item.status === "warn" ? "WARN" : "FAIL";
145
+ console.log(`${mark} ${item.name}: ${item.message}`);
146
+ }
147
+ console.log(ok ? "Ready for 10-minute SDRP integration." : "Not ready. Fix the FAIL items before coding checkout.");
148
+ }
149
+ if (!ok) {
150
+ process.exitCode = 1;
151
+ }
152
+ }
153
+
154
+ async function init(args) {
155
+ const framework = args[0];
156
+ const parsed = parseArgs(args.slice(1));
157
+ const target = parsed.target;
158
+ if (!["express", "fastapi"].includes(framework)) {
159
+ throw new Error("init requires framework: express or fastapi.");
160
+ }
161
+ if (!target) {
162
+ throw new Error("init requires --target <directory>.");
163
+ }
164
+ const from = join(rootDir, "templates", framework);
165
+ const to = resolve(process.cwd(), target);
166
+ await copyDir(from, to, Boolean(parsed.force));
167
+ console.log(`Copied ${framework} SDRP integration files to ${to}`);
168
+ console.log("Wire the exported router into your app, then run siglume-check readiness before opening checkout.");
169
+ }
170
+
171
+ async function copyDir(from, to, force) {
172
+ await mkdir(to, { recursive: true });
173
+ for (const entry of await readdir(from)) {
174
+ const src = join(from, entry);
175
+ const dst = join(to, entry);
176
+ const info = await stat(src);
177
+ if (info.isDirectory()) {
178
+ await copyDir(src, dst, force);
179
+ } else {
180
+ if (!force && await exists(dst)) {
181
+ throw new Error(`${dst} already exists. Re-run with --force to overwrite.`);
182
+ }
183
+ await mkdir(dirname(dst), { recursive: true });
184
+ await writeFile(dst, await readFile(src));
185
+ }
186
+ }
187
+ }
188
+
189
+ async function exists(path) {
190
+ try {
191
+ await stat(path);
192
+ return true;
193
+ } catch {
194
+ return false;
195
+ }
196
+ }
197
+
198
+ function loadDotEnv() {
199
+ try {
200
+ const text = readFileSync(resolve(process.cwd(), ".env"), "utf8");
201
+ for (const line of text.split(/\r?\n/)) {
202
+ const trimmed = line.trim();
203
+ if (!trimmed || trimmed.startsWith("#") || !trimmed.includes("=")) continue;
204
+ const [key, ...rest] = trimmed.split("=");
205
+ if (key && !process.env[key]) {
206
+ process.env[key] = rest.join("=").replace(/^["']|["']$/g, "");
207
+ }
208
+ }
209
+ } catch {
210
+ // .env is optional.
211
+ }
212
+ }
213
+
214
+ function check(checks, name, passed, message) {
215
+ checks.push({ name, status: passed ? "pass" : "fail", message: passed ? "ready" : message });
216
+ }
217
+
218
+ function warnIf(checks, name, condition, message) {
219
+ if (condition) {
220
+ checks.push({ name, status: "warn", message });
221
+ }
222
+ }
223
+
224
+ function hasFailures(checks) {
225
+ return checks.some((item) => item.status === "fail");
226
+ }
227
+
228
+ function isHttpsOrigin(value) {
229
+ try {
230
+ const url = new URL(value);
231
+ return url.protocol === "https:" && url.origin === value.replace(/\/$/, "");
232
+ } catch {
233
+ return false;
234
+ }
235
+ }
236
+
237
+ function isHttpsUrl(value) {
238
+ try {
239
+ const url = new URL(value);
240
+ return url.protocol === "https:";
241
+ } catch {
242
+ return false;
243
+ }
244
+ }
245
+
246
+ function normalizeCurrency(value) {
247
+ const currency = String(value || "").toUpperCase();
248
+ if (currency !== "JPY" && currency !== "USD") {
249
+ throw new Error("--currency must be JPY or USD.");
250
+ }
251
+ return currency;
252
+ }
253
+
254
+ function isStandardAmount(currency, amountMinor) {
255
+ return Number.isSafeInteger(amountMinor) && amountMinor >= (currency === "USD" ? 301 : 501);
256
+ }
257
+
258
+ function activeLike(value) {
259
+ return /^(active|ready|current|ok|enabled|paid|complete|completed)$/i.test(String(value || ""));
260
+ }
261
+
262
+ function apiErrorMessage(error, fallback) {
263
+ if (error instanceof SiglumeApiError) {
264
+ return `${fallback} ${error.code} (${error.status}).`;
265
+ }
266
+ return fallback;
267
+ }
package/dist/index.cjs CHANGED
@@ -83,7 +83,7 @@ var DIRECT_REQUEST_PAYMENT_RECEIPT_KIND = "sdrp_direct_payment";
83
83
  var DIRECT_REQUEST_PAYMENT_ALLOWANCE_RECEIPT_KIND = "sdrp_direct_payment_allowance";
84
84
  var DIRECT_REQUEST_PAYMENT_REFERENCE_TYPE = "sdrp_direct_payment_requirement";
85
85
  var DEFAULT_WEBHOOK_TOLERANCE_SECONDS = 300;
86
- var DIRECT_REQUEST_PAYMENT_SDK_VERSION = "0.4.17";
86
+ var DIRECT_REQUEST_PAYMENT_SDK_VERSION = "0.4.19";
87
87
  var DIRECT_REQUEST_PAYMENT_STANDARD_SETTLED_STATUS = "settled";
88
88
  var DIRECT_REQUEST_PAYMENT_METERED_ACCEPTED_STATUS = "pending_settlement";
89
89
  var DIRECT_REQUEST_PAYMENT_STANDARD_FINALITY = "per_payment_onchain";
@@ -327,8 +327,8 @@ var DirectRequestPaymentMerchantClient = class {
327
327
  return this.request("POST", "/sdrp/direct-payments/merchants", payload);
328
328
  }
329
329
  /**
330
- * Create a Hosted Checkout session (Stripe-Checkout-equivalent for human web
331
- * shoppers). Siglume authors the challenge server-side, persists a single-use
330
+ * Create a Hosted Checkout session for human web shoppers. Siglume authors
331
+ * the challenge server-side, persists a single-use
332
332
  * expiring session, and returns a `checkout_url`. Redirect the shopper there;
333
333
  * they log into Siglume, approve, and pay from their own wallet, then return
334
334
  * to your `success_url`. Fulfill on the `direct_payment.confirmed` webhook