Quellcode durchsuchen

对接airwallex的afterpay和klarna --- v1

fogwind vor 6 Tagen
Ursprung
Commit
cdec70c764

+ 44 - 7
src/app/(checkout)/checkout/_components/CheckoutPlaceOrder.tsx

@@ -1,22 +1,28 @@
 "use client";
 
-import { useState } from "react";
 import { usePlaceOrder } from "@/utils/hooks/usePlaceOrder";
 import PaypalButton from "./PaymentButton/PaypalButton";
-
+import { overlayLoading } from "@/components/theme/ui/kernel/loading/api";
+import { confirmDialog } from "@/components/theme/ui/kernel/confirm/api";
+import { useAppDispatch } from "@/store/hooks";
+import { clearCart } from "@/store/slices/cart-slice";
 export default function CheckoutPlaceOrder({
     paymentMethod,
     clickPlaceOrder, // 校验运输方式,地址 
 }: {
     paymentMethod: string;
     clickPlaceOrder: () => Promise<boolean>;
-}) { 
+}) {
+    const dispatch = useAppDispatch(); 
+
     const { createOrder } = usePlaceOrder(); 
     
     const handleCreateOrder = async () => {
         const res = await createOrder();
         console.log("createOrder res ---- ", res);
         if(!res.error && res.data) {
+            //创建订单成功后清空redux 购物车
+            dispatch(clearCart());
             return {
                 error: res.error,
                 msg: '',
@@ -33,6 +39,33 @@ export default function CheckoutPlaceOrder({
         }
     };
 
+    const airwallexPlaceOrder = async () => {
+        overlayLoading.start();
+        const vaild = await clickPlaceOrder();
+        if(vaild) {
+            const res = await createOrder({
+                paymentSuccessUrl: window.location.origin + '/paymentresult/result'
+            });
+            console.log("createOrder res ---- ", res);
+            if(!res.error && res.data) {
+                // 创建订单成功了,跳转支付页面
+                //创建订单成功后清空redux 购物车
+                dispatch(clearCart());
+                window.location.href = res.data.gatewayOrderId;
+            } else {
+                //创建订单出错了
+                overlayLoading.stop();
+                confirmDialog({
+                    title: "Warning",
+                    content: res.msg + " Create order failed. Please try again.",
+                    noCancel: true,
+                }).then(() => {});
+            }
+        } else {
+            overlayLoading.stop();
+        }
+    };
+
     return (
         <>
             <div className="relative w-full">
@@ -42,11 +75,15 @@ export default function CheckoutPlaceOrder({
                         onPaymentClick={clickPlaceOrder}
                     />
                 }
+                {(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>
+                }
+
             </div>
-           
-            {/* <button className="flex items-center justify-center w-full h-12 bg-ly-green text-white rounded-3xl text-ly-16 font-bold">
-                Place Order
-            </button> */}
         </>
     );
 }

+ 42 - 32
src/app/(checkout)/checkout/_components/ContinueToPay/PaymentMethodContinueTpPay.tsx

@@ -3,11 +3,12 @@
 import Image from "next/image";
 import { use } from "react";
 import { useForm, get } from "react-hook-form";
-import { useApolloClient } from "@apollo/client/react";
-import {CheckoutPaymentMethodsData} from "@/types/checkout/type";
+import {RepayOrderPaymentMethodsData} from "@/types/checkout/type";
 import {GraphqlRequestResult} from "@/types/graphqlFetch/type";
-import {CREATE_PAYMENT_REPLAY} from "@/graphql";
+import { usePlaceOrder } from "@/utils/hooks/usePlaceOrder";
 import PaypalButton from "../PaymentButton/PaypalButton";
+import { overlayLoading } from "@/components/theme/ui/kernel/loading/api";
+import { confirmDialog } from "@/components/theme/ui/kernel/confirm/api";
 
 interface PaymentReplayResult {
     orderId: string;
@@ -20,14 +21,14 @@ export function PaymentMethodContinueTpPay({
     defaultPaymentMethod,
     orderId,
 }: {
-    paymentMethodsDataPromise: Promise<GraphqlRequestResult<CheckoutPaymentMethodsData>>;
+    paymentMethodsDataPromise: Promise<GraphqlRequestResult<RepayOrderPaymentMethodsData>>;
     defaultPaymentMethod: {method: string; methodTitle: string;}
     orderId: string;
 }) {
     const paymentMethodsData = use(paymentMethodsDataPromise);
-    const paymentMethods =  paymentMethodsData.data?.collectionPaymentMethods || [];
+    const paymentMethods =  paymentMethodsData.data?.collectionRepayOrderPaymentMethods || [];
 
-    const client = useApolloClient();
+    const { paymentRepay } = usePlaceOrder(); 
   
     const {
         register,
@@ -46,37 +47,38 @@ export function PaymentMethodContinueTpPay({
     const selectedPaymentMethod = watch("paymentMethod");
     console.log('selectedPaymentMethod -------- ',selectedPaymentMethod);
     const handleCreateOrder = async () => {
-
-        return client.mutate({
-            mutation: CREATE_PAYMENT_REPLAY,
-            variables: {
-                orderId: Number(orderId),
-                paymentMethod: selectedPaymentMethod
-            }
-        }).then((res) => {
-            const resData = res?.data?.createPaymentReplay?.paymentReplay ?? null; 
-            const result: PaymentReplayResult = {
-                error: false,
-                msg: '',
-                orderId: resData?.gatewayOrderId ?? '',
-                webOrderId: resData?.orderId ?? ''
-            };
-            return result;
-        }).catch((err) => {
-            const result: PaymentReplayResult = {
-                error: true,
-                msg: err.message,
-                orderId: '',
-                webOrderId: ''
-            };
-            // showToast(err.message,'danger');
-            return result;
+        return await paymentRepay({
+            orderId: Number(orderId),
+            paymentMethod: selectedPaymentMethod
         });
 
     };
     const handleClickPay = async () => {
         return true;
-    }
+    };
+    const airwallexRepay = async () => {
+        overlayLoading.start();
+        const res = await paymentRepay({
+            orderId: Number(orderId),
+            paymentMethod: selectedPaymentMethod,
+            paymentSuccessUrl: window.location.origin + '/paymentresult/result'
+        });
+        
+        console.log("airwallexPlaceOrder res ---- ", res);
+        
+        if(!res.error && res.orderId) {
+            // 创建订单成功了,跳转支付页面
+            window.location.href = res.orderId;
+        } else {
+            //创建订单出错了
+            overlayLoading.stop();
+            confirmDialog({
+                title: "Warning",
+                content: res.msg + " Create order failed. Please try again.",
+                noCancel: true,
+            }).then(() => {});
+        }
+    };
     return (
         <>
             <form name="shipping method" className="w-full box-border px-4 mt-4">
@@ -122,6 +124,7 @@ export function PaymentMethodContinueTpPay({
                 <p className="text-ly-12 text-[#666666] leading-4.75">
                     By providing your information, you agree to Wiggins'sPrivacy Policyand Terms of Use.
                 </p>
+
                 <div className="mt-6 w-full">
                     {selectedPaymentMethod === 'paypal_smart_button' && 
                         <PaypalButton
@@ -130,6 +133,13 @@ export function PaymentMethodContinueTpPay({
                             isRePay={true}
                         />
                     }
+                    {(selectedPaymentMethod === 'awxklarna' || selectedPaymentMethod === '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={airwallexRepay}
+                        >
+                            Place Order
+                        </button>
+                    }
 
                 </div>
             </div>

+ 12 - 0
src/app/(checkout)/checkout/_components/LoadingCheckoutPlaceOrder.tsx

@@ -0,0 +1,12 @@
+export default function LoadingCheckoutPlaceOrder() { 
+    return (
+       
+        <div className="relative w-full animate-pulse">
+                        
+            <button className="flex items-center justify-center w-full h-12 bg-gray-300 rounded-3xl text-ly-16 font-bold"></button>
+                        
+        
+        </div>
+        
+    );
+}

+ 5 - 4
src/app/(checkout)/checkout/continuetopay/page.tsx

@@ -4,11 +4,11 @@ import { redirect, RedirectType } from 'next/navigation';
 import { authOptions } from "@utils/auth";
 import { authorizationGraphqlQuery, fullCacheGraphqlRequest} from "@/lib/graphql-fetch";
 import ContinueToPayOrderInfo from "../_components/ContinueToPay/ContinueToPayOrderInfo";
-import { GET_ORDER_DETAILS, GET_CHECKOUT_PAYMENT_METHODS, GET_CURRENCIES } from "@/graphql";
+import { GET_ORDER_DETAILS, GET_REPAYORDER_PAYMENT_METHODS, GET_CURRENCIES } from "@/graphql";
 // import { Country } from "@/types/checkout/type";
 import { OrderDetailsData } from "@/types/customer/type";
 import { CurrenciesData } from "@/types/currency/type";
-import { CheckoutPaymentMethodsData } from "@/types/checkout/type";
+import { RepayOrderPaymentMethodsData } from "@/types/checkout/type";
 import {PaymentMethodContinueTpPay} from "../_components/ContinueToPay/PaymentMethodContinueTpPay";
 
 // 只能存在一个待支付订单
@@ -53,10 +53,11 @@ export default async function ContinueToPay({searchParams}: {
     }
 
     const currencyRes = await fullCacheGraphqlRequest<CurrenciesData>(GET_CURRENCIES);
-    console.log("currencyRes ==========",currencyRes); 
     const currencyList = currencyRes.data?.currencies?.edges.map((item) => item.node) ?? [];
     // 获取支付方式列表
-    const paymentMethodsResponse = authorizationGraphqlQuery<CheckoutPaymentMethodsData>(GET_CHECKOUT_PAYMENT_METHODS);
+    const paymentMethodsResponse = authorizationGraphqlQuery<RepayOrderPaymentMethodsData>(GET_REPAYORDER_PAYMENT_METHODS,{
+        orderId: Number(orderid)
+    });
     
     const currencySymbol = currencyList.find(item => item.code === orderDetailData.orderCurrencyCode)?.symbol ?? '';
     

+ 101 - 0
src/app/(public)/paymentresult/_components/CancelOrFailure.tsx

@@ -0,0 +1,101 @@
+"use client";
+
+import {use, useEffect, useRef} from "react";
+import Link from "next/link";
+import {GraphqlRequestResult} from "@/types/graphqlFetch/type";
+import { OrderDetailsData } from "@/types/customer/type";
+import { usePlaceOrder } from "@/utils/hooks/usePlaceOrder";
+import Faqs from "./Faqs";
+import { useAppDispatch } from "@/store/hooks";
+import { fetchCartDetail } from "@/store/slices/cart-slice";
+export default function CancelOrFailure({
+    orderDetailPromise,
+    paymentStatus,
+    isGuest
+}: {
+    orderDetailPromise: Promise<GraphqlRequestResult<OrderDetailsData>>,
+    paymentStatus: string,
+    isGuest: boolean
+}) { 
+    const dispatch = useAppDispatch();
+    const promiseRes = use(orderDetailPromise);
+    const orderDetailRes = promiseRes.data?.customerOrder ?? null;
+    const {cancelOrder} = usePlaceOrder();
+    const orderId = orderDetailRes?.incrementId;
+    const orderStatus = orderDetailRes?.status;
+    const cancelOrderRef = useRef(false);
+    useEffect(() => {
+        console.log('isGuest ---- ',isGuest);
+        if(isGuest && !cancelOrderRef.current) {
+            
+            // 如果是游客,取消订单
+            console.log('游客,取消订单 ',orderId,orderStatus,cancelOrderRef.current);
+            if(orderId && orderStatus !=='canceled' && !cancelOrderRef.current) {
+                console.log('cancelOrder run ');
+                cancelOrder({
+                    orderId: Number(orderId),
+                }).then(() => {
+                    // 重新获取购物车
+                    dispatch(fetchCartDetail());
+                }).catch(() => {});
+            }
+            cancelOrderRef.current = true;
+        }
+    }, [orderId,orderStatus]);
+    return (
+        <div className="box-border px-4 w-full">
+            {paymentStatus === 'failure' &&
+                <>
+                    <div className="w-12 h-12 mx-auto mt-9">
+                        <svg className="failure block w-full h-full" width="200" height="200" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="27635"><path d="M736 332.8L556.8 512l179.2 179.2-44.8 44.8L512 556.8l-179.2 179.2-44.8-44.8L467.2 512 288 332.8l44.8-44.8L512 467.2l179.2-179.2 44.8 44.8z" p-id="27636"></path><path d="M512 0a512 512 0 1 1 0 1024A512 512 0 0 1 512 0z m0 64a448 448 0 1 0 0 896A448 448 0 0 0 512 64z" p-id="27637"></path></svg>
+                    </div>
+                    <p className="text-ly-16 text-center mt-6">
+                        {isGuest ?
+                            "payment Failed! Your order has been cancelled."
+                        :
+                            "Payment Failed! You can try again."
+                        }
+                        
+                    </p>
+                </>
+            }
+            {paymentStatus === 'cancel' &&
+                <>
+                    <div className="w-12 h-12 mx-auto mt-9">
+                        <svg className="warning block w-full h-full" width="200" height="200" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="24135"><path d="M874.6496 512a362.6496 362.6496 0 1 0-725.3504 0 362.6496 362.6496 0 0 0 725.3504 0z m64 0a426.6496 426.6496 0 1 1-853.3504 0 426.6496 426.6496 0 0 1 853.3504 0z m-458.7008 85.3504V298.7008h64v298.6496h-64z m0 128v-64h64v64h-64z" p-id="24136"></path></svg>
+                    </div>
+                    <p className="text-ly-16 text-center mt-6">
+                        {isGuest ?
+                            "payment cancelled! Your order has been cancelled."
+                        :
+                            "Payment cancelled! You can try again."
+                        }
+                        
+                    </p>
+                </>
+            }
+
+            <p className="text-ly-16 mt-4 flex justify-center">
+                <span className="px-3.75 leading-ly-28 bg-[#f0fffa]">Order #{orderId}</span>
+            </p>
+            {/* <p className="text-ly-12 text-center mt-4 leading-ly-22">
+                Hello, {orderDetailRes?.customerFirstName} <br/>
+                Thank you so much for your order !<br/>
+                We’ll get started on your order very soon!<br/>
+                You’ll receive an order confirmation email with details of your order in an hour, please be sure to check your email and confirm your order, that is very important for us to process your order.
+            </p> */}
+            {isGuest ?
+                <Link href="/" className="mt-6 flex justify-center items-center h-12 border-1 rounded-3xl text-ly-14">
+                    Continue Shopping
+                </Link>
+            :
+                <Link href={`/checkout/continuetopay?orderid=${orderId}`} className="mt-6 flex justify-center items-center h-12 border-1 rounded-3xl text-ly-14">
+                    Continue To Pay
+                </Link>
+            }
+            <div className="box-border w-full mt-6">
+                <Faqs />
+            </div>
+        </div>
+    );
+}

Datei-Diff unterdrückt, da er zu groß ist
+ 20 - 0
src/app/(public)/paymentresult/_components/Faqs.tsx


Datei-Diff unterdrückt, da er zu groß ist
+ 16 - 19
src/app/(public)/success/_components/OrderDetailWrapper.tsx


+ 34 - 0
src/app/(public)/paymentresult/_components/SkeletonCancelOrFailure.tsx

@@ -0,0 +1,34 @@
+
+export default function SkeletonCancelOrFailure() { 
+    return (
+        <div className="w-full animate-pulse px-0">
+
+            <div className="w-full">
+                <div className="box-border px-4 w-full">
+                    <div className="w-12 h-12 mx-auto mt-9 bg-gray-300"></div>
+                    <p className="text-ly-16 text-center mt-6">
+                        <span className="text-gray-300 bg-gray-300">Your Order Has Been Received</span>
+                    </p>
+                    <p className="text-ly-16 mt-4 flex justify-center">
+                        <span className="px-3.75 leading-ly-28 text-gray-300 bg-gray-300">Order #600000000</span>
+                    </p>
+              
+                    <div className="mt-6 flex justify-center items-center h-12 border-1 rounded-3xl text-ly-14">
+                        <span className="text-gray-300 bg-gray-300">Continue Shopping</span>
+                    </div>
+                </div>
+                <div className="box-border px-4 w-full mt-6">
+                    <div className="relative w-full bg-ly-lightgray box-border p-3">
+                        <button className="absolute top-3 right-3 w-6 h-6 bg-gray-300"></button>
+                        <p className="text-ly-13"><span className="text-gray-300 bg-gray-300">Faqs</span></p>
+                        <p className="text-ly-12 text-[#a6a6a6] mt-2">
+                            <span className="text-gray-300 bg-gray-300">Pls contact customer service if need any help</span>
+                        </p>
+                    </div>
+                </div>
+
+
+            </div>
+        </div>
+    );
+}

src/app/(public)/success/_components/SuccessPageSkeleton.tsx → src/app/(public)/paymentresult/_components/SuccessPageSkeleton.tsx


+ 64 - 0
src/app/(public)/paymentresult/result/page.tsx

@@ -0,0 +1,64 @@
+import {Suspense} from "react";
+import { getServerSession } from "next-auth";
+import { cookies } from 'next/headers';
+import { redirect, RedirectType } from 'next/navigation'
+import { authOptions } from "@utils/auth";
+import {authorizationGraphqlQuery} from "@/lib/graphql-fetch";
+import {GET_ORDER_DETAILS} from "@/graphql";
+import { OrderDetailsData } from "@/types/customer/type";
+import SuccessPageSkeleton from "../_components/SuccessPageSkeleton";
+import SkeletonCancelOrFailure from "../_components/SkeletonCancelOrFailure";
+import CancelOrFailure from "../_components/CancelOrFailure";
+import OrderDetailWrapper from "../_components/OrderDetailWrapper";
+import { GUEST_CART_TOKEN,GUEST_CART_ID } from "@/utils/constants";
+
+// 如果是游客:请求完订单详情后删除cookie里原来的carttoken cartid
+export default async function SuccessPage({searchParams}: {
+  searchParams?: Promise<{ [key: string]: string | string[] | undefined }>;
+})  {
+    const cookieStore = await cookies();
+    // 登录用户cookie里没有GUEST_CART_ID
+    if(!cookieStore.get(GUEST_CART_TOKEN)) {
+        redirect('/', RedirectType.replace);
+    }
+    const session = await getServerSession(authOptions);// 游客是null
+    const isGuest = session === null;
+    
+    const query = await searchParams; // awx_return_result
+    const orderid = query?.orderId;
+    const paymentResult = query?.awx_return_result ?? query?.return_result; // 支付状态
+
+
+    if (!orderid) {
+        redirect("/", RedirectType.replace);
+    }
+
+
+    const orderDetailPromise = authorizationGraphqlQuery<OrderDetailsData>(GET_ORDER_DETAILS,{
+        id: orderid,// `/api/shop/customer-orders/${orderid}`
+    });
+    // 如果是游客且支付成功,删除cookie里的GUEST_CART_TOKEN GUEST_CART_ID
+    if(isGuest && paymentResult === 'success') {
+        cookieStore.delete(GUEST_CART_TOKEN);
+        cookieStore.delete(GUEST_CART_ID);
+    }
+    return (
+        
+        <div className="w-full">
+            {paymentResult === 'success' && 
+                <Suspense fallback={<SuccessPageSkeleton />}>
+                    <OrderDetailWrapper isGuest={isGuest} orderDetailPromise={orderDetailPromise} />
+                </Suspense>
+
+            }
+            {(paymentResult === 'cancel' || paymentResult === 'failure') &&
+            //http://localhost:3001/paymentresult/result?orderId=2643&awx_return_result=cancel
+            // http://localhost:3001/paymentresult/result?orderId=2644&awx_return_result=failure
+                <Suspense fallback={<SkeletonCancelOrFailure/>}>
+                    <CancelOrFailure isGuest={isGuest} orderDetailPromise={orderDetailPromise} paymentStatus={paymentResult} />
+                </Suspense>
+            }
+            
+        </div>
+    );
+}

+ 0 - 33
src/app/(public)/success/page.tsx

@@ -1,33 +0,0 @@
-import {Suspense} from "react";
-import { cookies } from 'next/headers';
-import { redirect, RedirectType } from 'next/navigation'
-import {authorizationGraphqlQuery} from "@/lib/graphql-fetch";
-import {GET_ORDER_DETAILS} from "@/graphql";
-import { OrderDetailsData } from "@/types/customer/type";
-import SuccessPageSkeleton from "./_components/SuccessPageSkeleton";
-import OrderDetailWrapper from "./_components/OrderDetailWrapper";
-import { GUEST_CART_TOKEN,GUEST_CART_ID } from "@/utils/constants";
-
-// 如果是游客:请求完订单详情后删除cookie里原来的carttoken cartid
-export default async function SuccessPage({searchParams}: {
-  searchParams?: Promise<{ [key: string]: string | string[] | undefined }>;
-})  {
-    const cookieStore = await cookies();
-    // 登录用户cookie里没有GUEST_CART_ID
-    if(!cookieStore.get(GUEST_CART_TOKEN)) {
-        redirect('/', RedirectType.replace);
-    }
-    const query = await searchParams;
-    const orderid = query?.orderid;
-    const orderDetailPromise = authorizationGraphqlQuery<OrderDetailsData>(GET_ORDER_DETAILS,{
-        id: orderid,// `/api/shop/customer-orders/${orderid}`
-    });
-    return (
-        
-        <div className="w-full">
-            <Suspense fallback={<SuccessPageSkeleton />}>
-                <OrderDetailWrapper orderDetailPromise={orderDetailPromise} />
-            </Suspense>
-        </div>
-    );
-}

+ 6 - 0
src/graphql/checkout/mutations/CreateCheckoutOrder.ts

@@ -5,11 +5,17 @@ export const CREATE_PAYMENT_INITIATE: TypedDocumentNode<CreatePaymentInitiateDat
   mutation CreatePaymentInitiate(
       $expressCheckout: Boolean
       $paymentMethod: String
+      $paymentSuccessUrl: String
+      $paymentFailureUrl: String
+      $paymentCancelUrl: String
   ) {
       createPaymentInitiate(
         input: {
           expressCheckout: $expressCheckout
           paymentMethod: $paymentMethod
+          paymentSuccessUrl: $paymentSuccessUrl
+          paymentFailureUrl: $paymentFailureUrl
+          paymentCancelUrl: $paymentCancelUrl
         }
       ) {
           paymentInitiate {

+ 6 - 0
src/graphql/checkout/mutations/CreatePaymentReplay.ts

@@ -5,11 +5,17 @@ export const CREATE_PAYMENT_REPLAY: TypedDocumentNode<CreatePaymentReplayData> =
   mutation CreatePaymentReplay(
       $orderId: Int
       $paymentMethod: String
+      $paymentSuccessUrl: String
+      $paymentFailureUrl: String
+      $paymentCancelUrl: String
   ) {
       createPaymentReplay(
         input: {
           orderId: $orderId
           paymentMethod: $paymentMethod
+          paymentSuccessUrl: $paymentSuccessUrl
+          paymentFailureUrl: $paymentFailureUrl
+          paymentCancelUrl: $paymentCancelUrl
         }
       ) {
           paymentReplay{

+ 16 - 0
src/graphql/checkout/queries/GetRepayOrderPaymentMethods.ts

@@ -0,0 +1,16 @@
+import { gql,TypedDocumentNode } from "@apollo/client";
+import { RepayOrderPaymentMethodsData } from "@/types/checkout/type";
+
+export const GET_REPAYORDER_PAYMENT_METHODS: TypedDocumentNode<RepayOrderPaymentMethodsData> = gql`
+  query RepayOrderPaymentMethods($orderId: Int!) {
+    collectionRepayOrderPaymentMethods(orderId: $orderId) {
+      id
+      _id
+      method
+      title
+      description
+      icon
+      isAllowed
+    }
+  }
+`;

+ 2 - 1
src/graphql/checkout/queries/index.ts

@@ -2,4 +2,5 @@ export {GET_CHECKOUT_PAYMENT_METHODS} from "./GetCheckoutPaymentMethods" ;
 export {GET_CHECKOUT_SHIPPING_RATES} from "./GetCheckoutShippingRates" ;
 export {GET_CHECKOUT_ADDRESSES} from "./GetCheckoutAddress";
 export {GET_COUNTRIES} from "./GetCountries";
-export {GET_COUNTRY_STATES} from "./GetStates";
+export {GET_COUNTRY_STATES} from "./GetStates";
+export {GET_REPAYORDER_PAYMENT_METHODS} from "./GetRepayOrderPaymentMethods";

+ 13 - 0
src/types/checkout/type.ts

@@ -127,6 +127,9 @@ export interface CheckoutPaymentMethodsOperation {
   variables: Record<string, unknown>;
   data: CheckoutPaymentMethodsData;
 }
+export interface RepayOrderPaymentMethodsData {
+  collectionRepayOrderPaymentMethods: CheckoutPaymentMethod[];
+}
 
 // checkout save payment
 
@@ -235,6 +238,9 @@ export interface CreatePaymentInitiateData {
 export interface CreatePaymentInitiateVariables {
     expressCheckout?: boolean;
     paymentMethod?: string;
+    paymentSuccessUrl?: string;
+    paymentFailureUrl?: string;
+    paymentCancelUrl?: string;
 }
 
 // create payment callback
@@ -454,4 +460,11 @@ export interface CreatePaymentReplayPayload {
 }
 export interface CreatePaymentReplayData {
   createPaymentReplay: CreatePaymentReplayPayload;
+}
+export interface CreatePaymentReplayVariables {
+  orderId: number;
+  paymentMethod: string;
+  paymentSuccessUrl?: string;
+  paymentFailureUrl?: string;
+  paymentCancelUrl?: string;
 }

+ 34 - 1
src/utils/hooks/usePlaceOrder.ts

@@ -3,6 +3,7 @@ import {
     CREATE_PAYMENT_INITIATE,
     CREATE_PAYMENT_CALLBACK,
     CREATE_CANCEL_ORDER,
+    CREATE_PAYMENT_REPLAY
 } from "@/graphql";
 import {
     CreatePaymentInitiateVariables, 
@@ -11,6 +12,7 @@ import {
     CreatePaymentInitiate,
     CreatePaymentCallback,
     CreateCancelOrder,
+    CreatePaymentReplayVariables
 } from "@/types/checkout/type";
 
 interface CreateOrderResult {
@@ -28,6 +30,12 @@ interface CreateCancelOrderResult {
     msg: string;
     error: boolean;
 }
+interface PaymentReplayResult {
+    orderId: string;
+    webOrderId: string;
+    error: boolean;
+    msg: string;
+}
 export const usePlaceOrder = () => {
     const client = useApolloClient();
 
@@ -100,10 +108,35 @@ export const usePlaceOrder = () => {
         });
     }
 
+    const paymentRepay = (params: CreatePaymentReplayVariables) => { 
+
+        return client.mutate({
+            mutation: CREATE_PAYMENT_REPLAY,
+            variables: params
+        }).then((res) => {
+            const resData = res?.data?.createPaymentReplay?.paymentReplay ?? null; 
+            const result: PaymentReplayResult = {
+                error: false,
+                msg: '',
+                orderId: resData?.gatewayOrderId ?? '',
+                webOrderId: resData?.orderId ?? ''
+            };
+            return result;
+        }).catch((err) => {
+            const result: PaymentReplayResult = {
+                error: true,
+                msg: err.message,
+                orderId: '',
+                webOrderId: ''
+            };
+            return result;
+        });
+    };
 
   return {
     createOrder,
     createPaymentCallback,
-    cancelOrder
+    cancelOrder,
+    paymentRepay
   };
 };