@siglume/direct-request-payment 0.3.5 → 0.4.0
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 +75 -0
- package/README.md +142 -31
- package/dist/index.cjs +64 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +51 -1
- package/dist/index.d.ts +51 -1
- package/dist/index.js +64 -2
- package/dist/index.js.map +1 -1
- package/docs/announcement-ja.md +43 -6
- package/docs/api-reference.md +129 -3
- package/docs/merchant-quickstart.md +141 -6
- package/docs/pricing.md +98 -15
- package/docs/security.md +27 -5
- package/examples/express-checkout.ts +4 -2
- package/examples/setup-merchant.ts +9 -1
- package/package.json +8 -3
|
@@ -7,7 +7,7 @@ external merchant.
|
|
|
7
7
|
|
|
8
8
|
- Merchant server: owns the order, amount, currency, challenge secret, webhook
|
|
9
9
|
endpoint, and order fulfillment.
|
|
10
|
-
- Buyer: owns the Siglume wallet that pays the
|
|
10
|
+
- Buyer: owns the Siglume wallet that pays the on-chain payment transaction.
|
|
11
11
|
- Siglume: creates the payment requirement, prepares the wallet transaction,
|
|
12
12
|
verifies the receipt, and emits signed webhooks.
|
|
13
13
|
|
|
@@ -15,9 +15,128 @@ 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
17
|
This quickstart is for SDRP Standard Payment in an external merchant product.
|
|
18
|
-
Micro Payment and Nano Payment
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
Micro Payment and Nano Payment are applied automatically by amount and settled on
|
|
19
|
+
a weekly / monthly cadence (see [Pricing](./pricing.md#settlement-schedule)); they
|
|
20
|
+
are not browser checkout requirements you create with this SDK. Their provider
|
|
21
|
+
revenue remains unsettled until the later on-chain settlement succeeds.
|
|
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.** 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
|
+
When a person clicks "Pay with Siglume" on your site, create a session and
|
|
42
|
+
redirect them to the returned `checkout_url`. They sign into Siglume on the
|
|
43
|
+
hosted page, approve, and pay from their own wallet, then return to your
|
|
44
|
+
`success_url`. Siglume fixes the amount, currency, challenge, and return URLs
|
|
45
|
+
server-side, so the browser cannot tamper with the price or the redirect target.
|
|
46
|
+
|
|
47
|
+
Register your return-URL origins once (open-redirect defense). The origin of
|
|
48
|
+
your `webhook_callback_url` is auto-allowed in addition to these.
|
|
49
|
+
|
|
50
|
+
TypeScript:
|
|
51
|
+
|
|
52
|
+
```ts
|
|
53
|
+
import { DirectRequestPaymentMerchantClient } from "@siglume/direct-request-payment";
|
|
54
|
+
|
|
55
|
+
const merchant = new DirectRequestPaymentMerchantClient({
|
|
56
|
+
auth_token: process.env.SIGLUME_MERCHANT_AUTH_TOKEN!,
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
// Once, at setup: register the return-URL origin allowlist.
|
|
60
|
+
await merchant.setupCheckout({
|
|
61
|
+
merchant: "example_merchant",
|
|
62
|
+
display_name: "Example Merchant",
|
|
63
|
+
billing_plan: "launch",
|
|
64
|
+
billing_currency: "JPY",
|
|
65
|
+
webhook_callback_url: "https://merchant.example/siglume/webhook",
|
|
66
|
+
checkout_allowed_origins: ["https://www.example.com"],
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
// Per order: create a session and redirect the shopper to checkout_url.
|
|
70
|
+
const session = await merchant.createCheckoutSession({
|
|
71
|
+
merchant: "example_merchant",
|
|
72
|
+
amount_minor: 500, // server-fixed; the browser cannot change it
|
|
73
|
+
currency: "JPY",
|
|
74
|
+
nonce: order.id, // unique per order
|
|
75
|
+
success_url: "https://www.example.com/thanks",
|
|
76
|
+
cancel_url: "https://www.example.com/cart",
|
|
77
|
+
metadata: { order_id: order.id },
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
await orders.update(order.id, {
|
|
81
|
+
siglume_challenge_hash: session.challenge_hash,
|
|
82
|
+
siglume_payment_status: "pending",
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
redirect(session.checkout_url); // -> https://siglume.com/pay/<session_id>
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Python:
|
|
89
|
+
|
|
90
|
+
```py
|
|
91
|
+
import os
|
|
92
|
+
|
|
93
|
+
from siglume_direct_request_payment import DirectRequestPaymentMerchantClient
|
|
94
|
+
|
|
95
|
+
merchant = DirectRequestPaymentMerchantClient(
|
|
96
|
+
auth_token=os.environ["SIGLUME_MERCHANT_AUTH_TOKEN"],
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
# Once, at setup: register the return-URL origin allowlist.
|
|
100
|
+
merchant.setup_checkout(
|
|
101
|
+
merchant="example_merchant",
|
|
102
|
+
display_name="Example Merchant",
|
|
103
|
+
billing_plan="launch",
|
|
104
|
+
billing_currency="JPY",
|
|
105
|
+
webhook_callback_url="https://merchant.example/siglume/webhook",
|
|
106
|
+
checkout_allowed_origins=["https://www.example.com"],
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
# Per order: create a session and redirect the shopper to checkout_url.
|
|
110
|
+
session = merchant.create_checkout_session(
|
|
111
|
+
merchant="example_merchant",
|
|
112
|
+
amount_minor=500, # server-fixed; the browser cannot change it
|
|
113
|
+
currency="JPY",
|
|
114
|
+
nonce=order["id"], # unique per order
|
|
115
|
+
success_url="https://www.example.com/thanks",
|
|
116
|
+
cancel_url="https://www.example.com/cart",
|
|
117
|
+
metadata={"order_id": order["id"]},
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
orders.update(
|
|
121
|
+
order["id"],
|
|
122
|
+
{
|
|
123
|
+
"siglume_challenge_hash": session["challenge_hash"],
|
|
124
|
+
"siglume_payment_status": "pending",
|
|
125
|
+
},
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
# Redirect the shopper to session["checkout_url"]
|
|
129
|
+
# -> https://siglume.com/pay/<session_id>
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Fulfill exactly as in [section 4](#4-fulfill-from-webhook): on the signed
|
|
133
|
+
`direct_payment.confirmed` webhook, look up the order by `challenge_hash` and
|
|
134
|
+
mark it paid once. The session is single-use and expires (~30 minutes); you can
|
|
135
|
+
poll `getCheckoutSession` / `get_checkout_session` if you also want to show
|
|
136
|
+
status in your own UI, but the webhook is the source of truth. Honest framing:
|
|
137
|
+
the merchant plumbing integrates quickly, but human web payment still requires
|
|
138
|
+
the shopper to have — or create — a Siglume wallet and pay from it; it is not a
|
|
139
|
+
card-style "instant" checkout for first-time buyers.
|
|
21
140
|
|
|
22
141
|
## 1. Run Merchant Setup
|
|
23
142
|
|
|
@@ -42,7 +161,9 @@ const setup = await merchantClient.setupCheckout({
|
|
|
42
161
|
max_amount_minor: 100000,
|
|
43
162
|
});
|
|
44
163
|
|
|
45
|
-
|
|
164
|
+
// setup.env holds the merchant key plus the challenge and webhook secrets.
|
|
165
|
+
// Store them in your server-side secret manager; do not log the secret values.
|
|
166
|
+
console.log(`Configured merchant: ${setup.env.SIGLUME_DIRECT_PAYMENT_MERCHANT}`);
|
|
46
167
|
```
|
|
47
168
|
|
|
48
169
|
Python:
|
|
@@ -65,7 +186,9 @@ setup = merchant_client.setup_checkout(
|
|
|
65
186
|
max_amount_minor=100000,
|
|
66
187
|
)
|
|
67
188
|
|
|
68
|
-
|
|
189
|
+
# setup["env"] holds the merchant key plus the challenge and webhook secrets.
|
|
190
|
+
# Persist them to your server-side secret store; do not log the secret values.
|
|
191
|
+
print("Configured merchant:", setup["env"]["SIGLUME_DIRECT_PAYMENT_MERCHANT"])
|
|
69
192
|
```
|
|
70
193
|
|
|
71
194
|
`setupCheckout` / `setup_checkout` performs:
|
|
@@ -157,6 +280,18 @@ The nonce must be unique per order payment attempt and must not contain `:`.
|
|
|
157
280
|
|
|
158
281
|
## 3. Buyer Creates and Pays the Requirement
|
|
159
282
|
|
|
283
|
+
This is the AI agent / AtoA path: the buyer pays directly through
|
|
284
|
+
`DirectRequestPaymentClient` (or the marketplace tool
|
|
285
|
+
`market_confirm_direct_payment_and_execute`), rather than through Hosted
|
|
286
|
+
Checkout. It assumes the buyer agent is **already connected to Siglume before
|
|
287
|
+
the payment**: an AI client (Claude / ChatGPT / Cursor) connects through the
|
|
288
|
+
Siglume MCP server (OAuth authorization with a consent screen), or a custom app
|
|
289
|
+
holds the buyer's Siglume bearer token (JWT). Either way a Siglume
|
|
290
|
+
authentication context is established first — the merchant SDK does not log the
|
|
291
|
+
buyer in. Unattended runs are bounded by Siglume's approval gates / spending
|
|
292
|
+
budgets (per-run / daily / monthly auto-pay budgets, or Works approval), not by
|
|
293
|
+
the merchant.
|
|
294
|
+
|
|
160
295
|
After the buyer authenticates with Siglume, create the payment requirement with
|
|
161
296
|
the buyer's Siglume bearer token. Do not use a Developer Portal `cli_` API key
|
|
162
297
|
or merchant API key here.
|
package/docs/pricing.md
CHANGED
|
@@ -26,13 +26,14 @@ 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. |
|
|
30
|
-
| JPY 50-500 / about USD 0.30-3.00 | Micro Payment |
|
|
31
|
-
| Under JPY 1 to JPY 49 / under USD 0.01 to about USD 0.30 | Nano Payment |
|
|
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 |
|
|
30
|
+
| JPY 50-500 / about USD 0.30-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
|
+
| Under JPY 1 to JPY 49 / under USD 0.01 to about 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
|
-
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
Standard Payment settles per payment. Micro Payment and Nano Payment are
|
|
34
|
+
aggregated and settled on a fixed weekly / monthly cadence — see
|
|
35
|
+
[Settlement schedule](#settlement-schedule) for exactly when each band closes,
|
|
36
|
+
when revenue becomes settled, and how rejected requests behave.
|
|
36
37
|
|
|
37
38
|
USD pricing is the JPY tier converted at roughly 160 JPY/USD and rounded to
|
|
38
39
|
clean price points that keep the same 1:3:10 tier ratio.
|
|
@@ -41,21 +42,95 @@ If no paid plan is selected during merchant setup, the merchant account uses the
|
|
|
41
42
|
Launch plan. A merchant billing mandate is still required before accepting
|
|
42
43
|
payments so Siglume can collect the monthly base fee automatically.
|
|
43
44
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
included a free monthly allowance of 100 payments; that allowance has been
|
|
48
|
-
retired — the platform `fee_bps` response is always the source of truth.)
|
|
49
|
-
|
|
50
|
-
Per-payment fees are collected during payment settlement through the
|
|
51
|
-
DirectPaymentHub split. The merchant receives the net amount after that fee.
|
|
52
|
-
Monthly base fees are collected separately through the merchant billing mandate.
|
|
45
|
+
Per-payment fees are deducted at settlement, so the merchant receives the net
|
|
46
|
+
amount for each payment. Monthly base fees are collected separately through the
|
|
47
|
+
merchant billing mandate.
|
|
53
48
|
|
|
54
49
|
The same fee schedule applies in JPY and USD. The Siglume platform returns
|
|
55
50
|
`fee_bps` in the merchant's settlement currency on every payment requirement, so
|
|
56
51
|
the SDK never has to know which currency table to read — it just trusts the
|
|
57
52
|
value Siglume returns.
|
|
58
53
|
|
|
54
|
+
## Settlement schedule
|
|
55
|
+
|
|
56
|
+
Standard Payment, Micro Payment, and Nano Payment differ mainly in *when* a
|
|
57
|
+
confirmed payment turns into money in your settlement wallet.
|
|
58
|
+
|
|
59
|
+
| Band | Cadence | Period | You are paid |
|
|
60
|
+
| --- | --- | --- | --- |
|
|
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 |
|
|
64
|
+
|
|
65
|
+
### Micro weekly settlement
|
|
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.
|
|
69
|
+
- **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.
|
|
72
|
+
- **Settlement.** After the week closes, Siglume aggregates that week's Micro
|
|
73
|
+
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.
|
|
77
|
+
- **Revenue recognition.** A Micro payment is final only once its weekly
|
|
78
|
+
settlement confirms on-chain. Until then it is accrued, not settled.
|
|
79
|
+
|
|
80
|
+
### Nano monthly settlement
|
|
81
|
+
|
|
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.
|
|
85
|
+
- **Timezone.** As with Micro, period boundaries use the buyer's configured
|
|
86
|
+
settlement timezone, defaulting to UTC.
|
|
87
|
+
- **Settlement.** After the month closes, Siglume aggregates that month's Nano
|
|
88
|
+
payments — grouped per buyer, payee, token, and period — into on-chain
|
|
89
|
+
settlement(s), on the next settlement pass after the period closes.
|
|
90
|
+
- **Revenue recognition.** A Nano payment is final only once its monthly
|
|
91
|
+
settlement confirms on-chain.
|
|
92
|
+
|
|
93
|
+
### Failures, retries, and carry-over
|
|
94
|
+
|
|
95
|
+
- Settlement is on-chain, so there are no banking-holiday gaps — periods close on
|
|
96
|
+
the calendar boundary regardless of weekday.
|
|
97
|
+
- If a settlement fails because of insufficient balance, insufficient allowance,
|
|
98
|
+
inactive BudgetVault authorization, a per-payout cap, or an on-chain failure,
|
|
99
|
+
the affected batch is treated as past due. Siglume currently retries every 6
|
|
100
|
+
hours for up to 28 automatic attempts. After that, the batch remains past due
|
|
101
|
+
and requires manual resolution before another attempt.
|
|
102
|
+
- While a buyer has an unresolved failed Micro/Nano settlement for the same
|
|
103
|
+
payment band and token, new Micro/Nano usage is paused with the machine-readable
|
|
104
|
+
error `METERED_SETTLEMENT_PAST_DUE`; the provider API is not called.
|
|
105
|
+
- Outstanding amounts remain attached to the failed settlement and are retried
|
|
106
|
+
under this policy. They are not settled revenue, and Siglume does not advance,
|
|
107
|
+
guarantee, or insure provider revenue before on-chain settlement succeeds.
|
|
108
|
+
|
|
109
|
+
### Rejected / no-charge behavior
|
|
110
|
+
|
|
111
|
+
Micro and Nano run a budget check before the buyer's paid request is fulfilled:
|
|
112
|
+
|
|
113
|
+
- A buyer's wallet budget is consumed at the **gross amount** (your price plus
|
|
114
|
+
the protocol fee), held from the moment a request is accepted until its
|
|
115
|
+
settlement confirms.
|
|
116
|
+
- If the buyer's budget, scope, or amount band does not allow a request, it is
|
|
117
|
+
**rejected with no charge**: the request is not fulfilled, no amount is
|
|
118
|
+
accrued, and nothing is added to a settlement. A buyer near their budget
|
|
119
|
+
ceiling can have a request rejected even though earlier requests in the same
|
|
120
|
+
period succeeded.
|
|
121
|
+
- Treat Siglume's settled status and webhooks as the source of truth for what has
|
|
122
|
+
actually been paid.
|
|
123
|
+
|
|
124
|
+
### What is fixed vs platform-managed
|
|
125
|
+
|
|
126
|
+
The cadence is fixed: **Micro settles weekly, Nano settles monthly**, and a
|
|
127
|
+
payment is final only after its on-chain settlement confirms. The buyer-timezone
|
|
128
|
+
period boundaries and the current retry policy above are the public behavior as
|
|
129
|
+
of 2026-06-18. The scheduler lag between a period close and the on-chain
|
|
130
|
+
transaction is platform-managed; treat the platform's settlement status and
|
|
131
|
+
`fee_bps` response as authoritative rather than hard-coding local revenue
|
|
132
|
+
recognition.
|
|
133
|
+
|
|
59
134
|
## SDK Behavior
|
|
60
135
|
|
|
61
136
|
The SDK does not calculate merchant invoices or enforce plan limits locally.
|
|
@@ -72,3 +147,11 @@ The trial pricing is intended for:
|
|
|
72
147
|
- Membership services
|
|
73
148
|
- Paid API access
|
|
74
149
|
- Scheduled autopay for external merchant workflows
|
|
150
|
+
|
|
151
|
+
## Compatibility note
|
|
152
|
+
|
|
153
|
+
The Siglume API and merchant registry may still expose the legacy `billing_plan`
|
|
154
|
+
value `free` for the Launch tier. Treat `free` as a wire-compatibility key, not a
|
|
155
|
+
public plan name. (Until 2026-06-12 the Launch plan included a free monthly
|
|
156
|
+
allowance of 100 payments; that allowance has been retired — the platform
|
|
157
|
+
`fee_bps` response is always the source of truth.)
|
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:
|
|
@@ -106,9 +123,14 @@ Direct Request Payment is not:
|
|
|
106
123
|
- escrow
|
|
107
124
|
- a platform balance
|
|
108
125
|
- a card payment fallback
|
|
109
|
-
- the Micro Payment or Nano Payment meter
|
|
110
126
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
127
|
+
Each payment is an individual wallet payment backed by an on-chain receipt. Small
|
|
128
|
+
payments in the Micro and Nano amount bands are aggregated and settled on a
|
|
129
|
+
weekly / monthly cadence instead of one transaction at a time (see the
|
|
130
|
+
[pricing guide](./pricing.md#settlement-schedule)), but they are still wallet
|
|
131
|
+
payments, not a stored balance. Before a small payment is fulfilled, Siglume
|
|
132
|
+
checks the buyer's wallet budget and fails closed when it is invalid, so a
|
|
133
|
+
rejected request is never charged. Provider revenue for Micro and Nano remains
|
|
134
|
+
unsettled until the weekly or monthly on-chain settlement succeeds; Siglume does
|
|
135
|
+
not advance or guarantee revenue when a buyer's balance, allowance, BudgetVault
|
|
136
|
+
authorization, cap, or on-chain transaction fails.
|
|
@@ -99,8 +99,10 @@ app.post("/siglume/webhook", express.raw({ type: "application/json" }), asyncRou
|
|
|
99
99
|
}));
|
|
100
100
|
|
|
101
101
|
app.use((error: unknown, _req: express.Request, res: express.Response, _next: express.NextFunction) => {
|
|
102
|
-
|
|
103
|
-
|
|
102
|
+
// Log the detail server-side; never return raw error messages to the client —
|
|
103
|
+
// a payment error can otherwise leak internal API details or configuration.
|
|
104
|
+
console.error("checkout error:", error);
|
|
105
|
+
res.status(500).json({ error: "internal_error" });
|
|
104
106
|
});
|
|
105
107
|
|
|
106
108
|
app.listen(port);
|
|
@@ -14,4 +14,12 @@ const setup = await merchant.setupCheckout({
|
|
|
14
14
|
create_webhook_subscription: Boolean(process.env.SIGLUME_DIRECT_PAYMENT_WEBHOOK_URL),
|
|
15
15
|
});
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
// setup.env contains the merchant key PLUS the challenge and webhook secrets.
|
|
18
|
+
// Store these in your server-side secret manager. Never log the secret values —
|
|
19
|
+
// log only non-secret confirmation.
|
|
20
|
+
const env = setup.env ?? {};
|
|
21
|
+
console.log("Merchant configured:", {
|
|
22
|
+
merchant: env.SIGLUME_DIRECT_PAYMENT_MERCHANT,
|
|
23
|
+
challenge_secret: env.SIGLUME_DIRECT_PAYMENT_CHALLENGE_SECRET ? "****" : undefined,
|
|
24
|
+
webhook_secret: env.SIGLUME_WEBHOOK_SECRET ? "****" : undefined,
|
|
25
|
+
});
|
package/package.json
CHANGED
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@siglume/direct-request-payment",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "SDK for the Siglume Direct Request Payment SDRP payment protocol",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"siglume",
|
|
7
|
+
"sdrp",
|
|
8
|
+
"direct-request-payment",
|
|
7
9
|
"payment",
|
|
8
|
-
"
|
|
9
|
-
"
|
|
10
|
+
"micropayments",
|
|
11
|
+
"metered-billing",
|
|
10
12
|
"wallet",
|
|
13
|
+
"jpyc",
|
|
14
|
+
"usdc",
|
|
15
|
+
"checkout",
|
|
11
16
|
"sdk"
|
|
12
17
|
],
|
|
13
18
|
"license": "MIT",
|