@siglume/direct-request-payment 0.4.3 → 0.4.5

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.
@@ -36,7 +36,7 @@ and no new webhook.
36
36
  | --- | --- | --- |
37
37
  | `SIGLUME_DIRECT_PAYMENT_CHALLENGE_SECRET` | merchant server | HMAC secret for order challenges |
38
38
  | `SIGLUME_MERCHANT_AUTH_TOKEN` | merchant setup helper | merchant Siglume bearer token for self-service setup |
39
- | `SIGLUME_AUTH_TOKEN` | buyer payment helper | buyer Siglume bearer token for API calls |
39
+ | `SIGLUME_AUTH_TOKEN` | user-authenticated helper | buyer Siglume bearer token for payment / buyer statements, or provider Siglume bearer token for provider statements |
40
40
  | `SIGLUME_API_BASE` | optional | API base URL override; defaults to `https://siglume.com/v1` |
41
41
  | `SIGLUME_WEBHOOK_SECRET` | merchant server | webhook signing secret returned as `whsec_...` |
42
42
 
@@ -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",
@@ -495,8 +505,10 @@ or rotation.
495
505
  ## `DirectRequestPaymentClient`
496
506
 
497
507
  Thin wrapper around the current Siglume Direct Request Payment HTTP contract.
498
- Use it with the authenticated buyer's Siglume bearer token. Developer Portal
499
- `cli_` API keys are not accepted by these buyer-authenticated routes.
508
+ Use it with the authenticated Siglume user bearer token for the route you call:
509
+ buyer tokens for buyer payment and buyer statement routes, provider / merchant
510
+ tokens for provider statement routes. Developer Portal `cli_` API keys are not
511
+ accepted by these user-authenticated routes.
500
512
 
501
513
  This client creates SDRP Standard Payment requirements for external merchant
502
514
  checkout flows. Micro Payment and Nano Payment are applied automatically by
@@ -505,19 +517,21 @@ created explicitly through this client. Use the statement APIs below to see
505
517
  open-period usage, the close time, the final-notice schedule, and settled /
506
518
  unsettled / past-due revenue.
507
519
 
508
- Payment requirements include `fee_bps` from the Siglume platform. The SDK does
509
- not calculate merchant plan fees locally; see [Pricing](./pricing.md).
520
+ Standard Payment requirements include `fee_bps` from the Siglume platform. The
521
+ SDK does not calculate merchant plan fees locally. For Micro / Nano, use the
522
+ statement API amount fields (`protocol_fee_minor`, `gross_buyer_debit_minor`,
523
+ `buyer_debit_minor`, and `rounding_delta_minor`); see [Pricing](./pricing.md).
510
524
 
511
525
  ```ts
512
526
  const siglume = new DirectRequestPaymentClient({
513
- auth_token: buyerSiglumeBearerToken,
527
+ auth_token: buyerOrProviderSiglumeBearerToken,
514
528
  base_url: "https://siglume.com/v1",
515
529
  });
516
530
  ```
517
531
 
518
532
  ```py
519
533
  siglume = DirectRequestPaymentClient(
520
- auth_token=buyer_siglume_bearer_token,
534
+ auth_token=buyer_or_provider_siglume_bearer_token,
521
535
  base_url="https://siglume.com/v1",
522
536
  )
523
537
  ```
@@ -544,6 +558,29 @@ Input:
544
558
  - `allowance_amount_minor`: optional positive integer
545
559
  - `metadata`: optional JSON object
546
560
 
561
+ There is no public `idempotency_key` field on this requirement-create request.
562
+ For one-time external checkout, idempotency is the merchant-signed challenge
563
+ nonce: derive `nonce` from a durable order payment attempt, store the returned
564
+ `challenge_hash`, and use `request_hash_v2` when you need a canonical machine
565
+ hash for the same payment request. Do not retry the same order by minting a new
566
+ nonce unless you intentionally want a new payment attempt.
567
+
568
+ The returned requirement includes both compatibility and machine-readable
569
+ settlement fields:
570
+
571
+ - `request_hash`: legacy v1 request hash, retained for existing requirements
572
+ and integrations.
573
+ - `request_hash_v2`: canonical-JSON v2 request hash when the server can compute
574
+ one for the challenge-backed request.
575
+ - `pricing_band`: `standard`, `micro`, or `nano`.
576
+ - `settlement_cadence`: `per_payment`, `weekly`, or `monthly`.
577
+ - `finality`: machine-readable finality class such as
578
+ `per_payment_onchain` or `aggregated_onchain_settlement`.
579
+ - `protocol_fee_minor`: Micro / Nano protocol fee when applicable; `null` for
580
+ Standard Payment.
581
+ - `settlement_status`: `pending_payment`, `provisional`, `settled`,
582
+ `pending_settlement`, or another explicit operational state.
583
+
547
584
  ### `getPaymentRequirement(requirement_id)` / `get_payment_requirement(requirement_id)`
