fix(payment): route Philippine GCash separately from QRIS

This commit is contained in:
Codex
2026-07-29 19:13:14 +08:00
parent 3547f49bd9
commit ec3e256a8c
11 changed files with 583 additions and 180 deletions
@@ -2,6 +2,7 @@ import { describe, expect, it, vi } from "vitest";
import {
getPaymentUrl,
getPaymentUrlHostname,
getStripeClientSecret,
isEzpayPayment,
launchEzpayRedirect,
@@ -43,36 +44,103 @@ describe("payment launch helpers", () => {
).toBeNull();
});
it("resolves Ezpay URL and QR launch parameters without treating QR data as a URL", () => {
it("prioritizes a hosted GCash URL for Philippine checkout", () => {
expect(
resolveEzpayLaunchTarget({
provider: "ezpay",
channelType: "URL",
payData: "https://pay.example/qris",
}),
).toEqual({ kind: "url", paymentUrl: "https://pay.example/qris" });
payData: "https://pay.example/gcash",
}, { countryCode: "PH", currency: "PHP" }),
).toEqual({ kind: "url", paymentUrl: "https://pay.example/gcash" });
expect(
resolveEzpayLaunchTarget({
provider: "ezpay",
channelType: "QR",
payData: "00020101021226670016COM.NOBUBANK.WWW",
}),
payData: "000201010212ph-qr-payload",
cashierUrl: "https://pay.example/gcash-hosted",
}, { countryCode: "PH" }),
).toEqual({
kind: "url",
paymentUrl: "https://pay.example/gcash-hosted",
});
});
it("keeps a usable QR Ph fallback without calling it QRIS", () => {
expect(
resolveEzpayLaunchTarget(
{
provider: "ezpay",
channelType: "QR",
payData: "000201010212ph-qr-payload",
},
{ currency: "PHP" },
),
).toEqual({
kind: "qr",
experience: "gcashQrPh",
qrData: "000201010212ph-qr-payload",
});
expect(
resolveEzpayLaunchTarget(
{
provider: "ezpay",
payData: "000201010212ph-qr-payload",
},
{ countryCode: "PH" },
),
).toEqual({
kind: "qr",
experience: "gcashQrPh",
qrData: "000201010212ph-qr-payload",
});
});
it("keeps Indonesian QRIS ahead of an optional hosted URL", () => {
expect(
resolveEzpayLaunchTarget(
{
provider: "ezpay",
channelType: "QR",
payData: "00020101021226670016COM.NOBUBANK.WWW",
cashierUrl: "https://pay.example/indonesia",
},
{ countryCode: "ID", currency: "IDR" },
),
).toEqual({
kind: "qr",
experience: "qris",
qrData: "00020101021226670016COM.NOBUBANK.WWW",
});
});
it("reports a regional error only when both URL and QR data are absent", () => {
expect(
resolveEzpayLaunchTarget({
provider: "ezpay",
channelType: "QR",
payData: "",
}),
resolveEzpayLaunchTarget(
{
provider: "ezpay",
channelType: "QR",
payData: "",
},
{ countryCode: "PH" },
),
).toEqual({
kind: "error",
errorMessage: "QRIS payment data is missing. Please try again.",
errorMessage:
"GCash / QR Ph payment data is missing. Please try again.",
});
});
it("keeps diagnostics to the payment URL hostname", () => {
expect(
getPaymentUrlHostname(
"https://pay.example/gcash?token=must-not-appear-in-logs",
),
).toBe("pay.example");
expect(getPaymentUrlHostname("not-a-url")).toBeNull();
});
it("rejects VA and unknown Ezpay channel types with explicit errors", () => {
expect(
resolveEzpayLaunchTarget({ provider: "ezpay", channelType: "VA" }),