134 lines
3.1 KiB
TypeScript
134 lines
3.1 KiB
TypeScript
"use client";
|
|
|
|
import { Logger } from "@/utils/logger";
|
|
import { Result } from "@/utils/result";
|
|
|
|
import {
|
|
savePendingEzpayOrder,
|
|
type PendingPaymentReturnTo,
|
|
type PendingPaymentSubscriptionType,
|
|
type PendingPaymentTipCoffeeType,
|
|
} from "./pending_payment_order";
|
|
|
|
const log = new Logger("LibPaymentPaymentLaunch");
|
|
|
|
export function getPaymentUrl(payParams: Record<string, unknown>): string | null {
|
|
const keys = [
|
|
"cashierUrl",
|
|
"cashier_url",
|
|
"checkoutUrl",
|
|
"checkout_url",
|
|
"paymentUrl",
|
|
"payment_url",
|
|
"approvalUrl",
|
|
"approval_url",
|
|
"redirectUrl",
|
|
"redirect_url",
|
|
"url",
|
|
];
|
|
|
|
for (const key of keys) {
|
|
const value = payParams[key];
|
|
if (typeof value === "string" && value.length > 0) return value;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
export function isEzpayPayment(payParams: Record<string, unknown>): boolean {
|
|
const provider = payParams.provider;
|
|
return typeof provider === "string" && provider.toLowerCase() === "ezpay";
|
|
}
|
|
|
|
export function getStripeClientSecret(
|
|
payParams: Record<string, unknown>,
|
|
): string | null {
|
|
const provider = payParams.provider;
|
|
const clientSecret = payParams.clientSecret ?? payParams.client_secret;
|
|
const isStripeProvider =
|
|
typeof provider !== "string" || provider.toLowerCase() === "stripe";
|
|
|
|
if (
|
|
isStripeProvider &&
|
|
typeof clientSecret === "string" &&
|
|
clientSecret.length > 0
|
|
) {
|
|
return clientSecret;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
export interface LaunchEzpayRedirectInput {
|
|
orderId: string | null;
|
|
paymentUrl: string;
|
|
subscriptionType: PendingPaymentSubscriptionType;
|
|
tipCoffeeType?: PendingPaymentTipCoffeeType;
|
|
returnTo?: PendingPaymentReturnTo;
|
|
onOpened?: () => void;
|
|
onFailed: (errorMessage: string) => void;
|
|
}
|
|
|
|
export async function launchEzpayRedirect({
|
|
orderId,
|
|
paymentUrl,
|
|
subscriptionType,
|
|
tipCoffeeType,
|
|
returnTo,
|
|
onOpened,
|
|
onFailed,
|
|
}: LaunchEzpayRedirectInput): Promise<void> {
|
|
log.debug("[payment-launch] launchEzpayRedirect START", {
|
|
hasOrderId: Boolean(orderId),
|
|
orderId,
|
|
subscriptionType,
|
|
paymentUrl,
|
|
});
|
|
|
|
if (!orderId) {
|
|
const errorMessage = "Missing order id before opening Ezpay.";
|
|
log.error("[payment-launch] pending ezpay order save skipped", {
|
|
subscriptionType,
|
|
paymentUrl,
|
|
errorMessage,
|
|
});
|
|
onFailed(errorMessage);
|
|
return;
|
|
}
|
|
|
|
const saveResult = await savePendingEzpayOrder({
|
|
orderId,
|
|
subscriptionType,
|
|
...(tipCoffeeType ? { tipCoffeeType } : {}),
|
|
...(returnTo ? { returnTo } : {}),
|
|
});
|
|
if (Result.isErr(saveResult)) {
|
|
const errorMessage =
|
|
"Could not save payment order before opening Ezpay. Please try again.";
|
|
log.error("[payment-launch] pending ezpay order save failed", {
|
|
orderId,
|
|
subscriptionType,
|
|
error: saveResult.error,
|
|
});
|
|
onFailed(errorMessage);
|
|
return;
|
|
}
|
|
|
|
log.debug("[payment-launch] pending ezpay order saved", {
|
|
orderId,
|
|
subscriptionType,
|
|
});
|
|
|
|
log.debug("[payment-launch] launchEzpayRedirect NOW", {
|
|
orderId,
|
|
subscriptionType,
|
|
paymentUrl,
|
|
});
|
|
try {
|
|
window.location.href = paymentUrl;
|
|
onOpened?.();
|
|
} catch {
|
|
onFailed("Could not open Ezpay. Please try again.");
|
|
}
|
|
}
|