548
585
 
549
586
  Calls:
@@ -640,9 +677,9 @@ base URL configured on `DirectRequestPaymentClient`.
640
677
  `/sdrp/metered/my-summary`. The helper expects a JSON response. Use raw
641
678
  `fetch`, `curl`, or your HTTP client for CSV exports.
642
679
 
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.
680
+ Python does not expose a public generic request helper. Use the named Python
681
+ methods documented below for Micro / Nano statements, and ordinary HTTPS
682
+ requests for endpoints that do not yet have a named Python SDK method.
646
683
 
647
684
  ## Metered Statement APIs
648
685
 
@@ -667,13 +704,16 @@ Common query parameters:
667
704
  TypeScript:
668
705
 
669
706
  ```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");
707
+ const summary = await siglume.getBuyerMeteredSummary({
708
+ plan_type: "micro",
709
+ token_symbol: "JPYC",
710
+ });
711
+ ```
712
+
713
+ Python:
714
+
715
+ ```py
716
+ summary = siglume.get_buyer_metered_summary(plan_type="micro", token_symbol="JPYC")
677
717
  ```
678
718
 
679
719
  Use `open_periods` for current-period estimated debit,
@@ -687,6 +727,15 @@ GET /v1/sdrp/metered/my-usage-events
687
727
  GET /v1/sdrp/metered/my-settlement-batches
688
728
  ```
689
729
 
730
+ SDK methods:
731
+
732
+ - TypeScript: `listBuyerUsageEvents(...)`, `listBuyerSettlementBatches(...)`
733
+ - Python: `list_buyer_usage_events(...)`, `list_buyer_settlement_batches(...)`
734
+
735
+ Each accepts `plan_type`, `token_symbol`, `status`, `limit`, and `cursor`, and
736
+ returns `{items, next_cursor}`. When `next_cursor` is non-null, pass it back as
737
+ `cursor` to fetch the next page.
738
+
690
739
  Buyer-facing amount names are centered on the debit:
691
740
 
692
741
  - `estimated_buyer_debit_minor`
@@ -711,16 +760,16 @@ Common query parameters:
711
760
  TypeScript:
712
761
 
713
762
  ```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
- );
763
+ const providerSummary = await siglume.getProviderMeteredSummary({
764
+ plan_type: "micro",
765
+ token_symbol: "JPYC",
766
+ });
767
+ ```
768
+
769
+ Python:
770
+
771
+ ```py
772
+ provider_summary = siglume.get_provider_metered_summary(plan_type="micro", token_symbol="JPYC")
724
773
  ```
725
774
 
726
775
  Use `open_periods` for current-period expected revenue, `periods` for closed
@@ -736,6 +785,19 @@ GET /v1/sdrp/metered/provider/settlement-batches
736
785
  GET /v1/sdrp/metered/provider/settlement-batches/{settlement_batch_id}
737
786
  ```
738
787
 
788
+ SDK methods:
789
+
790
+ - TypeScript: `listProviderUsageEvents(...)`,
791
+ `listProviderSettlementBatches(...)`, `getProviderSettlementBatch(...)`
792
+ - Python: `list_provider_usage_events(...)`,
793
+ `list_provider_settlement_batches(...)`, `get_provider_settlement_batch(...)`
794
+
795
+ Provider list methods accept `plan_type`, `token_symbol`, `status`,
796
+ `listing_id`, `capability_key`, `limit`, and `cursor`. Detail accepts
797
+ `settlement_batch_id`, plus optional `listing_id` and `capability_key`. List
798
+ methods return `{items, next_cursor}`. When `next_cursor` is non-null, pass it
799
+ back as `cursor` to fetch the next page.
800
+
739
801
  Provider-facing amount names:
740
802
 
741
803
  - `provider_receivable_minor`
@@ -792,6 +854,13 @@ metered_usage_id,created_at,plan_type,settlement_cadence,period_start,period_end
792
854
  ```
793
855
 
794
856
  The CSV uses `buyer_period_ref`, not raw buyer account identifiers.
857
+ The CSV keeps the `rounding_delta_minor` column for schema stability, but usage
858
+ rows report `0`; the authoritative rounding adjustment is the settlement batch
859
+ field `rounding_delta_minor`.
860
+
861
+ Micro / Nano amount fields are decimal minor-unit strings. In JavaScript, do
862
+ not aggregate them with `number`; parse them with a decimal library. In Python,
863
+ use `Decimal` for accounting and reconciliation.
795
864
 
796
865
  ## Payload Builders
797
866
 
@@ -862,8 +931,17 @@ Returns `{ timestamp, signature }`.
862
931
  Validates and normalizes a parsed webhook event object (requires `id`, `type`,
863
932
  `api_version`, `occurred_at`, and an object `data`). Throws
864
933
  `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.
