From 7951aa9317a305fa7b73df9e582068881aacdd45 Mon Sep 17 00:00:00 2001 From: Codex Microtask Operator Date: Sat, 13 Jun 2026 01:47:45 +0200 Subject: [PATCH] Fallback invalid CoinPay checkout amounts --- .../contract/logicsrc-web.contract.test.ts | 23 +++++++++++++++++++ .../app/api/hire-us/coinpay-checkout/route.ts | 3 ++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/apps/logicsrc-web/contract/logicsrc-web.contract.test.ts b/apps/logicsrc-web/contract/logicsrc-web.contract.test.ts index e14773f..ddaec4f 100644 --- a/apps/logicsrc-web/contract/logicsrc-web.contract.test.ts +++ b/apps/logicsrc-web/contract/logicsrc-web.contract.test.ts @@ -221,6 +221,29 @@ describe("POST /api/hire-us/coinpay-checkout", () => { expect(body.payment.checkout_url).toBe("https://checkout.stripe.test/card-only"); }); + it("falls back when CoinPay returns an invalid checkout amount", async () => { + process.env.COINPAY_API_KEY = "cp_test_key"; + process.env.COINPAY_API_URL = "https://coinpayportal.example"; + process.env.COINPAY_BUSINESS_ID = "business-123"; + process.env.COINPAY_ELIGIBILITY_MERCHANT_ID = "merchant-123"; + + vi.spyOn(globalThis, "fetch").mockImplementation(async (input) => { + const url = typeof input === "string" ? input : input.toString(); + if (url.includes("/api/payments/merchant-eligibility")) { + return jsonResponse({ success: true, accepts_card: true, accepts_crypto: false, chains: [] }); + } + return jsonResponse({ success: true, payment: { id: "pay_123", amount_usd: "not-a-number" } }, 201); + }); + + const response = await coinpayCheckout( + new NextRequest("http://localhost/api/hire-us/coinpay-checkout", { method: "POST", body: "{}" }) + ); + const body = await response.json(); + + expect(response.status).toBe(201); + expect(body.payment.amount_usd).toBe(250); + }); + it("does not create checkout when no payment rail is available", async () => { process.env.COINPAY_API_KEY = "cp_test_key"; process.env.COINPAY_API_URL = "https://coinpayportal.example"; diff --git a/apps/logicsrc-web/src/app/api/hire-us/coinpay-checkout/route.ts b/apps/logicsrc-web/src/app/api/hire-us/coinpay-checkout/route.ts index 8175043..e9dff88 100644 --- a/apps/logicsrc-web/src/app/api/hire-us/coinpay-checkout/route.ts +++ b/apps/logicsrc-web/src/app/api/hire-us/coinpay-checkout/route.ts @@ -70,12 +70,13 @@ export async function POST(request: NextRequest) { } const payment = (payload.payment as Record) || {}; + const amountUsd = Number(payment.amount_usd ?? payment.amount ?? 250); return json( { success: true, payment: { id: payment.id, - amount_usd: Number(payment.amount_usd ?? payment.amount ?? 250), + amount_usd: Number.isFinite(amountUsd) ? amountUsd : 250, payment_method: payment.stripe_checkout_url ? "card" : paymentRail.method, currency: payment.currency ?? payment.blockchain ?? paymentRail.blockchain ?? paymentRail.currency, crypto_amount: payment.amount_crypto ?? payment.crypto_amount ?? null,