@mathrunet/masamune_cloudflare_purchase_stripe 3.2.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.
Files changed (91) hide show
  1. package/CHANGELOG.md +3 -0
  2. package/LICENSE +21 -0
  3. package/README.md +174 -0
  4. package/dist/functions.d.ts +44 -0
  5. package/dist/functions.js +47 -0
  6. package/dist/functions.js.map +1 -0
  7. package/dist/index.d.ts +25 -0
  8. package/dist/index.js +42 -0
  9. package/dist/index.js.map +1 -0
  10. package/dist/lib/meter/d1_usage_event_store.d.ts +128 -0
  11. package/dist/lib/meter/d1_usage_event_store.js +78 -0
  12. package/dist/lib/meter/d1_usage_event_store.js.map +1 -0
  13. package/dist/lib/meter/flush_meter.d.ts +19 -0
  14. package/dist/lib/meter/flush_meter.js +38 -0
  15. package/dist/lib/meter/flush_meter.js.map +1 -0
  16. package/dist/lib/meter/interface.d.ts +109 -0
  17. package/dist/lib/meter/interface.js +3 -0
  18. package/dist/lib/meter/interface.js.map +1 -0
  19. package/dist/lib/meter/kv_usage_buffer.d.ts +56 -0
  20. package/dist/lib/meter/kv_usage_buffer.js +50 -0
  21. package/dist/lib/meter/kv_usage_buffer.js.map +1 -0
  22. package/dist/lib/meter/record_usage.d.ts +29 -0
  23. package/dist/lib/meter/record_usage.js +72 -0
  24. package/dist/lib/meter/record_usage.js.map +1 -0
  25. package/dist/lib/meter/stripe_meter_client.d.ts +76 -0
  26. package/dist/lib/meter/stripe_meter_client.js +74 -0
  27. package/dist/lib/meter/stripe_meter_client.js.map +1 -0
  28. package/dist/lib/options.d.ts +179 -0
  29. package/dist/lib/options.js +132 -0
  30. package/dist/lib/options.js.map +1 -0
  31. package/dist/lib/purchase/d1_purchase_store.d.ts +78 -0
  32. package/dist/lib/purchase/d1_purchase_store.js +194 -0
  33. package/dist/lib/purchase/d1_purchase_store.js.map +1 -0
  34. package/dist/lib/purchase/helpers.d.ts +36 -0
  35. package/dist/lib/purchase/helpers.js +64 -0
  36. package/dist/lib/purchase/helpers.js.map +1 -0
  37. package/dist/lib/purchase/interface.d.ts +182 -0
  38. package/dist/lib/purchase/interface.js +27 -0
  39. package/dist/lib/purchase/interface.js.map +1 -0
  40. package/dist/lib/purchase/sync_payment.d.ts +15 -0
  41. package/dist/lib/purchase/sync_payment.js +79 -0
  42. package/dist/lib/purchase/sync_payment.js.map +1 -0
  43. package/dist/lib/stripe_client.d.ts +55 -0
  44. package/dist/lib/stripe_client.js +50 -0
  45. package/dist/lib/stripe_client.js.map +1 -0
  46. package/dist/meter.d.ts +21 -0
  47. package/dist/meter.js +38 -0
  48. package/dist/meter.js.map +1 -0
  49. package/dist/purchase.d.ts +58 -0
  50. package/dist/purchase.js +48 -0
  51. package/dist/purchase.js.map +1 -0
  52. package/dist/workers/stripe.d.ts +1 -0
  53. package/dist/workers/stripe.js +861 -0
  54. package/dist/workers/stripe.js.map +1 -0
  55. package/dist/workers/stripe_webhook.d.ts +1 -0
  56. package/dist/workers/stripe_webhook.js +384 -0
  57. package/dist/workers/stripe_webhook.js.map +1 -0
  58. package/dist/workers/stripe_webhook_connect.d.ts +1 -0
  59. package/dist/workers/stripe_webhook_connect.js +97 -0
  60. package/dist/workers/stripe_webhook_connect.js.map +1 -0
  61. package/dist/workers/stripe_webhook_secure.d.ts +1 -0
  62. package/dist/workers/stripe_webhook_secure.js +82 -0
  63. package/dist/workers/stripe_webhook_secure.js.map +1 -0
  64. package/jest.config.json +19 -0
  65. package/package.json +56 -0
  66. package/src/functions.ts +48 -0
  67. package/src/index.ts +25 -0
  68. package/src/lib/meter/d1_usage_event_store.ts +176 -0
  69. package/src/lib/meter/flush_meter.ts +45 -0
  70. package/src/lib/meter/interface.ts +118 -0
  71. package/src/lib/meter/kv_usage_buffer.ts +79 -0
  72. package/src/lib/meter/record_usage.ts +87 -0
  73. package/src/lib/meter/stripe_meter_client.ts +117 -0
  74. package/src/lib/options.ts +299 -0
  75. package/src/lib/purchase/d1_purchase_store.ts +268 -0
  76. package/src/lib/purchase/helpers.ts +77 -0
  77. package/src/lib/purchase/interface.ts +215 -0
  78. package/src/lib/purchase/sync_payment.ts +95 -0
  79. package/src/lib/stripe_client.ts +76 -0
  80. package/src/meter.ts +21 -0
  81. package/src/purchase.ts +66 -0
  82. package/src/workers/stripe.ts +881 -0
  83. package/src/workers/stripe_webhook.ts +414 -0
  84. package/src/workers/stripe_webhook_connect.ts +107 -0
  85. package/src/workers/stripe_webhook_secure.ts +91 -0
  86. package/test/helpers/mem_store.ts +97 -0
  87. package/test/meter.test.ts +217 -0
  88. package/test/purchase_store.test.ts +154 -0
  89. package/test/stripe.test.ts +146 -0
  90. package/test/stripe_webhook.test.ts +174 -0
  91. package/tsconfig.json +14 -0
