@farm.js/stripe 0.1.0-beta.99 → 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/README.md +2 -2
- package/dist/index.d.ts +37 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +239 -43
- package/dist/storage.d.ts +27 -0
- package/dist/storage.d.ts.map +1 -1
- package/dist/storage.js +185 -12
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
Stripe billing integration for Farm.js
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
See [Stability and Support](https://farmjs.dev/docs/stability) for what this package guarantees.
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
npm install @farm.js/stripe
|
|
8
|
+
npm install @farm.js/stripe
|
|
9
9
|
```
|
|
10
10
|
|
|
11
11
|
See the [Farm.js repository](https://github.com/farming-labs/farm.js) for documentation, examples, and support.
|
package/dist/index.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { type StripeBillingUpcomingInvoiceLineResult, type StripeBillingUpcoming
|
|
|
5
5
|
import { type StripeBillingMeter, type StripeBillingOptions, type StripeBillingProductKind, type StripeBillingUsageProperties } from "./storage.js";
|
|
6
6
|
export type { StripeBillingCurrentChargeLine, StripeBillingCurrentChargesResult, StripeBillingCheckInput, StripeBillingCheckResult, StripeBillingMeterUsageInput, StripeBillingMeterUsageResult, StripeBillingUpcomingInvoiceLineKind, StripeBillingUpcomingInvoiceLineResult, StripeBillingUpcomingInvoiceResult, StripeBillingUpcomingInvoiceTotalsResult, StripeBillingReportUsageInput, StripeBillingReportUsageResult, StripeBillingUpgradeInput, StripeBillingUpgradeProrationBehavior, StripeBillingUpgradeResult, StripeBillingFeaturesResult, StripeBillingLimitsResult, StripeBillingStatusResult, StripeBillingUsageInput, StripeBillingUsageResult, StripeCatalogMeterPrice, StripeCatalogProduct, StripeClientAPI, StripeDefaultClientAPI, StripeCheckoutInput, StripeCheckoutResult, StripeCheckoutTrialBehavior, StripeIntegrationProduct, StripePortalInput, StripePortalResult, StripeSessionLineItemResult, StripeSessionQuery, StripeSessionResult, StripeWebhookResult, } from "./client.js";
|
|
7
7
|
export { drizzleStorageAdapter, ormStorageAdapter, prismaStorageAdapter, sqliteStorageAdapter, } from "./storage.js";
|
|
8
|
-
export type { StripeBillingArgs, StripeBillingFeatures, StripeBillingHookTools, StripeBillingHooks, StripeBillingLimits, StripeBillingMeter, StripeBillingMeterState, StripeBillingOptions, StripeBillingOwner, StripeBillingPlan, StripeBillingProduct, StripeBillingProductKind, StripeBillingSeatLimitSource, StripeBillingSeatsMode, StripeBillingSeatsOptions, StripeBillingSnapshot, StripeBillingStatus, StripeBillingStorageAdapter, StripeBillingTrial, StripeBillingUsageProperties, StripeBillingUsageOptions, } from "./storage.js";
|
|
8
|
+
export type { StripeBillingArgs, StripeBillingCheckoutSessionClaim, StripeBillingFeatures, StripeBillingHookTools, StripeBillingHooks, StripeBillingLimits, StripeBillingMeter, StripeBillingMeterState, StripeBillingOptions, StripeBillingOwner, StripeBillingPlan, StripeBillingProduct, StripeBillingProductKind, StripeBillingSeatLimitSource, StripeBillingSeatsMode, StripeBillingSeatsOptions, StripeBillingSnapshot, StripeBillingStatus, StripeBillingStorageAdapter, StripeBillingTrial, StripeBillingUsageProperties, StripeBillingUsageOptions, } from "./storage.js";
|
|
9
9
|
export interface StripeWebhookEvent extends FarmWebhookEvent<"stripe", string, unknown, unknown> {
|
|
10
10
|
}
|
|
11
11
|
export type StripeWebhookConfig = FarmWebhookConfig<StripeWebhookEvent>;
|
|
@@ -277,6 +277,42 @@ export declare const stripeSchema: {
|
|
|
277
277
|
name: string;
|
|
278
278
|
}[];
|
|
279
279
|
};
|
|
280
|
+
billingCheckoutSession: {
|
|
281
|
+
name: string;
|
|
282
|
+
description: string;
|
|
283
|
+
fields: {
|
|
284
|
+
sessionId: {
|
|
285
|
+
type: "string";
|
|
286
|
+
name: string;
|
|
287
|
+
primaryKey: true;
|
|
288
|
+
};
|
|
289
|
+
ownerId: {
|
|
290
|
+
type: "string";
|
|
291
|
+
name: string;
|
|
292
|
+
required: true;
|
|
293
|
+
index: true;
|
|
294
|
+
};
|
|
295
|
+
ownerKind: {
|
|
296
|
+
type: "enum";
|
|
297
|
+
name: string;
|
|
298
|
+
required: true;
|
|
299
|
+
values: string[];
|
|
300
|
+
index: true;
|
|
301
|
+
};
|
|
302
|
+
stripeCustomerId: {
|
|
303
|
+
type: "string";
|
|
304
|
+
name: string;
|
|
305
|
+
nullable: true;
|
|
306
|
+
index: true;
|
|
307
|
+
};
|
|
308
|
+
processedAt: {
|
|
309
|
+
type: "datetime";
|
|
310
|
+
name: string;
|
|
311
|
+
required: true;
|
|
312
|
+
default: string;
|
|
313
|
+
};
|
|
314
|
+
};
|
|
315
|
+
};
|
|
280
316
|
};
|
|
281
317
|
meta: {
|
|
282
318
|
category: string;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import Stripe from "stripe";
|
|
2
|
-
import { createIntegrationOrm, defineIntegration, integrationRoute, } from "@farm.js/core";
|
|
2
|
+
import { createIntegrationOrm, declareSchemaTables, defineIntegration, integrationRoute, } from "@farm.js/core";
|
|
3
3
|
import { integrationConfig, normalizeWebhookConfig, resolveAppPath, toAbsoluteUrl, withSearchParams, } from "@farm.js/integration-utils";
|
|
4
4
|
import { createStripeClientApi, } from "./client.js";
|
|
5
5
|
import { ormStorageAdapter, } from "./storage.js";
|
|
@@ -298,6 +298,42 @@ export const stripeSchema = {
|
|
|
298
298
|
},
|
|
299
299
|
],
|
|
300
300
|
},
|
|
301
|
+
billingCheckoutSession: {
|
|
302
|
+
name: "billing_checkout_session",
|
|
303
|
+
description: "Processed Stripe checkout sessions used to deduplicate billing hooks.",
|
|
304
|
+
fields: {
|
|
305
|
+
sessionId: {
|
|
306
|
+
type: "string",
|
|
307
|
+
name: "session_id",
|
|
308
|
+
primaryKey: true,
|
|
309
|
+
},
|
|
310
|
+
ownerId: {
|
|
311
|
+
type: "string",
|
|
312
|
+
name: "owner_id",
|
|
313
|
+
required: true,
|
|
314
|
+
index: true,
|
|
315
|
+
},
|
|
316
|
+
ownerKind: {
|
|
317
|
+
type: "enum",
|
|
318
|
+
name: "owner_kind",
|
|
319
|
+
required: true,
|
|
320
|
+
values: ["user", "organization"],
|
|
321
|
+
index: true,
|
|
322
|
+
},
|
|
323
|
+
stripeCustomerId: {
|
|
324
|
+
type: "string",
|
|
325
|
+
name: "stripe_customer_id",
|
|
326
|
+
nullable: true,
|
|
327
|
+
index: true,
|
|
328
|
+
},
|
|
329
|
+
processedAt: {
|
|
330
|
+
type: "datetime",
|
|
331
|
+
name: "processed_at",
|
|
332
|
+
required: true,
|
|
333
|
+
default: "now",
|
|
334
|
+
},
|
|
335
|
+
},
|
|
336
|
+
},
|
|
301
337
|
},
|
|
302
338
|
meta: {
|
|
303
339
|
category: "payment",
|
|
@@ -1746,18 +1782,19 @@ function getBillingMeter(billing, key) {
|
|
|
1746
1782
|
const meter = billing?.meters?.[key];
|
|
1747
1783
|
return meter ?? null;
|
|
1748
1784
|
}
|
|
1749
|
-
function hasConfiguredStorageRuntimeClient(
|
|
1750
|
-
const storage =
|
|
1785
|
+
function hasConfiguredStorageRuntimeClient(config) {
|
|
1786
|
+
const storage = config.storage;
|
|
1751
1787
|
return (!!storage &&
|
|
1752
1788
|
typeof storage === "object" &&
|
|
1753
1789
|
"client" in storage &&
|
|
1754
1790
|
storage.client != null);
|
|
1755
1791
|
}
|
|
1756
|
-
async function resolveConfiguredStorageRuntimeClient(
|
|
1757
|
-
|
|
1792
|
+
async function resolveConfiguredStorageRuntimeClient(config) {
|
|
1793
|
+
// The guard is what establishes the shape, so narrowing happens after it.
|
|
1794
|
+
if (!hasConfiguredStorageRuntimeClient(config)) {
|
|
1758
1795
|
return undefined;
|
|
1759
1796
|
}
|
|
1760
|
-
const storage =
|
|
1797
|
+
const storage = config.storage;
|
|
1761
1798
|
const client = storage?.client;
|
|
1762
1799
|
return typeof client === "function"
|
|
1763
1800
|
? await client()
|
|
@@ -1771,7 +1808,7 @@ function createBillingHookTools(context, stripe, schema) {
|
|
|
1771
1808
|
stripe,
|
|
1772
1809
|
storage: {
|
|
1773
1810
|
getClient() {
|
|
1774
|
-
clientPromise ??= resolveConfiguredStorageRuntimeClient(context);
|
|
1811
|
+
clientPromise ??= resolveConfiguredStorageRuntimeClient(context.config);
|
|
1775
1812
|
return clientPromise;
|
|
1776
1813
|
},
|
|
1777
1814
|
getOrm() {
|
|
@@ -1785,7 +1822,7 @@ function createBillingHookTools(context, stripe, schema) {
|
|
|
1785
1822
|
};
|
|
1786
1823
|
}
|
|
1787
1824
|
function resolveConfiguredBillingStorage(context, tools) {
|
|
1788
|
-
if (!hasConfiguredStorageRuntimeClient(context)) {
|
|
1825
|
+
if (!hasConfiguredStorageRuntimeClient(context.config)) {
|
|
1789
1826
|
return undefined;
|
|
1790
1827
|
}
|
|
1791
1828
|
return ormStorageAdapter({
|
|
@@ -1826,6 +1863,19 @@ function resolveBillingPersistence(billing, context, stripe, schema = stripeSche
|
|
|
1826
1863
|
: storage?.clearBillingSnapshot
|
|
1827
1864
|
? (owner) => storage.clearBillingSnapshot(owner)
|
|
1828
1865
|
: undefined,
|
|
1866
|
+
claimCheckoutSession: billing?.hooks?.claimCheckoutSession
|
|
1867
|
+
? (claim) => billing.hooks.claimCheckoutSession(claim, tools)
|
|
1868
|
+
: storage?.claimCheckoutSession
|
|
1869
|
+
? (claim) => storage.claimCheckoutSession(claim)
|
|
1870
|
+
: undefined,
|
|
1871
|
+
// Released by whichever side made the claim.
|
|
1872
|
+
releaseCheckoutSession: billing?.hooks?.claimCheckoutSession
|
|
1873
|
+
? billing.hooks.releaseCheckoutSession
|
|
1874
|
+
? (sessionId) => billing.hooks.releaseCheckoutSession(sessionId, tools)
|
|
1875
|
+
: undefined
|
|
1876
|
+
: storage?.releaseCheckoutSession
|
|
1877
|
+
? (sessionId) => storage.releaseCheckoutSession(sessionId)
|
|
1878
|
+
: undefined,
|
|
1829
1879
|
};
|
|
1830
1880
|
}
|
|
1831
1881
|
function requireBillingMethod(value, label) {
|
|
@@ -2013,6 +2063,23 @@ function createBillingSnapshotFromSubscriptionChange(owner, result, billing, pro
|
|
|
2013
2063
|
},
|
|
2014
2064
|
};
|
|
2015
2065
|
}
|
|
2066
|
+
/**
|
|
2067
|
+
* Decide whether a checkout session belongs to the authenticated owner.
|
|
2068
|
+
*
|
|
2069
|
+
* Session ids travel through success-url query strings, browser history, and
|
|
2070
|
+
* referrers, so holding one is not proof of ownership. Checkout stamps
|
|
2071
|
+
* `ownerId`/`ownerKind` into session metadata, which is the authoritative
|
|
2072
|
+
* binding; the owner's stored customer id is accepted as a fallback for
|
|
2073
|
+
* sessions created before that metadata existed.
|
|
2074
|
+
*/
|
|
2075
|
+
function sessionBelongsToOwner(session, owner, ownerCustomerId) {
|
|
2076
|
+
const sessionOwnerId = session.metadata?.ownerId;
|
|
2077
|
+
const sessionOwnerKind = session.metadata?.ownerKind;
|
|
2078
|
+
if (sessionOwnerId) {
|
|
2079
|
+
return sessionOwnerId === owner.id && (!sessionOwnerKind || sessionOwnerKind === owner.kind);
|
|
2080
|
+
}
|
|
2081
|
+
return Boolean(ownerCustomerId) && session.customerId === ownerCustomerId;
|
|
2082
|
+
}
|
|
2016
2083
|
async function resolveBillingSnapshotForSession(session, products, billing, persistence, context) {
|
|
2017
2084
|
if (!billing) {
|
|
2018
2085
|
return null;
|
|
@@ -2023,13 +2090,126 @@ async function resolveBillingSnapshotForSession(session, products, billing, pers
|
|
|
2023
2090
|
const getByCustomerId = requireBillingMethod(persistence.getBillingAccountByStripeCustomerId, "getBillingAccountByStripeCustomerId");
|
|
2024
2091
|
existingSnapshot = await getByCustomerId(session.customerId);
|
|
2025
2092
|
if (!owner) {
|
|
2093
|
+
// No signed-in caller (the webhook path): the session's customer is the
|
|
2094
|
+
// only binding available.
|
|
2026
2095
|
owner = existingSnapshot?.owner ?? null;
|
|
2027
2096
|
}
|
|
2028
2097
|
}
|
|
2029
2098
|
if (!owner) {
|
|
2030
2099
|
return null;
|
|
2031
2100
|
}
|
|
2032
|
-
|
|
2101
|
+
if (!existingSnapshot && persistence.getBillingAccount) {
|
|
2102
|
+
existingSnapshot = await persistence.getBillingAccount(owner);
|
|
2103
|
+
}
|
|
2104
|
+
// A signed-in caller must not be able to bind someone else's checkout to
|
|
2105
|
+
// themselves by presenting its session id. Checkout stamps ownerId into the
|
|
2106
|
+
// session metadata, and an already-persisted snapshot names the customer's
|
|
2107
|
+
// real owner; either disagreeing with the caller means this session is not
|
|
2108
|
+
// theirs.
|
|
2109
|
+
const sessionOwnerId = session.metadata?.ownerId;
|
|
2110
|
+
const sessionOwnerKind = session.metadata?.ownerKind;
|
|
2111
|
+
const boundOwner = existingSnapshot?.owner;
|
|
2112
|
+
const mismatchesCaller = (sessionOwnerId !== undefined &&
|
|
2113
|
+
(sessionOwnerId !== owner.id ||
|
|
2114
|
+
(sessionOwnerKind !== undefined && sessionOwnerKind !== owner.kind))) ||
|
|
2115
|
+
(boundOwner !== undefined &&
|
|
2116
|
+
boundOwner !== null &&
|
|
2117
|
+
(boundOwner.id !== owner.id || boundOwner.kind !== owner.kind));
|
|
2118
|
+
if (mismatchesCaller) {
|
|
2119
|
+
return null;
|
|
2120
|
+
}
|
|
2121
|
+
return {
|
|
2122
|
+
snapshot: createBillingSnapshot(owner, session, billing, products, existingSnapshot?.planId ?? "free", existingSnapshot),
|
|
2123
|
+
previousSnapshot: existingSnapshot,
|
|
2124
|
+
};
|
|
2125
|
+
}
|
|
2126
|
+
function billingSnapshotStateEquals(left, right) {
|
|
2127
|
+
if (!right) {
|
|
2128
|
+
return false;
|
|
2129
|
+
}
|
|
2130
|
+
const sameDate = (a, b) => a?.getTime() === b?.getTime();
|
|
2131
|
+
return (left.owner.id === right.owner.id &&
|
|
2132
|
+
left.owner.kind === right.owner.kind &&
|
|
2133
|
+
left.planId === right.planId &&
|
|
2134
|
+
left.productId === right.productId &&
|
|
2135
|
+
left.status === right.status &&
|
|
2136
|
+
left.stripeCustomerId === right.stripeCustomerId &&
|
|
2137
|
+
left.stripeSubscriptionId === right.stripeSubscriptionId &&
|
|
2138
|
+
sameDate(left.currentPeriodEnd, right.currentPeriodEnd) &&
|
|
2139
|
+
left.cancelAtPeriodEnd === right.cancelAtPeriodEnd &&
|
|
2140
|
+
sameDate(left.trialEndsAt, right.trialEndsAt) &&
|
|
2141
|
+
sameDate(left.trialUsedAt, right.trialUsedAt) &&
|
|
2142
|
+
left.seatQuantity === right.seatQuantity &&
|
|
2143
|
+
left.seatAllowanceOverride === right.seatAllowanceOverride);
|
|
2144
|
+
}
|
|
2145
|
+
/**
|
|
2146
|
+
* Stripe's fulfilment rule: a Checkout Session grants what it sold only once it
|
|
2147
|
+
* is complete and its payment has cleared, or needed none. A session exists and
|
|
2148
|
+
* carries the plan in its metadata as soon as checkout starts, and a delayed
|
|
2149
|
+
* payment method completes the session before the money arrives, which Stripe
|
|
2150
|
+
* reports later as `checkout.session.async_payment_succeeded`.
|
|
2151
|
+
*/
|
|
2152
|
+
function isFulfilledCheckoutSession(session) {
|
|
2153
|
+
return (session.status === "complete" &&
|
|
2154
|
+
(session.paymentStatus === "paid" || session.paymentStatus === "no_payment_required"));
|
|
2155
|
+
}
|
|
2156
|
+
async function syncBillingCheckoutSession(session, products, billing, persistence, context) {
|
|
2157
|
+
// The success page can present the id of a session that is still open, so
|
|
2158
|
+
// without this a caller could start checkout for a paid plan, never pay, and
|
|
2159
|
+
// look the session up to be granted it.
|
|
2160
|
+
if (!isFulfilledCheckoutSession(session)) {
|
|
2161
|
+
return;
|
|
2162
|
+
}
|
|
2163
|
+
const resolved = await resolveBillingSnapshotForSession(session, products, billing, persistence, context);
|
|
2164
|
+
if (!resolved) {
|
|
2165
|
+
return;
|
|
2166
|
+
}
|
|
2167
|
+
const claimResult = persistence.claimCheckoutSession
|
|
2168
|
+
? await persistence.claimCheckoutSession({
|
|
2169
|
+
sessionId: session.id,
|
|
2170
|
+
owner: resolved.snapshot.owner,
|
|
2171
|
+
stripeCustomerId: resolved.snapshot.stripeCustomerId,
|
|
2172
|
+
})
|
|
2173
|
+
: null;
|
|
2174
|
+
if (claimResult === false ||
|
|
2175
|
+
(claimResult === null &&
|
|
2176
|
+
billingSnapshotStateEquals(resolved.snapshot, resolved.previousSnapshot))) {
|
|
2177
|
+
return;
|
|
2178
|
+
}
|
|
2179
|
+
try {
|
|
2180
|
+
await persistBillingSnapshot(resolved.snapshot, billing, persistence, resolved.previousSnapshot);
|
|
2181
|
+
await billing.hooks?.onCheckoutCompleted?.({
|
|
2182
|
+
...resolved.snapshot,
|
|
2183
|
+
sessionId: session.id,
|
|
2184
|
+
}, persistence.tools);
|
|
2185
|
+
}
|
|
2186
|
+
catch (error) {
|
|
2187
|
+
// The claim went in first so duplicate deliveries skip the hooks. If the
|
|
2188
|
+
// work it guarded failed, keep it and Stripe's retry finds the session
|
|
2189
|
+
// already claimed and does nothing, so the customer never gets the plan.
|
|
2190
|
+
if (claimResult === true && persistence.releaseCheckoutSession) {
|
|
2191
|
+
try {
|
|
2192
|
+
await persistence.releaseCheckoutSession(session.id);
|
|
2193
|
+
}
|
|
2194
|
+
catch (releaseError) {
|
|
2195
|
+
console.warn(`[farm:stripe] Could not release checkout session ${session.id} after a failure:`, releaseError);
|
|
2196
|
+
}
|
|
2197
|
+
}
|
|
2198
|
+
throw error;
|
|
2199
|
+
}
|
|
2200
|
+
}
|
|
2201
|
+
async function serializeBillingCheckoutSession(inflight, sessionId, task) {
|
|
2202
|
+
const previous = inflight.get(sessionId);
|
|
2203
|
+
const current = (previous ? previous.catch(() => undefined) : Promise.resolve()).then(task);
|
|
2204
|
+
inflight.set(sessionId, current);
|
|
2205
|
+
try {
|
|
2206
|
+
await current;
|
|
2207
|
+
}
|
|
2208
|
+
finally {
|
|
2209
|
+
if (inflight.get(sessionId) === current) {
|
|
2210
|
+
inflight.delete(sessionId);
|
|
2211
|
+
}
|
|
2212
|
+
}
|
|
2033
2213
|
}
|
|
2034
2214
|
async function persistBillingSnapshot(snapshot, billing, persistence, previousSnapshot = null) {
|
|
2035
2215
|
if (!billing) {
|
|
@@ -2091,6 +2271,7 @@ export function stripe(input = {}) {
|
|
|
2091
2271
|
const sessionPath = (input.sessionPath ?? "/billing/session");
|
|
2092
2272
|
const webhookPath = input.webhookPath ?? "/billing/webhook";
|
|
2093
2273
|
const webhookDefinitions = resolveStripeWebhooks(input, env, webhookPath);
|
|
2274
|
+
const billingCheckoutSessionSyncs = new Map();
|
|
2094
2275
|
const successPath = resolvePath(input.successPath, "Stripe integration successPath", "/success");
|
|
2095
2276
|
const cancelPath = resolvePath(input.cancelPath, "Stripe integration cancelPath", "/cancel");
|
|
2096
2277
|
const webhookRoutes = webhookDefinitions.map((definition) => integrationRoute.post(definition.path, {
|
|
@@ -2123,23 +2304,14 @@ export function stripe(input = {}) {
|
|
|
2123
2304
|
};
|
|
2124
2305
|
if (input.billing) {
|
|
2125
2306
|
const persistence = resolveBillingPersistence(input.billing, context, stripeSdk, integrationSchema);
|
|
2126
|
-
if (event.type === "checkout.session.completed"
|
|
2307
|
+
if ((event.type === "checkout.session.completed" ||
|
|
2308
|
+
event.type === "checkout.session.async_payment_succeeded") &&
|
|
2127
2309
|
event.data &&
|
|
2128
2310
|
typeof event.data === "object" &&
|
|
2129
2311
|
"id" in event.data &&
|
|
2130
2312
|
typeof event.data.id === "string") {
|
|
2131
2313
|
const session = await instance.retrieveCheckoutSession(event.data.id);
|
|
2132
|
-
|
|
2133
|
-
if (snapshot) {
|
|
2134
|
-
const previousSnapshot = session.customerId && persistence.getBillingAccountByStripeCustomerId
|
|
2135
|
-
? await persistence.getBillingAccountByStripeCustomerId(session.customerId)
|
|
2136
|
-
: null;
|
|
2137
|
-
await persistBillingSnapshot(snapshot, input.billing, persistence, previousSnapshot);
|
|
2138
|
-
await input.billing.hooks?.onCheckoutCompleted?.({
|
|
2139
|
-
...snapshot,
|
|
2140
|
-
sessionId: session.id,
|
|
2141
|
-
}, persistence.tools);
|
|
2142
|
-
}
|
|
2314
|
+
await serializeBillingCheckoutSession(billingCheckoutSessionSyncs, session.id, () => syncBillingCheckoutSession(session, configuredProducts, input.billing, persistence, context));
|
|
2143
2315
|
}
|
|
2144
2316
|
else if (event.data &&
|
|
2145
2317
|
typeof event.data === "object" &&
|
|
@@ -2226,7 +2398,7 @@ export function stripe(input = {}) {
|
|
|
2226
2398
|
}
|
|
2227
2399
|
},
|
|
2228
2400
|
}));
|
|
2229
|
-
|
|
2401
|
+
const integration = defineIntegration({
|
|
2230
2402
|
category: "payment",
|
|
2231
2403
|
type: "stripe",
|
|
2232
2404
|
instance: {
|
|
@@ -3310,21 +3482,47 @@ export function stripe(input = {}) {
|
|
|
3310
3482
|
async handler(request, context) {
|
|
3311
3483
|
const body = await readJsonObject(request);
|
|
3312
3484
|
try {
|
|
3313
|
-
|
|
3485
|
+
const requestedCustomerId = typeof body.customerId === "string" ? body.customerId : undefined;
|
|
3486
|
+
const requestedSessionId = typeof body.sessionId === "string" ? body.sessionId : undefined;
|
|
3487
|
+
let customerId;
|
|
3314
3488
|
const billingTools = input.billing
|
|
3315
3489
|
? createBillingHookTools(context, stripeSdk, integrationSchema)
|
|
3316
3490
|
: undefined;
|
|
3317
3491
|
const persistence = resolveBillingPersistence(input.billing, context, stripeSdk, integrationSchema, billingTools);
|
|
3318
|
-
if (
|
|
3319
|
-
|
|
3320
|
-
|
|
3321
|
-
|
|
3322
|
-
|
|
3492
|
+
if (input.billing) {
|
|
3493
|
+
// A portal session exposes invoices, payment methods, and
|
|
3494
|
+
// cancellation, so the signed-in owner is the only identity we
|
|
3495
|
+
// trust here. A customerId or sessionId from the request is
|
|
3496
|
+
// treated as a claim to verify, never as the identity itself.
|
|
3323
3497
|
const owner = await resolveBillingOwner(input.billing, context, persistence.tools);
|
|
3324
|
-
if (owner) {
|
|
3325
|
-
|
|
3326
|
-
|
|
3327
|
-
|
|
3498
|
+
if (!owner) {
|
|
3499
|
+
return Response.json({ error: "Stripe portal requires an authenticated billing owner." }, { status: 401 });
|
|
3500
|
+
}
|
|
3501
|
+
const getBillingAccount = requireBillingMethod(persistence.getBillingAccount, "getBillingAccount");
|
|
3502
|
+
const snapshot = await getBillingAccount(owner);
|
|
3503
|
+
customerId = snapshot?.stripeCustomerId ?? undefined;
|
|
3504
|
+
if (requestedCustomerId && requestedCustomerId !== customerId) {
|
|
3505
|
+
return Response.json({ error: "Stripe portal customerId does not belong to the billing owner." }, { status: 403 });
|
|
3506
|
+
}
|
|
3507
|
+
if (requestedSessionId) {
|
|
3508
|
+
const session = await instance.retrieveCheckoutSession(requestedSessionId);
|
|
3509
|
+
// Checkout stamps the owner into session metadata, which lets a
|
|
3510
|
+
// just-completed checkout open the portal before its snapshot
|
|
3511
|
+
// has been persisted without trusting a bare session id.
|
|
3512
|
+
if (!sessionBelongsToOwner(session, owner, customerId)) {
|
|
3513
|
+
return Response.json({ error: "Stripe portal sessionId does not belong to the billing owner." }, { status: 403 });
|
|
3514
|
+
}
|
|
3515
|
+
customerId = customerId ?? session.customerId ?? undefined;
|
|
3516
|
+
}
|
|
3517
|
+
}
|
|
3518
|
+
else {
|
|
3519
|
+
// Without billing there is no owner to authenticate against, so
|
|
3520
|
+
// the caller supplies the customer directly. This path is for
|
|
3521
|
+
// server-side callers that already did their own authorization.
|
|
3522
|
+
customerId = requestedCustomerId;
|
|
3523
|
+
if (!customerId && requestedSessionId) {
|
|
3524
|
+
const session = await instance.retrieveCheckoutSession(requestedSessionId);
|
|
3525
|
+
customerId = session.customerId ?? undefined;
|
|
3328
3526
|
}
|
|
3329
3527
|
}
|
|
3330
3528
|
if (!customerId) {
|
|
@@ -3376,17 +3574,7 @@ export function stripe(input = {}) {
|
|
|
3376
3574
|
const session = await instance.retrieveCheckoutSession(sessionId);
|
|
3377
3575
|
if (input.billing) {
|
|
3378
3576
|
const persistence = resolveBillingPersistence(input.billing, context, stripeSdk, integrationSchema);
|
|
3379
|
-
|
|
3380
|
-
if (snapshot) {
|
|
3381
|
-
const previousSnapshot = session.customerId && persistence.getBillingAccountByStripeCustomerId
|
|
3382
|
-
? await persistence.getBillingAccountByStripeCustomerId(session.customerId)
|
|
3383
|
-
: null;
|
|
3384
|
-
await persistBillingSnapshot(snapshot, input.billing, persistence, previousSnapshot);
|
|
3385
|
-
await input.billing.hooks?.onCheckoutCompleted?.({
|
|
3386
|
-
...snapshot,
|
|
3387
|
-
sessionId: session.id,
|
|
3388
|
-
}, persistence.tools);
|
|
3389
|
-
}
|
|
3577
|
+
await serializeBillingCheckoutSession(billingCheckoutSessionSyncs, session.id, () => syncBillingCheckoutSession(session, configuredProducts, input.billing, persistence, context));
|
|
3390
3578
|
}
|
|
3391
3579
|
return Response.json(session);
|
|
3392
3580
|
}
|
|
@@ -3402,4 +3590,12 @@ export function stripe(input = {}) {
|
|
|
3402
3590
|
...webhookRoutes,
|
|
3403
3591
|
],
|
|
3404
3592
|
});
|
|
3593
|
+
// Declared so `farm stripe migrate` can create the billing tables, and
|
|
3594
|
+
// `farm generate --orm` can include them in schema artifacts. The connection
|
|
3595
|
+
// lives in the app's `storage.client`, not in this integration's options.
|
|
3596
|
+
return declareSchemaTables(integration, {
|
|
3597
|
+
name: "stripe",
|
|
3598
|
+
schema: integrationSchema,
|
|
3599
|
+
resolveClient: (config) => resolveConfiguredStorageRuntimeClient(config),
|
|
3600
|
+
});
|
|
3405
3601
|
}
|
package/dist/storage.d.ts
CHANGED
|
@@ -104,6 +104,11 @@ export interface StripeBillingSnapshot {
|
|
|
104
104
|
seatAllowanceOverride: number | null;
|
|
105
105
|
metadata?: Record<string, string>;
|
|
106
106
|
}
|
|
107
|
+
export interface StripeBillingCheckoutSessionClaim {
|
|
108
|
+
sessionId: string;
|
|
109
|
+
owner: StripeBillingOwner;
|
|
110
|
+
stripeCustomerId: string | null;
|
|
111
|
+
}
|
|
107
112
|
export interface StripeBillingStorageAdapter {
|
|
108
113
|
getBillingAccount(owner: StripeBillingOwner): Promise<StripeBillingSnapshot | null>;
|
|
109
114
|
getBillingAccountByStripeCustomerId(customerId: string): Promise<StripeBillingSnapshot | null>;
|
|
@@ -115,6 +120,13 @@ export interface StripeBillingStorageAdapter {
|
|
|
115
120
|
}>;
|
|
116
121
|
saveBillingSnapshot(snapshot: StripeBillingSnapshot): Promise<void>;
|
|
117
122
|
clearBillingSnapshot(owner: StripeBillingOwner): Promise<void>;
|
|
123
|
+
/** Returns true for the first claim, false for a replay, or null when unsupported. */
|
|
124
|
+
claimCheckoutSession?(claim: StripeBillingCheckoutSessionClaim): Promise<boolean | null>;
|
|
125
|
+
/**
|
|
126
|
+
* Undo a claim whose work failed, so Stripe's retry of the same session runs
|
|
127
|
+
* it again instead of finding it already claimed.
|
|
128
|
+
*/
|
|
129
|
+
releaseCheckoutSession?(sessionId: string): Promise<void>;
|
|
118
130
|
}
|
|
119
131
|
export interface StripeBillingStorageTools {
|
|
120
132
|
getClient(): Promise<unknown | undefined>;
|
|
@@ -137,6 +149,14 @@ export interface StripeBillingHooks {
|
|
|
137
149
|
}>;
|
|
138
150
|
saveBillingSnapshot?(snapshot: StripeBillingSnapshot, args: StripeBillingArgs): Promise<void>;
|
|
139
151
|
clearBillingSnapshot?(owner: StripeBillingOwner, args: StripeBillingArgs): Promise<void>;
|
|
152
|
+
/** Persistently claim a checkout session before lifecycle hooks run. */
|
|
153
|
+
claimCheckoutSession?(claim: StripeBillingCheckoutSessionClaim, args: StripeBillingArgs): Promise<boolean | null>;
|
|
154
|
+
/**
|
|
155
|
+
* Remove a claim made by `claimCheckoutSession` when saving the snapshot or a
|
|
156
|
+
* checkout hook failed. Without it a failed checkout stays claimed and
|
|
157
|
+
* Stripe's retry is skipped.
|
|
158
|
+
*/
|
|
159
|
+
releaseCheckoutSession?(sessionId: string, args: StripeBillingArgs): Promise<void>;
|
|
140
160
|
onCheckoutCreated?(payload: {
|
|
141
161
|
owner: StripeBillingOwner;
|
|
142
162
|
planId: string;
|
|
@@ -183,10 +203,12 @@ export interface StripeBillingOptions {
|
|
|
183
203
|
type PrismaStorageOptions = {
|
|
184
204
|
prisma: unknown;
|
|
185
205
|
model?: string;
|
|
206
|
+
checkoutSessionModel?: string | false;
|
|
186
207
|
};
|
|
187
208
|
type StripeOrmStorageOptions = {
|
|
188
209
|
orm: unknown | Promise<unknown> | (() => unknown | Promise<unknown>);
|
|
189
210
|
model?: string;
|
|
211
|
+
checkoutSessionModel?: string | false;
|
|
190
212
|
};
|
|
191
213
|
export declare function prismaStorageAdapter(options: PrismaStorageOptions): StripeBillingStorageAdapter;
|
|
192
214
|
export declare function ormStorageAdapter(options: StripeOrmStorageOptions): StripeBillingStorageAdapter;
|
|
@@ -202,6 +224,7 @@ type SqliteDatabase = {
|
|
|
202
224
|
type SqliteStorageOptions = {
|
|
203
225
|
db: SqliteDatabase;
|
|
204
226
|
tableName?: string;
|
|
227
|
+
checkoutSessionTableName?: string | false;
|
|
205
228
|
};
|
|
206
229
|
export declare function sqliteStorageAdapter(options: SqliteStorageOptions): StripeBillingStorageAdapter;
|
|
207
230
|
type DrizzleStorageOptions = {
|
|
@@ -221,8 +244,12 @@ type DrizzleStorageOptions = {
|
|
|
221
244
|
where(condition: unknown): Promise<unknown> | unknown;
|
|
222
245
|
};
|
|
223
246
|
};
|
|
247
|
+
delete?(table: unknown): {
|
|
248
|
+
where(condition: unknown): Promise<unknown> | unknown;
|
|
249
|
+
};
|
|
224
250
|
};
|
|
225
251
|
table: Record<string, unknown>;
|
|
252
|
+
checkoutSessionTable?: Record<string, unknown>;
|
|
226
253
|
eq(left: unknown, right: unknown): unknown;
|
|
227
254
|
and(...conditions: unknown[]): unknown;
|
|
228
255
|
};
|
package/dist/storage.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"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"}
|
package/dist/storage.js
CHANGED
|
@@ -11,6 +11,18 @@ function requireOrmModel(options) {
|
|
|
11
11
|
}
|
|
12
12
|
return candidate;
|
|
13
13
|
}
|
|
14
|
+
function getOptionalOrmModel(orm, model) {
|
|
15
|
+
const modelClient = orm?.[model];
|
|
16
|
+
if (!modelClient || typeof modelClient !== "object") {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
const candidate = modelClient;
|
|
20
|
+
return typeof candidate.findFirst === "function" &&
|
|
21
|
+
typeof candidate.create === "function" &&
|
|
22
|
+
typeof candidate.update === "function"
|
|
23
|
+
? candidate
|
|
24
|
+
: null;
|
|
25
|
+
}
|
|
14
26
|
function createBillingSnapshotData(snapshot) {
|
|
15
27
|
return {
|
|
16
28
|
ownerId: snapshot.owner.id,
|
|
@@ -29,27 +41,38 @@ function createBillingSnapshotData(snapshot) {
|
|
|
29
41
|
updatedAt: new Date(),
|
|
30
42
|
};
|
|
31
43
|
}
|
|
32
|
-
|
|
44
|
+
/**
|
|
45
|
+
* Prisma's query engine surfaces `Unknown argument \`<field>\`` validation errors
|
|
46
|
+
* one at a time, naming the unknown argument that appears first in the
|
|
47
|
+
* `data` object's key-insertion order (not the order of any caller-supplied
|
|
48
|
+
* candidate list). Extract that field so the fallback can drop the column
|
|
49
|
+
* Prisma actually complained about instead of guessing by iteration order.
|
|
50
|
+
*/
|
|
51
|
+
function extractUnknownPrismaField(error) {
|
|
33
52
|
if (!(error instanceof Error)) {
|
|
34
|
-
return
|
|
53
|
+
return null;
|
|
35
54
|
}
|
|
36
|
-
const
|
|
37
|
-
return
|
|
55
|
+
const match = error.message.replace(/\s+/g, " ").match(/Unknown argument `([^`]+)`/);
|
|
56
|
+
return match ? (match[1] ?? null) : null;
|
|
38
57
|
}
|
|
39
58
|
async function withPrismaDataFieldsFallback(operation, data, fallbackFields) {
|
|
40
59
|
let nextData = { ...data };
|
|
41
|
-
|
|
60
|
+
const allowed = new Set(fallbackFields);
|
|
61
|
+
for (;;) {
|
|
42
62
|
try {
|
|
43
63
|
return await operation(nextData);
|
|
44
64
|
}
|
|
45
65
|
catch (error) {
|
|
46
|
-
|
|
66
|
+
const unknown = extractUnknownPrismaField(error);
|
|
67
|
+
// Re-throw unless Prisma reported an unknown argument that we are
|
|
68
|
+
// permitted to drop and that is still present in the payload (the
|
|
69
|
+
// `in nextData` guard also prevents any pathological retry loop).
|
|
70
|
+
if (!unknown || !allowed.has(unknown) || !(unknown in nextData)) {
|
|
47
71
|
throw error;
|
|
48
72
|
}
|
|
49
|
-
delete nextData[
|
|
73
|
+
delete nextData[unknown];
|
|
50
74
|
}
|
|
51
75
|
}
|
|
52
|
-
return await operation(nextData);
|
|
53
76
|
}
|
|
54
77
|
/**
|
|
55
78
|
* Serialize concurrent ensureCustomer calls per owner: the double-click /
|
|
@@ -188,16 +211,23 @@ function normalizeStatus(value) {
|
|
|
188
211
|
return "free";
|
|
189
212
|
}
|
|
190
213
|
}
|
|
214
|
+
function getPrismaDelegate(prisma, modelName) {
|
|
215
|
+
const delegate = prisma?.[modelName];
|
|
216
|
+
return delegate && typeof delegate === "object" ? delegate : null;
|
|
217
|
+
}
|
|
191
218
|
function requirePrismaDelegate(options) {
|
|
192
219
|
const modelName = options.model ?? "billingBillingAccount";
|
|
193
|
-
const delegate = options.prisma
|
|
194
|
-
if (!delegate
|
|
220
|
+
const delegate = getPrismaDelegate(options.prisma, modelName);
|
|
221
|
+
if (!delegate) {
|
|
195
222
|
throw new Error(`Stripe Prisma storage adapter could not find prisma.${modelName}.`);
|
|
196
223
|
}
|
|
197
224
|
return delegate;
|
|
198
225
|
}
|
|
199
226
|
export function prismaStorageAdapter(options) {
|
|
200
227
|
const delegate = requirePrismaDelegate(options);
|
|
228
|
+
const checkoutSessionDelegate = options.checkoutSessionModel === false
|
|
229
|
+
? null
|
|
230
|
+
: getPrismaDelegate(options.prisma, options.checkoutSessionModel ?? "billingBillingCheckoutSession");
|
|
201
231
|
async function findByOwner(owner) {
|
|
202
232
|
return await delegate.findFirst({
|
|
203
233
|
where: {
|
|
@@ -214,6 +244,35 @@ export function prismaStorageAdapter(options) {
|
|
|
214
244
|
});
|
|
215
245
|
}
|
|
216
246
|
return withSerializedEnsureCustomer({
|
|
247
|
+
async releaseCheckoutSession(sessionId) {
|
|
248
|
+
await checkoutSessionDelegate?.deleteMany?.({ where: { sessionId } });
|
|
249
|
+
},
|
|
250
|
+
async claimCheckoutSession(claim) {
|
|
251
|
+
if (!checkoutSessionDelegate) {
|
|
252
|
+
return null;
|
|
253
|
+
}
|
|
254
|
+
try {
|
|
255
|
+
await checkoutSessionDelegate.create({
|
|
256
|
+
data: {
|
|
257
|
+
sessionId: claim.sessionId,
|
|
258
|
+
ownerId: claim.owner.id,
|
|
259
|
+
ownerKind: claim.owner.kind,
|
|
260
|
+
stripeCustomerId: claim.stripeCustomerId,
|
|
261
|
+
processedAt: new Date(),
|
|
262
|
+
},
|
|
263
|
+
});
|
|
264
|
+
return true;
|
|
265
|
+
}
|
|
266
|
+
catch (error) {
|
|
267
|
+
const existing = await checkoutSessionDelegate.findFirst({
|
|
268
|
+
where: { sessionId: claim.sessionId },
|
|
269
|
+
});
|
|
270
|
+
if (existing) {
|
|
271
|
+
return false;
|
|
272
|
+
}
|
|
273
|
+
throw error;
|
|
274
|
+
}
|
|
275
|
+
},
|
|
217
276
|
async getBillingAccount(owner) {
|
|
218
277
|
const record = await findByOwner(owner);
|
|
219
278
|
return record ? toSnapshot(record) : null;
|
|
@@ -319,14 +378,30 @@ export function prismaStorageAdapter(options) {
|
|
|
319
378
|
}
|
|
320
379
|
export function ormStorageAdapter(options) {
|
|
321
380
|
const modelName = options.model ?? "billingAccount";
|
|
381
|
+
const checkoutSessionModelName = options.checkoutSessionModel === false
|
|
382
|
+
? null
|
|
383
|
+
: (options.checkoutSessionModel ?? "billingCheckoutSession");
|
|
384
|
+
let ormPromise;
|
|
322
385
|
let modelPromise;
|
|
386
|
+
let checkoutSessionModelPromise;
|
|
387
|
+
function getOrm() {
|
|
388
|
+
ormPromise ??= Promise.resolve(typeof options.orm === "function" ? options.orm() : options.orm);
|
|
389
|
+
return ormPromise;
|
|
390
|
+
}
|
|
323
391
|
async function getModel() {
|
|
324
|
-
modelPromise ??=
|
|
392
|
+
modelPromise ??= getOrm().then((orm) => requireOrmModel({
|
|
325
393
|
orm,
|
|
326
394
|
model: modelName,
|
|
327
395
|
}));
|
|
328
396
|
return modelPromise;
|
|
329
397
|
}
|
|
398
|
+
async function getCheckoutSessionModel() {
|
|
399
|
+
if (!checkoutSessionModelName) {
|
|
400
|
+
return null;
|
|
401
|
+
}
|
|
402
|
+
checkoutSessionModelPromise ??= getOrm().then((orm) => getOptionalOrmModel(orm, checkoutSessionModelName));
|
|
403
|
+
return checkoutSessionModelPromise;
|
|
404
|
+
}
|
|
330
405
|
async function findByOwner(owner) {
|
|
331
406
|
const model = await getModel();
|
|
332
407
|
return await model.findFirst({
|
|
@@ -345,6 +420,37 @@ export function ormStorageAdapter(options) {
|
|
|
345
420
|
});
|
|
346
421
|
}
|
|
347
422
|
return withSerializedEnsureCustomer({
|
|
423
|
+
async releaseCheckoutSession(sessionId) {
|
|
424
|
+
const model = await getCheckoutSessionModel();
|
|
425
|
+
await model?.deleteMany?.({ where: { sessionId } });
|
|
426
|
+
},
|
|
427
|
+
async claimCheckoutSession(claim) {
|
|
428
|
+
const model = await getCheckoutSessionModel();
|
|
429
|
+
if (!model) {
|
|
430
|
+
return null;
|
|
431
|
+
}
|
|
432
|
+
try {
|
|
433
|
+
await model.create({
|
|
434
|
+
data: {
|
|
435
|
+
sessionId: claim.sessionId,
|
|
436
|
+
ownerId: claim.owner.id,
|
|
437
|
+
ownerKind: claim.owner.kind,
|
|
438
|
+
stripeCustomerId: claim.stripeCustomerId,
|
|
439
|
+
processedAt: new Date(),
|
|
440
|
+
},
|
|
441
|
+
});
|
|
442
|
+
return true;
|
|
443
|
+
}
|
|
444
|
+
catch (error) {
|
|
445
|
+
const existing = await model.findFirst({
|
|
446
|
+
where: { sessionId: claim.sessionId },
|
|
447
|
+
});
|
|
448
|
+
if (existing) {
|
|
449
|
+
return false;
|
|
450
|
+
}
|
|
451
|
+
throw error;
|
|
452
|
+
}
|
|
453
|
+
},
|
|
348
454
|
async getBillingAccount(owner) {
|
|
349
455
|
const record = await findByOwner(owner);
|
|
350
456
|
return record ? toSnapshot(record) : null;
|
|
@@ -458,6 +564,9 @@ export function ormStorageAdapter(options) {
|
|
|
458
564
|
}
|
|
459
565
|
export function sqliteStorageAdapter(options) {
|
|
460
566
|
const tableName = options.tableName ?? "billing_account";
|
|
567
|
+
const checkoutSessionTableName = options.checkoutSessionTableName === false
|
|
568
|
+
? null
|
|
569
|
+
: (options.checkoutSessionTableName ?? "billing_checkout_session");
|
|
461
570
|
const db = options.db;
|
|
462
571
|
const tableInfoStatement = db.prepare(`PRAGMA table_info("${tableName}")`);
|
|
463
572
|
const supportedColumns = typeof tableInfoStatement.all === "function"
|
|
@@ -515,10 +624,37 @@ export function sqliteStorageAdapter(options) {
|
|
|
515
624
|
stripe_customer_id = ?,
|
|
516
625
|
updated_at = CURRENT_TIMESTAMP
|
|
517
626
|
WHERE owner_kind = ? AND owner_id = ?`);
|
|
627
|
+
let insertCheckoutSession = null;
|
|
628
|
+
let deleteCheckoutSession = null;
|
|
629
|
+
if (checkoutSessionTableName) {
|
|
630
|
+
try {
|
|
631
|
+
insertCheckoutSession = db.prepare(`INSERT OR IGNORE INTO "${checkoutSessionTableName}" (
|
|
632
|
+
session_id,
|
|
633
|
+
owner_id,
|
|
634
|
+
owner_kind,
|
|
635
|
+
stripe_customer_id,
|
|
636
|
+
processed_at
|
|
637
|
+
) VALUES (?, ?, ?, ?, CURRENT_TIMESTAMP)`);
|
|
638
|
+
deleteCheckoutSession = db.prepare(`DELETE FROM "${checkoutSessionTableName}" WHERE session_id = ?`);
|
|
639
|
+
}
|
|
640
|
+
catch {
|
|
641
|
+
// Older schemas have no checkout-session table. The caller falls back to
|
|
642
|
+
// snapshot comparison until the additive Stripe migration is applied.
|
|
643
|
+
}
|
|
644
|
+
}
|
|
518
645
|
function readByOwner(owner) {
|
|
519
646
|
return selectByOwner.get(owner.kind, owner.id) ?? null;
|
|
520
647
|
}
|
|
521
648
|
return withSerializedEnsureCustomer({
|
|
649
|
+
async releaseCheckoutSession(sessionId) {
|
|
650
|
+
deleteCheckoutSession?.run(sessionId);
|
|
651
|
+
},
|
|
652
|
+
async claimCheckoutSession(claim) {
|
|
653
|
+
if (!insertCheckoutSession) {
|
|
654
|
+
return null;
|
|
655
|
+
}
|
|
656
|
+
return (insertCheckoutSession.run(claim.sessionId, claim.owner.id, claim.owner.kind, claim.stripeCustomerId).changes > 0);
|
|
657
|
+
},
|
|
522
658
|
async getBillingAccount(owner) {
|
|
523
659
|
const record = readByOwner(owner);
|
|
524
660
|
return record ? toSnapshot(record) : null;
|
|
@@ -581,7 +717,7 @@ function drizzleHasColumn(table, key) {
|
|
|
581
717
|
return key in table;
|
|
582
718
|
}
|
|
583
719
|
export function drizzleStorageAdapter(options) {
|
|
584
|
-
const { db, table, eq, and } = options;
|
|
720
|
+
const { db, table, checkoutSessionTable, eq, and } = options;
|
|
585
721
|
async function firstByOwner(owner) {
|
|
586
722
|
const rows = await db
|
|
587
723
|
.select()
|
|
@@ -599,6 +735,43 @@ export function drizzleStorageAdapter(options) {
|
|
|
599
735
|
return rows[0] ?? null;
|
|
600
736
|
}
|
|
601
737
|
return withSerializedEnsureCustomer({
|
|
738
|
+
async releaseCheckoutSession(sessionId) {
|
|
739
|
+
if (!checkoutSessionTable || !db.delete)
|
|
740
|
+
return;
|
|
741
|
+
await db.delete(checkoutSessionTable).where(eq(checkoutSessionTable.sessionId, sessionId));
|
|
742
|
+
},
|
|
743
|
+
async claimCheckoutSession(claim) {
|
|
744
|
+
if (!checkoutSessionTable) {
|
|
745
|
+
return null;
|
|
746
|
+
}
|
|
747
|
+
const findClaim = async () => {
|
|
748
|
+
const rows = await db
|
|
749
|
+
.select()
|
|
750
|
+
.from(checkoutSessionTable)
|
|
751
|
+
.where(eq(checkoutSessionTable.sessionId, claim.sessionId))
|
|
752
|
+
.limit(1);
|
|
753
|
+
return rows[0] ?? null;
|
|
754
|
+
};
|
|
755
|
+
if (await findClaim()) {
|
|
756
|
+
return false;
|
|
757
|
+
}
|
|
758
|
+
try {
|
|
759
|
+
await db.insert(checkoutSessionTable).values({
|
|
760
|
+
sessionId: claim.sessionId,
|
|
761
|
+
ownerId: claim.owner.id,
|
|
762
|
+
ownerKind: claim.owner.kind,
|
|
763
|
+
stripeCustomerId: claim.stripeCustomerId,
|
|
764
|
+
processedAt: new Date(),
|
|
765
|
+
});
|
|
766
|
+
return true;
|
|
767
|
+
}
|
|
768
|
+
catch (error) {
|
|
769
|
+
if (await findClaim()) {
|
|
770
|
+
return false;
|
|
771
|
+
}
|
|
772
|
+
throw error;
|
|
773
|
+
}
|
|
774
|
+
},
|
|
602
775
|
async getBillingAccount(owner) {
|
|
603
776
|
const record = await firstByOwner(owner);
|
|
604
777
|
return record ? toSnapshot(record) : null;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@farm.js/stripe",
|
|
3
|
-
"version": "0.1.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"description": "Stripe billing integration for Farm.js",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -34,8 +34,8 @@
|
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"stripe": "^20.4.1",
|
|
37
|
-
"@farm.js/integration-utils": "0.1.0
|
|
38
|
-
"@farm.js/core": "0.1.0
|
|
37
|
+
"@farm.js/integration-utils": "0.1.0",
|
|
38
|
+
"@farm.js/core": "0.1.0"
|
|
39
39
|
},
|
|
40
40
|
"scripts": {
|
|
41
41
|
"build": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\" && tsc",
|