@siglume/direct-request-payment 0.3.6 → 0.4.1

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.
@@ -20,6 +20,128 @@ a weekly / monthly cadence (see [Pricing](./pricing.md#settlement-schedule)); th
20
20
  are not browser checkout requirements you create with this SDK. Their provider
21
21
  revenue remains unsettled until the later on-chain settlement succeeds.
22
22
 
23
+ ## Two Buyer Systems
24
+
25
+ There are two ways a buyer reaches you, and you integrate each differently:
26
+
27
+ - **Human web shopper → Hosted Checkout (Beta; server rollout in progress).** Create a checkout session and
28
+ redirect the shopper to the Siglume-hosted page (the
29
+ [section below](#hosted-checkout-human-web-shoppers)). This is the path that
30
+ resembles a Stripe-style hosted checkout.
31
+ - **AI agent / agent-to-agent (AtoA) → direct API / tools.** An autonomous
32
+ buyer pays through `DirectRequestPaymentClient` or the marketplace tool
33
+ `market_confirm_direct_payment_and_execute`, as in sections 2-4 below.
34
+
35
+ In both cases the buyer pays from a Siglume wallet (JPYC / USDC, not a card),
36
+ the merchant SDK never authenticates the buyer, and you fulfill on the same
37
+ `direct_payment.confirmed` webhook.
38
+
39
+ ## Hosted Checkout (Human Web Shoppers)
40
+
41
+ **Beta / server rollout:** Hosted Checkout is rolling out account by account.
42
+ Some merchant accounts may not have the server endpoint enabled yet. The SDK
43
+ raises `HostedCheckoutNotAvailableError` for rollout 404/409 responses.
44
+
45
+ When a person clicks "Pay with Siglume" on your site, create a session and
46
+ redirect them to the returned `checkout_url`. They sign into Siglume on the
47
+ hosted page, approve, and pay from their own wallet, then return to your
48
+ `success_url`. Siglume fixes the amount, currency, challenge, and return URLs
49
+ server-side, so the browser cannot tamper with the price or the redirect target.
50
+
51
+ Register your return-URL origins once (open-redirect defense). The origin of
52
+ your `webhook_callback_url` is auto-allowed in addition to these.
53
+
54
+ TypeScript:
55
+
56
+ ```ts
57
+ import { DirectRequestPaymentMerchantClient } from "@siglume/direct-request-payment";
58
+
59
+ const merchant = new DirectRequestPaymentMerchantClient({
60
+ auth_token: process.env.SIGLUME_MERCHANT_AUTH_TOKEN!,
61
+ });
62
+
63
+ // Once, at setup: register the return-URL origin allowlist.
64
+ await merchant.setupCheckout({
65
+ merchant: "example_merchant",
66
+ display_name: "Example Merchant",
67
+ billing_plan: "launch",
68
+ billing_currency: "JPY",
69
+ webhook_callback_url: "https://merchant.example/siglume/webhook",
70
+ checkout_allowed_origins: ["https://www.example.com"],
71
+ });
72
+
73
+ // Per order: create a session and redirect the shopper to checkout_url.
74
+ const session = await merchant.createCheckoutSession({
75
+ merchant: "example_merchant",
76
+ amount_minor: 500, // server-fixed; the browser cannot change it
77
+ currency: "JPY",
78
+ nonce: order.id, // unique per order
79
+ success_url: "https://www.example.com/thanks",
80
+ cancel_url: "https://www.example.com/cart",
81
+ metadata: { order_id: order.id },
82
+ });
83
+
84
+ await orders.update(order.id, {
85
+ siglume_challenge_hash: session.challenge_hash,
86
+ siglume_payment_status: "pending",
87
+ });
88
+
89
+ redirect(session.checkout_url); // -> https://siglume.com/pay/<session_id>
90
+ ```
91
+
92
+ Python:
93
+
94
+ ```py
95
+ import os
96
+
97
+ from siglume_direct_request_payment import DirectRequestPaymentMerchantClient
98
+
99
+ merchant = DirectRequestPaymentMerchantClient(
100
+ auth_token=os.environ["SIGLUME_MERCHANT_AUTH_TOKEN"],
101
+ )
102
+
103
+ # Once, at setup: register the return-URL origin allowlist.
104
+ merchant.setup_checkout(
105
+ merchant="example_merchant",
106
+ display_name="Example Merchant",
107
+ billing_plan="launch",
108
+ billing_currency="JPY",
109
+ webhook_callback_url="https://merchant.example/siglume/webhook",
110
+ checkout_allowed_origins=["https://www.example.com"],
111
+ )
112
+
113
+ # Per order: create a session and redirect the shopper to checkout_url.
114
+ session = merchant.create_checkout_session(
115
+ merchant="example_merchant",
116
+ amount_minor=500, # server-fixed; the browser cannot change it
117
+ currency="JPY",
118
+ nonce=order["id"], # unique per order
119
+ success_url="https://www.example.com/thanks",
120
+ cancel_url="https://www.example.com/cart",
121
+ metadata={"order_id": order["id"]},
122
+ )
123
+
124
+ orders.update(
125
+ order["id"],
126
+ {
127
+ "siglume_challenge_hash": session["challenge_hash"],
128
+ "siglume_payment_status": "pending",
129
+ },
130
+ )
131
+
132
+ # Redirect the shopper to session["checkout_url"]
133
+ # -> https://siglume.com/pay/<session_id>
134
+ ```
135
+
136
+ Fulfill exactly as in [section 4](#4-fulfill-from-webhook): on the signed
137
+ `direct_payment.confirmed` webhook, look up the order by `challenge_hash` and
138
+ mark it paid once. The session is single-use and expires (~30 minutes); you can
139
+ poll `getCheckoutSession` / `get_checkout_session` if you also want to show
140
+ status in your own UI, but the webhook is the source of truth. Honest framing:
141
+ the merchant plumbing integrates quickly, but human web payment still requires
142
+ the shopper to have — or create — a Siglume wallet and pay from it; it is not a
143
+ card-style "instant" checkout for first-time buyers.
144
+
23
145
  ## 1. Run Merchant Setup
24
146
 
25
147
  Run setup from the merchant server, CI, or an integration agent with the
@@ -162,6 +284,18 @@ The nonce must be unique per order payment attempt and must not contain `:`.
162
284
 
163
285
  ## 3. Buyer Creates and Pays the Requirement
164
286
 
287
+ This is the AI agent / AtoA path: the buyer pays directly through
288
+ `DirectRequestPaymentClient` (or the marketplace tool
289
+ `market_confirm_direct_payment_and_execute`), rather than through Hosted
290
+ Checkout. It assumes the buyer agent is **already connected to Siglume before
291
+ the payment**: an AI client (Claude / ChatGPT / Cursor) connects through the
292
+ Siglume MCP server (OAuth authorization with a consent screen), or a custom app
293
+ holds the buyer's Siglume bearer token (JWT). Either way a Siglume
294
+ authentication context is established first — the merchant SDK does not log the
295
+ buyer in. Unattended runs are bounded by Siglume's approval gates / spending
296
+ budgets (per-run / daily / monthly auto-pay budgets, or Works approval), not by
297
+ the merchant.
298
+
165
299
  After the buyer authenticates with Siglume, create the payment requirement with
166
300
  the buyer's Siglume bearer token. Do not use a Developer Portal `cli_` API key
167
301
  or merchant API key here.
package/docs/pricing.md CHANGED
@@ -59,34 +59,38 @@ confirmed payment turns into money in your settlement wallet.
59
59
  | Band | Cadence | Period | You are paid |
60
60
  | --- | --- | --- | --- |
61
61
  | Standard Payment | Per payment | n/a | On-chain, immediately after each payment confirms |
62
- | Micro Payment | Weekly | Buyer settlement timezone Monday 00:00 to the next Monday 00:00; default timezone is UTC | After the week closes, in aggregated on-chain settlement(s) grouped per buyer, payee, token, and period |
63
- | Nano Payment | Monthly | Buyer settlement timezone 1st 00:00 to the 1st of the next month 00:00; default timezone is UTC | After the month closes, in aggregated on-chain settlement(s) grouped per buyer, payee, token, and period |
62
+ | Micro Payment | Weekly | Fixed weekly slot assigned per account | After the period closes, after the final notice and an approximately 3-day pre-debit notice site, in aggregated on-chain settlement(s) grouped per buyer, payee, token, and period |
63
+ | Nano Payment | Monthly | Fixed monthly slot assigned per account | After the period closes, after the final notice and an approximately 3-day pre-debit notice site, in aggregated on-chain settlement(s) grouped per buyer, payee, token, and period |
64
64
 
65
65
  ### Micro weekly settlement
66
66
 
67
- - **Closing period.** Micro-band payments accrue across one calendar week:
68
- Monday 00:00 to the following Monday 00:00 in the buyer settlement timezone.
67
+ - **Closing period.** Micro-band payments accrue across one weekly period. The
68
+ specific closing weekday and time are assigned as a fixed slot per account to
69
+ spread settlement load.
69
70
  - **Timezone.** Period boundaries are evaluated in the buyer's configured
70
- settlement timezone, defaulting to UTC, so different buyers can close on
71
- slightly different local boundaries.
71
+ settlement timezone, defaulting to UTC. Assigned slots are persisted and are
72
+ not recalculated on the fly.
72
73
  - **Settlement.** After the week closes, Siglume aggregates that week's Micro
73
74
  payments — grouped per buyer, payee, token, and period — into on-chain
74
- settlement(s). Aggregation and payment run automatically on the next settlement
75
- pass after the period closes; there is a short, platform-managed lag between
76
- the close and the on-chain transaction.
75
+ settlement(s). Siglume sends the final debit notice first; the on-chain debit
76
+ is not attempted until the scheduled attempt time after an approximately
77
+ 3-day pre-debit notice site (`not_before_attempt_at`).
77
78
  - **Revenue recognition.** A Micro payment is final only once its weekly
78
79
  settlement confirms on-chain. Until then it is accrued, not settled.
79
80
 
80
81
  ### Nano monthly settlement
81
82
 
82
- - **Closing period.** Nano-band payments accrue across one calendar month:
83
- the 1st at 00:00 to the 1st of the next month at 00:00 in the buyer
84
- settlement timezone.
83
+ - **Closing period.** Nano-band payments accrue across one monthly period. The
84
+ specific closing day and time are assigned as a fixed slot per account to
85
+ spread settlement load.
85
86
  - **Timezone.** As with Micro, period boundaries use the buyer's configured
86
- settlement timezone, defaulting to UTC.
87
+ settlement timezone, defaulting to UTC. Assigned slots are persisted and are
88
+ not recalculated on the fly.
87
89
  - **Settlement.** After the month closes, Siglume aggregates that month's Nano
88
90
  payments — grouped per buyer, payee, token, and period — into on-chain
89
- settlement(s), on the next settlement pass after the period closes.
91
+ settlement(s). Siglume sends the final debit notice first; the on-chain debit
92
+ is not attempted until the scheduled attempt time after an approximately
93
+ 3-day pre-debit notice site (`not_before_attempt_at`).
90
94
  - **Revenue recognition.** A Nano payment is final only once its monthly
91
95
  settlement confirms on-chain.
92
96
 
package/docs/security.md CHANGED
@@ -49,6 +49,23 @@ autopay approval tag; it does not itself limit occurrences to once per day.
49
49
  Scheduled autopay execution is bounded by the buyer-approved per-run, daily, and
50
50
  monthly auto-pay budget.
51
51
 
52
+ ## Hosted Checkout Return URLs
53
+
54
+ Hosted Checkout adds a return-URL origin allowlist as open-redirect defense.
55
+ Register your allowed origins once via `checkout_allowed_origins` on
56
+ `setupCheckout` / `setupMerchant`. A checkout session's `success_url` and
57
+ `cancel_url` must be on a registered origin; the origin of your
58
+ `webhook_callback_url` is auto-allowed in addition. Each entry must be an
59
+ absolute origin such as `https://shop.example.com`; entries are normalized to
60
+ bare, lowercased origins and deduped. A return URL that is not on an allowed
61
+ origin is rejected, so an attacker cannot point a session at an arbitrary
62
+ redirect target.
63
+
64
+ For a Hosted Checkout session, Siglume authors the amount, currency, challenge,
65
+ and return URLs server-side at session creation. The browser cannot tamper with
66
+ the price or the redirect target, and the raw challenge is never exposed to the
67
+ browser or returned by `getCheckoutSession`.
68
+
52
69
  ## Do Not Trust Browser Amounts
53
70
 
54
71
  The merchant server owns:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@siglume/direct-request-payment",
3
- "version": "0.3.6",
3
+ "version": "0.4.1",
4
4
  "description": "SDK for the Siglume Direct Request Payment SDRP payment protocol",
5
5
  "keywords": [
6
6
  "siglume",