forked from boxyhq/saas-starter-kit
-
Notifications
You must be signed in to change notification settings - Fork 0
/
sync-stripe.js
115 lines (103 loc) · 3.1 KB
/
sync-stripe.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
const Stripe = require('stripe');
const { PrismaClient } = require('@prisma/client');
/**
* Synchronizes data between a database and the Stripe API.
* Retrieves active products and prices from Stripe, deletes existing data in the database,
* and inserts the new data. Prints the number of synced products and prices.
*
* @returns {Promise<void>} - A promise that resolves once the synchronization is complete.
*/
const sync = async () => {
const prisma = new PrismaClient();
try {
console.log('Starting sync with Stripe');
const stripe = getStripeInstance();
// Get all active products and prices
const [products, prices] = await Promise.all([
stripe.products.list({ active: true }),
stripe.prices.list({ active: true }),
]);
if (prices.data.length > 0 && products.data.length > 0) {
const operations = [
...cleanup(prisma),
...seedServices(products.data, prisma),
...seedPrices(prices.data, prisma),
];
await prisma.$transaction(operations);
await printStats(prisma);
console.log('Sync completed successfully');
process.exit(0);
} else {
if (prices.data.length === 0) {
throw new Error('No prices found on Stripe');
} else {
throw new Error('No products found on Stripe');
}
}
} catch (error) {
console.error('Error syncing with Stripe:', error);
process.exit(1);
}
};
sync();
// handle uncaught errors
process.on('uncaughtException', (error) => {
console.error('Uncaught Exception:', error);
process.exit(1);
});
async function printStats(prisma) {
const [productCount, priceCount] = await Promise.all([
prisma.service.count(),
prisma.price.count(),
]);
console.log('Products synced:', productCount);
console.log('Prices synced:', priceCount);
}
function cleanup(prisma) {
return [
// delete all prices from the database
prisma.price.deleteMany({}),
// Delete all products and prices from the database
prisma.service.deleteMany({}),
];
}
function getStripeInstance() {
if (process.env.STRIPE_SECRET_KEY) {
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY || '', {
apiVersion: '2022-11-15',
});
return stripe;
} else {
throw new Error('STRIPE_SECRET_KEY environment variable not set');
}
}
function seedPrices(prices, prisma) {
return prices.map((data) =>
prisma.price.create({
data: {
id: data.id,
billingScheme: data.billing_scheme,
currency: data.currency,
serviceId: data.product,
amount: data.unit_amount ? data.unit_amount / 100 : undefined,
metadata: data.recurring,
type: data.type,
created: new Date(data.created * 1000),
},
})
);
}
function seedServices(products, prisma) {
return products.map((data) =>
prisma.service.create({
data: {
id: data.id,
description: data.description || '',
features: (data.features || []).map((a) => a.name),
image: data.images.length > 0 ? data.images[0] : '',
name: data.name,
created: new Date(data.created * 1000),
},
})
);
}