@siglume/direct-request-payment 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Siglume Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,237 @@
1
+ # @siglume/direct-request-payment
2
+
3
+ Merchant SDK for Siglume Direct Request Payment checkout integrations.
4
+
5
+ Use this package when an external EC site, booking service, membership service,
6
+ or paid API wants to accept Siglume wallet payments without taking custody of
7
+ customer funds.
8
+
9
+ This SDK is intentionally separate from `@siglume/api-sdk`:
10
+
11
+ - `@siglume/api-sdk` is for publishing agent-facing APIs to the Siglume API Store.
12
+ - `@siglume/direct-request-payment` is for external merchants integrating
13
+ Siglume Direct Request Payment into their own checkout.
14
+
15
+ ## Install
16
+
17
+ ```bash
18
+ npm install @siglume/direct-request-payment
19
+ ```
20
+
21
+ ```bash
22
+ pip install siglume-direct-request-payment
23
+ ```
24
+
25
+ Node.js 18 or later is required for the TypeScript SDK. Python 3.11 or later is
26
+ required for the Python SDK.
27
+
28
+ ## Current Platform Contract
29
+
30
+ The public product name is **Siglume Direct Request Payment**. The current
31
+ platform payload still uses the internal mode name `external_402`; this SDK sets
32
+ that value for you when creating a payment requirement.
33
+
34
+ Payment requirement creation must run in the authenticated buyer's Siglume
35
+ context. Your merchant server must not use a merchant secret or API key to
36
+ charge a customer wallet. The merchant server creates the signed challenge; the
37
+ buyer-facing Siglume payment flow creates and pays the requirement.
38
+
39
+ `DirectRequestPaymentClient` requires the buyer's Siglume bearer token. Do not
40
+ use a Developer Portal `cli_` API key with this package.
41
+
42
+ ## Trial Pricing
43
+
44
+ Siglume Direct Request Payment is currently offered with trial-phase merchant
45
+ pricing designed for small EC sites, booking services, membership services, paid
46
+ APIs, and agent-to-agent payment experiments.
47
+
48
+ | Plan | Monthly fee | Payment fee |
49
+ | --- | ---: | ---: |
50
+ | Launch | JPY 0 | 0% through 100 payments/month, then 1.8% |
51
+ | Starter | JPY 980 | 1.0% |
52
+ | Growth | JPY 2,980 | 0.7% |
53
+ | Pro | JPY 9,800 | 0.5% |
54
+
55
+ The minimum fee is JPY 3 for each fee-bearing payment, including Launch-plan
56
+ payments after the included monthly allowance. A merchant billing mandate is
57
+ required before accepting payments, even on the Launch plan. The API and merchant
58
+ registry may still expose the internal plan key `free` for this tier. See
59
+ [docs/pricing.md](./docs/pricing.md) for details.
60
+
61
+ Per-payment fees are deducted at payment settlement time, so the merchant
62
+ receives the net amount. Monthly base fees are collected through the merchant
63
+ billing mandate. The listed public pricing is JPY-denominated; USD/USDC merchant
64
+ billing requires separately agreed terms.
65
+
66
+ ## Merchant Server: Create a Challenge
67
+
68
+ ```ts
69
+ import { createDirectRequestPaymentChallenge } from "@siglume/direct-request-payment";
70
+
71
+ const challenge = await createDirectRequestPaymentChallenge({
72
+ merchant: "example_merchant",
73
+ amount_minor: 1200,
74
+ currency: "JPY",
75
+ secret: process.env.SIGLUME_DIRECT_PAYMENT_CHALLENGE_SECRET!,
76
+ nonce: "order_123-attempt_1",
77
+ });
78
+
79
+ // Return only challenge.challenge to the buyer-facing checkout.
80
+ // Never return the challenge secret to the browser.
81
+ console.log(challenge.challenge);
82
+ ```
83
+
84
+ ```py
85
+ import os
86
+
87
+ from siglume_direct_request_payment import create_direct_request_payment_challenge
88
+
89
+ challenge = create_direct_request_payment_challenge(
90
+ merchant="example_merchant",
91
+ amount_minor=1200,
92
+ currency="JPY",
93
+ secret=os.environ["SIGLUME_DIRECT_PAYMENT_CHALLENGE_SECRET"],
94
+ nonce="order_123-attempt_1",
95
+ )
96
+
97
+ print(challenge["challenge"])
98
+ ```
99
+
100
+ The signed challenge binds:
101
+
102
+ - merchant key
103
+ - amount in minor units
104
+ - currency
105
+ - nonce
106
+
107
+ Changing any of those values invalidates the challenge.
108
+ The nonce must not contain `:` because the current platform challenge format is
109
+ `scheme:nonce:signature`.
110
+
111
+ ## Buyer Payment Flow
112
+
113
+ Use `DirectRequestPaymentClient` only with the authenticated buyer's Siglume
114
+ bearer token. `SIGLUME_AUTH_TOKEN` may be used in server-side payment-confirmation
115
+ helpers; `SIGLUME_API_KEY` and Developer Portal `cli_` keys are not accepted.
116
+
117
+ ```ts
118
+ import { DirectRequestPaymentClient } from "@siglume/direct-request-payment";
119
+
120
+ const siglume = new DirectRequestPaymentClient({
121
+ auth_token: buyerSiglumeBearerToken,
122
+ });
123
+
124
+ const requirement = await siglume.createPaymentRequirement({
125
+ merchant: "example_merchant",
126
+ amount_minor: 1200,
127
+ currency: "JPY",
128
+ challenge: challengeFromMerchantServer,
129
+ });
130
+
131
+ if (requirement.approve_transaction_request) {
132
+ await siglume.executeAllowanceTransaction(requirement, { await_finality: true });
133
+ }
134
+
135
+ const payment = await siglume.executePaymentTransaction(requirement, {
136
+ await_finality: true,
137
+ });
138
+
139
+ const receiptId = String(payment.receipt?.receipt_id ?? "");
140
+ const verified = await siglume.verifyPaymentRequirement(requirement.requirement_id, {
141
+ receipt_id: receiptId,
142
+ await_finality: false,
143
+ });
144
+
145
+ console.log(verified.status);
146
+ ```
147
+
148
+ ```py
149
+ from siglume_direct_request_payment import DirectRequestPaymentClient
150
+
151
+ siglume = DirectRequestPaymentClient(auth_token=buyer_siglume_bearer_token)
152
+
153
+ requirement = siglume.create_payment_requirement(
154
+ merchant="example_merchant",
155
+ amount_minor=1200,
156
+ currency="JPY",
157
+ challenge=challenge_from_merchant_server,
158
+ )
159
+
160
+ if requirement.get("approve_transaction_request"):
161
+ siglume.execute_allowance_transaction(requirement, await_finality=True)
162
+
163
+ payment = siglume.execute_payment_transaction(requirement, await_finality=True)
164
+ receipt_id = str((payment.get("receipt") or {}).get("receipt_id") or "")
165
+
166
+ verified = siglume.verify_payment_requirement(
167
+ requirement["requirement_id"],
168
+ receipt_id=receipt_id,
169
+ await_finality=False,
170
+ )
171
+
172
+ print(verified["status"])
173
+ ```
174
+
175
+ ## Webhooks
176
+
177
+ Your merchant system should treat Siglume webhooks as the durable delivery
178
+ signal. Always verify the signature against the raw request body before trusting
179
+ the payload. Create a marketplace webhook subscription with
180
+ `POST /v1/market/webhooks/subscriptions`; the response returns the `whsec_`
181
+ signing secret once.
182
+
183
+ ```ts
184
+ import { verifyDirectRequestPaymentWebhook } from "@siglume/direct-request-payment";
185
+
186
+ const { event } = await verifyDirectRequestPaymentWebhook(
187
+ process.env.SIGLUME_WEBHOOK_SECRET!,
188
+ rawRequestBody,
189
+ request.headers["siglume-signature"],
190
+ );
191
+
192
+ if (event.type === "direct_payment.confirmed") {
193
+ // Mark the order paid if event.data.challenge_hash/order mapping matches.
194
+ }
195
+ ```
196
+
197
+ ```py
198
+ import os
199
+
200
+ from siglume_direct_request_payment import verify_direct_request_payment_webhook
201
+
202
+ verified = verify_direct_request_payment_webhook(
203
+ os.environ["SIGLUME_WEBHOOK_SECRET"],
204
+ raw_request_body,
205
+ siglume_signature_header,
206
+ )
207
+
208
+ if verified["event"]["type"] == "direct_payment.confirmed":
209
+ # Mark the order paid if event.data.challenge_hash/order mapping matches.
210
+ pass
211
+ ```
212
+
213
+ ## Security Rules
214
+
215
+ - Keep the challenge secret on the merchant server only.
216
+ - Keep merchant order amount and currency server-authored.
217
+ - Use one nonce per order payment attempt.
218
+ - Store `challenge_hash` with the order and reject mismatches.
219
+ - Make order fulfillment idempotent by `requirement_id` and order id.
220
+ - Verify webhook signatures against the raw body.
221
+ - Do not use a merchant token to charge a customer wallet.
222
+ - Do not treat Direct Request Payment as stored value, prepaid points, escrow, or
223
+ a platform balance.
224
+
225
+ Read [docs/security.md](./docs/security.md) before going live.
226
+
227
+ ## Documentation
228
+
229
+ - [Merchant quickstart](./docs/merchant-quickstart.md)
230
+ - [API reference](./docs/api-reference.md)
231
+ - [Pricing](./docs/pricing.md)
232
+ - [Security guide](./docs/security.md)
233
+ - [Express checkout example](./examples/express-checkout.ts)
234
+
235
+ ## License
236
+
237
+ MIT