'use server'; import { z } from 'zod'; import { loadCurrentUserAccount } from '@/app/home/(user)/_lib/server/load-user-account'; import { getSupabaseServerClient } from '@kit/supabase/server-client'; import { addToCart, deleteLineItem, retrieveCart } from '@lib/data/cart'; import { StoreCartLineItem, StoreProductVariant } from '@medusajs/types'; import { MontonioOrderHandlerService } from '@/packages/billing/montonio/src'; import { requireUserInServerComponent } from '../server/require-user-in-server-component'; const medusaBackendUrl = process.env.MEDUSA_BACKEND_URL!; const siteUrl = process.env.NEXT_PUBLIC_SITE_URL!; const env = z .object({ medusaBackendUrl: z .string({ required_error: 'MEDUSA_BACKEND_URL is required', }) .min(1), siteUrl: z .string({ required_error: 'NEXT_PUBLIC_SITE_URL is required', }) .min(1), }) .parse({ medusaBackendUrl, siteUrl, }); export async function handleAddToCart({ selectedVariant, countryCode, }: { selectedVariant: StoreProductVariant countryCode: string }) { const supabase = getSupabaseServerClient(); const user = await requireUserInServerComponent(); const account = await loadCurrentUserAccount() if (!account) { throw new Error('Account not found'); } const quantity = 1; const cart = await addToCart({ variantId: selectedVariant.id, quantity, countryCode, }); const { error } = await supabase .schema('audit') .from('cart_entries') .insert({ variant_id: selectedVariant.id, operation: 'ADD_TO_CART', account_id: account.id, cart_id: cart.id, changed_by: user.id, }); if (error) { throw new Error('Error logging cart entry: ' + error.message); } return cart; } export async function handleNavigateToPayment({ language, paymentSessionId }: { language: string, paymentSessionId: string }) { const supabase = getSupabaseServerClient(); const user = await requireUserInServerComponent(); const account = await loadCurrentUserAccount() if (!account) { throw new Error('Account not found'); } const cart = await retrieveCart(); if (!cart) { throw new Error("No cart found"); } const paymentLink = await new MontonioOrderHandlerService().getMontonioPaymentLink({ notificationUrl: `${env.medusaBackendUrl}/api/billing/webhook`, returnUrl: `${env.siteUrl}/home/cart/montonio-callback`, amount: cart.total, currency: cart.currency_code.toUpperCase(), description: `Order from Medreport`, locale: language, merchantReference: `${account.id}:${paymentSessionId}:${cart.id}`, }); const { error } = await supabase .schema('audit') .from('cart_entries') .insert({ operation: 'NAVIGATE_TO_PAYMENT', account_id: account.id, cart_id: cart.id, changed_by: user.id, }); if (error) { throw new Error('Error logging cart entry: ' + error.message); } return paymentLink; } export async function handleLineItemTimeout({ lineItem, }: { lineItem: StoreCartLineItem }) { const supabase = getSupabaseServerClient(); const user = await requireUserInServerComponent(); const account = await loadCurrentUserAccount() if (!account) { throw new Error('Account not found'); } await deleteLineItem(lineItem.id); const { error } = await supabase .schema('audit') .from('cart_entries') .insert({ operation: 'LINE_ITEM_TIMEOUT', account_id: account.id, cart_id: lineItem.cart_id, changed_by: user.id, }); if (error) { throw new Error('Error logging cart entry: ' + error.message); } }