Files
medreport_mrb2b/app/home/(user)/(dashboard)/cart/montonio-callback/actions.ts

54 lines
1.5 KiB
TypeScript

'use server';
import { MontonioOrderToken } from '@/app/home/(user)/_components/cart/types';
import { loadCurrentUserAccount } from '@/app/home/(user)/_lib/server/load-user-account';
import { retrieveCart } from '@lib/data/cart';
import jwt from 'jsonwebtoken';
import { handlePlaceOrder } from '../../../_lib/server/cart-actions';
const MONTONIO_PAID_STATUS = 'PAID';
async function decodeOrderToken(orderToken: string) {
const secretKey = process.env.MONTONIO_SECRET_KEY as string;
const decoded = jwt.verify(orderToken, secretKey, {
algorithms: ['HS256'],
}) as MontonioOrderToken;
if (decoded.paymentStatus !== MONTONIO_PAID_STATUS) {
throw new Error('Payment not successful');
}
return decoded;
}
async function getCartByOrderToken(decoded: MontonioOrderToken) {
const [, , cartId] = decoded.merchantReferenceDisplay.split(':');
if (!cartId) {
throw new Error('Cart ID not found');
}
const cart = await retrieveCart(cartId);
if (!cart) {
throw new Error('Cart not found');
}
return cart;
}
export async function processMontonioCallback(orderToken: string) {
const { account } = await loadCurrentUserAccount();
if (!account) {
throw new Error('Account not found in context');
}
try {
const decoded = await decodeOrderToken(orderToken);
const cart = await getCartByOrderToken(decoded);
const result = await handlePlaceOrder({ cart });
return result;
} catch (error) {
console.error('Failed to place order', error);
throw new Error(`Failed to place order, message=${error}`);
}
}