@downcity/services 0.1.67 → 0.1.69

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.
Files changed (55) hide show
  1. package/bin/accounts/index.d.ts +1 -5
  2. package/bin/accounts/index.d.ts.map +1 -1
  3. package/bin/accounts/index.js +1 -4
  4. package/bin/accounts/index.js.map +1 -1
  5. package/bin/balance/index.d.ts +1 -1
  6. package/bin/balance/index.d.ts.map +1 -1
  7. package/bin/balance/index.js +1 -1
  8. package/bin/balance/index.js.map +1 -1
  9. package/bin/balance/service.d.ts +0 -4
  10. package/bin/balance/service.d.ts.map +1 -1
  11. package/bin/balance/service.js +0 -6
  12. package/bin/balance/service.js.map +1 -1
  13. package/bin/billing/index.d.ts +1 -1
  14. package/bin/billing/index.d.ts.map +1 -1
  15. package/bin/billing/index.js +1 -1
  16. package/bin/billing/index.js.map +1 -1
  17. package/bin/billing/service.d.ts +0 -4
  18. package/bin/billing/service.d.ts.map +1 -1
  19. package/bin/billing/service.js +0 -6
  20. package/bin/billing/service.js.map +1 -1
  21. package/bin/index.d.ts +6 -6
  22. package/bin/index.d.ts.map +1 -1
  23. package/bin/index.js +5 -5
  24. package/bin/index.js.map +1 -1
  25. package/bin/payment/helpers.d.ts +68 -0
  26. package/bin/payment/helpers.d.ts.map +1 -0
  27. package/bin/payment/helpers.js +148 -0
  28. package/bin/payment/helpers.js.map +1 -0
  29. package/bin/payment/index.d.ts +10 -28
  30. package/bin/payment/index.d.ts.map +1 -1
  31. package/bin/payment/index.js +9 -890
  32. package/bin/payment/index.js.map +1 -1
  33. package/bin/payment/providers.d.ts +25 -0
  34. package/bin/payment/providers.d.ts.map +1 -0
  35. package/bin/payment/providers.js +415 -0
  36. package/bin/payment/providers.js.map +1 -0
  37. package/bin/payment/routes.d.ts +29 -0
  38. package/bin/payment/routes.d.ts.map +1 -0
  39. package/bin/payment/routes.js +394 -0
  40. package/bin/payment/routes.js.map +1 -0
  41. package/bin/payment/service.d.ts +448 -0
  42. package/bin/payment/service.d.ts.map +1 -0
  43. package/bin/payment/service.js +72 -0
  44. package/bin/payment/service.js.map +1 -0
  45. package/bin/payment/types.d.ts +11 -18
  46. package/bin/payment/types.d.ts.map +1 -1
  47. package/bin/usage/index.d.ts +3 -174
  48. package/bin/usage/index.d.ts.map +1 -1
  49. package/bin/usage/index.js +2 -117
  50. package/bin/usage/index.js.map +1 -1
  51. package/bin/usage/service.d.ts +353 -0
  52. package/bin/usage/service.d.ts.map +1 -0
  53. package/bin/usage/service.js +140 -0
  54. package/bin/usage/service.js.map +1 -0
  55. package/package.json +2 -2