934
+ `direct_payment.confirmed` event does not carry a supported Direct Request
935
+ Payment mode (`external_402` or `metered_settlement_batch`). The `payload`
936
+ argument is positional in both languages.
937
+
938
+ For `direct_payment.confirmed`, inspect `event.data.pricing_band`,
939
+ `event.data.settlement_cadence`, `event.data.finality`,
940
+ `event.data.protocol_fee_minor`, and `event.data.settlement_status` instead of
941
+ inferring whether the event means per-payment on-chain confirmation or an
942
+ aggregated Micro / Nano settlement confirmation. `event.data.request_hash_v2`
943
+ is present on new challenge-backed requirements; keep accepting
944
+ `event.data.request_hash` for historical payloads.
867
945
 
868
946
  ### `verifyDirectRequestPaymentWebhook(secret, body, signature_header, options)` / `verify_direct_request_payment_webhook(secret, body, signature_header, *, tolerance_seconds=300, now=None)`
869
947
 
@@ -910,6 +988,7 @@ Both packages export these importable constants:
910
988
  | `DIRECT_REQUEST_PAYMENT_ALLOWANCE_RECEIPT_KIND` | `sdrp_direct_payment_allowance` |
911
989
  | `DIRECT_REQUEST_PAYMENT_REFERENCE_TYPE` | `sdrp_direct_payment_requirement` |
912
990
  | `DEFAULT_WEBHOOK_TOLERANCE_SECONDS` | `300` |
991
+ | `DIRECT_REQUEST_PAYMENT_SDK_VERSION` | package version string |
913
992
 
914
993
  The `external_402` / `siglume-external-402-*` values are legacy wire-compat
915
994
  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,37 @@ 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
+ For low-count Nano batches, the ceiling can make the effective buyer burden per
110
+ usage higher than the headline "USD 0.001 / usage" protocol fee. The protocol
111
+ fee remains the decimal statement amount; the extra integer-minor-unit
112
+ adjustment is recorded as `rounding_delta_minor` on the settlement batch.
113
+
114
+ `rounding_delta_minor` belongs to the buyer debit and Siglume's rounding
115
+ adjustment accounting for that batch. It is not provider revenue. Provider
116
+ reports should use `provider_receivable_minor`,
117
+ `settled_provider_receivable_minor`, `unsettled_provider_receivable_minor`, and
118
+ `past_due_provider_receivable_minor`.
119
+
120
+ Micro / Nano amount fields are decimal minor-unit strings. JavaScript
121
+ integrations should aggregate them with a decimal library, not `number`. Python
122
+ integrations should use `Decimal` for accounting.
123
+
95
124
  ### Usage Events
96
125
 
97
126
  ```text
@@ -103,8 +132,12 @@ Query parameters:
103
132
  - `plan_type`: `micro` or `nano`
104
133
  - `token_symbol`: `JPYC` or `USDC`
105
134
  - `status`: for example `pending_settlement`, `settled`, `failed_chargeable`
135
+ - `cursor`: pass the previous response's `next_cursor` to fetch the next page
106
136
  - `limit`: 1 to 500
107
137
 
138
+ SDK methods: `listBuyerUsageEvents(...)` / `list_buyer_usage_events(...)`.
139
+ They return `{items, next_cursor}`.
140
+
108
141
  Buyer usage event amount fields:
109
142
 
110
143
  - `provider_usage_amount_minor`: provider price for the usage event
@@ -125,8 +158,12 @@ Query parameters:
125
158
  - `token_symbol`: `JPYC` or `USDC`
126
159
  - `status`: `notice_pending`, `ready`, `submitted`, `settled`, `failed`,
127
160
  `past_due`, or `notice_delivery_failed`
161
+ - `cursor`: pass the previous response's `next_cursor` to fetch the next page
128
162
  - `limit`: 1 to 200
129
163
 
164
+ SDK methods: `listBuyerSettlementBatches(...)` /
165
+ `list_buyer_settlement_batches(...)`. They return `{items, next_cursor}`.
166
+
130
167
  Buyer batch amount fields:
131
168
 
132
169
  - `estimated_buyer_debit_minor`: total buyer debit for the batch
@@ -157,20 +194,19 @@ const siglume = new DirectRequestPaymentClient({
157
194
  auth_token: providerSiglumeBearerToken,
158
195
  });
159
196
 
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
- );
197
+ const providerSummary = await siglume.getProviderMeteredSummary({
198
+ plan_type: "micro",
199
+ token_symbol: "JPYC",
200
+ });
171
201
  ```
