@siglume/direct-request-payment 0.4.5 → 0.4.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.4.7 - 2026-06-19
4
+
5
+ Documentation-only patch release.
6
+
7
+ - Clarified that SDRP merchant setup and billing mandate terms assume acceptance
8
+ of automatic Micro / Nano delayed aggregated settlement for low-price bands.
9
+ - Replaced merchant-specific override wording with the operational rule that
10
+ products requiring immediate settlement should be priced in the Standard band.
11
+
12
+ ## 0.4.6 - 2026-06-19
13
+
14
+ Patch release for the external webhook-state re-review.
15
+
16
+ - Changed webhook examples to branch Standard settled payments, Micro / Nano
17
+ accepted-but-unsettled usage, and metered settlement batches separately.
18
+ - Added Hosted Checkout settlement machine fields and metered settlement batch
19
+ webhook fields to TypeScript types and API docs.
20
+ - Clarified public Nano one-time amount limits, Micro / Nano idempotency key
21
+ placement, and per-batch rounding adjustment behavior.
22
+ - Added `pytest python_tests` to the PyPI Trusted Publishing release workflow.
23
+
3
24
  ## 0.4.5 - 2026-06-19
4
25
 
5
26
  Patch release for the public beta re-review.
package/README.md CHANGED
@@ -67,12 +67,16 @@ card-style "instant" checkout for first-time buyers.
67
67
  Some merchant accounts may not have the server endpoint enabled yet. In that
68
68
  case `createCheckoutSession(...)` / `getCheckoutSession(...)` raises
69
69
  `HostedCheckoutNotAvailableError` instead of exposing the raw rollout 404/409.
70
- Keep fulfilling only from the signed `direct_payment.confirmed` webhook.
70
+ Keep the signed `direct_payment.confirmed` webhook as the durable signal, and
71
+ inspect its settlement machine fields before marking any order paid.
71
72
 
72
73
  Hosted Checkout is a Siglume-hosted page that turns a "Pay with Siglume" button
73
74
  into a completed wallet payment, then returns the shopper to your store. It
74
- orchestrates the same rails as the agent flow — there is no new money movement
75
- and the merchant fulfills on the same `direct_payment.confirmed` webhook.
75
+ orchestrates the same rails as the agent flow — there is no new money movement.
76
+ Fulfillment still starts from the signed `direct_payment.confirmed` webhook, but
77
+ you must inspect the settlement machine fields before deciding whether the event
78
+ means Standard settled payment, Micro / Nano accepted usage, or aggregated
79
+ Micro / Nano settlement.
76
80
 
77
81
  ```ts
78
82
  import { DirectRequestPaymentMerchantClient } from "@siglume/direct-request-payment";
@@ -99,9 +103,12 @@ const session = await merchant.createCheckoutSession({
99
103
  });
100
104
  redirect(session.checkout_url); // -> https://siglume.com/pay/<session_id>
101
105
 
102
- // 3. Fulfill when the signed direct_payment.confirmed webhook arrives (the
103
- // source of truth). Poll merchant.getCheckoutSession(session.session_id) if
104
- // you also want to show status in your own UI.
106
+ // 3. Handle the signed direct_payment.confirmed webhook. Fulfill Standard only
107
+ // when pricing_band=standard, finality=per_payment_onchain, and
108
+ // settlement_status=settled. Treat Micro / Nano as accepted but unsettled
109
+ // until the later metered settlement batch is settled.
110
+ // Poll merchant.getCheckoutSession(session.session_id) if you also want to
111
+ // show status in your own UI.
105
112
  ```
106
113
 
107
114
  ```py
@@ -131,9 +138,12 @@ session = merchant.create_checkout_session(
131
138
  )
132
139
  redirect(session["checkout_url"]) # -> https://siglume.com/pay/<session_id>
133
140
 
134
- # 3. Fulfill when the signed direct_payment.confirmed webhook arrives (the
135
- # source of truth). Poll merchant.get_checkout_session(session["session_id"])
136
- # if you also want to show status in your own UI.
141
+ # 3. Handle the signed direct_payment.confirmed webhook. Fulfill Standard only
142
+ # when pricing_band=standard, finality=per_payment_onchain, and
143
+ # settlement_status=settled. Treat Micro / Nano as accepted but unsettled
144
+ # until the later metered settlement batch is settled.
145
+ # Poll merchant.get_checkout_session(session["session_id"]) if you also want
146
+ # to show status in your own UI.
137
147
  ```
138
148
 