@@ -0,0 +1,394 @@
1
+ /**
2
+ * Payment 服务路由与事件处理。
3
+ *
4
+ * 关键点(中文)
5
+ * - 被 PaymentService.install() 调用,完成所有 /v1/payment/* 路由注册。
6
+ * - 所有 balance 交互通过传入的 service 对象进行,不直接依赖 BalanceService 类型。
7
+ */
8
+ import { resolvePaymentRedirectURL } from "./redirect.js";
9
+ import { errorMessage, htmlResponse, normalizeOptionalText, normalizeRequired, randomId, renderRedirectPage, } from "./helpers.js";
10
+ /**
11
+ * 注册 Payment 服务路由。
12
+ */
13
+ export function installPaymentRoutes(service, ctx) {
14
+ const providers = service.getProviders();
15
+ const payments = ctx.table("payments");
16
+ const events = ctx.table("events");
17
+ ctx.route({
18
+ method: "GET",
19
+ path: "/methods",
20
+ auth: [],
21
+ handler(requestCtx) {
22
+ return requestCtx.jsonResponse({
23
+ items: providers.map((provider) => provider.method(ctx)),
24
+ });
25
+ },
26
+ });
27
+ ctx.route({
28
+ method: "POST",
29
+ path: "/checkout/create",
30
+ auth: ["user"],
31
+ async handler(requestCtx) {
32
+ const body = await requestCtx.json();
33
+ const provider = readProvider(providers, body.method_id || body.provider);
34
+ const method = provider.method(ctx);
35
+ if (!method.enabled) {
36
+ const reason = method.reason ? `: ${method.reason}` : "";
37
+ return requestCtx.jsonResponse({ error: `Payment provider ${provider.id} is disabled${reason}` }, 400);
38
+ }
39
+ const userId = normalizeRequired(requestCtx.user?.user_id, "user_id");
40
+ const topup = await service.readTopup(normalizeRequired(body.topup_id, "topup_id"));
41
+ if (topup.user_id !== userId) {
42
+ return requestCtx.jsonResponse({ error: "Topup does not belong to current user" }, 403);
43
+ }
44
+ if (topup.status !== "pending") {
45
+ return requestCtx.jsonResponse({ error: `Topup is already ${topup.status}` }, 409);
46
+ }
47
+ const existing = await findActivePaymentByTopup(payments, provider.id, topup.topup_id);
48
+ if (existing)
49
+ return requestCtx.jsonResponse(toCheckoutResult(existing));
50
+ const paymentId = `pay_${randomId()}`;
51
+ const successURL = resolvePaymentRedirectURL({
52
+ path: "/v1/payment/redirect/success",
53
+ ctx,
54
+ request: requestCtx.request,
55
+ });
56
+ const cancelURL = resolvePaymentRedirectURL({
57
+ path: "/v1/payment/redirect/cancel",
58
+ ctx,
59
+ request: requestCtx.request,
60
+ });
61
+ const created = await provider.createCheckout({
62
+ payment_id: paymentId,
63
+ topup,
64
+ request: requestCtx.request,
65
+ ctx,
66
+ success_url: successURL,
67
+ cancel_url: cancelURL,
68
+ });
69
+ const now = new Date().toISOString();
70
+ const row = {
71
+ payment_id: paymentId,
72
+ provider: provider.id,
73
+ topup_id: topup.topup_id,
74
+ user_id: topup.user_id,
75
+ provider_session_id: normalizeOptionalText(created.provider_session_id),
76
+ provider_payment_id: normalizeOptionalText(created.provider_payment_id),
77
+ provider_order_id: normalizeOptionalText(created.provider_order_id),
78
+ amount: topup.amount,
79
+ currency: method.currency,
80
+ status: "pending",
81
+ checkout_url: created.checkout_url,
82
+ metadata_json: JSON.stringify({
83
+ note: topup.note,
84
+ provider: provider.id,
85
+ ...(created.metadata ?? {}),
86
+ }),
87
+ created_at: now,
88
+ updated_at: now,
89
+ };
90
+ await payments.insert(row);
91
+ return requestCtx.jsonResponse(toCheckoutResult(row));
92
+ },
93
+ });
94
+ ctx.route({
95
+ method: "GET",
96
+ path: "/payments/me",
97
+ auth: ["user"],
98
+ async handler(requestCtx) {
99
+ const userId = normalizeRequired(requestCtx.user?.user_id, "user_id");
100
+ return requestCtx.jsonResponse({ items: sortPayments(await payments.select({ user_id: userId })) });
101
+ },
102
+ });
103
+ ctx.route({
104
+ method: "GET",
105
+ path: "/payments",
106
+ auth: ["admin"],
107
+ async handler(requestCtx) {
108
+ return requestCtx.jsonResponse({ items: sortPayments(await payments.select()) });
109
+ },
110
+ });
111
+ ctx.route({
112
+ method: "GET",
113
+ path: "/events",
114
+ auth: ["admin"],
115
+ async handler(requestCtx) {
116
+ return requestCtx.jsonResponse({ items: sortEvents(await events.select()) });
117
+ },
118
+ });
119
+ ctx.route({
120
+ method: "POST",
121
+ path: "/webhook",
122
+ auth: [],
123
+ async handler(requestCtx) {
124
+ const raw = await requestCtx.text();
125
+ const provider = readWebhookProvider(providers, requestCtx.request);
126
+ let webhookEvent;
127
+ try {
128
+ webhookEvent = provider
129
+ ? await provider.parseWebhook({ raw, request: requestCtx.request, ctx })
130
+ : await autoParseWebhook(providers, { raw, request: requestCtx.request, ctx });
131
+ }
132
+ catch (error) {
133
+ return requestCtx.jsonResponse({ error: errorMessage(error) }, 400);
134
+ }
135
+ const eventProvider = provider ?? readProvider(providers, webhookEvent.meta?.provider);
136
+ const eventId = `${eventProvider.id}:${normalizeRequired(webhookEvent.event_id, "payment event id")}`;
137
+ const existing = (await events.select({ event_id: eventId }))[0];
138
+ if (existing) {
139
+ return requestCtx.jsonResponse({
140
+ received: true,
141
+ event_id: eventId,
142
+ provider: eventProvider.id,
143
+ sync_status: existing.sync_status,
144
+ });
145
+ }
146
+ await events.insert({
147
+ event_id: eventId,
148
+ provider: eventProvider.id,
149
+ type: webhookEvent.type,
150
+ payload_json: JSON.stringify(webhookEvent.payload),
151
+ sync_status: "pending",
152
+ sync_error: "",
153
+ created_at: new Date().toISOString(),
154
+ });
155
+ try {
156
+ const syncStatus = await syncPaymentEvent({
157
+ provider: eventProvider,
158
+ event: webhookEvent,
159
+ payments,
160
+ service,
161
+ });
162
+ await updateEvent(events, eventId, syncStatus, "");
163
+ return requestCtx.jsonResponse({
164
+ received: true,
165
+ event_id: eventId,
166
+ provider: eventProvider.id,
167
+ sync_status: syncStatus,
168
+ });
169
+ }
170
+ catch (error) {
171
+ const message = errorMessage(error);
172
+ await updateEvent(events, eventId, "failed", message);
173
+ return requestCtx.jsonResponse({
174
+ received: true,
175
+ event_id: eventId,
176
+ provider: eventProvider.id,
177
+ sync_status: "failed",
178
+ error: message,
179
+ }, 500);
180
+ }
181
+ },
182
+ });
183
+ ctx.route({
184
+ method: "GET",
185
+ path: "/redirect/success",
186
+ auth: [],
187
+ handler(requestCtx) {
188
+ return htmlResponse(renderRedirectPage({
189
+ title: "Payment successful",
190
+ heading: "Payment completed",
191
+ description: "Your payment has been accepted. If the balance view has not refreshed yet, close this page and return to your app.",
192
+ request: requestCtx.request,
193
+ }));
194
+ },
195
+ });
196
+ ctx.route({
197
+ method: "GET",
198
+ path: "/redirect/cancel",
199
+ auth: [],
200
+ handler(requestCtx) {
201
+ return htmlResponse(renderRedirectPage({
202
+ title: "Payment canceled",
203
+ heading: "Payment canceled",
204
+ description: "No charge was completed. You can close this page and return to your app to try again later.",
205
+ request: requestCtx.request,
206
+ }));
207
+ },
208
+ });
209
+ }
210
+ /**
211
+ * 同步 webhook 事件到本地支付记录与 balance。
212
+ */
213
+ async function syncPaymentEvent(input) {
214
+ const { provider, event, payments, service } = input;
215
+ if (event.status === "ignored")
216
+ return "ignored";
217
+ const payment = await findPaymentByWebhookEvent(payments, provider.id, event);
218
+ if (!payment)
219
+ return "ignored";
220
+ if (event.status === "paid" && payment.status === "paid")
221
+ return "applied";
222
+ if (payment.status !== "pending" && event.status !== "paid")
223
+ return "ignored";
224
+ if (event.status === "paid") {
225
+ const topup = await service.readTopup(payment.topup_id);
226
+ if (topup.status === "pending") {
227
+ await service.finishTopup(payment.topup_id, {
228
+ note: `${provider.id} topup`,
229
+ ref: event.ref || event.provider_payment_id || event.provider_order_id || event.provider_session_id || payment.provider_session_id,
230
+ meta: {
231
+ provider: provider.id,
232
+ payment_id: payment.payment_id,
233
+ provider_session_id: event.provider_session_id || payment.provider_session_id,
234
+ provider_payment_id: event.provider_payment_id || payment.provider_payment_id,
235
+ provider_order_id: event.provider_order_id || payment.provider_order_id,
236
+ ...(event.meta ?? {}),
237
+ },
238
+ });
239
+ }
240
+ }
241
+ await updatePayment(payments, payment.payment_id, {
242
+ status: event.status,
243
+ provider_session_id: event.provider_session_id || payment.provider_session_id,
244
+ provider_payment_id: event.provider_payment_id || payment.provider_payment_id,
245
+ provider_order_id: event.provider_order_id || payment.provider_order_id,
246
+ });
247
+ return "applied";
248
+ }
249
+ /**
250
+ * 根据 webhook 事件查找对应支付记录。
251
+ */
252
+ async function findPaymentByWebhookEvent(payments, provider, event) {
253
+ if (event.payment_id) {
254
+ const record = (await payments.select({ payment_id: event.payment_id, provider }))[0];
255
+ if (record)
256
+ return record;
257
+ }
258
+ if (event.provider_session_id) {
259
+ const record = (await payments.select({ provider, provider_session_id: event.provider_session_id }))[0];
260
+ if (record)
261
+ return record;
262
+ }
263
+ if (event.provider_payment_id) {
264
+ const record = (await payments.select({ provider, provider_payment_id: event.provider_payment_id }))[0];
265
+ if (record)
266
+ return record;
267
+ }
268
+ if (event.provider_order_id) {
269
+ const record = (await payments.select({ provider, provider_order_id: event.provider_order_id }))[0];
270
+ if (record)
271
+ return record;
272
+ }
273
+ if (event.topup_id)
274
+ return await findActivePaymentByTopup(payments, provider, event.topup_id);
275
+ return undefined;
276
+ }
277
+ /**
278
+ * 查找某充值单对应的最新的 pending 支付记录。
279
+ */
280
+ async function findActivePaymentByTopup(payments, provider, topupId) {
281
+ const rows = sortPayments(await payments.select({ provider, topup_id: topupId }));
282
+ return rows.find((row) => row.status === "pending");
283
+ }
284
+ /**
285
+ * 更新支付记录。
286
+ */
287
+ async function updatePayment(payments, paymentId, input) {
288
+ await payments.update({
289
+ where: { payment_id: paymentId },
290
+ values: {
291
+ status: input.status,
292
+ provider_session_id: normalizeOptionalText(input.provider_session_id),
293
+ provider_payment_id: normalizeOptionalText(input.provider_payment_id),
294
+ provider_order_id: normalizeOptionalText(input.provider_order_id),
295
+ updated_at: new Date().toISOString(),
296
+ },
297
+ });
298
+ }
299
+ /**
300
+ * 更新事件同步状态。
301
+ */
302
+ async function updateEvent(events, eventId, syncStatus, syncError) {
303
+ await events.update({
304
+ where: { event_id: eventId },
305
+ values: {
306
+ sync_status: syncStatus,
307
+ sync_error: syncError.trim(),
308
+ },
309
+ });
310
+ }
311
+ /**
312
+ * 把 payment 行转成 checkout 创建结果。
313
+ */
314
+ function toCheckoutResult(row) {
315
+ return {
316
+ payment_id: row.payment_id,
317
+ provider: row.provider,
318
+ topup_id: row.topup_id,
319
+ provider_session_id: row.provider_session_id,
320
+ provider_payment_id: row.provider_payment_id,
321
+ provider_order_id: row.provider_order_id,
322
+ checkout_url: row.checkout_url,
323
+ status: row.status,
324
+ };
325
+ }
326
+ /**
327
+ * 读取指定 provider。
328
+ */
329
+ function readProvider(providers, value) {
330
+ const id = normalizeOptionalText(value);
331
+ if (!id)
332
+ throw new TypeError("payment method_id is required");
333
+ const provider = providers.find((item) => item.id === id);
334
+ if (!provider)
335
+ throw new Error(`Payment provider ${id} is not available`);
336
+ return provider;
337
+ }
338
+ /**
339
+ * 根据请求特征识别 webhook 来源 provider。
340
+ */
341
+ function readWebhookProvider(providers, request) {
342
+ const url = new URL(request.url);
343
+ const explicit = normalizeOptionalText(url.searchParams.get("provider"));
344
+ if (explicit)
345
+ return readProvider(providers, explicit);
346
+ if (request.headers.has("stripe-signature"))
347
+ return providers.find((provider) => provider.id === "stripe");
348
+ if (request.headers.has("creem-signature"))
349
+ return providers.find((provider) => provider.id === "creem");
350
+ if (request.headers.has("x-waffo-signature"))
351
+ return providers.find((provider) => provider.id === "waffo");
352
+ if (request.headers.has("webhook-signature") || request.headers.has("svix-signature")) {
353
+ return providers.find((provider) => provider.id === "dodo");
354
+ }
355
+ return undefined;
356
+ }
357
+ /**
358
+ * 自动尝试所有 provider 解析 webhook。
359
+ */
360
+ async function autoParseWebhook(providers, input) {
361
+ for (const provider of providers) {
362
+ try {
363
+ const event = await provider.parseWebhook(input);
364
+ return {
365
+ ...event,
366
+ meta: {
367
+ ...(event.meta ?? {}),
368
+ provider: provider.id,
369
+ },
370
+ };
371
+ }
372
+ catch {
373
+ // 关键点(中文):自动识别只是兜底,单个 provider 解析失败继续尝试下一个。
374
+ }
375
+ }
376
+ throw new Error("Payment webhook provider is required");
377
+ }
378
+ /**
379
+ * 支付记录按更新时间倒序。
380
+ */
381
+ function sortPayments(rows) {
382
+ return [...rows].sort((left, right) => {
383
+ if (left.updated_at === right.updated_at)
384
+ return right.created_at.localeCompare(left.created_at);
385
+ return right.updated_at.localeCompare(left.updated_at);
386
+ });
387
+ }
388
+ /**
389
+ * 事件记录按创建时间倒序。
390
+ */
391
+ function sortEvents(rows) {
392
+ return [...rows].sort((left, right) => right.created_at.localeCompare(left.created_at));
393
+ }
394
+ //# sourceMappingURL=routes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routes.js","sourceRoot":"","sources":["../../src/payment/routes.ts"],"names":[],"mappings":"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"}