172
202
 
173
- Raw HTTP / Python:
203
+ Python:
204
+
205
+ ```py
206
+ provider_summary = siglume.get_provider_metered_summary(plan_type="micro", token_symbol="JPYC")
207
+ ```
208
+
209
+ Raw HTTP:
174
210
 
175
211
  ```bash
176
212
  curl https://siglume.com/v1/sdrp/metered/provider/summary?plan_type=micro\&token_symbol=JPYC \
@@ -208,8 +244,12 @@ Query parameters:
208
244
  - `status`
209
245
  - `listing_id`
210
246
  - `capability_key`
247
+ - `cursor`: pass the previous response's `next_cursor` to fetch the next page
211
248
  - `limit`: 1 to 500
212
249
 
250
+ SDK methods: `listProviderUsageEvents(...)` /
251
+ `list_provider_usage_events(...)`. They return `{items, next_cursor}`.
252
+
213
253
  Provider usage event fields include:
214
254
 
215
255
  - `provider_receivable_minor`
@@ -238,10 +278,15 @@ Query parameters for the list endpoint:
238
278
  - `status`
239
279
  - `listing_id`
240
280
  - `capability_key`
281
+ - `cursor`: pass the previous response's `next_cursor` to fetch the next page
241
282
  - `limit`: 1 to 200
242
283
 
243
284
  The detail endpoint also accepts `listing_id` and `capability_key`.
244
285
 
286
+ SDK methods: `listProviderSettlementBatches(...)` /
287
+ `list_provider_settlement_batches(...)` and `getProviderSettlementBatch(...)` /
288
+ `get_provider_settlement_batch(...)`. List methods return `{items, next_cursor}`.
289
+
245
290
  Important batch fields:
246
291
 
247
292
  | Field | Meaning |
@@ -285,6 +330,10 @@ metered_usage_id,created_at,plan_type,settlement_cadence,period_start,period_end
285
330
  ```
286
331
 
287
332
  The CSV uses `buyer_period_ref`, not `buyer_user_id`.
333
+ `rounding_delta_minor` is present for a stable usage-event schema, but per-row
334
+ values are `0`. The authoritative rounding adjustment is the settlement batch
335
+ `rounding_delta_minor`; do not allocate that adjustment to provider revenue
336
+ from individual CSV rows.
288
337
 
289
338
  ## Notifications
290
339
 
@@ -326,6 +375,45 @@ Public failure fields are sanitized. Show `failure_reason_code`,
326
375
  `failure_reason_label`, `failure_reason_help`, and `support_reference` to users
327
376
  or support staff. Do not depend on raw platform failure messages.
328
377
 
378
+ ## Usage Accounting by Result
379
+
380
+ Use idempotency keys for every paid operation. Siglume records one chargeable
381
+ usage event per idempotency key within the same buyer / listing / operation
382
+ scope.
383
+
384
+ | Case | Provider API executed? | Usage counted? | Integration rule |
385
+ | --- | --- | --- | --- |
386
+ | Budget gate rejected | No | No | Treat the request as rejected with no charge. The provider must not fulfill work. |
387
+ | Provider returns 2xx | Yes | Yes | Chargeable usage is recorded once. Fulfill idempotently by order id / requirement id / idempotency key. |
388
+ | 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. |
389
+ | Provider returns 5xx | Yes | No by default | Treat as unfulfilled; retry from the caller with the same idempotency key if safe. |
390
+ | 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. |
391
+ | 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. |
392
+ | Duplicate idempotency key | Maybe | One usage event | Return/reconcile the first outcome; do not create another chargeable event. |
393
+ | 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. |
394
+ | 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. |
395
+
396
+ `failed_chargeable` means the provider-side work is treated as completed or
397
+ economically accepted even though the caller may have observed a failure state.
398
+ It is for cases such as "provider completed the operation, but the client
399
+ connection failed before receiving the response." It is not a catch-all for
400
+ provider 5xx errors. Integrations should make this state rare and defensible by
401
+ using stable idempotency keys and provider-side completion records.
402
+
403
+ ## Operational Status Handling
404
+
405
+ | Status | Buyer / provider view | Automatic processing | Operator action | Integration guidance |
406
+ | --- | --- | --- | --- | --- |
407
+ | `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. |
408
+ | `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`. |
409
+ | `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`. |
410
+ | `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. |
411
+
412
+ Future platform versions may add explicit terminal states such as
413
+ `closed_unpaid`, `uncollectible`, or `written_off`. Treat unknown terminal
414
+ settlement states as not settled unless `status === "settled"` and
415
+ `chain_receipt_id` is present.
416
+
329
417
  ## Operational Recipes
330
418
 
331
419
  ### "How much did we use this week or month?"