139
149
  Siglume fixes the amount, currency, challenge, and return URLs **server-side** at
@@ -183,7 +193,12 @@ weekly / monthly settlement schedule are in [docs/pricing.md](./docs/pricing.md)
183
193
  Provider revenue in the Micro and Nano bands is not settled revenue until the
184
194
  weekly or monthly on-chain settlement succeeds. Siglume keeps outstanding failed
185
195
  settlements for retry under the published policy, but does not advance or
186
- guarantee provider revenue before settlement succeeds.
196
+ guarantee provider revenue before settlement succeeds. Merchant setup and the
197
+ billing mandate terms assume the merchant accepts this Micro / Nano delayed
198
+ aggregated settlement model whenever they offer amounts in these bands. If a
199
+ product cannot fulfill before provider revenue is settled, keep the price in the
200
+ Standard band; in practice, do not offer JPY 500-and-under or USD 3-and-under
201
+ items for that product.
187
202
  Micro / Nano budget checks reserve spending capacity only; they do not lock,
188
203
  escrow, or guarantee the buyer's wallet balance, allowance, or settlement funds.
189
204
  Sub-minor-unit Nano fees are accumulated with decimal precision and rounded only
@@ -208,7 +223,8 @@ and CSV exports, see
208
223
  - buyer-authenticated payment requirement creation
209
224
  - prepared wallet transaction execution payloads
210
225
  - payment requirement verification
211
- - authenticated TypeScript JSON requests to Micro / Nano statement APIs
226
+ - authenticated TypeScript JSON requests and named Python helpers for Micro /
227
+ Nano statement APIs
212
228
  - signed webhook verification
213
229
 
214
230
  It does not custody funds or manage customer wallets. Merchant setup runs through
