`
`async function fundWallet(userId: string, amount: Decimal, reference: string) {
return await prisma.$transaction(async (tx) => {
// 1. Check for duplicate
const existing = await tx.transaction.findUnique({ where: { reference } });
if (existing) return existing;
// 2. Lock wallet row (prevents race conditions)
const wallet = await tx.wallet.findUnique({
where: { userId },
});
if (!wallet || wallet.status !== 'ACTIVE') {
throw new Error('Wallet not available');
}
// 3. Create transaction record first
const newBalance = wallet.balance.plus(amount);
const transaction = await tx.transaction.create({
data: {
walletId: wallet.id,
type: 'CREDIT',
amount,
balanceAfter: newBalance,
reference,
status: 'COMPLETED',
description: 'Wallet funding via Paystack',
},
});
// 4. Update wallet balance
await tx.wallet.update({
where: { id: wallet.id },
data: { balance: newBalance },
});
return transaction;
});
}
Top comments (0)