Merge branch 'dev/credits-v2' of https://github.com/MkSaaSHQ/mksaas-template into dev/credits-v2
This commit is contained in:
commit
74d7cf44a1
@ -21,6 +21,11 @@ export async function getUserCredits(userId: string): Promise<number> {
|
||||
return record[0]?.currentCredits || 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update user's current credit balance
|
||||
* @param userId - User ID
|
||||
* @param credits - New credit balance
|
||||
*/
|
||||
export async function updateUserCredits(userId: string, credits: number) {
|
||||
const db = await getDb();
|
||||
await db
|
||||
@ -29,6 +34,11 @@ export async function updateUserCredits(userId: string, credits: number) {
|
||||
.where(eq(userCredit.userId, userId));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update user's last refresh time
|
||||
* @param userId - User ID
|
||||
* @param date - Last refresh time
|
||||
*/
|
||||
export async function updateUserLastRefreshAt(userId: string, date: Date) {
|
||||
const db = await getDb();
|
||||
await db
|
||||
@ -63,11 +73,11 @@ export async function saveCreditTransaction({
|
||||
type,
|
||||
description
|
||||
);
|
||||
throw new Error('Invalid params');
|
||||
throw new Error('saveCreditTransaction, invalid params');
|
||||
}
|
||||
if (!Number.isFinite(amount) || amount === 0) {
|
||||
console.error('saveCreditTransaction, invalid amount', userId, amount);
|
||||
throw new Error('Invalid amount');
|
||||
throw new Error('saveCreditTransaction, invalid amount');
|
||||
}
|
||||
const db = await getDb();
|
||||
await db.insert(creditTransaction).values({
|
||||
@ -107,18 +117,18 @@ export async function addCredits({
|
||||
}) {
|
||||
if (!userId || !type || !description) {
|
||||
console.error('addCredits, invalid params', userId, type, description);
|
||||
throw new Error('Invalid params');
|
||||
throw new Error('addCredits, invalid params');
|
||||
}
|
||||
if (!Number.isFinite(amount) || amount <= 0) {
|
||||
console.error('addCredits, invalid amount', userId, amount);
|
||||
throw new Error('Invalid amount');
|
||||
throw new Error('addCredits, invalid amount');
|
||||
}
|
||||
if (
|
||||
expireDays !== undefined &&
|
||||
(!Number.isFinite(expireDays) || expireDays <= 0)
|
||||
) {
|
||||
console.error('addCredits, invalid expire days', userId, expireDays);
|
||||
throw new Error('Invalid expire days');
|
||||
throw new Error('addCredits, invalid expire days');
|
||||
}
|
||||
// Process expired credits first
|
||||
await processExpiredCredits(userId);
|
||||
@ -194,11 +204,11 @@ export async function consumeCredits({
|
||||
}) {
|
||||
if (!userId || !description) {
|
||||
console.error('consumeCredits, invalid params', userId, description);
|
||||
throw new Error('Invalid params');
|
||||
throw new Error('consumeCredits, invalid params');
|
||||
}
|
||||
if (!Number.isFinite(amount) || amount <= 0) {
|
||||
console.error('consumeCredits, invalid amount', userId, amount);
|
||||
throw new Error('Invalid amount');
|
||||
throw new Error('consumeCredits, invalid amount');
|
||||
}
|
||||
// Process expired credits first
|
||||
await processExpiredCredits(userId);
|
||||
|
@ -9,6 +9,9 @@ export enum CREDIT_TRANSACTION_TYPE {
|
||||
EXPIRE = 'EXPIRE', // Credits expired
|
||||
}
|
||||
|
||||
/**
|
||||
* Credit package price
|
||||
*/
|
||||
export interface CreditPackagePrice {
|
||||
priceId: string; // Stripe price ID (not product id)
|
||||
amount: number; // Price amount in currency units (dollars, euros, etc.)
|
||||
|
@ -1,4 +1,6 @@
|
||||
import { websiteConfig } from '@/config/website';
|
||||
import { addCredits } from '@/credits/credits';
|
||||
import { CREDIT_TRANSACTION_TYPE } from '@/credits/types';
|
||||
import { getDb } from '@/db/index';
|
||||
import { defaultMessages } from '@/i18n/messages';
|
||||
import { LOCALE_COOKIE_NAME, routing } from '@/i18n/routing';
|
||||
@ -129,6 +131,19 @@ export const auth = betterAuth({
|
||||
console.error('Newsletter subscription error:', error);
|
||||
}
|
||||
}
|
||||
// Add register gift credits to the user if enabled in website config
|
||||
if (
|
||||
websiteConfig.credits.registerGiftCredits.enable &&
|
||||
websiteConfig.credits.registerGiftCredits.credits > 0
|
||||
) {
|
||||
await addCredits({
|
||||
userId: user.id,
|
||||
amount: websiteConfig.credits.registerGiftCredits.credits,
|
||||
type: CREDIT_TRANSACTION_TYPE.REGISTER_GIFT,
|
||||
description: 'Register gift credits',
|
||||
expireDays: websiteConfig.credits.registerGiftCredits.expireDays,
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -772,14 +772,6 @@ export class StripeProvider implements PaymentProvider {
|
||||
return;
|
||||
}
|
||||
|
||||
// get priceId from session metadata, not from line items
|
||||
// const priceId = session.line_items?.data[0]?.price?.id;
|
||||
const priceId = session.metadata?.priceId;
|
||||
if (!priceId) {
|
||||
console.warn(`<< No priceId found for checkout session ${session.id}`);
|
||||
return;
|
||||
}
|
||||
|
||||
// get credits from session metadata
|
||||
const credits = session.metadata?.credits;
|
||||
if (!credits) {
|
||||
@ -787,8 +779,15 @@ export class StripeProvider implements PaymentProvider {
|
||||
return;
|
||||
}
|
||||
|
||||
// get credit package
|
||||
const creditPackage = getCreditPackageByIdInServer(packageId);
|
||||
if (!creditPackage) {
|
||||
console.warn(`<< Credit package ${packageId} not found`);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// Add credits to user account using existing addCredits method
|
||||
// add credits to user account
|
||||
const amount = session.amount_total ? session.amount_total / 100 : 0;
|
||||
await addCredits({
|
||||
userId,
|
||||
@ -796,10 +795,11 @@ export class StripeProvider implements PaymentProvider {
|
||||
type: CREDIT_TRANSACTION_TYPE.PURCHASE,
|
||||
description: `Credit package purchase: ${packageId} - ${credits} credits for $${amount}`,
|
||||
paymentId: session.id,
|
||||
expireDays: creditPackage.expireDays,
|
||||
});
|
||||
|
||||
console.log(
|
||||
`<< Added ${credits} credits to user ${userId} for $${amount}`
|
||||
`<< Added ${credits} credits to user ${userId} for $${amount}${creditPackage.expireDays ? ` (expires in ${creditPackage.expireDays} days)` : ' (no expiration)'}`
|
||||
);
|
||||
} catch (error) {
|
||||
console.error(
|
||||
@ -830,6 +830,13 @@ export class StripeProvider implements PaymentProvider {
|
||||
}
|
||||
|
||||
try {
|
||||
// Get credit package to get expiration info
|
||||
const creditPackage = getCreditPackageByIdInServer(packageId);
|
||||
if (!creditPackage) {
|
||||
console.warn(`<< Credit package ${packageId} not found`);
|
||||
return;
|
||||
}
|
||||
|
||||
// Add credits to user account using existing addCredits method
|
||||
await addCredits({
|
||||
userId,
|
||||
@ -837,10 +844,11 @@ export class StripeProvider implements PaymentProvider {
|
||||
type: CREDIT_TRANSACTION_TYPE.PURCHASE,
|
||||
description: `Credit package purchase: ${packageId} - ${credits} credits for $${paymentIntent.amount / 100}`,
|
||||
paymentId: paymentIntent.id,
|
||||
expireDays: creditPackage.expireDays,
|
||||
});
|
||||
|
||||
console.log(
|
||||
`<< Successfully processed payment intent ${paymentIntent.id}: Added ${credits} credits to user ${userId}`
|
||||
`<< Successfully processed payment intent ${paymentIntent.id}: Added ${credits} credits to user ${userId}${creditPackage.expireDays ? ` (expires in ${creditPackage.expireDays} days)` : ' (no expiration)'}`
|
||||
);
|
||||
} catch (error) {
|
||||
console.error(
|
||||
|
Loading…
Reference in New Issue
Block a user