@@ -246,14 +262,19 @@ amounts differ.
246
262
  | Under JPY 50 / up to USD 0.30 | Nano Payment | Applied automatically by amount | USD 0.001 / usage, about JPY 0.2 | Monthly settlement - see [Settlement schedule](./docs/pricing.md#settlement-schedule) |
247
263
 
248
264
  A merchant billing mandate is required before accepting payments, even on the
249
- Launch plan. The current public API does not expose a flag that forces a
250
- JPY 500-and-under / USD 3-and-under payment into Standard immediate settlement.
251
- If immediate on-chain settlement is a hard requirement, price the item in the
252
- Standard band or confirm a merchant-specific contract with Siglume before
253
- launch. For Standard Payment, `fee_bps` returned on a payment requirement is the
254
- authoritative fee rate for that payment in the merchant's settlement currency.
255
- For Micro / Nano, the statement APIs expose `protocol_fee_minor`,
256
- `gross_buyer_debit_minor`, `buyer_debit_minor`, and `rounding_delta_minor`.
265
+ Launch plan. The current public API chooses the payment band from
266
+ `amount_minor`; JPY 500-and-under / USD 3-and-under payments are routed to
267
+ Micro / Nano delayed aggregated settlement. Accepting the SDRP merchant terms
268
+ means accepting automatic Micro / Nano delayed aggregated settlement for those
269
+ low-price bands. If immediate on-chain settlement is a hard requirement, price
270
+ the item in the Standard band; in practice, do not offer JPY 500-and-under or
271
+ USD 3-and-under items for that product. Public Direct Payment / Hosted Checkout
272
+ `amount_minor` is a positive integer in minor currency units, so public one-time
273
+ Nano amounts start at JPY 1 or USD 0.01. For Standard Payment, `fee_bps`
274
+ returned on a payment requirement is the authoritative fee rate for that payment
275
+ in the merchant's settlement currency. For Micro / Nano, the statement APIs
276
+ expose `protocol_fee_minor`, `gross_buyer_debit_minor`, `buyer_debit_minor`, and
277
+ `rounding_delta_minor`.
257
278
  The full fee table and the weekly / monthly settlement schedule live in
258
279
  [docs/pricing.md](./docs/pricing.md). Statement APIs for "how much was used,
259
280
  when will it close, when can it debit, and what is settled" are documented in
@@ -513,7 +534,19 @@ const { event } = await verifyDirectRequestPaymentWebhook(
513
534
  );
514
535
 
515
536
  if (event.type === "direct_payment.confirmed") {
516
- // Mark the order paid if event.data.challenge_hash/order mapping matches.
537
+ if (event.data.mode === "metered_settlement_batch") {
538
+ // Reconcile settled Micro / Nano batches by settlement_batch_id /
539
+ // usage_event_digest; these events do not carry an order challenge hash.
540
+ } else if (
541
+ event.data.pricing_band === "standard" &&
542
+ event.data.finality === "per_payment_onchain" &&
543
+ event.data.settlement_status === "settled"
544
+ ) {
545
+ // Mark the order paid once if event.data.challenge_hash/order mapping matches.
546
+ } else if (event.data.pricing_band === "micro" || event.data.pricing_band === "nano") {
547
+ // Mark fulfilled-but-unsettled only if your business allows fulfillment
548
+ // before the aggregated Micro / Nano settlement succeeds.
549
+ }
517
550
  }
518
551
  ```
519
552
 
@@ -529,14 +562,30 @@ verified = verify_direct_request_payment_webhook(
529
562
  )
530
563
 
531
564
  if verified["event"]["type"] == "direct_payment.confirmed":
532
- # Mark the order paid if event.data.challenge_hash/order mapping matches.
533
- pass
565
+ data = verified["event"]["data"]
566
+ if data.get("mode") == "metered_settlement_batch":
567
+ # Reconcile settled Micro / Nano batches by settlement_batch_id /
568
+ # usage_event_digest; these events do not carry an order challenge hash.
569
+ pass
570
+ elif (
571
+ data.get("pricing_band") == "standard"
572
+ and data.get("finality") == "per_payment_onchain"
573
+ and data.get("settlement_status") == "settled"
574
+ ):
575
+ # Mark the order paid once if event.data.challenge_hash/order mapping matches.
576
+ pass
577
+ elif data.get("pricing_band") in ("micro", "nano"):
578
+ # Mark fulfilled-but-unsettled only if your business allows fulfillment
579
+ # before the aggregated Micro / Nano settlement succeeds.
580
+ pass
534
581
  ```
535
582
 
536
583
  New `direct_payment.confirmed` payloads include `pricing_band`,
537
- `settlement_cadence`, `finality`, `protocol_fee_minor`, `settlement_status`, and
538
- when available `request_hash_v2`. Use these machine fields instead of inferring
539
- settlement semantics from the event name alone.
584
+ `settlement_cadence`, `finality`, `protocol_fee_minor`, `settlement_status`,
585
+ `settlement_batch_id`, `chain_receipt_id`, `usage_event_digest`, `settled_at`,
586
+ and when available `request_hash_v2`. Use these machine fields instead of
587
+ inferring settlement semantics from the event name alone. Do not mark an order
588
+ paid from the event type alone.
540
589
 
541
590
  ## Security Rules
542
591
 
@@ -559,7 +608,8 @@ Read [docs/security.md](./docs/security.md) before going live.
559
608
  - Store `SIGLUME_DIRECT_PAYMENT_CHALLENGE_SECRET` only on the merchant server.
560
609
  - Store the returned `SIGLUME_WEBHOOK_SECRET` only on the merchant server.
561
610
  - Persist `challenge_hash`, `requirement_id`, and fulfillment state per order.
562
- - Fulfill orders only from verified webhook data, with idempotency.
611
+ - Fulfill orders only from verified webhook data, with idempotency, after
612
+ checking `pricing_band`, `finality`, and `settlement_status`.
563
613
  - Treat `fee_bps` returned by Siglume as the Standard Payment runtime fee source
564
614
  of truth; use statement API amount fields for Micro / Nano.
565
615
 
package/dist/index.cjs CHANGED
@@ -78,7 +78,7 @@ var DIRECT_REQUEST_PAYMENT_RECEIPT_KIND = "sdrp_direct_payment";
78
78
  var DIRECT_REQUEST_PAYMENT_ALLOWANCE_RECEIPT_KIND = "sdrp_direct_payment_allowance";
79
79
  var DIRECT_REQUEST_PAYMENT_REFERENCE_TYPE = "sdrp_direct_payment_requirement";
80
80
  var DEFAULT_WEBHOOK_TOLERANCE_SECONDS = 300;
81
- var DIRECT_REQUEST_PAYMENT_SDK_VERSION = "0.4.5";
81
+ var DIRECT_REQUEST_PAYMENT_SDK_VERSION = "0.4.7";
82
82
  var DIRECT_REQUEST_PAYMENT_CONFIRMED_WEBHOOK_MODES = /* @__PURE__ */ new Set([DIRECT_REQUEST_PAYMENT_MODE, "metered_settlement_batch"]);
83
83
  var SiglumeDirectRequestPaymentError = class extends Error {
84
84
  constructor(message) {