From f411c6ed1190dc0259ce8ab879b05fd2d5b10c27 Mon Sep 17 00:00:00 2001 From: Steven Tey Date: Fri, 17 Jan 2025 13:33:33 -0800 Subject: [PATCH] feat: Use dub.customer.list to issue dual-sided incentives (#18452) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [FEAT] Use dub.customer to issue dual-sided incentives * update dub implementation * uncommit yarn.lock * Update yarn.lock * account for self-hosting * remove comments --------- Co-authored-by: Omar López Co-authored-by: Peer Richelsen --- apps/api/v1/pages/api/teams/_post.ts | 20 ++++++++++++++++++-- packages/features/auth/lib/dub.ts | 13 +++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/apps/api/v1/pages/api/teams/_post.ts b/apps/api/v1/pages/api/teams/_post.ts index 0a4807fa18467b..3e8b116070f539 100644 --- a/apps/api/v1/pages/api/teams/_post.ts +++ b/apps/api/v1/pages/api/teams/_post.ts @@ -2,6 +2,7 @@ import type { NextApiRequest } from "next"; import { getStripeCustomerIdFromUserId } from "@calcom/app-store/stripepayment/lib/customer"; import stripe from "@calcom/app-store/stripepayment/lib/server"; +import { getDubCustomer } from "@calcom/features/auth/lib/dub"; import { IS_PRODUCTION } from "@calcom/lib/constants"; import { IS_TEAM_BILLING_ENABLED, WEBAPP_URL } from "@calcom/lib/constants"; import { HttpError } from "@calcom/lib/http-error"; @@ -192,11 +193,26 @@ const generateTeamCheckoutSession = async ({ pendingPaymentTeamId: number; ownerId: number; }) => { - const customer = await getStripeCustomerIdFromUserId(ownerId); + const [customer, dubCustomer] = await Promise.all([ + getStripeCustomerIdFromUserId(ownerId), + getDubCustomer(ownerId.toString()), + ]); + const session = await stripe.checkout.sessions.create({ customer, mode: "subscription", - allow_promotion_codes: true, + ...(dubCustomer?.discount?.couponId + ? { + discounts: [ + { + coupon: + process.env.NODE_ENV !== "production" && dubCustomer.discount.couponTestId + ? dubCustomer.discount.couponTestId + : dubCustomer.discount.couponId, + }, + ], + } + : { allow_promotion_codes: true }), success_url: `${WEBAPP_URL}/api/teams/api/create?session_id={CHECKOUT_SESSION_ID}`, cancel_url: `${WEBAPP_URL}/settings/my-account/profile`, line_items: [ diff --git a/packages/features/auth/lib/dub.ts b/packages/features/auth/lib/dub.ts index 59acf19b971d21..fc3317594ff9f2 100644 --- a/packages/features/auth/lib/dub.ts +++ b/packages/features/auth/lib/dub.ts @@ -3,3 +3,16 @@ import { Dub } from "dub"; export const dub = new Dub({ token: process.env.DUB_API_KEY, }); + +export const getDubCustomer = async (userId: string) => { + if (!process.env.DUB_API_KEY) { + return null; + } + + const customer = await dub.customers.list({ + externalId: userId, + includeExpandedFields: true, + }); + + return customer.length > 0 ? customer[0] : null; +};