26 lines
1.3 KiB
TypeScript
26 lines
1.3 KiB
TypeScript
|
|
import { getCurrentUser } from '../utils/auth';
|
||
|
|
import { checkoutSchema, createOrder } from '../utils/store';
|
||
|
|
import { getPayments } from '../utils/payments';
|
||
|
|
import { recordAudit } from '../utils/audit';
|
||
|
|
import { sendEmail } from '../utils/email';
|
||
|
|
|
||
|
|
export default defineEventHandler(async (event) => {
|
||
|
|
const parsed = checkoutSchema.safeParse(await readBody(event).catch(() => ({})));
|
||
|
|
if (!parsed.success) {
|
||
|
|
throw createError({ statusCode: 400, statusMessage: 'Please provide a valid email, address and cart.' });
|
||
|
|
}
|
||
|
|
const user = await getCurrentUser(event);
|
||
|
|
const result = await createOrder(parsed.data, user?.id, getPayments(event));
|
||
|
|
if (!result.ok) throw createError({ statusCode: 409, statusMessage: result.error });
|
||
|
|
|
||
|
|
await recordAudit({ actorId: user?.id ?? null, action: 'order.created', target: result.order.providerRef ?? result.order.id, meta: { total: result.order.total } });
|
||
|
|
await sendEmail(event, {
|
||
|
|
to: result.order.email,
|
||
|
|
subject: `Order ${result.order.id.slice(0, 8)} confirmed`,
|
||
|
|
html: `<p>Thanks! Your order of $${(result.order.total / 100).toFixed(2)} is confirmed.</p>`,
|
||
|
|
}).catch((e) => console.error('[email] order', e));
|
||
|
|
|
||
|
|
setResponseStatus(event, 201);
|
||
|
|
return { order: { id: result.order.id, status: result.order.status, total: result.order.total } };
|
||
|
|
});
|