| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331 |
- "use client";
- import { useRouter } from 'next/navigation'
- import {AirwallexCartNumberElementType} from "@/lib/Airwallex/airwallexInit";
- import PaypalButton from "./PaymentButton/PaypalButton";
- import { overlayLoading } from "@/components/theme/ui/kernel/loading/api";
- import { PlaceOrderFunction,KlarnaOtherData } from "@/types/checkout/type";
- import { useCustomToast } from "@/utils/hooks/useToast";
- import { usePlaceOrder } from "@/utils/hooks/usePlaceOrder";
- import { confirmDialog } from "@/components/theme/ui/kernel/confirm/api";
- import { useConfig } from '@utils/hooks/useConfig';
- import KlarnaButton from "./PaymentButton/KlarnaButton";
- export default function CheckoutPlaceOrder({
- paymentMethod,
- clickPlaceOrder,
- validateCheckout,// 校验运输方式,地址
- }: {
- paymentMethod: string;
- clickPlaceOrder: PlaceOrderFunction;
- validateCheckout: () => Promise<boolean>;
- }) {
- const router = useRouter();
- const {store} = useConfig();
- const { showToast } = useCustomToast();
- const { createPaymentCallback } = usePlaceOrder();
- const currentCurrencyCode = store.currentCurrency;
- const paypalCreateOrder = async () => {
- overlayLoading.start();
- const valid = await validateCheckout();
- if(!valid) {
- overlayLoading.stop();
- return {
- error: true,
- msg: '',
- orderId: '',
- webOrderId: ''
- };
- }
- // 校验通过
- const placeOrderRes = await clickPlaceOrder();
- if(placeOrderRes.data !== null) {
- return {
- error: false,
- msg: '',
- orderId: placeOrderRes.data.gatewayOrderId,
- webOrderId: placeOrderRes.data.orderId
- };
- } else {
- return {
- error: true,
- msg: '',
- orderId: '',
- webOrderId: ''
- };
- }
- };
- const airwallexPlaceOrder = async () => {
- overlayLoading.start();
- const valid = await validateCheckout();
- if(!valid) {
- overlayLoading.stop();
- return;
- }
- const placeOrderRes = await clickPlaceOrder({
- paymentSuccessUrl: window.location.origin + '/paymentresult/result'
- });
- overlayLoading.stop();
- if(placeOrderRes.data !== null) {
- window.location.href = placeOrderRes.data.gatewayOrderId;
- }
- };
- const cardAirwallexPlaceOrder = async () => {
- overlayLoading.start();
- const valid = await validateCheckout();
- if(!valid) {
- overlayLoading.stop();
- return;
- }
- const placeOrderRes = await clickPlaceOrder<AirwallexCartNumberElementType>();
- if(placeOrderRes.data !== null && placeOrderRes.otherData !== null) {
- const webOrderId = placeOrderRes.data.orderId;
- const cardNumberElement = placeOrderRes.otherData;
- const paymentIntentIdClientSecret = placeOrderRes.data.gatewayOrderId.split(':');
- const paymentIntentId = paymentIntentIdClientSecret[0];
- const paymentIntentClientSecret = paymentIntentIdClientSecret[1];
- cardNumberElement.confirm({
- intent_id: paymentIntentId,
- client_secret: paymentIntentClientSecret,
- }).then((result) => {
- overlayLoading.stop();
- console.log('cardNumberElement.confirm result ---- ', result);
- // 支付成功 跳转页面
- router.replace('/paymentresult/result?orderId=' + webOrderId + '&return_result=success');
- }).catch((error) => {
- overlayLoading.stop();
- console.log('cardNumberElement.confirm error ---- ', error);
- // 支付失败
- router.replace('/paymentresult/result?orderId=' + webOrderId + '&return_result=failure');
- });
- }
- };
- const afterpayPlaceOrder = async () => {
- if(window.AfterPay) {
- overlayLoading.start();
- const valid = await validateCheckout();
- if(!valid) {
- overlayLoading.stop();
- return;
- }
- const placeOrderRes = await clickPlaceOrder({
- paymentSuccessUrl: window.location.origin + '/paymentresult/result',
- paymentCancelUrl: window.location.origin + '/paymentresult/result'
- });
-
- if(placeOrderRes.data !== null) {
- const afterpayToken = placeOrderRes.data.gatewayOrderId;
- const webOrderId = placeOrderRes.data.orderId;
- let countryCode = "US";
- if(currentCurrencyCode === "CAD") {
- countryCode = "CA";
- } else if(currentCurrencyCode === "AUD") {
- countryCode = "AU";
- } else if(currentCurrencyCode === "NZD") {
- countryCode = "NZ";
- } else if(currentCurrencyCode === "GBP") {
- countryCode = "GB";
- }
- // if(paymentMethod === "clearpay") {
- // countryCode = "GB";
- // }
- window.AfterPay.initialize({countryCode: countryCode});
- // To avoid triggering browser anti-popup rules, the AfterPay.open()
- // function must be directly called inside the click event listener
- window.AfterPay.open();
- // If you don't already have a checkout token at this point, you can
- // AJAX to your backend to retrieve one here. The spinning animation
- // will continue until `AfterPay.transfer` is called.
- // If you fail to get a token you can call AfterPay.close()
- window.AfterPay.onComplete = async (event) => {
- console.log('window.AfterPay.onComplete event ---- ', event);
- const status: "success" | "cancel" | "failure" = event.data.status === "SUCCESS" ? 'success' : 'cancel';
- const resCallback = await createPaymentCallback({
- orderId: Number(webOrderId),
- gatewayOrderId: event.data.orderToken,
- status: status,
- });
- overlayLoading.stop();
- if (event.data.status == "SUCCESS") {
- // The customer confirmed the payment schedule.
- // The token is now ready to be captured from your server backend.
- // 跳转结果页 成功
- if(!resCallback.error) {
- // 后端capture成功,跳转到成功落地页
- router.replace('/paymentresult/result?orderId=' + webOrderId + '&return_result=success');
- } else {
- // capture 失败,提示错误
- confirmDialog({
- title: "Somthing Wrong",
- content: resCallback.msg + " Please contact customer service." + " OrderId: "+ webOrderId,
- noCancel: true,
- }).then(() => {
- router.replace('/');
- });
-
- }
-
- } else {
- // The customer cancelled the payment or closed the popup window.
- // 跳转结果页 取消
- router.replace('/paymentresult/result?orderId=' + webOrderId + '&return_result=cancel');
- }
- }
- window.AfterPay.transfer({token: afterpayToken});
- }
- } else {
- showToast("Please wait for the Afterpay to load completely.","warning");
- }
- };
- const klarnaPlaceOrder = async () => {
- overlayLoading.start();
- const valid = await validateCheckout();
- if(!valid) {
- overlayLoading.stop();
- return;
- }
- const placeOrderRes = await clickPlaceOrder<KlarnaOtherData>({
- paymentSuccessUrl: window.location.origin + '/paymentresult/result',
- paymentCancelUrl: window.location.origin + '/paymentresult/result'
- });
-
- if(placeOrderRes.data !== null && placeOrderRes.otherData) {
- const klarnaToken = placeOrderRes.data.gatewayOrderId;
- const webOrderId = placeOrderRes.data.orderId;
- const {billingAddress, shippingAddress} = placeOrderRes.otherData;
- const klarnaClientToken = klarnaToken.split("|")[0];
- const klarnaVerifyToken = klarnaToken.split("|")[1];
- window.Klarna.Payments.init({
- client_token: klarnaClientToken,
- });
- //klarna-widget-container
- window.Klarna.Payments.load({
- container: '#klarna-widget-container',
- }, (response) => {
- if(!response.show_form) { // klarna不可用
- // 跳转结果页
- router.replace('/paymentresult/result?orderId=' + webOrderId + '&return_result=failure');
- } else {
-
- window.Klarna.Payments.authorize(
- {},
- {
- billing_address: {
- given_name: billingAddress.firstName,
- family_name: billingAddress.lastName,
- email: billingAddress.email,
- phone: billingAddress.phone,
- street_address: billingAddress.address,
- postal_code: billingAddress.postcode,
- city: billingAddress.city,
- country: billingAddress.country
- },
- shipping_address: {
- given_name: shippingAddress.firstName,
- family_name: shippingAddress.lastName,
- email: shippingAddress.email,
- street_address: shippingAddress.address,
- postal_code: shippingAddress.postcode,
- city: shippingAddress.city,
- phone: shippingAddress.phone,
- region: shippingAddress.state,
- country: shippingAddress.country
- },
- // customer: {
- // date_of_birth: "1941-03-21",
- // },
- },
- async function(res) {
- console.log('klarna authorize res ---- ',res);
- if(res.approved && res.authorization_token) { // 可以支付
- const resCallback = await createPaymentCallback({
- orderId: Number(webOrderId),
- gatewayOrderId: res.authorization_token,
- verifyToken: klarnaVerifyToken,
- status: "success",
- });
- // 跳转结果页
- overlayLoading.stop();
- if(!resCallback.error) {
- router.replace('/paymentresult/result?orderId=' + webOrderId + '&return_result=success');
- } else {
- // callback 失败,提示错误
- confirmDialog({
- title: "Somthing Wrong",
- content: resCallback.msg + " Please contact customer service." + " OrderId: "+ webOrderId,
- noCancel: true,
- }).then(() => {
- router.replace('/');
- });
-
- }
- } else {
- // if(res.show_form) { // klarna可用,但是有报错
- // } else {
- // // klarna 不可用 跳转结果页
- // }
- overlayLoading.stop();
- router.replace('/paymentresult/result?orderId=' + webOrderId + '&return_result=failure');
- }
- }
- );
-
- }
- });
-
- }
-
- };
- return (
- <>
- <div className="relative w-full">
- {paymentMethod === 'paypal_smart_button' &&
- <PaypalButton
- createOrder={paypalCreateOrder}
- />
- }
- {(paymentMethod === 'awxklarna' || paymentMethod === 'awxafterpay') &&
- <button className="flex items-center justify-center w-full h-12 bg-ly-green text-white rounded-3xl text-ly-16 font-bold"
- onClick={airwallexPlaceOrder}
- >
- Place Order
- </button>
- }
- {paymentMethod === 'airwallex' &&
- <button className="flex items-center justify-center w-full h-12 bg-ly-green text-white rounded-3xl text-ly-16 font-bold"
- onClick={cardAirwallexPlaceOrder}
- >
- Place Order
- </button>
- }
- {(paymentMethod === 'afterpay' || paymentMethod === 'clearpay') &&
- <button className="flex items-center justify-center w-full h-12 bg-ly-green text-white rounded-3xl text-ly-16 font-bold"
- onClick={afterpayPlaceOrder}
- >
- Place Order
- </button>
- }
- {paymentMethod === 'klarna' &&
- <KlarnaButton clickHandler={klarnaPlaceOrder} />
- }
-
- </div>
- </>
- );
- }
|