diff --git a/server/src/external/stripe/webhookHandlers/handleCusDiscountDeleted.ts b/server/src/external/stripe/webhookHandlers/handleCusDiscountDeleted.ts index 9b292e000..192c61d2c 100644 --- a/server/src/external/stripe/webhookHandlers/handleCusDiscountDeleted.ts +++ b/server/src/external/stripe/webhookHandlers/handleCusDiscountDeleted.ts @@ -7,164 +7,163 @@ import { notNullish } from "@/utils/genUtils.js"; import { createStripeCli } from "../utils.js"; export async function handleCusDiscountDeleted({ - db, - org, - discount, - env, - logger, - res, + db, + org, + discount, + env, + logger, + res, }: { - db: DrizzleCli; - org: any; - discount: any; - env: any; - logger: any; - res: any; + db: DrizzleCli; + org: any; + discount: any; + env: any; + logger: any; + res: any; }) { - const customer = await CusService.getByStripeId({ - db, - stripeId: discount.customer, - }); + const customer = await CusService.getByStripeId({ + db, + stripeId: discount.customer, + }); - if (!customer) { - logger.warn(`discount.deleted: customer ${discount.customer} not found`); - return; - } + if (!customer) { + logger.warn(`discount.deleted: customer ${discount.customer} not found`); + return; + } - if (customer.env !== env || customer.org_id !== org.id) { - logger.info( - `discount.deleted: env or org mismatch, skipping, ${customer.env} !== ${env} || ${customer.org_id} !== ${org.id}`, - ); - return; - } + if (customer.env !== env || customer.org_id !== org.id) { + logger.info( + `discount.deleted: env or org mismatch, skipping, ${customer.env} !== ${env} || ${customer.org_id} !== ${org.id}` + ); + return; + } - // Check if any redemptions available, and apply to customer if so - const redemptions = await RewardRedemptionService.getUnappliedRedemptions({ - db, - internalCustomerId: customer.internal_id, - }); + // Check if any redemptions available, and apply to customer if so + const redemptions = await RewardRedemptionService.getUnappliedRedemptions({ + db, + internalCustomerId: customer.internal_id, + }); - logger.info( - `discount.deleted:, discount ID: ${discount.id}, found ${redemptions.length} redemptions`, - ); + logger.info( + `discount.deleted:, discount ID: ${discount.id}, found ${redemptions.length} redemptions` + ); - if (redemptions.length == 0) return; + if (redemptions.length == 0) return; - const paidProductRedemption = redemptions.find( - (r) => - r.reward_program.reward.id === - (typeof discount.coupon == "string" - ? discount.coupon - : discount.coupon.id), - ); + const paidProductRedemption = redemptions.find( + (r) => + r.reward_program.reward.id === + (typeof discount.coupon == "string" + ? discount.coupon + : discount.coupon.id) + ); - if (discount.subscription) { - logger.info( - `Discount is a subscription, paidProductRedemption: ${paidProductRedemption?.id}`, - ); + if (discount.subscription) { + logger.info( + `Discount is a subscription, paidProductRedemption: ${paidProductRedemption?.id}` + ); - if (!paidProductRedemption) return; + if (!paidProductRedemption) return; - // Re-apply coupon and mark applied / redeemer applied to true - const stripeCli = createStripeCli({ - org, - env, - }); + // Re-apply coupon and mark applied / redeemer applied to true + const stripeCli = createStripeCli({ + org, + env, + }); - // Mark reward redemption as applied / redeemer applied to true + // Mark reward redemption as applied / redeemer applied to true + const sub = await stripeCli.subscriptions.retrieve(discount.subscription); - const sub = await stripeCli.subscriptions.retrieve(discount.subscription); + // can't really test because it modifies subscription affected by test clock... + try { + await stripeCli.subscriptions.update(discount.subscription, { + discounts: [ + ...(sub.discounts as string[]).map((d: string) => ({ + discount: d, + })), + { + coupon: paidProductRedemption.reward_program.reward.id as string, + }, + ], + }); + } catch (error: any) { + logger.error( + `Failed to update subscription ${discount.subscription} with paid product coupon, error: ${error.message}` + ); + throw error; + } - // can't really test because it modifies subscription affected by test clock... - try { - await stripeCli.subscriptions.update(discount.subscription, { - discounts: [ - ...(sub.discounts as string[]).map((d: string) => ({ - discount: d, - })), - { - coupon: paidProductRedemption.reward_program.reward.id as string, - }, - ], - }); - } catch (error: any) { - logger.error( - `Failed to update subscription ${discount.subscription} with paid product coupon, error: ${error.message}`, - ); - throw error; - } + // Mark reward redemption as applied / redeemer applied to true + const isReferrer = + paidProductRedemption.referral_code.internal_customer_id === + customer.internal_id; - // Mark reward redemption as applied / redeemer applied to true - const isReferrer = - paidProductRedemption.referral_code.internal_customer_id === - customer.internal_id; + await RewardRedemptionService.update({ + db, + id: paidProductRedemption.id, + updates: { + applied: isReferrer ? true : undefined, + redeemer_applied: isReferrer ? undefined : true, + }, + }); - await RewardRedemptionService.update({ - db, - id: paidProductRedemption.id, - updates: { - applied: isReferrer ? true : undefined, - redeemer_applied: isReferrer ? undefined : true, - }, - }); + return; + } - return; - } + const redemption = redemptions[0]; - const redemption = redemptions[0]; + // Apply redemption to customer + const stripeCli = createStripeCli({ + org, + env, + }); - // Apply redemption to customer - const stripeCli = createStripeCli({ - org, - env, - }); + const stripeCus = (await stripeCli.customers.retrieve( + discount.customer + )) as Stripe.Customer; - const stripeCus = (await stripeCli.customers.retrieve( - discount.customer, - )) as Stripe.Customer; + if (stripeCus && notNullish(stripeCus.discount)) { + logger.info( + `discount.deleted: stripe customer ${discount.customer} already has a discount` + ); + return; + } - if (stripeCus && notNullish(stripeCus.discount)) { - logger.info( - `discount.deleted: stripe customer ${discount.customer} already has a discount`, - ); - return; - } + const reward = await RewardService.get({ + db, + orgId: org.id, + env, + idOrInternalId: redemption.reward_program.internal_reward_id!, + }); - const reward = await RewardService.get({ - db, - orgId: org.id, - env, - idOrInternalId: redemption.reward_program.internal_reward_id!, - }); + if (!reward) { + logger.warn( + `discount.deleted: reward ${redemption.reward_program.internal_id} not found` + ); + return; + } - if (!reward) { - logger.warn( - `discount.deleted: reward ${redemption.reward_program.internal_id} not found`, - ); - return; - } + const legacyStripe = createStripeCli({ + org, + env, + legacyVersion: true, + }); - const legacyStripe = createStripeCli({ - org, - env, - legacyVersion: true, - }); + await legacyStripe.customers.update(discount.customer, { + // @ts-expect-error + coupon: reward.id, + }); - await legacyStripe.customers.update(discount.customer, { - // @ts-expect-error - coupon: reward.id, - }); + await RewardRedemptionService.update({ + db, + id: redemption.id, + updates: { + applied: true, + }, + }); - await RewardRedemptionService.update({ - db, - id: redemption.id, - updates: { - applied: true, - }, - }); - - logger.info( - `discount.deleted: applied reward ${reward.name} on customer ${customer.name} (${customer.id})`, - ); - logger.info(`Redemption ID: ${redemption.id}`); + logger.info( + `discount.deleted: applied reward ${reward.name} on customer ${customer.name} (${customer.id})` + ); + logger.info(`Redemption ID: ${redemption.id}`); } diff --git a/server/src/internal/api/rewards/rewardProgramRouter.ts b/server/src/internal/api/rewards/rewardProgramRouter.ts index 17c6c33d0..8f183eeca 100644 --- a/server/src/internal/api/rewards/rewardProgramRouter.ts +++ b/server/src/internal/api/rewards/rewardProgramRouter.ts @@ -46,8 +46,6 @@ rewardProgramRouter.put("/:id", (req, res) => env, }); - // console.log("Existing program:", existingProgram); - if (!existingProgram) { throw new RecaseError({ message: `Program with ID ${id} does not exist`, @@ -65,7 +63,7 @@ rewardProgramRouter.put("/:id", (req, res) => env, }); - // console.log("Updating program to:", rewardProgram); + // Update on existing redemptions? (should be none unless affecting stacked rewards...) if ( rewardProgram.when == RewardTriggerEvent.Checkout &&