@odla-ai/chapter 0.39.2 → 0.40.1
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 +8 -0
- package/dist/{chunk-BIYWPPH6.js → chunk-E5OXQ3DC.js} +5 -1
- package/dist/chunk-E5OXQ3DC.js.map +1 -0
- package/dist/{copy-context-Dbu9Bbq1.d.ts → copy-context-B14OOiYq.d.ts} +2 -0
- package/dist/index.cjs +36 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +36 -6
- package/dist/index.js.map +1 -1
- package/dist/ui/admin/index.d.ts +2 -2
- package/dist/ui/index.d.ts +1 -1
- package/dist/ui/index.js +1 -1
- package/dist/ui/member/index.d.ts +6 -2
- package/dist/ui/member/index.js +1 -1
- package/dist/worker/index.cjs +84 -23
- package/dist/worker/index.cjs.map +1 -1
- package/dist/worker/index.d.cts +7 -0
- package/dist/worker/index.d.ts +7 -0
- package/dist/worker/index.js +84 -23
- package/dist/worker/index.js.map +1 -1
- package/package.json +1 -1
- package/runbooks/greenfield.md +19 -8
- package/dist/chunk-BIYWPPH6.js.map +0 -1
package/dist/ui/admin/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as preact from 'preact';
|
|
2
2
|
import { ComponentChildren, JSX } from 'preact';
|
|
3
3
|
import { CrmClient, Crm, CrmRecord } from '@odla-ai/crm';
|
|
4
|
-
import { a as Chapter, b as ChapterCopy, M as MemberContentDocument, E as EffectiveMemberContent, c as MemberContentTierAuthority } from '../../copy-context-
|
|
5
|
-
export { C as ChapterCopyProvider, u as useChapterCopy } from '../../copy-context-
|
|
4
|
+
import { a as Chapter, b as ChapterCopy, M as MemberContentDocument, E as EffectiveMemberContent, c as MemberContentTierAuthority } from '../../copy-context-B14OOiYq.js';
|
|
5
|
+
export { C as ChapterCopyProvider, u as useChapterCopy } from '../../copy-context-B14OOiYq.js';
|
|
6
6
|
import { CrmLifecycleAdapter, CrmWorkspaceMasterContext, CrmWorkspaceRecordContext, RecordPanelTab } from '@odla-ai/crm/ui';
|
|
7
7
|
|
|
8
8
|
/** Normalized public auth configuration consumed by the Clerk gate. */
|
package/dist/ui/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { AdminAccountMenuProps, AdminBuilderLibraryData, AdminChrome, AdminMemberContentData, AdminNote, AdminPage, AdminResource, AdminRouteState, AdminRouteTarget, AdminRouting, AdminSection, AdminSectionContext, AdminWorkspace, AdminWorkspaceNavProps, AdmissionGrantsWorkspace, AvailabilitySectionOptions, BillingSectionOptions, BuilderLibraryAdmin, ChapterAdmin, ChapterAdminAuthAdapter, ChapterAdminAuthConfig, ChapterAdminAuthLoadContext, ChapterAdminProps, ChapterAdminUser, CollectionSectionOptions, DashboardSectionOptions, EmailSectionOptions, LeaderNetworkOverview, MeetingsSectionOptions, MemberContentAdmin, NetworkRecordsWorkspace, NetworkShareActions, NetworkShareActionsProps, Panel, PeopleSectionOptions, RecordActions, RecordActionsProps, ThemeWarning, adminFetch, adminRouteFromUrl, adminRouteHref, adminSectionFromUrl, adminSectionHref, admissionGrantsWorkspace, applicationLifecycleAdapter, availabilitySection, billingSection, builderLibrarySection, collectionSection, dashboardSection, defaultAdminSections, defaultAdminWorkspaces, emailSection, loadChapterAdminConfig, loadChapterAdminUser, meetingsSection, memberContentSection, networkRecordsWorkspace, peopleSection, useAdminResource } from './admin/index.js';
|
|
2
|
-
export { C as ChapterCopyProvider, u as useChapterCopy } from '../copy-context-
|
|
2
|
+
export { C as ChapterCopyProvider, u as useChapterCopy } from '../copy-context-B14OOiYq.js';
|
|
3
3
|
export { ApiFn, BrandStyle, BrandStyleProps, GiftOfferCards, GiftOfferCardsMode, GiftOfferCardsProps, JoinBookingSimulation, JoinConfig, JoinFlowState, JoinIsland, JoinIslandProps, JoinSimulation, JoinStepRenderContext, JoinSubmitRenderContext, JoinTier, JoinTierRenderContext, MEMBERSHIP_CARD_TOKEN_DEFAULTS, MemberContentArea, MemberContentAreaProps, MemberGifts, MemberProvisionalRenderContext, MembersArea, MembersAreaProps, MembershipCardTokenName, MembershipCards, MembershipCardsMode, MembershipCardsProps, PaymentPriceLines, PaymentStep, PaymentStepProps, PaymentStepSimulation, RescheduleProps, Rescheduler, Slot, SlotPicker, SlotPickerClasses, SlotPickerProps, SubResponse, TierPlaceholder, dayKey, dayLabel, fmtDate, fmtMoney, fullLabel, groupSlotsByDay, loadJoinResume, membershipApplicationHref, tierNeedsPayment, timeLabel, tzShort, useTierSelection } from './member/index.js';
|
|
4
4
|
import 'preact';
|
|
5
5
|
import '@odla-ai/crm';
|
package/dist/ui/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as preact from 'preact';
|
|
2
2
|
import { ComponentChildren, JSX } from 'preact';
|
|
3
|
-
import { d as MemberContentProjection, e as MemberContentPageProjection, b as ChapterCopy, f as ChapterBrand } from '../../copy-context-
|
|
4
|
-
export { C as ChapterCopyProvider, u as useChapterCopy } from '../../copy-context-
|
|
3
|
+
import { d as MemberContentProjection, e as MemberContentPageProjection, b as ChapterCopy, f as ChapterBrand } from '../../copy-context-B14OOiYq.js';
|
|
4
|
+
export { C as ChapterCopyProvider, u as useChapterCopy } from '../../copy-context-B14OOiYq.js';
|
|
5
5
|
import { FieldType, FieldConditions } from '@odla-ai/crm';
|
|
6
6
|
|
|
7
7
|
/** A bookable slot: a start instant in epoch milliseconds. */
|
|
@@ -164,6 +164,8 @@ interface PaymentStepProps {
|
|
|
164
164
|
applicationId: string;
|
|
165
165
|
/** Refund-policy copy the applicant must acknowledge to start payment. */
|
|
166
166
|
refundPolicyText: string;
|
|
167
|
+
/** Plain-language merchant identity shown before the applicant consents. */
|
|
168
|
+
merchantDisclosureText?: string;
|
|
167
169
|
/** Called once the payment succeeds (or is processing) — advance to booking. */
|
|
168
170
|
onPaid: (result: {
|
|
169
171
|
gift: boolean;
|
|
@@ -340,6 +342,8 @@ interface JoinConfig {
|
|
|
340
342
|
name: string;
|
|
341
343
|
paymentsReady: boolean;
|
|
342
344
|
refundPolicyText?: string;
|
|
345
|
+
/** Plain-language merchant identity displayed before payment consent. */
|
|
346
|
+
merchantDisclosureText?: string;
|
|
343
347
|
/** Offered membership tiers, in display order. Empty on a chapter that
|
|
344
348
|
* declares none, in which case no tier is posted and nothing renders. */
|
|
345
349
|
tiers?: readonly JoinTier[];
|
package/dist/ui/member/index.js
CHANGED
package/dist/worker/index.cjs
CHANGED
|
@@ -350,6 +350,7 @@ function joinConfig(group, paymentsReady, tiers = [], conditions = {}) {
|
|
|
350
350
|
conditions,
|
|
351
351
|
disclaimerText: group.disclaimerText ?? "",
|
|
352
352
|
refundPolicyText: group.refundPolicyText ?? "",
|
|
353
|
+
merchantDisclosureText: group.merchantDisclosureText ?? "",
|
|
353
354
|
trustCopy: group.trustCopy ?? "",
|
|
354
355
|
commitmentText: group.commitmentText ?? "",
|
|
355
356
|
normsText: group.normsText ?? "",
|
|
@@ -2353,7 +2354,14 @@ function policyOf(value, errors) {
|
|
|
2353
2354
|
errors.push("document.policy must be an object");
|
|
2354
2355
|
return void 0;
|
|
2355
2356
|
}
|
|
2356
|
-
const allowed2 = /* @__PURE__ */ new Set([
|
|
2357
|
+
const allowed2 = /* @__PURE__ */ new Set([
|
|
2358
|
+
"disclaimerText",
|
|
2359
|
+
"refundPolicyText",
|
|
2360
|
+
"merchantDisclosureText",
|
|
2361
|
+
"trustCopy",
|
|
2362
|
+
"commitmentText",
|
|
2363
|
+
"normsText"
|
|
2364
|
+
]);
|
|
2357
2365
|
unknownKeys(input, allowed2, "document.policy", errors);
|
|
2358
2366
|
const result = {};
|
|
2359
2367
|
for (const key of allowed2) {
|
|
@@ -3382,12 +3390,16 @@ function findApplicationRef(obj) {
|
|
|
3382
3390
|
const applicationId = candidates.map(pick).find(Boolean);
|
|
3383
3391
|
const appId = candidates.map((metadata) => typeof metadata.odlaAppId === "string" ? metadata.odlaAppId : void 0).find(Boolean);
|
|
3384
3392
|
const environment = candidates.map((metadata) => typeof metadata.odlaEnvironment === "string" ? metadata.odlaEnvironment : void 0).find(Boolean);
|
|
3393
|
+
const dataEnvironment = candidates.map((metadata) => typeof metadata.odlaDataEnvironment === "string" ? metadata.odlaDataEnvironment : void 0).find(Boolean);
|
|
3394
|
+
const runtime = candidates.map((metadata) => typeof metadata.odlaRuntime === "string" ? metadata.odlaRuntime : void 0).find(Boolean);
|
|
3385
3395
|
const customerId = typeof obj.customer === "string" ? obj.customer : void 0;
|
|
3386
3396
|
return {
|
|
3387
3397
|
...applicationId ? { applicationId } : {},
|
|
3388
3398
|
...customerId ? { customerId } : {},
|
|
3389
3399
|
...appId ? { appId } : {},
|
|
3390
|
-
...environment ? { environment } : {}
|
|
3400
|
+
...environment ? { environment } : {},
|
|
3401
|
+
...dataEnvironment ? { dataEnvironment } : {},
|
|
3402
|
+
...runtime ? { runtime } : {}
|
|
3391
3403
|
};
|
|
3392
3404
|
}
|
|
3393
3405
|
function findGiftRef(obj) {
|
|
@@ -3397,17 +3409,31 @@ function findGiftRef(obj) {
|
|
|
3397
3409
|
const subscription = obj.subscription_details ?? parent?.subscription_details;
|
|
3398
3410
|
const giftIntentId = pick(metaOf(obj)) ?? pick(metaOf(subscription));
|
|
3399
3411
|
const subscriptionId = typeof obj.subscription === "string" ? obj.subscription : typeof subscription?.subscription === "string" ? String(subscription.subscription) : void 0;
|
|
3400
|
-
|
|
3412
|
+
const candidates = [metaOf(obj), metaOf(subscription)];
|
|
3413
|
+
const pickIdentity = (name) => candidates.map((metadata) => typeof metadata[name] === "string" ? String(metadata[name]) : void 0).find(Boolean);
|
|
3414
|
+
const appId = pickIdentity("odlaAppId");
|
|
3415
|
+
const environment = pickIdentity("odlaEnvironment");
|
|
3416
|
+
const dataEnvironment = pickIdentity("odlaDataEnvironment");
|
|
3417
|
+
const runtime = pickIdentity("odlaRuntime");
|
|
3418
|
+
return {
|
|
3419
|
+
...giftIntentId ? { giftIntentId } : {},
|
|
3420
|
+
providerObjectId: subscriptionId ?? String(obj.id ?? ""),
|
|
3421
|
+
...appId ? { appId } : {},
|
|
3422
|
+
...environment ? { environment } : {},
|
|
3423
|
+
...dataEnvironment ? { dataEnvironment } : {},
|
|
3424
|
+
...runtime ? { runtime } : {}
|
|
3425
|
+
};
|
|
3401
3426
|
}
|
|
3402
3427
|
function normalizeWebhookEvent(event) {
|
|
3403
3428
|
const obj = event.data?.object ?? {};
|
|
3404
3429
|
const gift = findGiftRef(obj);
|
|
3405
3430
|
if (gift.giftIntentId) {
|
|
3431
|
+
const { giftIntentId, providerObjectId, ...identity } = gift;
|
|
3406
3432
|
if (event.type === "payment_intent.succeeded" || event.type === "invoice.paid" && obj.billing_reason === "subscription_create") {
|
|
3407
|
-
return { kind: "gift_paid", giftIntentId
|
|
3433
|
+
return { kind: "gift_paid", giftIntentId, providerObjectId, ...identity };
|
|
3408
3434
|
}
|
|
3409
|
-
if (event.type === "charge.refunded") return { kind: "gift_revoked", giftIntentId
|
|
3410
|
-
if (event.type === "customer.subscription.deleted") return { kind: "gift_revoked", giftIntentId
|
|
3435
|
+
if (event.type === "charge.refunded") return { kind: "gift_revoked", giftIntentId, ...identity, reason: "refunded" };
|
|
3436
|
+
if (event.type === "customer.subscription.deleted") return { kind: "gift_revoked", giftIntentId, ...identity, reason: "canceled" };
|
|
3411
3437
|
return { kind: "ignored", type: event.type };
|
|
3412
3438
|
}
|
|
3413
3439
|
const ref = findApplicationRef(obj);
|
|
@@ -3484,7 +3510,9 @@ function createStripeProvider(config) {
|
|
|
3484
3510
|
groupId: input.groupId,
|
|
3485
3511
|
email: input.email,
|
|
3486
3512
|
odlaAppId: input.appId,
|
|
3487
|
-
odlaEnvironment: input.environment
|
|
3513
|
+
odlaEnvironment: input.environment,
|
|
3514
|
+
odlaDataEnvironment: input.environment,
|
|
3515
|
+
...input.runtime ? { odlaRuntime: input.runtime } : {}
|
|
3488
3516
|
};
|
|
3489
3517
|
let customerId = input.existingCustomerId;
|
|
3490
3518
|
if (!customerId) {
|
|
@@ -3772,12 +3800,16 @@ var clientSecret = (value) => {
|
|
|
3772
3800
|
const nested = confirmation?.client_secret ?? intent?.client_secret;
|
|
3773
3801
|
return typeof nested === "string" && nested ? nested : null;
|
|
3774
3802
|
};
|
|
3775
|
-
async function startGiftProviderCheckout(secretKey, intent, email, existingCustomerId) {
|
|
3803
|
+
async function startGiftProviderCheckout(secretKey, intent, email, existingCustomerId, runtime) {
|
|
3776
3804
|
const offer = intent.offerSnapshot;
|
|
3777
3805
|
const metadata = {
|
|
3778
3806
|
giftIntentId: intent.id,
|
|
3779
3807
|
chapterId: intent.chapterId,
|
|
3780
3808
|
environment: intent.environment,
|
|
3809
|
+
odlaAppId: intent.chapterId,
|
|
3810
|
+
odlaEnvironment: intent.environment,
|
|
3811
|
+
odlaDataEnvironment: intent.environment,
|
|
3812
|
+
...runtime ? { odlaRuntime: runtime } : {},
|
|
3781
3813
|
offerId: intent.offerId
|
|
3782
3814
|
};
|
|
3783
3815
|
let customerId = existingCustomerId;
|
|
@@ -3827,6 +3859,7 @@ async function startGiftIntent(db, input) {
|
|
|
3827
3859
|
id: input.id,
|
|
3828
3860
|
chapterId: input.chapterId,
|
|
3829
3861
|
environment: input.environment,
|
|
3862
|
+
...input.runtime ? { runtime: input.runtime } : {},
|
|
3830
3863
|
purchaserType: input.purchaserType,
|
|
3831
3864
|
purchaserEmailNormalized: input.purchaserEmailNormalized,
|
|
3832
3865
|
...input.purchaserApplicationId ? { purchaserApplicationId: input.purchaserApplicationId } : {},
|
|
@@ -3846,7 +3879,7 @@ async function startGiftIntent(db, input) {
|
|
|
3846
3879
|
stored = write.duplicate ? first2((await db.query({ giftPurchaseIntents: { $: { where: { id: input.id }, limit: 1 } } })).giftPurchaseIntents) : attrs;
|
|
3847
3880
|
if (!write.duplicate) giftCode = prepared.code;
|
|
3848
3881
|
}
|
|
3849
|
-
if (!stored || stored.chapterId !== input.chapterId || stored.environment !== input.environment || stored.offerId !== input.offer.id || stored.purchaserEmailNormalized !== input.purchaserEmailNormalized) {
|
|
3882
|
+
if (!stored || stored.chapterId !== input.chapterId || stored.environment !== input.environment || stored.runtime !== input.runtime || stored.offerId !== input.offer.id || stored.purchaserEmailNormalized !== input.purchaserEmailNormalized) {
|
|
3850
3883
|
throw new Error("gift purchase intent does not match this checkout");
|
|
3851
3884
|
}
|
|
3852
3885
|
if (stored.status === "paid") throw new Error("gift purchase is already paid");
|
|
@@ -3854,7 +3887,8 @@ async function startGiftIntent(db, input) {
|
|
|
3854
3887
|
input.stripeSecret,
|
|
3855
3888
|
stored,
|
|
3856
3889
|
input.purchaserEmail,
|
|
3857
|
-
typeof stored.providerCustomerId === "string" ? stored.providerCustomerId : input.existingCustomerId
|
|
3890
|
+
typeof stored.providerCustomerId === "string" ? stored.providerCustomerId : input.existingCustomerId,
|
|
3891
|
+
input.runtime
|
|
3858
3892
|
);
|
|
3859
3893
|
await db.transact([{ t: "update", ns: "giftPurchaseIntents", id: input.id, attrs: {
|
|
3860
3894
|
status: "checkout_ready",
|
|
@@ -3873,18 +3907,29 @@ async function startGiftIntent(db, input) {
|
|
|
3873
3907
|
};
|
|
3874
3908
|
}
|
|
3875
3909
|
|
|
3910
|
+
// src/stripe-runtime.ts
|
|
3911
|
+
function stripeWebhookSecretName(runtime) {
|
|
3912
|
+
if (!runtime) return "stripe_webhook_secret";
|
|
3913
|
+
if (!/^[a-z0-9]{2,12}$/.test(runtime) || runtime === "prod" || runtime === "production") {
|
|
3914
|
+
throw new Error("ODLA_RUNTIME is invalid");
|
|
3915
|
+
}
|
|
3916
|
+
return `stripe_webhook_secret__${runtime}`;
|
|
3917
|
+
}
|
|
3918
|
+
|
|
3919
|
+
// src/payments-route-support.ts
|
|
3920
|
+
var paymentErrorCode = (error) => error && typeof error === "object" && typeof error.code === "string" ? error.code : "unknown";
|
|
3921
|
+
function paymentLineItems(group) {
|
|
3922
|
+
const standard = Number(group.standardPriceCents ?? 0);
|
|
3923
|
+
const discount = Number(group.foundingDiscountCents ?? 0);
|
|
3924
|
+
return { standardCents: standard, discountCents: discount, dueTodayCents: standard - discount };
|
|
3925
|
+
}
|
|
3926
|
+
|
|
3876
3927
|
// src/worker-routes-payments.ts
|
|
3877
|
-
var codeOf = (err) => err && typeof err === "object" && typeof err.code === "string" ? err.code : "unknown";
|
|
3878
3928
|
async function firstRow2(db, ns, q) {
|
|
3879
3929
|
const res = await db.query({ [ns]: { $: q } });
|
|
3880
3930
|
const rows4 = res[ns];
|
|
3881
3931
|
return Array.isArray(rows4) ? rows4[0] : void 0;
|
|
3882
3932
|
}
|
|
3883
|
-
function lineItems(group) {
|
|
3884
|
-
const standard = Number(group.standardPriceCents ?? 0);
|
|
3885
|
-
const discount = Number(group.foundingDiscountCents ?? 0);
|
|
3886
|
-
return { standardCents: standard, discountCents: discount, dueTodayCents: standard - discount };
|
|
3887
|
-
}
|
|
3888
3933
|
async function findApplication(db, event) {
|
|
3889
3934
|
if ("applicationId" in event && event.applicationId) {
|
|
3890
3935
|
return firstRow2(db, "applications", { where: { id: event.applicationId }, limit: 1 });
|
|
@@ -3975,6 +4020,7 @@ async function startSubscription(req, env, ctx) {
|
|
|
3975
4020
|
chapterId: ctx.chapter.id,
|
|
3976
4021
|
environment: env.ODLA_ENV,
|
|
3977
4022
|
offer,
|
|
4023
|
+
...env.ODLA_RUNTIME ? { runtime: env.ODLA_RUNTIME } : {},
|
|
3978
4024
|
purchaserType: "application",
|
|
3979
4025
|
purchaserEmail: String(app.email ?? ""),
|
|
3980
4026
|
purchaserEmailNormalized: normalizeChapterEmail(String(app.email ?? "")),
|
|
@@ -4007,6 +4053,7 @@ async function startSubscription(req, env, ctx) {
|
|
|
4007
4053
|
result = await provider.createSubscription({
|
|
4008
4054
|
appId: env.ODLA_APP_ID,
|
|
4009
4055
|
environment: env.ODLA_ENV,
|
|
4056
|
+
...env.ODLA_RUNTIME ? { runtime: env.ODLA_RUNTIME } : {},
|
|
4010
4057
|
applicationId,
|
|
4011
4058
|
groupId: String(group.id),
|
|
4012
4059
|
email: String(app.email ?? ""),
|
|
@@ -4015,29 +4062,35 @@ async function startSubscription(req, env, ctx) {
|
|
|
4015
4062
|
existingCustomerId: typeof app.stripeCustomerId === "string" ? app.stripeCustomerId : void 0
|
|
4016
4063
|
});
|
|
4017
4064
|
} catch (err) {
|
|
4018
|
-
return json({ error: "payment setup failed", code:
|
|
4065
|
+
return json({ error: "payment setup failed", code: paymentErrorCode(err) }, 502);
|
|
4019
4066
|
}
|
|
4020
4067
|
await db.transact([
|
|
4021
4068
|
{
|
|
4022
4069
|
t: "update",
|
|
4023
4070
|
ns: "applications",
|
|
4024
4071
|
id: applicationId,
|
|
4025
|
-
attrs: {
|
|
4072
|
+
attrs: {
|
|
4073
|
+
stripeCustomerId: result.customerId,
|
|
4074
|
+
stripeSubscriptionId: result.subscriptionId,
|
|
4075
|
+
...env.ODLA_RUNTIME ? { stripeRuntime: env.ODLA_RUNTIME } : {},
|
|
4076
|
+
refundPolicyAckAt: Date.now()
|
|
4077
|
+
}
|
|
4026
4078
|
}
|
|
4027
4079
|
]);
|
|
4028
|
-
return json({ clientSecret: result.clientSecret, publishableKey: group.stripePublishableKey ?? null, lineItems:
|
|
4080
|
+
return json({ clientSecret: result.clientSecret, publishableKey: group.stripePublishableKey ?? null, lineItems: paymentLineItems(group) });
|
|
4029
4081
|
}
|
|
4030
4082
|
async function ingestWebhook(req, env, ctx) {
|
|
4031
4083
|
const db = ctx.makeDb(env);
|
|
4032
|
-
const webhookSecret = await getVaultSecret(db,
|
|
4084
|
+
const webhookSecret = await getVaultSecret(db, stripeWebhookSecretName(env.ODLA_RUNTIME));
|
|
4033
4085
|
if (!webhookSecret) return json({ error: "webhook not configured" }, 503);
|
|
4034
4086
|
const rawBody = await req.text();
|
|
4035
4087
|
const ingest = await createStripeProvider({ webhookSecret }).ingestWebhook(rawBody, req.headers.get("stripe-signature") ?? "");
|
|
4036
4088
|
if (!ingest.ok) return json({ error: "invalid signature" }, 400);
|
|
4037
4089
|
const { eventId, event } = ingest;
|
|
4038
4090
|
if (event.kind === "ignored") return json({ ok: true, ignored: event.type });
|
|
4039
|
-
const identifiedEnvironment = event.appId !== void 0 || event.environment !== void 0;
|
|
4040
|
-
|
|
4091
|
+
const identifiedEnvironment = event.appId !== void 0 || event.environment !== void 0 || event.dataEnvironment !== void 0 || event.runtime !== void 0;
|
|
4092
|
+
const eventDataEnvironment = event.dataEnvironment ?? event.environment;
|
|
4093
|
+
if (env.ODLA_APP_ID && identifiedEnvironment && (event.appId !== env.ODLA_APP_ID || eventDataEnvironment !== env.ODLA_ENV || event.runtime !== void 0 && event.runtime !== env.ODLA_RUNTIME)) {
|
|
4041
4094
|
return json({ ok: true, matched: false });
|
|
4042
4095
|
}
|
|
4043
4096
|
if (event.kind === "gift_paid" || event.kind === "gift_revoked") {
|
|
@@ -4045,6 +4098,9 @@ async function ingestWebhook(req, env, ctx) {
|
|
|
4045
4098
|
if (!intent || intent.chapterId !== ctx.chapter.id || intent.environment !== env.ODLA_ENV) {
|
|
4046
4099
|
return json({ ok: true, matched: false });
|
|
4047
4100
|
}
|
|
4101
|
+
if (event.runtime === void 0 && typeof intent.runtime === "string" && intent.runtime !== env.ODLA_RUNTIME) {
|
|
4102
|
+
return json({ ok: true, matched: false });
|
|
4103
|
+
}
|
|
4048
4104
|
if (event.kind === "gift_paid") {
|
|
4049
4105
|
if (intent.providerObjectId !== event.providerObjectId) return json({ ok: true, matched: false });
|
|
4050
4106
|
if (intent.status === "refunded" || intent.status === "canceled") return json({ ok: true, matched: false });
|
|
@@ -4068,6 +4124,9 @@ async function ingestWebhook(req, env, ctx) {
|
|
|
4068
4124
|
}
|
|
4069
4125
|
const app = await findApplication(db, event);
|
|
4070
4126
|
if (!app) return json({ ok: true, matched: false });
|
|
4127
|
+
if (event.runtime === void 0 && typeof app.stripeRuntime === "string" && app.stripeRuntime !== env.ODLA_RUNTIME) {
|
|
4128
|
+
return json({ ok: true, matched: false });
|
|
4129
|
+
}
|
|
4071
4130
|
const patch = webhookPatch(event, String(app.status ?? ""));
|
|
4072
4131
|
let next = app;
|
|
4073
4132
|
if (Object.keys(patch).length) {
|
|
@@ -4139,7 +4198,8 @@ var handleGifts = async (req, url, env, ctx) => {
|
|
|
4139
4198
|
return json({
|
|
4140
4199
|
offers: publicGiftOffers(control3?.document.giftOffers, Date.now()),
|
|
4141
4200
|
claims: buyerGiftClaims(rows2(found.giftClaims).sort((a, b) => Number(b.createdAt) - Number(a.createdAt)), Date.now()),
|
|
4142
|
-
refundPolicyText: typeof group?.refundPolicyText === "string" ? group.refundPolicyText : ""
|
|
4201
|
+
refundPolicyText: typeof group?.refundPolicyText === "string" ? group.refundPolicyText : "",
|
|
4202
|
+
merchantDisclosureText: typeof group?.merchantDisclosureText === "string" ? group.merchantDisclosureText : ""
|
|
4143
4203
|
});
|
|
4144
4204
|
}
|
|
4145
4205
|
if (req.method === "POST" && url.pathname === "/api/gifts/checkout") {
|
|
@@ -4170,6 +4230,7 @@ var handleGifts = async (req, url, env, ctx) => {
|
|
|
4170
4230
|
offer,
|
|
4171
4231
|
purchaserType: "member",
|
|
4172
4232
|
purchaserEmail: user.email,
|
|
4233
|
+
...env.ODLA_RUNTIME ? { runtime: env.ODLA_RUNTIME } : {},
|
|
4173
4234
|
purchaserEmailNormalized: emailNormalized,
|
|
4174
4235
|
purchaserUserId: user.userId,
|
|
4175
4236
|
...typeof app?.stripeCustomerId === "string" ? { existingCustomerId: app.stripeCustomerId } : {},
|