@siglume/direct-request-payment 0.4.20 → 0.4.22
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 +25 -0
- package/README.md +8 -3
- package/bin/siglume-sdrp.mjs +416 -5
- package/dist/index.cjs +13 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +13 -3
- package/dist/index.js.map +1 -1
- package/docs/api-reference.md +3 -0
- package/docs/pricing.md +1 -1
- package/docs/quickstart-10-minutes.md +90 -9
- package/docs/sandbox.md +60 -0
- package/docs/troubleshooting.md +11 -3
- package/examples/hosted-checkout-python/pyproject.toml +1 -1
- package/package.json +10 -2
- package/templates/express/README.md +16 -2
- package/templates/express/siglume-order-store.sql.ts +585 -0
- package/templates/fastapi/README.md +18 -3
- package/templates/fastapi/siglume_order_store_sqlalchemy.py +313 -0
|
@@ -11,7 +11,43 @@ The SDK supplies the readiness check, route files, webhook verification, payment
|
|
|
11
11
|
classification, and the order-store adapter contract. Your app supplies the
|
|
12
12
|
real order lookup and fulfillment writes.
|
|
13
13
|
|
|
14
|
-
## 0.
|
|
14
|
+
## 0. Run the sandbox first
|
|
15
|
+
|
|
16
|
+
Do this before touching live Siglume credentials. The local sandbox is a tiny
|
|
17
|
+
Siglume-compatible API server bundled with the SDK. It creates fake checkout
|
|
18
|
+
sessions, signs webhooks with your sandbox secret, records delivery status, and
|
|
19
|
+
never charges a wallet.
|
|
20
|
+
|
|
21
|
+
In one terminal, point it at your product's local webhook route:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npx siglume-sdrp sandbox \
|
|
25
|
+
--origin http://localhost:3000 \
|
|
26
|
+
--webhook-url http://localhost:3000/payments/webhooks/siglume
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Use the values it prints in your product `.env`:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
SIGLUME_ENV=sandbox
|
|
33
|
+
SIGLUME_API_BASE=http://127.0.0.1:8787/v1
|
|
34
|
+
SIGLUME_MERCHANT_AUTH_TOKEN=sandbox_merchant_token
|
|
35
|
+
SIGLUME_DIRECT_PAYMENT_MERCHANT=sandbox_merchant
|
|
36
|
+
SHOP_PUBLIC_ORIGIN=http://localhost:3000
|
|
37
|
+
SHOP_WEBHOOK_URL=http://localhost:3000/payments/webhooks/siglume
|
|
38
|
+
SIGLUME_WEBHOOK_SECRET=whsec_sandbox_local
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Then run:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
npx siglume-check readiness --sandbox
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
The sandbox readiness check proves your local server can receive a signed
|
|
48
|
+
`direct_payment.confirmed` delivery before you use live credentials.
|
|
49
|
+
|
|
50
|
+
## 1. Live readiness
|
|
15
51
|
|
|
16
52
|
Install the SDK in your product.
|
|
17
53
|
|
|
@@ -64,7 +100,7 @@ npx siglume-check readiness --no-api --json
|
|
|
64
100
|
human web checkout path, run readiness without `--no-api` and fix every FAIL
|
|
65
101
|
item.
|
|
66
102
|
|
|
67
|
-
##
|
|
103
|
+
## 2. Copy integration files into your product
|
|
68
104
|
|
|
69
105
|
For Express:
|
|
70
106
|
|
|
@@ -81,7 +117,7 @@ siglume-sdrp init fastapi --target app/siglume
|
|
|
81
117
|
These commands copy framework-specific route files into your codebase. The
|
|
82
118
|
generated files are intentionally small and are meant to be edited.
|
|
83
119
|
|
|
84
|
-
##
|
|
120
|
+
## 3. Mount the routes
|
|
85
121
|
|
|
86
122
|
Express:
|
|
87
123
|
|
|
@@ -125,7 +161,7 @@ app.include_router(
|
|
|
125
161
|
)
|
|
126
162
|
```
|
|
127
163
|
|
|
128
|
-
##
|
|
164
|
+
## 4. Adapter responsibilities
|
|
129
165
|
|
|
130
166
|
Replace the example store with your product's order database. The adapter must:
|
|
131
167
|
|
|
@@ -146,7 +182,51 @@ Micro / Nano, checkout returns `METERED_INTEGRATION_REQUIRED` until you set
|
|
|
146
182
|
fulfilled-but-unsettled state, settlement reconciliation, past-due handling, and
|
|
147
183
|
terminal write-off handling.
|
|
148
184
|
|
|
149
|
-
##
|
|
185
|
+
## 5. Use a real database adapter
|
|
186
|
+
|
|
187
|
+
The copied files include durable database adapters. Use these before opening
|
|
188
|
+
checkout to users; the `*.example.*` stores are only for reading the interface.
|
|
189
|
+
|
|
190
|
+
Express:
|
|
191
|
+
|
|
192
|
+
```ts
|
|
193
|
+
import {
|
|
194
|
+
createPrismaSiglumeOrderStore,
|
|
195
|
+
createTypeOrmSiglumeOrderStore,
|
|
196
|
+
createSequelizeSiglumeOrderStore,
|
|
197
|
+
createDrizzleSiglumeOrderStore,
|
|
198
|
+
} from "./siglume/siglume-order-store.sql.js";
|
|
199
|
+
|
|
200
|
+
const order_store = createPrismaSiglumeOrderStore(prisma, {
|
|
201
|
+
dialect: "postgres",
|
|
202
|
+
orders_table: "orders",
|
|
203
|
+
order_id_column: "id",
|
|
204
|
+
amount_minor_column: "amount_minor",
|
|
205
|
+
currency_column: "currency",
|
|
206
|
+
});
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
FastAPI:
|
|
210
|
+
|
|
211
|
+
```py
|
|
212
|
+
from sqlalchemy.orm import sessionmaker
|
|
213
|
+
from .siglume.siglume_order_store_sqlalchemy import (
|
|
214
|
+
SQLAlchemySiglumeOrderStore,
|
|
215
|
+
create_sqlalchemy_engine,
|
|
216
|
+
create_sqlalchemy_siglume_schema,
|
|
217
|
+
)
|
|
218
|
+
|
|
219
|
+
engine = create_sqlalchemy_engine(os.environ["DATABASE_URL"])
|
|
220
|
+
create_sqlalchemy_siglume_schema(engine)
|
|
221
|
+
SessionLocal = sessionmaker(engine, future=True)
|
|
222
|
+
order_store = SQLAlchemySiglumeOrderStore(SessionLocal)
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
The adapters persist one checkout attempt per order, reuse the checkout URL on
|
|
226
|
+
retries, record webhook event ids only after the order update/review write
|
|
227
|
+
succeeds, and keep duplicate deliveries from double-fulfilling an order.
|
|
228
|
+
|
|
229
|
+
## 6. Start checkout from your frontend
|
|
150
230
|
|
|
151
231
|
Call your own server route:
|
|
152
232
|
|
|
@@ -158,16 +238,17 @@ curl -X POST https://api.your-product.example/payments/checkout/siglume/start \
|
|
|
158
238
|
|
|
159
239
|
Redirect the shopper to the returned `checkout_url`.
|
|
160
240
|
|
|
161
|
-
##
|
|
241
|
+
## 7. Done means
|
|
162
242
|
|
|
163
243
|
Your product is integrated when:
|
|
164
244
|
|
|
165
|
-
- `npx siglume-check readiness` passes,
|
|
245
|
+
- `npx siglume-check readiness --sandbox` passes against your local product,
|
|
246
|
+
- `npx siglume-check readiness` passes against live Siglume credentials,
|
|
166
247
|
- your product has mounted checkout and webhook routes,
|
|
167
|
-
- your order database
|
|
248
|
+
- your order database uses the SQL/ORM adapter or an equivalent transactional store,
|
|
168
249
|
- the signed webhook verifies against the raw body,
|
|
169
250
|
- `standard_settled` marks the order paid once,
|
|
170
|
-
- duplicate webhook deliveries do not double-fulfill the order.
|
|
251
|
+
- a failed webhook handler is retried and duplicate webhook deliveries do not double-fulfill the order.
|
|
171
252
|
|
|
172
253
|
For Micro / Nano revenue reconciliation, read
|
|
173
254
|
[Payment lifecycle](./payment-lifecycle.md) and
|
package/docs/sandbox.md
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# SDRP Sandbox
|
|
2
|
+
|
|
3
|
+
Use the SDK sandbox before live Siglume credentials. It is a local
|
|
4
|
+
Siglume-compatible API server for product integration testing. It creates fake
|
|
5
|
+
checkout sessions, signs `direct_payment.confirmed` webhooks, records delivery
|
|
6
|
+
status, and never charges a wallet.
|
|
7
|
+
|
|
8
|
+
Start your product locally first, then run:
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npx siglume-sdrp sandbox \
|
|
12
|
+
--origin http://localhost:3000 \
|
|
13
|
+
--webhook-url http://localhost:3000/payments/webhooks/siglume
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Set the printed environment variables in your product:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
SIGLUME_ENV=sandbox
|
|
20
|
+
SIGLUME_API_BASE=http://127.0.0.1:8787/v1
|
|
21
|
+
SIGLUME_MERCHANT_AUTH_TOKEN=sandbox_merchant_token
|
|
22
|
+
SIGLUME_DIRECT_PAYMENT_MERCHANT=sandbox_merchant
|
|
23
|
+
SHOP_PUBLIC_ORIGIN=http://localhost:3000
|
|
24
|
+
SHOP_WEBHOOK_URL=http://localhost:3000/payments/webhooks/siglume
|
|
25
|
+
SIGLUME_WEBHOOK_SECRET=whsec_sandbox_local
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Then verify the integration:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npx siglume-check readiness --sandbox
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Create a checkout through your own product route:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
curl -X POST http://localhost:3000/payments/checkout/siglume/start \
|
|
38
|
+
-H "content-type: application/json" \
|
|
39
|
+
-d "{\"order_id\":\"order_123\"}"
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Open the returned `checkout_url` and click the sandbox confirm button. Your
|
|
43
|
+
product should receive a signed webhook and mark the Standard order paid once.
|
|
44
|
+
|
|
45
|
+
Sandbox Micro / Nano behavior follows the same public classifications:
|
|
46
|
+
|
|
47
|
+
- JPY 501+ / USD 3.01+ returns `standard_settled`.
|
|
48
|
+
- JPY 50-500 / USD 0.31-3.00 returns `metered_usage_accepted` with weekly Micro settlement fields.
|
|
49
|
+
- JPY 1-49 / USD 0.01-0.30 returns `metered_usage_accepted` with monthly Nano settlement fields.
|
|
50
|
+
|
|
51
|
+
The generated route defaults to Standard-only, so Micro / Nano checkout returns
|
|
52
|
+
`METERED_INTEGRATION_REQUIRED` until you explicitly enable metered handling.
|
|
53
|
+
|
|
54
|
+
Before live launch:
|
|
55
|
+
|
|
56
|
+
- run `npx siglume-check readiness --sandbox` against the local product,
|
|
57
|
+
- run the same checkout path and confirm a sandbox webhook,
|
|
58
|
+
- switch to live `SIGLUME_MERCHANT_AUTH_TOKEN`, `SIGLUME_DIRECT_PAYMENT_MERCHANT`, `SHOP_PUBLIC_ORIGIN`, `SHOP_WEBHOOK_URL`, and `SIGLUME_WEBHOOK_SECRET`,
|
|
59
|
+
- run `npx siglume-check readiness` without `--sandbox`,
|
|
60
|
+
- confirm the live webhook subscription and signing secret are for the live product URL.
|
package/docs/troubleshooting.md
CHANGED
|
@@ -11,12 +11,15 @@ Hosted Checkout is enabled account by account during beta. Check this before
|
|
|
11
11
|
building a human web checkout:
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
|
+
npx siglume-check readiness --sandbox
|
|
14
15
|
npx siglume-check readiness
|
|
15
16
|
```
|
|
16
17
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
Run `--sandbox` against the local SDK sandbox first. Then run the same command
|
|
19
|
+
without `--sandbox` against live credentials. The command validates local
|
|
20
|
+
configuration, reads the merchant account, checks the active billing mandate,
|
|
21
|
+
confirms the webhook subscription, creates one unpaid expiring checkout session,
|
|
22
|
+
and queues a signed webhook test delivery.
|
|
20
23
|
|
|
21
24
|
- The merchant account exists.
|
|
22
25
|
- The merchant billing mandate is active.
|
|
@@ -31,6 +34,11 @@ unpaid expiring checkout session, and queues a signed webhook test delivery.
|
|
|
31
34
|
`--no-api` is only for local config smoke tests. `--no-probe` is a partial API
|
|
32
35
|
check and does not report readiness as ready.
|
|
33
36
|
|
|
37
|
+
If sandbox readiness fails, make sure `SIGLUME_ENV=sandbox`,
|
|
38
|
+
`SIGLUME_API_BASE=http://127.0.0.1:8787/v1`, `SHOP_PUBLIC_ORIGIN`, and
|
|
39
|
+
`SHOP_WEBHOOK_URL` all point to your local product, and that
|
|
40
|
+
`siglume-sdrp sandbox --webhook-url ...` is still running.
|
|
41
|
+
|
|
34
42
|
If `createCheckoutSession(...)` or `getCheckoutSession(...)` raises
|
|
35
43
|
`HostedCheckoutNotAvailableError`, do not show the raw 404/409 to the buyer.
|
|
36
44
|
Stop the human checkout flow and contact Siglume support or your Siglume account
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@siglume/direct-request-payment",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.22",
|
|
4
4
|
"description": "SDK for the Siglume Direct Request Payment SDRP payment protocol",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"siglume",
|
|
@@ -79,9 +79,17 @@
|
|
|
79
79
|
"pack:check": "npm pack --json"
|
|
80
80
|
},
|
|
81
81
|
"devDependencies": {
|
|
82
|
+
"@types/express": "^5.0.6",
|
|
82
83
|
"@types/node": "^20.16.5",
|
|
84
|
+
"@types/sql.js": "^1.4.11",
|
|
85
|
+
"esbuild": "^0.28.1",
|
|
86
|
+
"express": "^5.2.1",
|
|
87
|
+
"sql.js": "^1.14.1",
|
|
83
88
|
"tsup": "^8.3.0",
|
|
84
89
|
"typescript": "^5.6.3",
|
|
85
|
-
"vitest": "^
|
|
90
|
+
"vitest": "^4.1.9"
|
|
91
|
+
},
|
|
92
|
+
"overrides": {
|
|
93
|
+
"esbuild": "^0.28.1"
|
|
86
94
|
}
|
|
87
95
|
}
|
|
@@ -10,7 +10,16 @@ import {
|
|
|
10
10
|
createSiglumeSdrpWebhookHandler,
|
|
11
11
|
type SiglumeSdrpRouterOptions,
|
|
12
12
|
} from "./siglume/siglume-sdrp-routes.js";
|
|
13
|
-
import {
|
|
13
|
+
import { createPrismaSiglumeOrderStore } from "./siglume/siglume-order-store.sql.js";
|
|
14
|
+
import { prisma } from "../db/prisma.js";
|
|
15
|
+
|
|
16
|
+
const siglumeOrderStore = createPrismaSiglumeOrderStore(prisma, {
|
|
17
|
+
dialect: "postgres",
|
|
18
|
+
orders_table: "orders",
|
|
19
|
+
order_id_column: "id",
|
|
20
|
+
amount_minor_column: "amount_minor",
|
|
21
|
+
currency_column: "currency",
|
|
22
|
+
});
|
|
14
23
|
|
|
15
24
|
const siglumeOptions: SiglumeSdrpRouterOptions = {
|
|
16
25
|
merchant: process.env.SIGLUME_DIRECT_PAYMENT_MERCHANT!,
|
|
@@ -31,7 +40,12 @@ app.use(express.json());
|
|
|
31
40
|
app.use("/payments", createSiglumeSdrpCheckoutRouter(siglumeOptions));
|
|
32
41
|
```
|
|
33
42
|
|
|
34
|
-
|
|
43
|
+
Use `siglume-order-store.sql.ts` for a durable database-backed adapter. It
|
|
44
|
+
supports Prisma, TypeORM, Sequelize, Drizzle, and any driver that can implement
|
|
45
|
+
the small `SiglumeSqlExecutor` interface. Run
|
|
46
|
+
`createSiglumeSdrpSqlSchema({ dialect: "postgres" })` once in a migration or
|
|
47
|
+
translate the returned SQL into your migration tool.
|
|
48
|
+
|
|
35
49
|
Keep `processWebhookEventOnce()` transactional: record the webhook event as
|
|
36
50
|
processed only after the order update or review write succeeds. The generated
|
|
37
51
|
route defaults to Standard-only. Enable `allow_metered_payments` only after you
|