@siglume/direct-request-payment 0.4.3 → 0.4.4

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.
@@ -267,7 +267,15 @@ Returns the `sha256:`-prefixed hash for an existing challenge string.
267
267
  ## `directRequestPaymentRequestHash(input)` / `direct_request_payment_request_hash(...)`
268
268
 
269
269
  Returns the SDK-side request hash material for merchant, amount, currency, and
270
- challenge. This is mostly useful for tests and internal assertions.
270
+ challenge. This is the legacy v1 hash retained for wire compatibility and
271
+ existing idempotency assertions.
272
+
273
+ ## `directRequestPaymentRequestHashV2(input)` / `direct_request_payment_request_hash_v2(...)`
274
+
275
+ Returns the v2 request hash for the same fields using canonical JSON before
276
+ hashing. New tests and server-side assertions should prefer this value when the
277
+ API response includes `request_hash_v2`; keep accepting `request_hash` for older
278
+ requirements and historical webhook payloads.
271
279
 
272
280
  ## `DirectRequestPaymentMerchantClient`
273
281
 
@@ -308,8 +316,10 @@ Input:
308
316
  Hosted Checkout (open-redirect defense). A Hosted Checkout `success_url` /
309
317
  `cancel_url` must be on a registered origin; the origin of
310
318
  `webhook_callback_url` is auto-allowed in addition. Each entry must be an
311
- absolute origin such as `https://shop.example.com`; entries are normalized to
312
- bare, lowercased origins and deduped.
319
+ absolute origin such as `https://shop.example.com`; production origins must
320
+ use `https`. Development `http` origins are accepted only for `localhost`,
321
+ `127.0.0.1`, or `[::1]`. Userinfo is rejected. Entries are normalized to bare,
322
+ lowercased origins and deduped.
313
323
 
314
324
  In addition to the `setupMerchant` inputs above, `setupCheckout` accepts these
315
325
  orchestration toggles:
@@ -371,7 +381,7 @@ POST /v1/sdrp/direct-payments/checkout-sessions
371
381
  ```ts
372
382
  const session = await merchant.createCheckoutSession({
373
383
  merchant: "example_merchant",
374
- amount_minor: 500,
384
+ amount_minor: 1200,
375
385
  currency: "JPY",
376
386
  nonce: order.id,
377
387
  success_url: "https://www.your-shop.com/thanks",
@@ -383,7 +393,7 @@ const session = await merchant.createCheckoutSession({
383
393
  ```py
