feat(payment): support Indonesia QRIS checkout
This commit is contained in:
@@ -11,6 +11,36 @@ import {
|
||||
|
||||
const log = new Logger("LibPaymentPaymentLaunch");
|
||||
|
||||
export type EzpayLaunchTarget =
|
||||
| { kind: "url"; paymentUrl: string }
|
||||
| { kind: "qr"; qrData: string }
|
||||
| { kind: "error"; errorMessage: string };
|
||||
|
||||
function getNonEmptyString(
|
||||
payParams: Record<string, unknown>,
|
||||
...keys: string[]
|
||||
): string | null {
|
||||
for (const key of keys) {
|
||||
const value = payParams[key];
|
||||
if (typeof value === "string" && value.trim().length > 0) {
|
||||
return value.trim();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function getHttpPaymentUrl(value: string | null): string | null {
|
||||
if (!value) return null;
|
||||
try {
|
||||
const parsed = new URL(value);
|
||||
return parsed.protocol === "https:" || parsed.protocol === "http:"
|
||||
? value
|
||||
: null;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export function getPaymentUrl(payParams: Record<string, unknown>): string | null {
|
||||
const keys = [
|
||||
"cashierUrl",
|
||||
@@ -39,6 +69,61 @@ export function isEzpayPayment(payParams: Record<string, unknown>): boolean {
|
||||
return typeof provider === "string" && provider.toLowerCase() === "ezpay";
|
||||
}
|
||||
|
||||
export function resolveEzpayLaunchTarget(
|
||||
payParams: Record<string, unknown>,
|
||||
): EzpayLaunchTarget {
|
||||
const rawChannelType = getNonEmptyString(
|
||||
payParams,
|
||||
"channelType",
|
||||
"channel_type",
|
||||
);
|
||||
const channelType = rawChannelType?.toUpperCase() ?? null;
|
||||
const payData = getNonEmptyString(payParams, "payData", "pay_data");
|
||||
|
||||
if (channelType === "QR") {
|
||||
return payData
|
||||
? { kind: "qr", qrData: payData }
|
||||
: {
|
||||
kind: "error",
|
||||
errorMessage: "QRIS payment data is missing. Please try again.",
|
||||
};
|
||||
}
|
||||
|
||||
if (channelType === "VA") {
|
||||
return {
|
||||
kind: "error",
|
||||
errorMessage: "Virtual account payments are not supported in this app.",
|
||||
};
|
||||
}
|
||||
|
||||
if (channelType === "URL") {
|
||||
const paymentUrl =
|
||||
getHttpPaymentUrl(payData) ?? getHttpPaymentUrl(getPaymentUrl(payParams));
|
||||
return paymentUrl
|
||||
? { kind: "url", paymentUrl }
|
||||
: {
|
||||
kind: "error",
|
||||
errorMessage: "Ezpay payment URL is missing or invalid. Please try again.",
|
||||
};
|
||||
}
|
||||
|
||||
if (channelType) {
|
||||
return {
|
||||
kind: "error",
|
||||
errorMessage: `Unsupported Ezpay payment channel: ${channelType}.`,
|
||||
};
|
||||
}
|
||||
|
||||
const legacyPaymentUrl = getHttpPaymentUrl(getPaymentUrl(payParams));
|
||||
return legacyPaymentUrl
|
||||
? { kind: "url", paymentUrl: legacyPaymentUrl }
|
||||
: {
|
||||
kind: "error",
|
||||
errorMessage:
|
||||
"Ezpay payment parameters did not include a supported URL or QRIS code.",
|
||||
};
|
||||
}
|
||||
|
||||
export function getStripeClientSecret(
|
||||
payParams: Record<string, unknown>,
|
||||
): string | null {
|
||||
|
||||
Reference in New Issue
Block a user