@@ -0,0 +1,132 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveStripeClient = resolveStripeClient;
4
+ exports.resolveStripeSecretKey = resolveStripeSecretKey;
5
+ exports.resolveStripeMeterEventName = resolveStripeMeterEventName;
6
+ exports.resolveStripeWebhookSecret = resolveStripeWebhookSecret;
7
+ exports.resolveStripeWebhookConnectSecret = resolveStripeWebhookConnectSecret;
8
+ exports.resolveStripePurchaseStore = resolveStripePurchaseStore;
9
+ exports.resolveStripeEmailSender = resolveStripeEmailSender;
10
+ const http_error_1 = require("@mathrunet/masamune_cloudflare/dist/lib/src/http_error");
11
+ const d1_purchase_store_1 = require("./purchase/d1_purchase_store");
12
+ const stripe_client_1 = require("./stripe_client");
13
+ /**
14
+ * Resolve the Stripe SDK client from options and the resolved secret key.
15
+ *
16
+ * オプションと解決済みシークレットキーからStripe SDKクライアントを解決します。
17
+ */
18
+ function resolveStripeClient(context, options, secretKey) {
19
+ if (options.stripeClient) {
20
+ return options.stripeClient(context, secretKey);
21
+ }
22
+ return (0, stripe_client_1.createStripeClient)({ secretKey });
23
+ }
24
+ /**
25
+ * Resolve the Stripe secret key from options and `context.env`.
26
+ *
27
+ * オプションと`context.env`からStripeのシークレットキーを解決します。
28
+ */
29
+ function resolveStripeSecretKey(context, options) {
30
+ return (0, http_error_1.resolveConfig)(context, options.secretKey, "PURCHASE_STRIPE_SECRETKEY") ?? "";
31
+ }
32
+ /**
33
+ * Resolve the Stripe meter event name from options and `context.env`.
34
+ *
35
+ * オプションと`context.env`からStripeのMeterイベント名を解決します。
36
+ */
37
+ function resolveStripeMeterEventName(context, options) {
38
+ return (0, http_error_1.resolveConfig)(context, options.meterEventName, "PURCHASE_STRIPE_METER_EVENT_NAME");
39
+ }
40
+ /**
41
+ * Resolve the main webhook signing secret from options and `context.env`.
42
+ *
43
+ * オプションと`context.env`からメインWebhookの署名シークレットを解決します。
44
+ */
45
+ function resolveStripeWebhookSecret(context, options) {
46
+ return (0, http_error_1.resolveConfig)(context, options.webhookSecret, "PURCHASE_STRIPE_WEBHOOKSECRET") ?? "";
47
+ }
48
+ /**
49
+ * Resolve the Connect webhook signing secret from options and `context.env`.
50
+ *
51
+ * オプションと`context.env`からConnect用Webhookの署名シークレットを解決します。
52
+ */
53
+ function resolveStripeWebhookConnectSecret(context, options) {
54
+ return (0, http_error_1.resolveConfig)(context, options.webhookConnectSecret, "PURCHASE_STRIPE_WEBHOOKCONNECTSECRET") ?? "";
55
+ }
56
+ /**
57
+ * Resolve the purchase data store from options and `context.env`.
58
+ *
59
+ * オプションと`context.env`から購入データストアを解決します。
60
+ */
61
+ function resolveStripePurchaseStore(context, options) {
62
+ if (options.store) {
63
+ return options.store(context);
64
+ }
65
+ const binding = options.d1Binding ?? "DB";
66
+ const env = (context.env ?? {});
67
+ const db = env[binding];
68
+ if (!db) {
69
+ throw new Error(`The D1 binding "${binding}" is not found. Set options.store or options.d1Binding.`);
70
+ }
71
+ return new d1_purchase_store_1.D1StripePurchaseStore(db, options.tables ?? {});
72
+ }
73
+ /**
74
+ * Resolve the email sender from options and `context.env`.
75
+ *
76
+ * Returns `null` when no provider is configured.
77
+ *
78
+ * オプションと`context.env`からメール送信手段を解決します。
79
+ *
80
+ * プロバイダーが未設定の場合は`null`を返します。
81
+ */
82
+ function resolveStripeEmailSender(context, options) {
83
+ if (options.sendEmail) {
84
+ const sendEmail = options.sendEmail;
85
+ return (email) => sendEmail(context, email);
86
+ }
87
+ const provider = (0, http_error_1.resolveConfig)(context, undefined, "PURCHASE_STRIPE_EMAILPROVIDER") ?? "sendgrid";
88
+ switch (provider) {
89
+ case "sendgrid": {
90
+ const apiKey = (0, http_error_1.resolveConfig)(context, undefined, "MAIL_SENDGRID_APIKEY");
91
+ if (!apiKey) {
92
+ return null;
93
+ }
94
+ return (email) => sendWithSendGrid(apiKey, email);
95
+ }
96
+ default: {
97
+ return null;
98
+ }
99
+ }
100
+ }
101
+ // SendGrid REST API (v3) 直呼び。@mathrunet/masamune_cloudflare_mail_sendgrid と
102
+ // 同一の送信仕様だが、同パッケージの再エクスポート連鎖をWorkersバンドルへ
103
+ // 持ち込まないためここにインライン実装する。
104
+ async function sendWithSendGrid(apiKey, email) {
105
+ const res = await fetch("https://api.sendgrid.com/v3/mail/send", {
106
+ method: "POST",
107
+ headers: {
108
+ "Authorization": `Bearer ${apiKey}`,
109
+ "Content-Type": "application/json",
110
+ },
111
+ body: JSON.stringify({
112
+ personalizations: [
113
+ {
114
+ to: [{ email: email.to }],
115
+ },
116
+ ],
117
+ from: { email: email.from },
118
+ subject: email.subject,
119
+ content: [
120
+ {
121
+ type: "text/plain",
122
+ value: email.text,
123
+ },
124
+ ],
125
+ }),
126
+ });
127
+ if (!res.ok) {
128
+ const body = await res.text();
129
+ throw new Error(`Failed to send mail through SendGrid: ${res.status} ${body}`);
130
+ }
131
+ }
132
+ //# sourceMappingURL=options.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"options.js","sourceRoot":"","sources":["../../src/lib/options.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,78 @@
1
+ import { SqlDatabaseLike } from "../meter/d1_usage_event_store";
2
+ import { StripeDocumentData, StripePaymentDocument, StripePurchaseDocument, StripePurchaseStore, StripeUserDocument } from "./interface";
3
+ /**
4
+ * Table name options for [D1StripePurchaseStore].
5
+ *
6
+ * Expected default schema (see the package README for the full DDL):
7
+ *
8
+ * - `stripe_users(user_id PK, customer_id, account_id, data, created_at, updated_at)`
9
+ * - `stripe_payments(user_id, payment_id, data, created_at, updated_at, PK(user_id, payment_id))`
10
+ * - `stripe_purchases(order_id PK, user_id, purchase_id, subscription_id, data, created_at, updated_at)`
11
+ *
12
+ * [D1StripePurchaseStore]のテーブル名オプション。
13
+ *
14
+ * 想定するデフォルトスキーマ(完全なDDLはパッケージREADMEを参照):
15
+ *
16
+ * - `stripe_users(user_id PK, customer_id, account_id, data, created_at, updated_at)`
17
+ * - `stripe_payments(user_id, payment_id, data, created_at, updated_at, PK(user_id, payment_id))`
18
+ * - `stripe_purchases(order_id PK, user_id, purchase_id, subscription_id, data, created_at, updated_at)`
19
+ */
20
+ export interface D1StripePurchaseStoreOptions {
21
+ /**
22
+ * Users table name. Defaults to `stripe_users`.
23
+ *
24
+ * ユーザーテーブル名。デフォルトは`stripe_users`。
25
+ */
26
+ usersTable?: string | undefined;
27
+ /**
28
+ * Payments table name. Defaults to `stripe_payments`.
29
+ *
30
+ * 支払い方法テーブル名。デフォルトは`stripe_payments`。
31
+ */
32
+ paymentsTable?: string | undefined;
33
+ /**
34
+ * Purchases table name. Defaults to `stripe_purchases`.
35
+ *
36
+ * 購入テーブル名。デフォルトは`stripe_purchases`。
37
+ */
38
+ purchasesTable?: string | undefined;
39
+ }
40
+ /**
41
+ * [StripePurchaseStore] backed by Cloudflare D1 (or any compatible SQL database).
42
+ *
43
+ * Documents are stored as JSON in the `data` column while lookup keys
44
+ * (`customer_id` / `account_id` / `purchase_id` / `subscription_id`) are kept in
45
+ * sync as indexed columns.
46
+ *
47
+ * Cloudflare D1(または互換SQLデータベース)を用いた[StripePurchaseStore]。
48
+ *
49
+ * ドキュメントは`data`カラムへJSONとして保存し、検索キー
50
+ * (`customer_id` / `account_id` / `purchase_id` / `subscription_id`)は
51
+ * インデックス付きカラムとして同期します。
52
+ */
53
+ export declare class D1StripePurchaseStore implements StripePurchaseStore {
54
+ /**
55
+ * [StripePurchaseStore] backed by Cloudflare D1 (or any compatible SQL database).
56
+ *
57
+ * Cloudflare D1(または互換SQLデータベース)を用いた[StripePurchaseStore]。
58
+ */
59
+ constructor(db: SqlDatabaseLike, options?: D1StripePurchaseStoreOptions);
60
+ private readonly _db;
61
+ private readonly _users;
62
+ private readonly _payments;
63
+ private readonly _purchases;
64
+ private static _parse;
65
+ getUser(userId: string): Promise<StripeUserDocument | null>;
66
+ findUserByCustomerId(customerId: string): Promise<StripeUserDocument | null>;
67
+ findUserByAccountId(accountId: string): Promise<StripeUserDocument | null>;
68
+ saveUser(userId: string, update: StripeDocumentData): Promise<void>;
69
+ listPayments(userId: string): Promise<StripePaymentDocument[]>;
70
+ savePayment(userId: string, paymentId: string, update: StripeDocumentData): Promise<void>;
71
+ deletePayment(userId: string, paymentId: string): Promise<void>;
72
+ getPurchase(orderId: string, userId?: string | undefined): Promise<StripePurchaseDocument | null>;
73
+ findPurchaseByPurchaseId(purchaseId: string): Promise<StripePurchaseDocument | null>;
74
+ findPurchaseBySubscriptionId(subscriptionId: string): Promise<StripePurchaseDocument | null>;
75
+ savePurchase(orderId: string, update: StripeDocumentData, options?: {
76
+ userId?: string | undefined;
77
+ }): Promise<void>;
78
+ }
@@ -0,0 +1,194 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.D1StripePurchaseStore = void 0;
4
+ const interface_1 = require("./interface");
5
+ /**
6
+ * [StripePurchaseStore] backed by Cloudflare D1 (or any compatible SQL database).
7
+ *
8
+ * Documents are stored as JSON in the `data` column while lookup keys
9
+ * (`customer_id` / `account_id` / `purchase_id` / `subscription_id`) are kept in
10
+ * sync as indexed columns.
11
+ *
12
+ * Cloudflare D1(または互換SQLデータベース)を用いた[StripePurchaseStore]。
13
+ *
14
+ * ドキュメントは`data`カラムへJSONとして保存し、検索キー
15
+ * (`customer_id` / `account_id` / `purchase_id` / `subscription_id`)は
16
+ * インデックス付きカラムとして同期します。
17
+ */
18
+ class D1StripePurchaseStore {
19
+ /**
20
+ * [StripePurchaseStore] backed by Cloudflare D1 (or any compatible SQL database).
21
+ *
22
+ * Cloudflare D1(または互換SQLデータベース)を用いた[StripePurchaseStore]。
23
+ */
24
+ constructor(db, options = {}) {
25
+ this._db = db;
26
+ this._users = options.usersTable ?? "stripe_users";
27
+ this._payments = options.paymentsTable ?? "stripe_payments";
28
+ this._purchases = options.purchasesTable ?? "stripe_purchases";
29
+ }
30
+ _db;
31
+ _users;
32
+ _payments;
33
+ _purchases;
34
+ static _parse(row) {
35
+ if (!row) {
36
+ return null;
37
+ }
38
+ try {
39
+ return JSON.parse(row.data ?? "{}");
40
+ }
41
+ catch {
42
+ return {};
43
+ }
44
+ }
45
+ async getUser(userId) {
46
+ const res = await this._db
47
+ .prepare(`SELECT data FROM ${this._users} WHERE user_id = ?`)
48
+ .bind(userId)
49
+ .all();
50
+ const data = D1StripePurchaseStore._parse(res.results?.[0]);
51
+ return data === null ? null : { userId, data };
52
+ }
53
+ async findUserByCustomerId(customerId) {
54
+ const res = await this._db
55
+ .prepare(`SELECT user_id, data FROM ${this._users} WHERE customer_id = ? LIMIT 1`)
56
+ .bind(customerId)
57
+ .all();
58
+ const row = res.results?.[0];
59
+ const data = D1StripePurchaseStore._parse(row);
60
+ return row && data !== null ? { userId: row.user_id, data } : null;
61
+ }
62
+ async findUserByAccountId(accountId) {
63
+ const res = await this._db
64
+ .prepare(`SELECT user_id, data FROM ${this._users} WHERE account_id = ? LIMIT 1`)
65
+ .bind(accountId)
66
+ .all();
67
+ const row = res.results?.[0];
68
+ const data = D1StripePurchaseStore._parse(row);
69
+ return row && data !== null ? { userId: row.user_id, data } : null;
70
+ }
71
+ async saveUser(userId, update) {
72
+ const now = Date.now();
73
+ const existing = await this.getUser(userId);
74
+ const merged = (0, interface_1.mergeDocumentData)(existing?.data ?? {}, update);
75
+ const customerId = typeof merged["customer"] === "string" ? merged["customer"] : null;
76
+ const accountId = typeof merged["account"] === "string" ? merged["account"] : null;
77
+ if (existing) {
78
+ await this._db
79
+ .prepare(`UPDATE ${this._users}
80
+ SET customer_id = ?, account_id = ?, data = ?, updated_at = ?
81
+ WHERE user_id = ?`)
82
+ .bind(customerId, accountId, JSON.stringify(merged), now, userId)
83
+ .run();
84
+ }
85
+ else {
86
+ await this._db
87
+ .prepare(`INSERT INTO ${this._users}
88
+ (user_id, customer_id, account_id, data, created_at, updated_at)
89
+ VALUES (?, ?, ?, ?, ?, ?)`)
90
+ .bind(userId, customerId, accountId, JSON.stringify(merged), now, now)
91
+ .run();
92
+ }
93
+ }
94
+ async listPayments(userId) {
95
+ const res = await this._db
96
+ .prepare(`SELECT payment_id, data FROM ${this._payments} WHERE user_id = ?`)
97
+ .bind(userId)
98
+ .all();
99
+ return (res.results ?? []).map((row) => ({
100
+ userId,
101
+ paymentId: row.payment_id,
102
+ data: D1StripePurchaseStore._parse(row) ?? {},
103
+ }));
104
+ }
105
+ async savePayment(userId, paymentId, update) {
106
+ const now = Date.now();
107
+ const res = await this._db
108
+ .prepare(`SELECT data FROM ${this._payments} WHERE user_id = ? AND payment_id = ?`)
109
+ .bind(userId, paymentId)
110
+ .all();
111
+ const existing = D1StripePurchaseStore._parse(res.results?.[0]);
112
+ const merged = (0, interface_1.mergeDocumentData)(existing ?? {}, update);
113
+ if (existing !== null) {
114
+ await this._db
115
+ .prepare(`UPDATE ${this._payments} SET data = ?, updated_at = ?
116
+ WHERE user_id = ? AND payment_id = ?`)
117
+ .bind(JSON.stringify(merged), now, userId, paymentId)
118
+ .run();
119
+ }
120
+ else {
121
+ await this._db
122
+ .prepare(`INSERT INTO ${this._payments}
123
+ (user_id, payment_id, data, created_at, updated_at)
124
+ VALUES (?, ?, ?, ?, ?)`)
125
+ .bind(userId, paymentId, JSON.stringify(merged), now, now)
126
+ .run();
127
+ }
128
+ }
129
+ async deletePayment(userId, paymentId) {
130
+ await this._db
131
+ .prepare(`DELETE FROM ${this._payments} WHERE user_id = ? AND payment_id = ?`)
132
+ .bind(userId, paymentId)
133
+ .run();
134
+ }
135
+ async getPurchase(orderId, userId) {
136
+ const res = userId
137
+ ? await this._db
138
+ .prepare(`SELECT user_id, data FROM ${this._purchases} WHERE order_id = ? AND user_id = ?`)
139
+ .bind(orderId, userId)
140
+ .all()
141
+ : await this._db
142
+ .prepare(`SELECT user_id, data FROM ${this._purchases} WHERE order_id = ?`)
143
+ .bind(orderId)
144
+ .all();
145
+ const row = res.results?.[0];
146
+ const data = D1StripePurchaseStore._parse(row);
147
+ return row && data !== null ? { orderId, userId: row.user_id ?? null, data } : null;
148
+ }
149
+ async findPurchaseByPurchaseId(purchaseId) {
150
+ const res = await this._db
151
+ .prepare(`SELECT order_id, user_id, data FROM ${this._purchases} WHERE purchase_id = ? LIMIT 1`)
152
+ .bind(purchaseId)
153
+ .all();
154
+ const row = res.results?.[0];
155
+ const data = D1StripePurchaseStore._parse(row);
156
+ return row && data !== null ? { orderId: row.order_id, userId: row.user_id ?? null, data } : null;
157
+ }
158
+ async findPurchaseBySubscriptionId(subscriptionId) {
159
+ const res = await this._db
160
+ .prepare(`SELECT order_id, user_id, data FROM ${this._purchases} WHERE subscription_id = ? LIMIT 1`)
161
+ .bind(subscriptionId)
162
+ .all();
163
+ const row = res.results?.[0];
164
+ const data = D1StripePurchaseStore._parse(row);
165
+ return row && data !== null ? { orderId: row.order_id, userId: row.user_id ?? null, data } : null;
166
+ }
167
+ async savePurchase(orderId, update, options = {}) {
168
+ const now = Date.now();
169
+ const existing = await this.getPurchase(orderId);
170
+ const merged = (0, interface_1.mergeDocumentData)(existing?.data ?? {}, update);
171
+ const userId = options.userId
172
+ ?? (typeof merged["user"] === "string" ? merged["user"] : existing?.userId ?? null);
173
+ const purchaseId = typeof merged["purchaseId"] === "string" ? merged["purchaseId"] : null;
174
+ const subscriptionId = typeof merged["subscription"] === "string" ? merged["subscription"] : null;
175
+ if (existing) {
176
+ await this._db
177
+ .prepare(`UPDATE ${this._purchases}
178
+ SET user_id = ?, purchase_id = ?, subscription_id = ?, data = ?, updated_at = ?
179
+ WHERE order_id = ?`)
180
+ .bind(userId, purchaseId, subscriptionId, JSON.stringify(merged), now, orderId)
181
+ .run();
182
+ }
183
+ else {
184
+ await this._db
185
+ .prepare(`INSERT INTO ${this._purchases}
186
+ (order_id, user_id, purchase_id, subscription_id, data, created_at, updated_at)
187
+ VALUES (?, ?, ?, ?, ?, ?, ?)`)
188
+ .bind(orderId, userId, purchaseId, subscriptionId, JSON.stringify(merged), now, now)
189
+ .run();
190
+ }
191
+ }
192
+ }
193
+ exports.D1StripePurchaseStore = D1StripePurchaseStore;
194
+ //# sourceMappingURL=d1_purchase_store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"d1_purchase_store.js","sourceRoot":"","sources":["../../../src/lib/purchase/d1_purchase_store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ import Stripe from "stripe";
2
+ import { Context } from "hono";
3
+ import { StripePurchaseWorkersOptions } from "../options";
4
+ import { StripePurchaseStore, StripeUserDocument } from "./interface";
5
+ /**
6
+ * Resolve the default payment method of a user, following the same fallback
7
+ * chain as the Firebase implementation: stored `defaultPayment` -> customer's
8
+ * `invoice_settings.default_payment_method` -> first stored payment method.
9
+ * The resolved value is saved back to the user document.
10
+ *
11
+ * Firebase実装と同じフォールバック連鎖でユーザーのデフォルト支払い方法を
12
+ * 解決します: 保存済み`defaultPayment` → カスタマーの
13
+ * `invoice_settings.default_payment_method` → 保存済み支払い方法の先頭。
14
+ * 解決した値はユーザードキュメントへ書き戻します。
15
+ */
16
+ export declare function resolveDefaultPayment(options: {
17
+ stripeClient: Stripe;
18
+ store: StripePurchaseStore;
19
+ user: StripeUserDocument;
20
+ }): Promise<string>;
21
+ /**
22
+ * Resolve the email address of a user (parity with `admin.auth().getUser()` in
23
+ * the Firebase implementation): `options.resolveUserEmail` -> `email` field of
24
+ * the user document -> billing details of the default payment method.
25
+ *
26
+ * ユーザーのメールアドレスを解決します(Firebase実装の
27
+ * `admin.auth().getUser()`相当): `options.resolveUserEmail` → ユーザー
28
+ * ドキュメントの`email`フィールド → デフォルト支払い方法のbilling details。
29
+ */
30
+ export declare function resolveUserEmail(options: {
31
+ context: Context;
32
+ workersOptions: StripePurchaseWorkersOptions;
33
+ stripeClient: Stripe;
34
+ user: StripeUserDocument;
35
+ defaultPayment?: string | undefined;
36
+ }): Promise<string>;
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveDefaultPayment = resolveDefaultPayment;
4
+ exports.resolveUserEmail = resolveUserEmail;
5
+ const http_error_1 = require("@mathrunet/masamune_cloudflare/dist/lib/src/http_error");
6
+ /**
7
+ * Resolve the default payment method of a user, following the same fallback
8
+ * chain as the Firebase implementation: stored `defaultPayment` -> customer's
9
+ * `invoice_settings.default_payment_method` -> first stored payment method.
10
+ * The resolved value is saved back to the user document.
11
+ *
12
+ * Firebase実装と同じフォールバック連鎖でユーザーのデフォルト支払い方法を
13
+ * 解決します: 保存済み`defaultPayment` → カスタマーの
14
+ * `invoice_settings.default_payment_method` → 保存済み支払い方法の先頭。
15
+ * 解決した値はユーザードキュメントへ書き戻します。
16
+ */
17
+ async function resolveDefaultPayment(options) {
18
+ const { stripeClient, store, user } = options;
19
+ let defaultPayment = user.data["defaultPayment"];
20
+ if (defaultPayment) {
21
+ return defaultPayment;
22
+ }
23
+ const customer = await stripeClient.customers.retrieve(user.data["customer"]);
24
+ defaultPayment = (customer.invoice_settings.default_payment_method ?? undefined);
25
+ if (!defaultPayment) {
26
+ const payments = await store.listPayments(user.userId);
27
+ if (payments.length <= 0) {
28
+ throw new http_error_1.HttpError(404, "The payment method is not found.");
29
+ }
30
+ defaultPayment = payments[0]?.data["id"];
31
+ if (!defaultPayment) {
32
+ throw new http_error_1.HttpError(404, "The payment method is not found.");
33
+ }
34
+ }
35
+ await store.saveUser(user.userId, { defaultPayment });
36
+ return defaultPayment;
37
+ }
38
+ /**
39
+ * Resolve the email address of a user (parity with `admin.auth().getUser()` in
40
+ * the Firebase implementation): `options.resolveUserEmail` -> `email` field of
41
+ * the user document -> billing details of the default payment method.
42
+ *
43
+ * ユーザーのメールアドレスを解決します(Firebase実装の
44
+ * `admin.auth().getUser()`相当): `options.resolveUserEmail` → ユーザー
45
+ * ドキュメントの`email`フィールド → デフォルト支払い方法のbilling details。
46
+ */
47
+ async function resolveUserEmail(options) {
48
+ const { context, workersOptions, stripeClient, user, defaultPayment } = options;
49
+ let email = workersOptions.resolveUserEmail
50
+ ? await workersOptions.resolveUserEmail(context, user.userId)
51
+ : undefined;
52
+ if (!email && typeof user.data["email"] === "string") {
53
+ email = user.data["email"];
54
+ }
55
+ if (!email && defaultPayment) {
56
+ const paymentMethod = await stripeClient.paymentMethods.retrieve(defaultPayment);
57
+ email = paymentMethod?.billing_details?.email ?? undefined;
58
+ }
59
+ if (!email) {
60
+ throw new http_error_1.HttpError(404, "The user's email is not found.");
61
+ }
62
+ return email;
63
+ }
64
+ //# sourceMappingURL=helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../../src/lib/purchase/helpers.ts"],"names":[],"mappings":";;AAiBA,sDA0BC;AAWD,4CAsBC;AA1ED,uFAAmF;AAInF;;;;;;;;;;GAUG;AACI,KAAK,UAAU,qBAAqB,CAAC,OAI3C;IACG,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC;IAC9C,IAAI,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAuB,CAAC;IACvE,IAAI,cAAc,EAAE,CAAC;QACjB,OAAO,cAAc,CAAC;IAC1B,CAAC;IACD,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,SAAS,CAAC,QAAQ,CAClD,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CACL,CAAC;IACrB,cAAc,GAAG,CAAC,QAAQ,CAAC,gBAAgB,CAAC,sBAAsB,IAAI,SAAS,CAAuB,CAAC;IACvG,IAAI,CAAC,cAAc,EAAE,CAAC;QAClB,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACvD,IAAI,QAAQ,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;YACvB,MAAM,IAAI,sBAAS,CAAC,GAAG,EAAE,kCAAkC,CAAC,CAAC;QACjE,CAAC;QACD,cAAc,GAAG,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAuB,CAAC;QAC/D,IAAI,CAAC,cAAc,EAAE,CAAC;YAClB,MAAM,IAAI,sBAAS,CAAC,GAAG,EAAE,kCAAkC,CAAC,CAAC;QACjE,CAAC;IACL,CAAC;IACD,MAAM,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,cAAc,EAAE,CAAC,CAAC;IACtD,OAAO,cAAc,CAAC;AAC1B,CAAC;AAED;;;;;;;;GAQG;AACI,KAAK,UAAU,gBAAgB,CAAC,OAMtC;IACG,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,IAAI,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC;IAChF,IAAI,KAAK,GAAG,cAAc,CAAC,gBAAgB;QACvC,CAAC,CAAC,MAAM,cAAc,CAAC,gBAAgB,CAAC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC;QAC7D,CAAC,CAAC,SAAS,CAAC;IAChB,IAAI,CAAC,KAAK,IAAI,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,QAAQ,EAAE,CAAC;QACnD,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC;IACD,IAAI,CAAC,KAAK,IAAI,cAAc,EAAE,CAAC;QAC3B,MAAM,aAAa,GAAG,MAAM,YAAY,CAAC,cAAc,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;QACjF,KAAK,GAAG,aAAa,EAAE,eAAe,EAAE,KAAK,IAAI,SAAS,CAAC;IAC/D,CAAC;IACD,IAAI,CAAC,KAAK,EAAE,CAAC;QACT,MAAM,IAAI,sBAAS,CAAC,GAAG,EAAE,gCAAgC,CAAC,CAAC;IAC/D,CAAC;IACD,OAAO,KAAK,CAAC;AACjB,CAAC"}