384
394
  session = merchant.create_checkout_session(
385
395
  merchant="example_merchant",
386
- amount_minor=500,
396
+ amount_minor=1200,
387
397
  currency="JPY",
388
398
  nonce=order["id"],
389
399
  success_url="https://www.your-shop.com/thanks",
@@ -505,8 +515,10 @@ created explicitly through this client. Use the statement APIs below to see
505
515
  open-period usage, the close time, the final-notice schedule, and settled /
506
516
  unsettled / past-due revenue.
507
517
 
508
- Payment requirements include `fee_bps` from the Siglume platform. The SDK does
509
- not calculate merchant plan fees locally; see [Pricing](./pricing.md).
518
+ Standard Payment requirements include `fee_bps` from the Siglume platform. The
519
+ SDK does not calculate merchant plan fees locally. For Micro / Nano, use the
520
+ statement API amount fields (`protocol_fee_minor`, `gross_buyer_debit_minor`,
521
+ `buyer_debit_minor`, and `rounding_delta_minor`); see [Pricing](./pricing.md).
510
522
 
511
523
  ```ts
512
524
  const siglume = new DirectRequestPaymentClient({
@@ -544,6 +556,22 @@ Input:
544
556
  - `allowance_amount_minor`: optional positive integer
545
557
  - `metadata`: optional JSON object
546
558
 
559
+ The returned requirement includes both compatibility and machine-readable
560
+ settlement fields:
561
+
562
+ - `request_hash`: legacy v1 request hash, retained for existing requirements
563
+ and integrations.
564
+ - `request_hash_v2`: canonical-JSON v2 request hash when the server can compute
565
+ one for the challenge-backed request.
566
+ - `pricing_band`: `standard`, `micro`, or `nano`.
567
+ - `settlement_cadence`: `per_payment`, `weekly`, or `monthly`.
568
+ - `finality`: machine-readable finality class such as
569
+ `per_payment_onchain` or `aggregated_onchain_settlement`.
570
+ - `protocol_fee_minor`: Micro / Nano protocol fee when applicable; `null` for
571
+ Standard Payment.
572
+ - `settlement_status`: `pending_payment`, `provisional`, `settled`,
573
+ `pending_settlement`, or another explicit operational state.
574
+
547
575
  ### `getPaymentRequirement(requirement_id)` / `get_payment_requirement(requirement_id)`
548
576
 
549
577
  Calls:
@@ -640,9 +668,9 @@ base URL configured on `DirectRequestPaymentClient`.
640
668
  `/sdrp/metered/my-summary`. The helper expects a JSON response. Use raw
641
669
  `fetch`, `curl`, or your HTTP client for CSV exports.
642
670
 
643
- Python does not expose a public generic request helper in this release. Use
644
- ordinary HTTPS requests with the same Siglume bearer token for endpoints that do
645
- not yet have a named Python SDK method.
671
+ Python does not expose a public generic request helper. Use the named Python
672
+ methods documented below for Micro / Nano statements, and ordinary HTTPS
673
+ requests for endpoints that do not yet have a named Python SDK method.
646
674
 
647
675
  ## Metered Statement APIs
648
676
 
@@ -667,13 +695,16 @@ Common query parameters:
667
695
  TypeScript:
668
696
 
669
697
  ```ts
670
- const summary = await siglume.request<{
671
- role: "buyer";
672
- open_periods: Array<Record<string, unknown>>;
673
- settlement_batches: Array<Record<string, unknown>>;
674
- past_due_blocks: Array<Record<string, unknown>>;
675
- balance_sufficiency: Record<string, unknown>;
676
- }>("GET", "/sdrp/metered/my-summary?plan_type=micro&token_symbol=JPYC");
698
+ const summary = await siglume.getBuyerMeteredSummary({
699
+ plan_type: "micro",
700
+ token_symbol: "JPYC",
701
+ });
702
+ ```
703
+
704
+ Python:
705
+
706
+ ```py
707
+ summary = siglume.get_buyer_metered_summary(plan_type="micro", token_symbol="JPYC")
677
708
  ```
678
709
 
679
710
  Use `open_periods` for current-period estimated debit,
@@ -687,6 +718,14 @@ GET /v1/sdrp/metered/my-usage-events
687
718
  GET /v1/sdrp/metered/my-settlement-batches
688
719
  ```
689
720
 
721
+ SDK methods:
722
+
723
+ - TypeScript: `listBuyerUsageEvents(...)`, `listBuyerSettlementBatches(...)`
724
+ - Python: `list_buyer_usage_events(...)`, `list_buyer_settlement_batches(...)`
725
+
726
+ Each accepts `plan_type`, `token_symbol`, `status`, and `limit`, and returns
727
+ `{items, next_cursor}`.
728
+
690
729
  Buyer-facing amount names are centered on the debit:
691
730
 
692
731
  - `estimated_buyer_debit_minor`
@@ -711,16 +750,16 @@ Common query parameters:
711
750
  TypeScript:
712
751
 
713
752
  ```ts
714
- const providerSummary = await siglume.request<{
715
- role: "provider";
716
- timezone: string;
717
- open_periods: Array<Record<string, unknown>>;
718
- periods: Array<Record<string, unknown>>;
719
- totals: Record<string, string>;
720
- }>(
721
- "GET",
722
- "/sdrp/metered/provider/summary?plan_type=micro&token_symbol=JPYC",
723
- );
753
+ const providerSummary = await siglume.getProviderMeteredSummary({
754
+ plan_type: "micro",
755
+ token_symbol: "JPYC",
756
+ });
757
+ ```
758
+
759
+ Python:
760
+
761
+ ```py
762
+ provider_summary = siglume.get_provider_metered_summary(plan_type="micro", token_symbol="JPYC")
724
763
  ```
725
764
 
726
765
  Use `open_periods` for current-period expected revenue, `periods` for closed
@@ -736,6 +775,18 @@ GET /v1/sdrp/metered/provider/settlement-batches
736
775
  GET /v1/sdrp/metered/provider/settlement-batches/{settlement_batch_id}
737
776
  ```
738
777
 
778
+ SDK methods:
779
+
780
+ - TypeScript: `listProviderUsageEvents(...)`,
781
+ `listProviderSettlementBatches(...)`, `getProviderSettlementBatch(...)`
782
+ - Python: `list_provider_usage_events(...)`,
783
+ `list_provider_settlement_batches(...)`, `get_provider_settlement_batch(...)`
784
+
785
+ Provider list methods accept `plan_type`, `token_symbol`, `status`,
786
+ `listing_id`, `capability_key`, and `limit`. Detail accepts
787
+ `settlement_batch_id`, plus optional `listing_id` and `capability_key`. List
788
+ methods return `{items, next_cursor}`.
789
+
739
790
  Provider-facing amount names:
740
791
 
741
792
  - `provider_receivable_minor`
@@ -862,8 +913,17 @@ Returns `{ timestamp, signature }`.
862
913
  Validates and normalizes a parsed webhook event object (requires `id`, `type`,
863
914
  `api_version`, `occurred_at`, and an object `data`). Throws
864
915
  `SiglumeWebhookPayloadError` on a malformed event, or when a
865
- `direct_payment.confirmed` event does not carry `data.mode = "external_402"`. The
866
- `payload` argument is positional in both languages.
916
+ `direct_payment.confirmed` event does not carry a supported Direct Request
917
+ Payment mode (`external_402` or `metered_settlement_batch`). The `payload`
918
+ argument is positional in both languages.
919
+
920
+ For `direct_payment.confirmed`, inspect `event.data.pricing_band`,
921
+ `event.data.settlement_cadence`, `event.data.finality`,
922
+ `event.data.protocol_fee_minor`, and `event.data.settlement_status` instead of
923
+ inferring whether the event means per-payment on-chain confirmation or an
924
+ aggregated Micro / Nano settlement confirmation. `event.data.request_hash_v2`
925
+ is present on new challenge-backed requirements; keep accepting
926
+ `event.data.request_hash` for historical payloads.
867
927
 
868
928
  ### `verifyDirectRequestPaymentWebhook(secret, body, signature_header, options)` / `verify_direct_request_payment_webhook(secret, body, signature_header, *, tolerance_seconds=300, now=None)`
869
929
 
@@ -910,6 +970,7 @@ Both packages export these importable constants:
910
970
  | `DIRECT_REQUEST_PAYMENT_ALLOWANCE_RECEIPT_KIND` | `sdrp_direct_payment_allowance` |
911
971
  | `DIRECT_REQUEST_PAYMENT_REFERENCE_TYPE` | `sdrp_direct_payment_requirement` |
912
972
  | `DEFAULT_WEBHOOK_TOLERANCE_SECONDS` | `300` |
973
+ | `DIRECT_REQUEST_PAYMENT_SDK_VERSION` | package version string |
913
974
 
914
975
  The `external_402` / `siglume-external-402-*` values are legacy wire-compat
915
976
  identifiers, not public product names (see the README "Compatibility Notes").
@@ -14,11 +14,12 @@ external merchant.
14
14
  The merchant server must not create charges with a customer wallet. It signs the
15
15
  order challenge; the buyer-facing Siglume payment flow pays it.
16
16
 
17
- This quickstart is for SDRP Standard Payment in an external merchant product.
18
- Micro Payment and Nano Payment are applied automatically by amount and settled on
19
- account-assigned weekly / monthly slots after the final notice and close-plus-3-day
20
- site (see [Pricing](./pricing.md#settlement-schedule)); they are not browser
21
- checkout requirements you create with this SDK. Their provider revenue remains
17
+ This quickstart uses Standard-band example amounts. Micro Payment and Nano
18
+ Payment are applied automatically by amount through the same Hosted Checkout or
19
+ agent/API flow; you do not create a separate Micro/Nano object or pass a
20
+ "force Standard" flag. Micro/Nano are settled on account-assigned weekly /
21
+ monthly slots after the final notice and close-plus-3-day window (see
22
+ [Pricing](./pricing.md#settlement-schedule)), and provider revenue remains
22
23
  unsettled until the later on-chain settlement succeeds.
23
24
 
24
25
  ## Two Buyer Systems
@@ -74,7 +75,7 @@ await merchant.setupCheckout({
74
75
  // Per order: create a session and redirect the shopper to checkout_url.
75
76
  const session = await merchant.createCheckoutSession({
76
77
  merchant: "example_merchant",
77
- amount_minor: 500, // server-fixed; the browser cannot change it
78
+ amount_minor: 1200, // server-fixed; the browser cannot change it
78
79
  currency: "JPY",
79
80
  nonce: order.id, // unique per order
80
81
  success_url: "https://www.example.com/thanks",
@@ -114,7 +115,7 @@ merchant.setup_checkout(
114
115
  # Per order: create a session and redirect the shopper to checkout_url.
115
116
  session = merchant.create_checkout_session(
116
117
  merchant="example_merchant",
117
- amount_minor=500, # server-fixed; the browser cannot change it
118
+ amount_minor=1200, # server-fixed; the browser cannot change it
118
119
  currency="JPY",
119
120
  nonce=order["id"], # unique per order
120
121
  success_url="https://www.example.com/thanks",
@@ -452,14 +453,10 @@ const siglume = new DirectRequestPaymentClient({
452
453
  auth_token: providerSiglumeBearerToken,
453
454
  });
454
455
 
455
- const summary = await siglume.request<{
456
- open_periods: Array<Record<string, unknown>>;
457
- periods: Array<Record<string, unknown>>;
458
- totals: Record<string, string>;
459
- }>(
460
- "GET",
461
- "/sdrp/metered/provider/summary?plan_type=micro&token_symbol=JPYC",
462
- );
456
+ const summary = await siglume.getProviderMeteredSummary({
457
+ plan_type: "micro",
458
+ token_symbol: "JPYC",
459
+ });
463
460
 
464
461
  console.log(summary.totals.settled_provider_receivable_minor);
465
462
  console.log(summary.totals.unsettled_provider_receivable_minor);
@@ -474,9 +471,14 @@ curl https://siglume.com/v1/sdrp/metered/provider/settlement-batches/<batch-id>/
474
471
  -o sdrp-metered.csv
475
472
  ```
476
473
 
477
- Python does not expose a public generic request helper in this release. Use
478
- ordinary HTTPS requests with the provider's Siglume bearer token for these
479
- statement endpoints.
474
+ Python exposes the same named helper:
475
+
476
+ ```py
477
+ from siglume_direct_request_payment import DirectRequestPaymentClient
478
+
479
+ siglume = DirectRequestPaymentClient(auth_token=provider_siglume_bearer_token)
480
+ summary = siglume.get_provider_metered_summary(plan_type="micro", token_symbol="JPYC")
481
+ ```
480
482
 
481
483
  Do not book Micro / Nano provider revenue as settled revenue until the batch is
482
484
  `settled` and `chain_receipt_id` is present. See
@@ -19,8 +19,8 @@ Siglume applies the settlement band from the amount.
19
19
 
20
20
  | Band | Cadence | Period close | First debit attempt | Revenue recognition |
21
21
  | --- | --- | --- | --- | --- |
22
- | Micro Payment | Weekly | Account-assigned fixed weekly slot in the buyer settlement timezone | After final debit notice delivery and the fixed close-plus-3-day site | Only after the aggregated settlement confirms on-chain |
23
- | Nano Payment | Monthly | Account-assigned fixed monthly slot in the buyer settlement timezone | After final debit notice delivery and the fixed close-plus-3-day site | Only after the aggregated settlement confirms on-chain |
22
+ | Micro Payment | Weekly | Account-assigned fixed weekly slot in the buyer settlement timezone | After final debit notice delivery and the fixed close-plus-3-day window | Only after the aggregated settlement confirms on-chain |
23
+ | Nano Payment | Monthly | Account-assigned fixed monthly slot in the buyer settlement timezone | After final debit notice delivery and the fixed close-plus-3-day window | Only after the aggregated settlement confirms on-chain |
24
24
 
25
25
  The schedule is platform-managed. Buyers and providers can see the assigned
26
26
  period and scheduled attempt times through the statement APIs, but cannot choose
@@ -45,10 +45,8 @@ token. Provider responses never include raw `buyer_user_id`, buyer email, or raw
45
45
  wallet identifiers. Use `buyer_period_ref` to reconcile repeated usage by the
46
46
  same buyer within the provider's statement period without receiving buyer PII.
47
47
 
48
- TypeScript can call JSON statement endpoints with
49
- `DirectRequestPaymentClient.request<T>()`. Python does not expose a public
50
- generic request helper in this release; use ordinary HTTPS requests with the
51
- same bearer token.
48
+ TypeScript and Python expose named helpers for the JSON statement endpoints.
49
+ Use raw HTTPS only for the CSV export.
52
50
 
53
51
  ## Buyer Statement APIs
54
52
 
@@ -63,19 +61,19 @@ const siglume = new DirectRequestPaymentClient({
63
61
  auth_token: buyerSiglumeBearerToken,
64
62
  });
65
63
 
66
- const summary = await siglume.request<{
67
- role: "buyer";
68
- open_periods: Array<Record<string, unknown>>;
69
- settlement_batches: Array<Record<string, unknown>>;
70
- past_due_blocks: Array<Record<string, unknown>>;
71
- balance_sufficiency: Record<string, unknown>;
72
- }>(
73
- "GET",
74
- "/sdrp/metered/my-summary?plan_type=micro&token_symbol=JPYC",
75
- );
64
+ const summary = await siglume.getBuyerMeteredSummary({
65
+ plan_type: "micro",
66
+ token_symbol: "JPYC",
67
+ });
68
+ ```
69
+
70
+ Python:
71
+
72
+ ```py
73
+ summary = siglume.get_buyer_metered_summary(plan_type="micro", token_symbol="JPYC")
76
74
  ```
77
75
 
78
- Raw HTTP / Python:
76
+ Raw HTTP:
79
77
 
80
78
  ```bash
81
79
  curl https://siglume.com/v1/sdrp/metered/my-summary?plan_type=micro\&token_symbol=JPYC \
@@ -92,6 +90,28 @@ open period. It can report `wallet_balance_checked: false` or
92
90
  `allowance_checked: false`; in that case it is guidance, not a final on-chain
93
91
  guarantee.
94
92
 
93
+ ## Amount Rounding
94
+
95
+ Micro / Nano usage rows keep provider price and protocol fee values as decimal
96
+ minor-unit amounts. This allows Nano fees such as about JPY 0.2 per usage to be
97
+ accounted without rounding every event.
98
+
99
+ Rounding happens once when a settlement batch is created:
100
+
101
+ ```text
102
+ provider_usage_amount_minor = sum(provider price minor units for accepted usage)
103
+ protocol_fee_minor = sum(Micro/Nano fixed protocol fee minor units for accepted usage)
104
+ gross_buyer_debit_minor = provider_usage_amount_minor + protocol_fee_minor
105
+ buyer_debit_minor = ceil(gross_buyer_debit_minor)
106
+ rounding_delta_minor = buyer_debit_minor - gross_buyer_debit_minor
107
+ ```
108
+
109
+ `rounding_delta_minor` belongs to the buyer debit and Siglume's rounding
110
+ adjustment accounting for that batch. It is not provider revenue. Provider
111
+ reports should use `provider_receivable_minor`,
112
+ `settled_provider_receivable_minor`, `unsettled_provider_receivable_minor`, and
113
+ `past_due_provider_receivable_minor`.
114
+
95
115
  ### Usage Events
96
116
 
97
117
  ```text
@@ -105,6 +125,9 @@ Query parameters:
105
125
  - `status`: for example `pending_settlement`, `settled`, `failed_chargeable`
106
126
  - `limit`: 1 to 500
107
127
 
128
+ SDK methods: `listBuyerUsageEvents(...)` / `list_buyer_usage_events(...)`.
129
+ They return `{items, next_cursor}`.
130
+
108
131
  Buyer usage event amount fields:
109
132
 
110
133
  - `provider_usage_amount_minor`: provider price for the usage event
@@ -127,6 +150,9 @@ Query parameters:
127
150
  `past_due`, or `notice_delivery_failed`
128
151
  - `limit`: 1 to 200
129
152
 
153
+ SDK methods: `listBuyerSettlementBatches(...)` /
154
+ `list_buyer_settlement_batches(...)`. They return `{items, next_cursor}`.
155
+
130
156
  Buyer batch amount fields:
131
157
 
132
158
  - `estimated_buyer_debit_minor`: total buyer debit for the batch
@@ -157,20 +183,19 @@ const siglume = new DirectRequestPaymentClient({
157
183
  auth_token: providerSiglumeBearerToken,
158
184
  });
159
185
 
160
- const providerSummary = await siglume.request<{
161
- role: "provider";
162
- timezone: string;
163
- filters: Record<string, unknown>;
164
- open_periods: Array<Record<string, unknown>>;
165
- periods: Array<Record<string, unknown>>;
166
- totals: Record<string, string>;
167
- }>(
168
- "GET",
169
- "/sdrp/metered/provider/summary?plan_type=micro&token_symbol=JPYC",
170
- );
186
+ const providerSummary = await siglume.getProviderMeteredSummary({
187
+ plan_type: "micro",
188
+ token_symbol: "JPYC",
189
+ });
190
+ ```
191
+
192
+ Python:
193
+
194
+ ```py
195
+ provider_summary = siglume.get_provider_metered_summary(plan_type="micro", token_symbol="JPYC")
171
196
  ```
172
197
 
173
- Raw HTTP / Python:
198
+ Raw HTTP:
174
199
 
175
200
  ```bash
176
201
  curl https://siglume.com/v1/sdrp/metered/provider/summary?plan_type=micro\&token_symbol=JPYC \
@@ -210,6 +235,9 @@ Query parameters:
210
235
  - `capability_key`
211
236
  - `limit`: 1 to 500
212
237
 
238
+ SDK methods: `listProviderUsageEvents(...)` /
239
+ `list_provider_usage_events(...)`. They return `{items, next_cursor}`.
240
+
213
241
  Provider usage event fields include:
214
242
 
215
243
  - `provider_receivable_minor`
@@ -242,6 +270,10 @@ Query parameters for the list endpoint:
242
270
 
243
271
  The detail endpoint also accepts `listing_id` and `capability_key`.
244
272
 
273
+ SDK methods: `listProviderSettlementBatches(...)` /
274
+ `list_provider_settlement_batches(...)` and `getProviderSettlementBatch(...)` /
275
+ `get_provider_settlement_batch(...)`. List methods return `{items, next_cursor}`.
276
+
245
277
  Important batch fields:
246
278
 
247
279
  | Field | Meaning |
@@ -326,6 +358,40 @@ Public failure fields are sanitized. Show `failure_reason_code`,
326
358
  `failure_reason_label`, `failure_reason_help`, and `support_reference` to users
327
359
  or support staff. Do not depend on raw platform failure messages.
328
360
 
361
+ ## Usage Accounting by Result
362
+
363
+ Use idempotency keys for every paid operation. Siglume records one chargeable
364
+ usage event per idempotency key within the same buyer / listing / operation
365
+ scope.
366
+
367
+ | Case | Provider API executed? | Usage counted? | Integration rule |
368
+ | --- | --- | --- | --- |
369
+ | Budget gate rejected | No | No | Treat the request as rejected with no charge. The provider must not fulfill work. |
370
+ | Provider returns 2xx | Yes | Yes | Chargeable usage is recorded once. Fulfill idempotently by order id / requirement id / idempotency key. |
371
+ | Provider returns 4xx | Yes | Usually no, unless your integration deliberately marks the work as accepted before returning the 4xx | Prefer returning 2xx for completed work and 4xx only for unfulfilled client errors. Document any deliberate `failed_chargeable` mapping in your provider. |
372
+ | Provider returns 5xx | Yes | No by default | Treat as unfulfilled; retry from the caller with the same idempotency key if safe. |
373
+ | Provider timeout | Unknown | No by default unless the provider later confirms successful work under the same idempotency key | Reconcile by idempotency key before retrying side effects. |
374
+ | Client disconnects after provider success | Yes | Yes if the provider completed work and Siglume observed/records that success | The client may see failure while the provider completed work; use idempotency to avoid duplicate fulfillment. |
375
+ | Duplicate idempotency key | Maybe | One usage event | Return/reconcile the first outcome; do not create another chargeable event. |
376
+ | Usage cancellation/refund before settlement | Depends on platform support and status | Not self-service in this SDK release | Contact support or use the platform path Siglume provides for the account; do not mutate CSV/statement totals locally. |
377
+ | Refund/adjustment after settlement | Settled on-chain | Not self-service in this SDK release | Handle through an explicit adjustment/refund process; do not reverse settled revenue by editing statements. |
378
+
379
+ `failed_chargeable` means the provider-side work is treated as completed or
380
+ economically accepted even though the caller may have observed a failure state.
381
+ It is for cases such as "provider completed the operation, but the client
382
+ connection failed before receiving the response." It is not a catch-all for
383
+ provider 5xx errors. Integrations should make this state rare and defensible by
384
+ using stable idempotency keys and provider-side completion records.
385
+
386
+ ## Operational Status Handling
387
+
388
+ | Status | Buyer / provider view | Automatic processing | Operator action | Integration guidance |
389
+ | --- | --- | --- | --- | --- |
390
+ | `notice_delivery_failed` | Buyer debit is not yet allowed; provider revenue remains unsettled | Notice delivery can be retried or reviewed | Required if delivery keeps failing | Do not attempt your own debit notice or mark revenue settled. Show support context only. |
391
+ | `submitted_reconcile_required` | A settlement submission exists but final on-chain outcome is not yet reconciled | Reconciliation may complete if a receipt is found | Required if reconciliation stalls | Do not retry payment yourself. Wait for `settled`, `failed_retryable`, or `past_due`. |
392
+ | `past_due` | Buyer has an unresolved settlement block; provider sees past-due revenue | New Micro / Nano usage for the same buyer / plan / token is paused | Operator requeue or manual resolution only | Do not promise collection or provider payment. Ask the buyer to repair balance / allowance / BudgetVault / caps and reference `support_reference`. |
393
+ | `failed_chargeable` | Usage is still chargeable because provider work was accepted or completed | Included in later settlement attempts | Review if the provider disputes completion | Keep fulfillment idempotent and preserve evidence keyed by idempotency key. |
394
+
329
395
  ## Operational Recipes
330
396
 
331
397
  ### "How much did we use this week or month?"
package/docs/pricing.md CHANGED
@@ -26,16 +26,21 @@ quoted per currency.
26
26
 
27
27
  | Payment amount | Applied automatically | What you select | Fee | Settlement |
28
28
  | --- | --- | --- | --- | --- |
29
- | Over JPY 500 / over USD 3.00, or whenever immediate finality is required | 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 |
29
+ | Over JPY 500 / over USD 3.00 | 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 |
30
30
  | JPY 50-500 / over USD 0.30 and up to USD 3.00 | Micro Payment | Applied automatically by amount | USD 0.01 / Tx, about JPY 2 | Aggregated and settled **weekly** (see [Settlement schedule](#settlement-schedule)) |
31
31
  | Under JPY 50 / up to USD 0.30 | Nano Payment | Applied automatically by amount | USD 0.001 / usage, about JPY 0.2 | Aggregated and settled **monthly** (see [Settlement schedule](#settlement-schedule)) |
32
32
 
33
33
  Standard Payment settles per payment. Micro Payment and Nano Payment are
34
34
  aggregated and settled in account-assigned weekly / monthly slots - see
35
35
  [Settlement schedule](#settlement-schedule) for how each band closes, when the
36
- pre-debit notice site elapses, when revenue becomes settled, and how rejected
36
+ pre-debit notice window elapses, when revenue becomes settled, and how rejected
37
37
  requests behave.
38
38
 
39
+ The current public API chooses the band from `amount_minor`; it does not expose
40
+ `settlement_mode: "immediate"` or `require_immediate_finality: true`. If a
41
+ merchant needs immediate on-chain finality, the payment amount must be in the
42
+ Standard band or the merchant must have a separately agreed platform contract.
43
+
39
44
  For the operational statement APIs, CSV export, buyer past-due blocks, and the
40
45
  field-by-field meaning of `scheduled_debit_at`, `not_before_attempt_at`,
41
46
  `execution_status`, and `buyer_period_ref`, see
@@ -52,10 +57,13 @@ Per-payment fees are deducted at settlement, so the merchant receives the net
52
57
  amount for each payment. Monthly base fees are collected separately through the
53
58
  merchant billing mandate.
54
59
 
55
- The same fee schedule applies in JPY and USD. The Siglume platform returns
56
- `fee_bps` in the merchant's settlement currency on every payment requirement, so
57
- the SDK never has to know which currency table to read it just trusts the
58
- value Siglume returns.
60
+ The same Standard Payment percentage schedule applies in JPY and USD. For
61
+ Standard Payment, the Siglume platform returns `fee_bps` in the merchant's
62
+ settlement currency on the payment requirement, so the SDK never has to know
63
+ which currency table to read — it just trusts the value Siglume returns. For
64
+ Micro / Nano, the authoritative fee fields are the statement API amounts:
65
+ `protocol_fee_minor`, `gross_buyer_debit_minor`, `buyer_debit_minor`, and
66
+ `rounding_delta_minor`.
59
67
 
60
68
  ## Settlement schedule
61
69
 
@@ -65,8 +73,8 @@ confirmed payment turns into money in your settlement wallet.
65
73
  | Band | Cadence | Period | You are paid |
66
74
  | --- | --- | --- | --- |
67
75
  | Standard Payment | Per payment | n/a | On-chain, immediately after each payment confirms |
68
- | Micro Payment | Weekly | Account-assigned fixed weekly slot in the buyer settlement timezone; the assigned close time is visible through the statement APIs | After the period closes and the roughly 3-day pre-debit notice site has elapsed, in aggregated on-chain settlement(s) grouped per buyer, payee, token, and period |
69
- | Nano Payment | Monthly | Account-assigned fixed monthly slot in the buyer settlement timezone; the assigned close time is visible through the statement APIs | After the period closes and the roughly 3-day pre-debit notice site has elapsed, in aggregated on-chain settlement(s) grouped per buyer, payee, token, and period |
76
+ | Micro Payment | Weekly | Account-assigned fixed weekly slot in the buyer settlement timezone; the assigned close time is visible through the statement APIs | After the period closes and the roughly 3-day pre-debit notice window has elapsed, in aggregated on-chain settlement(s) grouped per buyer, payee, token, and period |
77
+ | Nano Payment | Monthly | Account-assigned fixed monthly slot in the buyer settlement timezone; the assigned close time is visible through the statement APIs | After the period closes and the roughly 3-day pre-debit notice window has elapsed, in aggregated on-chain settlement(s) grouped per buyer, payee, token, and period |
70
78
 
71
79
  ### Micro weekly settlement
72
80
 
@@ -80,7 +88,7 @@ confirmed payment turns into money in your settlement wallet.
80
88
  payments — grouped per buyer, payee, token, and period — into on-chain
81
89
  settlement(s). Siglume sends the final debit notice first; the on-chain debit
82
90
  is not attempted until the scheduled attempt time after an approximately
83
- 3-day pre-debit notice site (`not_before_attempt_at`).
91
+ 3-day pre-debit notice window (`not_before_attempt_at`).
84
92
  - **Revenue recognition.** A Micro payment is final only once its weekly
85
93
  settlement confirms on-chain. Until then it is accrued, not settled.
86
94
 
@@ -96,7 +104,7 @@ confirmed payment turns into money in your settlement wallet.
96
104
  payments — grouped per buyer, payee, token, and period — into on-chain
97
105
  settlement(s). Siglume sends the final debit notice first; the on-chain debit
98
106
  is not attempted until the scheduled attempt time after an approximately
99
- 3-day pre-debit notice site (`not_before_attempt_at`).
107
+ 3-day pre-debit notice window (`not_before_attempt_at`).
100
108
  - **Revenue recognition.** A Nano payment is final only once its monthly
101
109
  settlement confirms on-chain.
102
110
 
@@ -115,14 +123,18 @@ confirmed payment turns into money in your settlement wallet.
115
123
  - Outstanding amounts remain attached to the failed settlement and are retried
116
124
  under this policy. They are not settled revenue, and Siglume does not advance,
117
125
  guarantee, or insure provider revenue before on-chain settlement succeeds.
126
+ - A `past_due` batch remains recorded until operator resolution or requeue, but
127
+ this does not guarantee collection from the buyer or payment to the provider.
118
128
 
119
129
  ### Rejected / no-charge behavior
120
130
 
121
131
  Micro and Nano run a budget check before the buyer's paid request is fulfilled:
122
132
 
123
- - A buyer's wallet budget is consumed at the **gross amount** (your price plus
124
- the protocol fee), held from the moment a request is accepted until its
125
- settlement confirms.
133
+ - A buyer's wallet budget reservation is consumed at the **gross amount** (your
134
+ price plus the protocol fee) from acceptance until settlement confirms. This
135
+ is a reservation against Siglume spending limits; it does not lock, escrow,
136
+ preserve, or guarantee the buyer's token balance, allowance, BudgetVault
137
+ authorization, or payment source.
126
138
  - If the buyer's budget, scope, or amount band does not allow a request, it is
127
139
  **rejected with no charge**: the request is not fulfilled, no amount is
128
140
  accrued, and nothing is added to a settlement. A buyer near their budget
@@ -137,10 +149,35 @@ Micro and Nano run a budget check before the buyer's paid request is fulfilled:
137
149
  The cadence is fixed: **Micro settles weekly, Nano settles monthly**, and a
138
150
  payment is final only after its on-chain settlement confirms. Micro and Nano are
139
151
  automatic amount bands, not customer-selected options. The account-assigned
140
- period boundaries, roughly 3-day pre-debit notice site, and current retry policy
152
+ period boundaries, roughly 3-day pre-debit notice window, and current retry policy
141
153
  above are the public behavior as of 2026-06-18. Treat the platform's statement
142
- status, `not_before_attempt_at`, and `fee_bps` response as authoritative rather
143
- than hard-coding local revenue recognition.
154
+ status, `not_before_attempt_at`, Standard `fee_bps`, and Micro / Nano statement
155
+ amount fields as authoritative rather than hard-coding local revenue
156
+ recognition.
157
+
158
+ ## Micro / Nano Amount Rounding
159
+
160
+ Micro / Nano fees are stored internally as decimal minor-unit values so
161
+ sub-yen and sub-cent Nano fees are not silently rounded per usage event. The
162
+ current settlement rule is:
163
+
164
+ ```text
165
+ provider_usage_amount_minor = sum(provider price minor units for accepted usage)
166
+ protocol_fee_minor = sum(Micro/Nano fixed protocol fee minor units for accepted usage)
167
+ gross_buyer_debit_minor = provider_usage_amount_minor + protocol_fee_minor
168
+ buyer_debit_minor = ceil(gross_buyer_debit_minor)
169
+ rounding_delta_minor = buyer_debit_minor - gross_buyer_debit_minor
170
+ ```
171
+
172
+ Rounding happens once when the settlement batch is created, not per usage event.
173
+ The rounding mode is ceiling to the next integer token minor unit because
174
+ on-chain settlement cannot debit fractional JPYC/USDC minor units. The positive
175
+ `rounding_delta_minor` is part of the buyer debit for that batch and is retained
176
+ as a rounding adjustment in Siglume's settlement accounting; it is not provider
177
+ revenue. Providers should reconcile their revenue with
178
+ `provider_receivable_minor`, `settled_provider_receivable_minor`,
179
+ `unsettled_provider_receivable_minor`, and
180
+ `past_due_provider_receivable_minor`, not with `buyer_debit_minor`.
144
181
 
145
182
  ## Statement APIs and Notices
146
183
 
@@ -154,14 +191,15 @@ Use [Micro / Nano Statements and Notices](./metered-statements.md) to integrate:
154
191
  - provider usage-event CSV export,
155
192
  - buyer summaries for open-period estimated debit and past-due blocks,
156
193
  - sanitized public failure reasons and support references,
157
- - the fixed final notice plus close-plus-3-day debit site.
194
+ - the fixed final notice plus close-plus-3-day debit window.
158
195
 
159
196
  ## SDK Behavior
160
197
 
161
198
  The SDK does not calculate merchant invoices or enforce plan limits locally.
162
199
  Instead, it exposes billing-related values returned by Siglume, including
163
- `fee_bps` on a payment requirement. This keeps merchant billing centralized in
164
- the Siglume platform and avoids stale client-side pricing logic.
200
+ Standard Payment `fee_bps` on a payment requirement and Micro / Nano statement
201
+ amount fields. This keeps merchant billing centralized in the Siglume platform
202
+ and avoids stale client-side pricing logic.
165
203
 
166
204
  ## Supported Use Cases
167
205
 
@@ -179,4 +217,5 @@ The Siglume API and merchant registry may still expose the legacy `billing_plan`
179
217
  value `free` for the Launch tier. Treat `free` as a wire-compatibility key, not a
180
218
  public plan name. (Until 2026-06-12 the Launch plan included a free monthly
181
219
  allowance of 100 payments; that allowance has been retired — the platform
182
- `fee_bps` response is always the source of truth.)
220
+ Standard `fee_bps` response and Micro / Nano statement amount fields are always
221
+ the source of truth.)
package/docs/security.md CHANGED
@@ -61,6 +61,11 @@ bare, lowercased origins and deduped. A return URL that is not on an allowed
61
61
  origin is rejected, so an attacker cannot point a session at an arbitrary
62
62
  redirect target.
63
63
 
64
+ Production allowlist entries must use `https`. Development `http` entries are
65
+ accepted only for `http://localhost`, `http://127.0.0.1`, or `http://[::1]`
66
+ (with optional ports). Userinfo such as `https://user@shop.example.com` is
67
+ rejected so an attacker cannot rely on origin-spoofing URL forms.
68
+
64
69
  For a Hosted Checkout session, Siglume authors the amount, currency, challenge,
65
70
  and return URLs server-side at session creation. The browser cannot tamper with
66
71
  the price or the redirect target, and the raw challenge is never exposed to the
@@ -159,3 +164,9 @@ a rejected request is never charged. Provider revenue for Micro and Nano remains
159
164
  unsettled until the aggregated on-chain settlement succeeds; Siglume does not
160
165
  advance or guarantee revenue when a buyer's balance, allowance, BudgetVault
161
166
  authorization, cap, or on-chain transaction fails.
167
+
168
+ A Micro / Nano budget reservation is not a token lock, escrow, or payment
169
+ guarantee. It reserves room against Siglume spending limits only. A later
170
+ settlement can still fail if the buyer no longer has sufficient balance,
171
+ allowance, BudgetVault authorization, or cap room; `past_due` records the issue
172
+ but does not guarantee eventual collection or provider payment.