diff --git a/site/app/api/lemon-squeezy/models.ts b/site/app/api/lemon-squeezy/models.ts index 7993cc652..1d83cfae7 100644 --- a/site/app/api/lemon-squeezy/models.ts +++ b/site/app/api/lemon-squeezy/models.ts @@ -3,20 +3,20 @@ import { z } from 'zod' const Attributes = z .object({ pause: z.any().optional(), - status: z.enum(['ON_TRIAL', 'ACTIVE', 'PAUSED', 'PAST_DUE', 'UNPAID', 'CANCELLED', 'EXPIRED']), - orderId: z.number(), - storeId: z.number(), - cancelled: z.date().nullable().optional(), - userName: z.string(), - cardBrand: z.enum(['VISA', 'MASTERCARD', 'AMERICAN_EXPRESS', 'DISCOVER', 'JCB', 'DINERS_CLUB']), - productId: z.number(), - variantId: z.number(), - customerId: z.number(), - productName: z.string(), - variantName: z.string(), - orderItemId: z.number(), - cardLastFour: z.string(), - statusFormatted: z.string(), + status: z.enum(['on_trial', 'active', 'paused', 'past_due', 'unpaid', 'cancelled', 'expired']), + order_id: z.number(), + store_id: z.number(), + cancelled: z.boolean().nullable().optional(), + user_name: z.string(), + card_brand: z.enum(['visa', 'mastercard', 'american_express', 'discover', 'jcb', 'diners_club']), + product_id: z.number(), + variant_id: z.number(), + customer_id: z.number(), + product_name: z.string(), + variant_name: z.string(), + order_item_id: z.number(), + card_last_four: z.string(), + status_formatted: z.string(), }) const Links = z @@ -37,8 +37,8 @@ const Relationships = z product: Order, variant: Order, customer: Order, - orderItem: Order, - subscriptionInvoices: Order, + 'order-item': Order, + 'subscription-invoices': Order, }) const Data = z @@ -52,12 +52,8 @@ const Data = z const Meta = z .object({ - testMode: z.boolean(), - eventName: z.string(), - customData: z - .object({ - userId: z.string(), - }) + test_mode: z.boolean(), + event_name: z.string(), }) export const SLemonSqueezyWebhookRequest = z diff --git a/site/app/api/lemon-squeezy/route.ts b/site/app/api/lemon-squeezy/route.ts index 6482b0016..14f14f6d6 100644 --- a/site/app/api/lemon-squeezy/route.ts +++ b/site/app/api/lemon-squeezy/route.ts @@ -37,10 +37,9 @@ export async function POST(request: Request) { if (type === 'subscriptions') { const parsedBody = SLemonSqueezyWebhookRequest.parse(body) - if (parsedBody.meta.eventName === 'subscription_created') { + if (parsedBody.meta.event_name === 'subscription_created') { const createdSubscription = await prisma.subscription.create({ data: { - userId: parsedBody.meta.customData.userId, id: parsedBody.data.id, ...parsedBody.data.attributes, }, @@ -56,13 +55,12 @@ export async function POST(request: Request) { }) } - if (parsedBody.meta.eventName === 'subscription_updated') { + if (parsedBody.meta.event_name === 'subscription_updated') { const updatedSubscription = await prisma.subscription.update({ where: { id: parsedBody.data.id, }, data: { - userId: parsedBody.meta.customData.userId, id: parsedBody.data.id, ...parsedBody.data.attributes, }, diff --git a/site/components/ProductVariants.tsx b/site/components/ProductVariants.tsx index 0ccfa538f..9ceb37993 100644 --- a/site/components/ProductVariants.tsx +++ b/site/components/ProductVariants.tsx @@ -56,9 +56,9 @@ export default function ProductVariants({ productId }: { productId: string }) { const email = session?.user?.email const name = session?.user?.name - //const userId = session?.user?.id + // const userId = session?.userId - //url.searchParams.append('checkout[custom][user_id]', userId) + // url.searchParams.append('checkout[custom][user_id]', userId) if (email) url.searchParams.append('checkout[email]', email) if (name) url.searchParams.append('checkout[name]', name) diff --git a/site/prisma/migrations/20231022220224_added_lemon_squeezy/migration.sql b/site/prisma/migrations/20231022220224_added_lemon_squeezy/migration.sql deleted file mode 100644 index 426863369..000000000 --- a/site/prisma/migrations/20231022220224_added_lemon_squeezy/migration.sql +++ /dev/null @@ -1,161 +0,0 @@ --- CreateEnum -CREATE TYPE "SubscriptionStatus" AS ENUM ('ON_TRIAL', 'ACTIVE', 'PAUSED', 'PAST_DUE', 'UNPAID', 'CANCELLED', 'EXPIRED'); - --- CreateEnum -CREATE TYPE "PauseMode" AS ENUM ('VOID', 'FREE'); - --- CreateEnum -CREATE TYPE "CardBrand" AS ENUM ('VISA', 'MASTERCARD', 'AMERICAN_EXPRESS', 'DISCOVER', 'JCB', 'DINERS_CLUB'); - --- CreateEnum -CREATE TYPE "BillingReason" AS ENUM ('INITIAL', 'RENEWAL', 'UPDATED'); - --- CreateEnum -CREATE TYPE "InvoiceStatus" AS ENUM ('PAID', 'OPEN', 'VOID', 'UNCOLLECTIBLE', 'DRAFT'); - --- CreateEnum -CREATE TYPE "StorePlan" AS ENUM ('FRESH', 'SWEET', 'FREE'); - --- CreateEnum -CREATE TYPE "ProductStatus" AS ENUM ('DRAFT', 'PUBLISHED'); - --- CreateEnum -CREATE TYPE "VariantStatus" AS ENUM ('PENDING', 'DRAFT', 'PUBLISHED'); - --- CreateEnum -CREATE TYPE "VariantInterval" AS ENUM ('DAY', 'WEEK', 'MONTH', 'YEAR'); - --- CreateEnum -CREATE TYPE "LicenseLengthUnit" AS ENUM ('DAYS', 'MONTHS', 'YEARS'); - --- CreateTable -CREATE TABLE "Subscription" ( - "id" SERIAL NOT NULL, - "user_id" TEXT NOT NULL, - "store_id" INTEGER, - "customer_id" INTEGER, - "order_id" INTEGER, - "order_item_id" INTEGER, - "product_id" INTEGER, - "variant_id" INTEGER, - "product_name" TEXT, - "variant_name" TEXT, - "user_name" TEXT, - "user_email" TEXT, - "status" "SubscriptionStatus" NOT NULL, - "status_formatted" TEXT, - "card_brand" "CardBrand" NOT NULL, - "card_last_four" TEXT NOT NULL, - "pause" JSONB, - "cancelled" TIMESTAMP(3), - - CONSTRAINT "Subscription_pkey" PRIMARY KEY ("id") -); - --- CreateTable -CREATE TABLE "SubscriptionInvoice" ( - "id" SERIAL NOT NULL, - "store_id" INTEGER, - "subscription_id" INTEGER, - "billing_reason" "BillingReason" NOT NULL, - "card_brand" "CardBrand" NOT NULL, - "card_last_four" TEXT NOT NULL, - "currency" TEXT NOT NULL, - "currency_rate" DECIMAL(65,30) NOT NULL, - "subtotal" INTEGER NOT NULL, - "discount_total" INTEGER NOT NULL, - "tax" INTEGER NOT NULL, - "total" INTEGER NOT NULL, - "subtotal_usd" INTEGER NOT NULL, - "discount_total_usd" INTEGER NOT NULL, - "tax_usd" INTEGER NOT NULL, - "total_usd" INTEGER NOT NULL, - "status" "InvoiceStatus" NOT NULL, - "status_formatted" TEXT, - "refunded" BOOLEAN NOT NULL, - "refunded_at" TIMESTAMP(3), - "urls" JSONB, - "created_at" TIMESTAMP(3) NOT NULL, - "updated_at" TIMESTAMP(3) NOT NULL, - "test_mode" BOOLEAN NOT NULL, - - CONSTRAINT "SubscriptionInvoice_pkey" PRIMARY KEY ("id") -); - --- CreateTable -CREATE TABLE "Store" ( - "id" TEXT NOT NULL, - "name" TEXT NOT NULL, - "slug" TEXT NOT NULL, - "domain" TEXT NOT NULL, - "url" TEXT NOT NULL, - "avatar_url" TEXT NOT NULL, - "plan" "StorePlan" NOT NULL, - "country" TEXT NOT NULL, - "country_nicename" TEXT NOT NULL, - "currency" TEXT NOT NULL, - "total_sales" INTEGER NOT NULL, - "total_revenue" INTEGER NOT NULL, - "thirty_day_sales" INTEGER NOT NULL, - "thirty_day_revenue" INTEGER NOT NULL, - "created_at" TIMESTAMP(3) NOT NULL, - "updated_at" TIMESTAMP(3) NOT NULL, - - CONSTRAINT "Store_pkey" PRIMARY KEY ("id") -); - --- CreateTable -CREATE TABLE "Product" ( - "id" TEXT NOT NULL, - "store_id" INTEGER NOT NULL, - "name" TEXT NOT NULL, - "slug" TEXT NOT NULL, - "description" TEXT NOT NULL, - "status" "ProductStatus" NOT NULL, - "status_formatted" TEXT NOT NULL, - "thumb_url" TEXT, - "large_thumb_url" TEXT, - "price" INTEGER NOT NULL, - "pay_what_you_want" BOOLEAN NOT NULL, - "from_price" INTEGER, - "to_price" INTEGER, - "buy_now_url" TEXT NOT NULL, - "price_formatted" TEXT NOT NULL, - "created_at" TIMESTAMP(3) NOT NULL, - "updated_at" TIMESTAMP(3) NOT NULL, - "test_mode" BOOLEAN NOT NULL, - - CONSTRAINT "Product_pkey" PRIMARY KEY ("id") -); - --- CreateTable -CREATE TABLE "ProductVariant" ( - "id" TEXT NOT NULL, - "product_id" INTEGER NOT NULL, - "name" TEXT NOT NULL, - "slug" TEXT NOT NULL, - "description" TEXT NOT NULL, - "price" INTEGER NOT NULL, - "is_subscription" BOOLEAN NOT NULL, - "interval" "VariantInterval", - "interval_count" INTEGER, - "has_free_trial" BOOLEAN NOT NULL, - "trial_interval" "VariantInterval" NOT NULL, - "trial_interval_count" INTEGER NOT NULL, - "pay_what_you_want" BOOLEAN NOT NULL, - "min_price" INTEGER, - "suggested_price" INTEGER, - "has_license_keys" BOOLEAN NOT NULL, - "license_activation_limit" INTEGER, - "is_license_limit_unlimited" BOOLEAN NOT NULL, - "license_length_value" INTEGER, - "license_length_unit" "LicenseLengthUnit" NOT NULL, - "is_license_length_unlimited" BOOLEAN NOT NULL, - "sort" INTEGER NOT NULL, - "status" "VariantStatus" NOT NULL, - "status_formatted" TEXT NOT NULL, - "created_at" TIMESTAMP(3) NOT NULL, - "updated_at" TIMESTAMP(3) NOT NULL, - - CONSTRAINT "ProductVariant_pkey" PRIMARY KEY ("id") -); diff --git a/site/prisma/migrations/20230827215954_init/migration.sql b/site/prisma/migrations/20231112220356_init/migration.sql similarity index 69% rename from site/prisma/migrations/20230827215954_init/migration.sql rename to site/prisma/migrations/20231112220356_init/migration.sql index e785d42d6..ed85f140f 100644 --- a/site/prisma/migrations/20230827215954_init/migration.sql +++ b/site/prisma/migrations/20231112220356_init/migration.sql @@ -1,3 +1,9 @@ +-- CreateEnum +CREATE TYPE "SubscriptionStatus" AS ENUM ('on_trial', 'active', 'paused', 'past_due', 'unpaid', 'cancelled', 'expired'); + +-- CreateEnum +CREATE TYPE "CardBrand" AS ENUM ('visa', 'mastercard', 'american_express', 'discover', 'jcb', 'diners_club'); + -- CreateTable CREATE TABLE "accounts" ( "id" TEXT NOT NULL, @@ -45,6 +51,29 @@ CREATE TABLE "verificationtokens" ( "expires" TIMESTAMP(3) NOT NULL ); +-- CreateTable +CREATE TABLE "Subscription" ( + "id" SERIAL NOT NULL, + "store_id" INTEGER, + "customer_id" INTEGER, + "order_id" INTEGER, + "order_item_id" INTEGER, + "product_id" INTEGER, + "variant_id" INTEGER, + "product_name" TEXT, + "variant_name" TEXT, + "user_name" TEXT, + "user_email" TEXT, + "status" "SubscriptionStatus" NOT NULL, + "status_formatted" TEXT, + "card_brand" "CardBrand" NOT NULL, + "card_last_four" TEXT NOT NULL, + "pause" JSONB, + "cancelled" BOOLEAN, + + CONSTRAINT "Subscription_pkey" PRIMARY KEY ("id") +); + -- CreateIndex CREATE UNIQUE INDEX "accounts_provider_provider_account_id_key" ON "accounts"("provider", "provider_account_id"); diff --git a/site/prisma/schema.prisma b/site/prisma/schema.prisma index 7b1fc63dd..d65e616b8 100644 --- a/site/prisma/schema.prisma +++ b/site/prisma/schema.prisma @@ -60,186 +60,40 @@ model VerificationToken { } enum SubscriptionStatus { - ON_TRIAL - ACTIVE - PAUSED - PAST_DUE - UNPAID - CANCELLED - EXPIRED -} - -enum PauseMode { - VOID - FREE + on_trial + active + paused + past_due + unpaid + cancelled + expired } enum CardBrand { - VISA - MASTERCARD - AMERICAN_EXPRESS - DISCOVER - JCB - DINERS_CLUB + visa + mastercard + american_express + discover + jcb + diners_club } model Subscription { id Int @id @default(autoincrement()) - userId String @map("user_id") - storeId Int? @map("store_id") - customerId Int? @map("customer_id") - orderId Int? @map("order_id") - orderItemId Int? @map("order_item_id") - productId Int? @map("product_id") - variantId Int? @map("variant_id") - productName String? @map("product_name") - variantName String? @map("variant_name") - userName String? @map("user_name") - userEmail String? @map("user_email") - status SubscriptionStatus @map("status") - statusFormatted String? @map("status_formatted") - cardBrand CardBrand @map("card_brand") - cardLastFour String @map("card_last_four") + store_id Int? + customer_id Int? + order_id Int? + order_item_id Int? + product_id Int? + variant_id Int? + product_name String? + variant_name String? + user_name String? + user_email String? + status SubscriptionStatus + status_formatted String? + card_brand CardBrand + card_last_four String pause Json? - cancelled DateTime? -} - -enum BillingReason { - INITIAL - RENEWAL - UPDATED -} - -enum InvoiceStatus { - PAID - OPEN - VOID - UNCOLLECTIBLE - DRAFT -} - -model SubscriptionInvoice { - id Int @id @default(autoincrement()) - storeId Int? @map("store_id") - subscriptionId Int? @map("subscription_id") - billingReason BillingReason @map("billing_reason") - cardBrand CardBrand @map("card_brand") - cardLastFour String @map("card_last_four") - currency String @map("currency") - currencyRate Decimal @map("currency_rate") - subtotal Int @map("subtotal") - discountTotal Int @map("discount_total") - tax Int @map("tax") - total Int @map("total") - subtotalUsd Int @map("subtotal_usd") - discountTotalUsd Int @map("discount_total_usd") - taxUsd Int @map("tax_usd") - totalUsd Int @map("total_usd") - status InvoiceStatus @map("status") - statusFormatted String? @map("status_formatted") - refunded Boolean @map("refunded") - refundedAt DateTime? @map("refunded_at") - urls Json? @map("urls") - createdAt DateTime @map("created_at") - updatedAt DateTime @map("updated_at") - testMode Boolean @map("test_mode") -} - - enum StorePlan { - FRESH - SWEET - FREE -} - -model Store { - id String @id @map("id") - name String @map("name") - slug String @map("slug") - domain String @map("domain") - url String @map("url") - avatarUrl String @map("avatar_url") - plan StorePlan @map("plan") - country String @map("country") - countryNicename String @map("country_nicename") - currency String @map("currency") - totalSales Int @map("total_sales") - totalRevenue Int @map("total_revenue") - thirtyDaySales Int @map("thirty_day_sales") - thirtyDayRevenue Int @map("thirty_day_revenue") - createdAt DateTime @map("created_at") - updatedAt DateTime @map("updated_at") -} - -enum ProductStatus { - DRAFT - PUBLISHED -} - -model Product { - id String @id @map("id") - storeId Int @map("store_id") - name String @map("name") - slug String @map("slug") - description String @map("description") - status ProductStatus @map("status") - statusFormatted String @map("status_formatted") - thumbUrl String? @map("thumb_url") - largeThumbUrl String? @map("large_thumb_url") - price Int @map("price") - payWhatYouWant Boolean @map("pay_what_you_want") - fromPrice Int? @map("from_price") - toPrice Int? @map("to_price") - buyNowUrl String @map("buy_now_url") - priceFormatted String @map("price_formatted") - createdAt DateTime @map("created_at") - updatedAt DateTime @map("updated_at") - testMode Boolean @map("test_mode") -} - -enum VariantStatus { - PENDING - DRAFT - PUBLISHED -} - -enum VariantInterval { - DAY - WEEK - MONTH - YEAR -} - -enum LicenseLengthUnit { - DAYS - MONTHS - YEARS -} - -model ProductVariant { - id String @id @map("id") - productId Int @map("product_id") - name String @map("name") - slug String @map("slug") - description String @map("description") - price Int @map("price") - isSubscription Boolean @map("is_subscription") - interval VariantInterval? @map("interval") - intervalCount Int? @map("interval_count") - hasFreeTrial Boolean @map("has_free_trial") - trialInterval VariantInterval @map("trial_interval") - trialIntervalCount Int @map("trial_interval_count") - payWhatYouWant Boolean @map("pay_what_you_want") - minPrice Int? @map("min_price") - suggestedPrice Int? @map("suggested_price") - hasLicenseKeys Boolean @map("has_license_keys") - licenseActivationLimit Int? @map("license_activation_limit") - isLicenseLimitUnlimited Boolean @map("is_license_limit_unlimited") - licenseLengthValue Int? @map("license_length_value") - licenseLengthUnit LicenseLengthUnit @map("license_length_unit") - isLicenseLengthUnlimited Boolean @map("is_license_length_unlimited") - sort Int @map("sort") - status VariantStatus @map("status") - statusFormatted String @map("status_formatted") - createdAt DateTime @map("created_at") - updatedAt DateTime @map("updated_at") + cancelled Boolean? }