From b2003ad30d054fb62f5be1944c5eadf8d744b2db Mon Sep 17 00:00:00 2001 From: k4rli Date: Mon, 4 Aug 2025 12:49:03 +0300 Subject: [PATCH] feat(MED-131): move medipost xml logic to service --- README.md | 5 +-- app/api/order/medipost-create/route.ts | 51 ++------------------------ lib/services/medipost.service.ts | 40 ++++++++++++++++++++ 3 files changed, 46 insertions(+), 50 deletions(-) diff --git a/README.md b/README.md index 20a28d9..3ace0ef 100644 --- a/README.md +++ b/README.md @@ -108,9 +108,8 @@ To access admin pages follow these steps: 3. Customer pays and is redirected back to **B2B** `GET B2B/home/cart/montonio-callback?order-token=$JWT` - **Medusa** order is created and cart is emptied - email is sent to customer -4. When **Montonio** has confirmed payment, it will call **Medusa** webhook endpoint and **Medusa** will mark order payment as captured. - **Medusa** sends `POST B2B/api/order/medipost-create` with `medusaOrderId`. B2B sends order XML as private message to Medipost. - This could possibly later happen on montonio-callback URL also but currently not possible in Medusa + - B2B sends order XML as private message to Medipost. + When **Montonio** has confirmed payment, it will call **Medusa** webhook endpoint and **Medusa** will mark order payment as captured. In background a job will call `POST B2B/api/job/sync-analysis-results` every n minutes and sync private messages with responses from **Medipost**. diff --git a/app/api/order/medipost-create/route.ts b/app/api/order/medipost-create/route.ts index 28c919a..10b9ea1 100644 --- a/app/api/order/medipost-create/route.ts +++ b/app/api/order/medipost-create/route.ts @@ -1,51 +1,8 @@ -import { retrieveOrder } from "@lib/data"; import { NextRequest, NextResponse } from "next/server"; -import { getAccountAdmin } from "~/lib/services/account.service"; -import { composeOrderXML, sendPrivateMessage } from "~/lib/services/medipost.service"; -import { getOrder, updateOrder } from "~/lib/services/order.service"; - -interface MedipostCreateRequest { - medusaOrderId: string; -} +import { sendOrderToMedipost } from "~/lib/services/medipost.service"; export const POST = async (request: NextRequest) => { - const { medusaOrderId } = (await request.json()) as MedipostCreateRequest; - const medusaOrder = await retrieveOrder(medusaOrderId) - const medreportOrder = await getOrder({ medusaOrderId }); - - const account = await getAccountAdmin({ primaryOwnerUserId: medreportOrder.user_id }); - - const ANALYSIS_ELEMENT_HANDLE_PREFIX = 'analysis-element-'; - const orderedAnalysisElementsIds = (medusaOrder?.items ?? []) - .filter((item) => item.product?.handle?.startsWith(ANALYSIS_ELEMENT_HANDLE_PREFIX)) - .map((item) => { - const id = Number(item.product?.handle?.replace(ANALYSIS_ELEMENT_HANDLE_PREFIX, '')); - if (Number.isNaN(id)) { - return null; - } - return id; - }) - .filter(Boolean) as number[]; - const orderXml = await composeOrderXML({ - person: { - idCode: account.personal_code!, - firstName: account.name ?? '', - lastName: account.last_name ?? '', - phone: account.phone ?? '', - }, - orderedAnalysisElementsIds, - orderedAnalysesIds: [], - orderId: medusaOrderId, - orderCreatedAt: new Date(medreportOrder.created_at), - comment: '', - }); - - await sendPrivateMessage(orderXml); - - await updateOrder({ - orderId: medreportOrder.id, - orderStatus: 'PROCESSING', - }); - - return NextResponse.json({ orderXml }); + const { medusaOrderId } = (await request.json()) as { medusaOrderId: string }; + await sendOrderToMedipost({ medusaOrderId }); + return NextResponse.json({ success: true }); }; diff --git a/lib/services/medipost.service.ts b/lib/services/medipost.service.ts index 1ec637c..d9955a6 100644 --- a/lib/services/medipost.service.ts +++ b/lib/services/medipost.service.ts @@ -39,6 +39,8 @@ import { getSupabaseServerAdminClient } from '@/packages/supabase/src/clients/se import { getOrder } from './order.service'; import { getAnalysisElementsAdmin } from './analysis-element.service'; import { getAnalyses } from './analyses.service'; +import { retrieveOrder } from '@lib/data/orders'; +import { getAccountAdmin } from './account.service'; const BASE_URL = process.env.MEDIPOST_URL!; const USER = process.env.MEDIPOST_USER!; @@ -622,3 +624,41 @@ export async function syncPrivateMessage({ return AnalysisOrderStatus[status]; } + +export async function sendOrderToMedipost({ + medusaOrderId, +}: { + medusaOrderId: string; +}) { + const medusaOrder = await retrieveOrder(medusaOrderId) + const medreportOrder = await getOrder({ medusaOrderId }); + + const account = await getAccountAdmin({ primaryOwnerUserId: medreportOrder.user_id }); + + const ANALYSIS_ELEMENT_HANDLE_PREFIX = 'analysis-element-'; + const orderedAnalysisElementsIds = (medusaOrder?.items ?? []) + .filter((item) => item.product?.handle?.startsWith(ANALYSIS_ELEMENT_HANDLE_PREFIX)) + .map((item) => { + const id = Number(item.product?.handle?.replace(ANALYSIS_ELEMENT_HANDLE_PREFIX, '')); + if (Number.isNaN(id)) { + return null; + } + return id; + }) + .filter(Boolean) as number[]; + const orderXml = await composeOrderXML({ + person: { + idCode: account.personal_code!, + firstName: account.name ?? '', + lastName: account.last_name ?? '', + phone: account.phone ?? '', + }, + orderedAnalysisElementsIds, + orderedAnalysesIds: [], + orderId: medusaOrderId, + orderCreatedAt: new Date(medreportOrder.created_at), + comment: '', + }); + + await sendPrivateMessage(orderXml); +}