mirror of
https://github.com/lukevella/rallly.git
synced 2025-04-29 10:16:32 +02:00
🗃️ Make subscription fields required (#1565)
This commit is contained in:
parent
7cf578bedf
commit
9dd99619e5
5 changed files with 67 additions and 23 deletions
|
@ -141,7 +141,9 @@ export async function POST(request: NextRequest) {
|
||||||
case "customer.subscription.created": {
|
case "customer.subscription.created": {
|
||||||
const { id } = event.data.object as Stripe.Subscription;
|
const { id } = event.data.object as Stripe.Subscription;
|
||||||
|
|
||||||
const subscription = await stripe.subscriptions.retrieve(id);
|
const subscription = await stripe.subscriptions.retrieve(id, {
|
||||||
|
expand: ["items.data.price.currency_options"],
|
||||||
|
});
|
||||||
|
|
||||||
// check if the subscription is active
|
// check if the subscription is active
|
||||||
const isActive =
|
const isActive =
|
||||||
|
@ -166,12 +168,21 @@ export async function POST(request: NextRequest) {
|
||||||
|
|
||||||
const subscriptionItem = subscription.items.data[0];
|
const subscriptionItem = subscription.items.data[0];
|
||||||
const interval = subscriptionItem.price.recurring?.interval;
|
const interval = subscriptionItem.price.recurring?.interval;
|
||||||
|
const currency = subscription.currency;
|
||||||
|
const amount =
|
||||||
|
subscriptionItem.price.currency_options?.[currency]?.unit_amount ??
|
||||||
|
subscriptionItem.price.unit_amount;
|
||||||
|
|
||||||
if (!interval) {
|
if (!interval) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Missing interval in subscription ${subscription.id}`,
|
`Missing interval in subscription ${subscription.id}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!amount) {
|
||||||
|
throw new Error(`Missing amount in subscription ${subscription.id}`);
|
||||||
|
}
|
||||||
|
|
||||||
// create or update the subscription in the database
|
// create or update the subscription in the database
|
||||||
await prisma.subscription.upsert({
|
await prisma.subscription.upsert({
|
||||||
where: {
|
where: {
|
||||||
|
@ -181,9 +192,9 @@ export async function POST(request: NextRequest) {
|
||||||
id: subscription.id,
|
id: subscription.id,
|
||||||
active: isActive,
|
active: isActive,
|
||||||
priceId: price.id,
|
priceId: price.id,
|
||||||
currency: subscriptionItem.price.currency,
|
currency,
|
||||||
interval,
|
interval,
|
||||||
amount: subscriptionItem.price.unit_amount,
|
amount,
|
||||||
status: subscription.status,
|
status: subscription.status,
|
||||||
createdAt: toDate(subscription.created),
|
createdAt: toDate(subscription.created),
|
||||||
periodStart: toDate(subscription.current_period_start),
|
periodStart: toDate(subscription.current_period_start),
|
||||||
|
@ -192,9 +203,9 @@ export async function POST(request: NextRequest) {
|
||||||
update: {
|
update: {
|
||||||
active: isActive,
|
active: isActive,
|
||||||
priceId: price.id,
|
priceId: price.id,
|
||||||
currency: subscriptionItem.price.currency,
|
currency,
|
||||||
interval,
|
interval,
|
||||||
amount: subscriptionItem.price.unit_amount,
|
amount,
|
||||||
status: subscription.status,
|
status: subscription.status,
|
||||||
createdAt: toDate(subscription.created),
|
createdAt: toDate(subscription.created),
|
||||||
periodStart: toDate(subscription.current_period_start),
|
periodStart: toDate(subscription.current_period_start),
|
||||||
|
|
|
@ -3,7 +3,6 @@ import { prisma } from "@rallly/database";
|
||||||
import { stripe } from "../lib/stripe";
|
import { stripe } from "../lib/stripe";
|
||||||
|
|
||||||
(async function syncSubscriptionData() {
|
(async function syncSubscriptionData() {
|
||||||
const BATCH_SIZE = 10;
|
|
||||||
let processed = 0;
|
let processed = 0;
|
||||||
let failed = 0;
|
let failed = 0;
|
||||||
|
|
||||||
|
@ -11,23 +10,35 @@ import { stripe } from "../lib/stripe";
|
||||||
select: {
|
select: {
|
||||||
id: true,
|
id: true,
|
||||||
},
|
},
|
||||||
take: BATCH_SIZE,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
console.info(`🚀 Syncing ${userSubscriptions.length} subscriptions...`)
|
console.info(`🚀 Syncing ${userSubscriptions.length} subscriptions...`);
|
||||||
|
|
||||||
for (const userSubscription of userSubscriptions) {
|
for (const userSubscription of userSubscriptions) {
|
||||||
try {
|
try {
|
||||||
const subscription = await stripe.subscriptions.retrieve(
|
const subscription = await stripe.subscriptions.retrieve(
|
||||||
userSubscription.id,
|
userSubscription.id,
|
||||||
|
{
|
||||||
|
expand: ["items.data.price.currency_options"],
|
||||||
|
},
|
||||||
);
|
);
|
||||||
|
const currency = subscription.currency;
|
||||||
const subscriptionItem = subscription.items.data[0];
|
const subscriptionItem = subscription.items.data[0];
|
||||||
|
const currencyOption =
|
||||||
|
subscriptionItem.price.currency_options?.[currency];
|
||||||
const interval = subscriptionItem.price.recurring?.interval;
|
const interval = subscriptionItem.price.recurring?.interval;
|
||||||
|
const amount =
|
||||||
|
currencyOption?.unit_amount ?? subscriptionItem.price.unit_amount;
|
||||||
|
|
||||||
if (!interval) {
|
if (!interval) {
|
||||||
console.info(`🚨 Missing interval in subscription ${subscription.id}`);
|
console.info(`🚨 Missing interval in subscription ${subscription.id}`);
|
||||||
+ failed++;
|
failed++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!amount) {
|
||||||
|
console.info(`🚨 Missing amount in subscription ${subscription.id}`);
|
||||||
|
failed++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,17 +47,20 @@ import { stripe } from "../lib/stripe";
|
||||||
id: subscription.id,
|
id: subscription.id,
|
||||||
},
|
},
|
||||||
data: {
|
data: {
|
||||||
amount: subscriptionItem.price.unit_amount,
|
amount,
|
||||||
currency: subscriptionItem.price.currency,
|
currency,
|
||||||
interval: subscriptionItem.price.recurring?.interval,
|
|
||||||
status: subscription.status,
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
console.info(`✅ Subscription ${subscription.id} synced`);
|
console.info(
|
||||||
|
`✅ Subscription ${subscription.id} synced - ${currency}${amount}`,
|
||||||
|
);
|
||||||
processed++;
|
processed++;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`❌ Failed to sync subscription ${userSubscription.id}:`, error);
|
console.error(
|
||||||
|
`❌ Failed to sync subscription ${userSubscription.id}:`,
|
||||||
|
error,
|
||||||
|
);
|
||||||
failed++;
|
failed++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
/*
|
||||||
|
Warnings:
|
||||||
|
|
||||||
|
- You are about to drop the column `interval_count` on the `subscriptions` table. All the data in the column will be lost.
|
||||||
|
- Made the column `currency` on table `subscriptions` required. This step will fail if there are existing NULL values in that column.
|
||||||
|
- Made the column `interval` on table `subscriptions` required. This step will fail if there are existing NULL values in that column.
|
||||||
|
- Made the column `amount` on table `subscriptions` required. This step will fail if there are existing NULL values in that column.
|
||||||
|
- Made the column `status` on table `subscriptions` required. This step will fail if there are existing NULL values in that column.
|
||||||
|
|
||||||
|
*/
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "subscriptions" DROP COLUMN "interval_count",
|
||||||
|
ALTER COLUMN "currency" SET NOT NULL,
|
||||||
|
ALTER COLUMN "interval" SET NOT NULL,
|
||||||
|
ALTER COLUMN "amount" SET NOT NULL,
|
||||||
|
ALTER COLUMN "status" SET NOT NULL;
|
|
@ -88,12 +88,11 @@ model UserPaymentData {
|
||||||
model Subscription {
|
model Subscription {
|
||||||
id String @id
|
id String @id
|
||||||
priceId String @map("price_id")
|
priceId String @map("price_id")
|
||||||
amount Int?
|
amount Int
|
||||||
status String?
|
status String
|
||||||
active Boolean
|
active Boolean
|
||||||
currency String?
|
currency String
|
||||||
interval String?
|
interval String
|
||||||
intervalCount Int? @map("interval_count")
|
|
||||||
createdAt DateTime @default(now()) @map("created_at")
|
createdAt DateTime @default(now()) @map("created_at")
|
||||||
periodStart DateTime @map("period_start")
|
periodStart DateTime @map("period_start")
|
||||||
periodEnd DateTime @map("period_end")
|
periodEnd DateTime @map("period_end")
|
||||||
|
|
|
@ -129,10 +129,14 @@ async function main() {
|
||||||
subscription: {
|
subscription: {
|
||||||
create: {
|
create: {
|
||||||
id: "sub_123",
|
id: "sub_123",
|
||||||
|
currency: "usd",
|
||||||
|
amount: 700,
|
||||||
|
interval: "month",
|
||||||
|
status: "active",
|
||||||
active: true,
|
active: true,
|
||||||
priceId: "price_123",
|
priceId: "price_123",
|
||||||
periodStart: new Date(),
|
periodStart: new Date(),
|
||||||
periodEnd: dayjs().add(1, "year").toDate(),
|
periodEnd: dayjs().add(1, "month").toDate(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
Loading…
Add table
Reference in a new issue