@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.
- package/CHANGELOG.md +36 -0
- package/README.md +33 -10
- package/dist/index.cjs +124 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +146 -1
- package/dist/index.d.ts +146 -1
- package/dist/index.js +124 -7
- package/dist/index.js.map +1 -1
- package/docs/announcement-ja.md +8 -8
- package/docs/api-reference.md +113 -34
- package/docs/merchant-quickstart.md +20 -18
- package/docs/metered-statements.md +117 -29
- package/docs/pricing.md +66 -20
- package/docs/security.md +26 -10
- package/examples/express-checkout.ts +12 -30
- package/package.json +1 -1
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
|
|
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
|
|
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
|
|
56
|
-
`fee_bps` in the merchant's
|
|
57
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
124
|
-
the protocol fee)
|
|
125
|
-
|
|
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,42 @@ 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
|
|
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`,
|
|
143
|
-
than hard-coding local revenue
|
|
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`.
|
|
181
|
+
|
|
182
|
+
For low-count Nano batches, the integer ceiling can make the effective buyer
|
|
183
|
+
burden per usage higher than the headline USD 0.001 / usage protocol fee. The
|
|
184
|
+
decimal protocol fee remains visible as `protocol_fee_minor`; the difference
|
|
185
|
+
created by integer-token settlement is visible as `rounding_delta_minor` on the
|
|
186
|
+
batch. JavaScript integrations should not sum Micro / Nano minor amounts with
|
|
187
|
+
`number`; use a decimal library. Python integrations should use `Decimal`.
|
|
144
188
|
|
|
145
189
|
## Statement APIs and Notices
|
|
146
190
|
|
|
@@ -154,14 +198,15 @@ Use [Micro / Nano Statements and Notices](./metered-statements.md) to integrate:
|
|
|
154
198
|
- provider usage-event CSV export,
|
|
155
199
|
- buyer summaries for open-period estimated debit and past-due blocks,
|
|
156
200
|
- sanitized public failure reasons and support references,
|
|
157
|
-
- the fixed final notice plus close-plus-3-day debit
|
|
201
|
+
- the fixed final notice plus close-plus-3-day debit window.
|
|
158
202
|
|
|
159
203
|
## SDK Behavior
|
|
160
204
|
|
|
161
205
|
The SDK does not calculate merchant invoices or enforce plan limits locally.
|
|
162
206
|
Instead, it exposes billing-related values returned by Siglume, including
|
|
163
|
-
`fee_bps` on a payment requirement
|
|
164
|
-
|
|
207
|
+
Standard Payment `fee_bps` on a payment requirement and Micro / Nano statement
|
|
208
|
+
amount fields. This keeps merchant billing centralized in the Siglume platform
|
|
209
|
+
and avoids stale client-side pricing logic.
|
|
165
210
|
|
|
166
211
|
## Supported Use Cases
|
|
167
212
|
|
|
@@ -179,4 +224,5 @@ The Siglume API and merchant registry may still expose the legacy `billing_plan`
|
|
|
179
224
|
value `free` for the Launch tier. Treat `free` as a wire-compatibility key, not a
|
|
180
225
|
public plan name. (Until 2026-06-12 the Launch plan included a free monthly
|
|
181
226
|
allowance of 100 payments; that allowance has been retired — the platform
|
|
182
|
-
`fee_bps` response
|
|
227
|
+
Standard `fee_bps` response and Micro / Nano statement amount fields are always
|
|
228
|
+
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
|
|
@@ -114,6 +119,12 @@ Fulfill exactly once per order. Store at least:
|
|
|
114
119
|
Duplicate webhook deliveries and manual redelivery can occur. A duplicate
|
|
115
120
|
webhook with the same requirement id must not ship the order twice.
|
|
116
121
|
|
|
122
|
+
The public requirement-create API does not accept an `idempotency_key` field.
|
|
123
|
+
For one-time external checkout, the durable idempotency material is the
|
|
124
|
+
merchant-authored challenge nonce plus the returned `challenge_hash` /
|
|
125
|
+
`request_hash_v2`. Reuse the same order-attempt nonce when reconciling a retry;
|
|
126
|
+
mint a new nonce only for a new payment attempt.
|
|
127
|
+
|
|
117
128
|
## Micro / Nano Statement Privacy
|
|
118
129
|
|
|
119
130
|
Micro Payment and Nano Payment introduce operational statement APIs and CSV
|
|
@@ -149,13 +160,18 @@ Direct Request Payment is not:
|
|
|
149
160
|
- a platform balance
|
|
150
161
|
- a card payment fallback
|
|
151
162
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
wallet
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
163
|
+
Standard Payment is settled individually with its own on-chain receipt. Micro
|
|
164
|
+
and Nano usage events are included in an aggregated settlement batch, and the
|
|
165
|
+
batch is backed by an on-chain receipt. They are still wallet payments, not a
|
|
166
|
+
stored balance. Before a small payment is fulfilled, Siglume checks the buyer's
|
|
167
|
+
wallet budget and fails closed when it is invalid, so a rejected request is
|
|
168
|
+
never charged. Provider revenue for Micro and Nano remains unsettled until the
|
|
169
|
+
aggregated on-chain settlement succeeds; Siglume does not advance or guarantee
|
|
170
|
+
revenue when a buyer's balance, allowance, BudgetVault authorization, cap, or
|
|
171
|
+
on-chain transaction fails.
|
|
172
|
+
|
|
173
|
+
A Micro / Nano budget reservation is not a token lock, escrow, or payment
|
|
174
|
+
guarantee. It reserves room against Siglume spending limits only. A later
|
|
175
|
+
settlement can still fail if the buyer no longer has sufficient balance,
|
|
176
|
+
allowance, BudgetVault authorization, or cap room; `past_due` records the issue
|
|
177
|
+
but does not guarantee eventual collection or provider payment.
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import express from "express";
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
DirectRequestPaymentClient,
|
|
3
|
+
DirectRequestPaymentMerchantClient,
|
|
5
4
|
verifyDirectRequestPaymentWebhook,
|
|
6
5
|
} from "@siglume/direct-request-payment";
|
|
7
6
|
|
|
8
7
|
const app = express();
|
|
9
8
|
const port = Number(process.env.PORT || 3000);
|
|
10
9
|
const merchantKey = process.env.SIGLUME_DIRECT_PAYMENT_MERCHANT || "example_merchant";
|
|
10
|
+
const siglumeMerchant = new DirectRequestPaymentMerchantClient({
|
|
11
|
+
auth_token: process.env.SIGLUME_MERCHANT_AUTH_TOKEN,
|
|
12
|
+
});
|
|
11
13
|
|
|
12
14
|
// Use JSON for normal routes. Use raw body only on the webhook route.
|
|
13
15
|
app.use((req, res, next) => {
|
|
@@ -35,49 +37,29 @@ app.post("/checkout/siglume/start", asyncRoute(async (req, res) => {
|
|
|
35
37
|
}
|
|
36
38
|
|
|
37
39
|
order.payment_attempt = Number(order.payment_attempt || 0) + 1;
|
|
38
|
-
const
|
|
40
|
+
const session = await siglumeMerchant.createCheckoutSession({
|
|
39
41
|
merchant: merchantKey,
|
|
40
42
|
amount_minor: order.amount_minor,
|
|
41
43
|
currency: order.currency,
|
|
42
|
-
secret: process.env.SIGLUME_DIRECT_PAYMENT_CHALLENGE_SECRET!,
|
|
43
44
|
nonce: `${order.id}-attempt_${order.payment_attempt}`,
|
|
45
|
+
success_url: `${process.env.SHOP_PUBLIC_ORIGIN || "https://shop.example.com"}/thanks`,
|
|
46
|
+
cancel_url: `${process.env.SHOP_PUBLIC_ORIGIN || "https://shop.example.com"}/cart`,
|
|
47
|
+
metadata: { order_id: order.id },
|
|
44
48
|
});
|
|
45
49
|
|
|
46
|
-
order.siglume_challenge_hash =
|
|
50
|
+
order.siglume_challenge_hash = session.challenge_hash;
|
|
51
|
+
order.siglume_checkout_session_id = session.session_id;
|
|
47
52
|
order.siglume_payment_status = "pending";
|
|
48
53
|
|
|
49
54
|
res.json({
|
|
50
55
|
order_id: order.id,
|
|
51
56
|
amount_minor: order.amount_minor,
|
|
52
57
|
currency: order.currency,
|
|
53
|
-
|
|
58
|
+
checkout_url: session.checkout_url,
|
|
59
|
+
session_id: session.session_id,
|
|
54
60
|
});
|
|
55
61
|
}));
|
|
56
62
|
|
|
57
|
-
app.post("/checkout/siglume/pay", asyncRoute(async (req, res) => {
|
|
58
|
-
const order = orders.get(String(req.body.order_id || ""));
|
|
59
|
-
if (!order) {
|
|
60
|
-
res.status(404).json({ error: "order_not_found" });
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
// In production, obtain this from the authenticated buyer's Siglume session
|
|
65
|
-
// or a hosted Siglume payment confirmation flow. Do not use a merchant secret
|
|
66
|
-
// to charge a customer wallet.
|
|
67
|
-
const siglume = new DirectRequestPaymentClient({
|
|
68
|
-
auth_token: String(req.headers.authorization || "").replace(/^Bearer\s+/i, ""),
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
const requirement = await siglume.createPaymentRequirement({
|
|
72
|
-
merchant: merchantKey,
|
|
73
|
-
amount_minor: order.amount_minor,
|
|
74
|
-
currency: order.currency,
|
|
75
|
-
challenge: String(req.body.siglume_challenge || ""),
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
res.json({ requirement });
|
|
79
|
-
}));
|
|
80
|
-
|
|
81
63
|
app.post("/siglume/webhook", express.raw({ type: "application/json" }), asyncRoute(async (req, res) => {
|
|
82
64
|
const header = String(req.headers["siglume-signature"] || "");
|
|
83
65
|
const { event } = await verifyDirectRequestPaymentWebhook(
|