diff --git a/payment_sdk/src/assets/images/awaitingPayment.png b/payment_sdk/src/assets/images/awaitingPayment.png new file mode 100644 index 0000000..0b45b26 Binary files /dev/null and b/payment_sdk/src/assets/images/awaitingPayment.png differ diff --git a/payment_sdk/src/components/PaymentModal.tsx b/payment_sdk/src/components/PaymentModal.tsx index affa94d..b30995c 100644 --- a/payment_sdk/src/components/PaymentModal.tsx +++ b/payment_sdk/src/components/PaymentModal.tsx @@ -79,11 +79,11 @@ const PaymentModal = ({ const getCtaText = () => { switch (paymentState) { case ResponseScreenStatuses.SUCCESS: + case ResponseScreenStatuses.COMPLETE: + case ResponseScreenStatuses.CANCELLED: return paymentSuccessCtaText; case ResponseScreenStatuses.FAILED: return paymentFailedCtaText; - case ResponseScreenStatuses.CANCELLED: - return paymentSuccessCtaText; default: return ""; } @@ -92,14 +92,14 @@ const PaymentModal = ({ const ctaOnPress = () => { switch (paymentState) { case ResponseScreenStatuses.SUCCESS: + case ResponseScreenStatuses.COMPLETE: + case ResponseScreenStatuses.CANCELLED: return closeSheet(false); case ResponseScreenStatuses.FAILED: return dispatch({ type: Actions.SET_PAYMENT_STATE, payload: "", }); - case ResponseScreenStatuses.CANCELLED: - return closeSheet(false); default: return ""; } @@ -110,8 +110,6 @@ const PaymentModal = ({ !( paymentState === ResponseScreenStatuses.SUCCESS || paymentState === ResponseScreenStatuses.CANCELLED || - // TODO: Fix this type error - // @ts-expect-error - Property 'COMPLETE' does not exist on type 'ResponseScreenStatuses'. paymentState === ResponseScreenStatuses.COMPLETE ) ); @@ -128,26 +126,24 @@ const PaymentModal = ({ - {!paymentState ? 'PAYMENT_OPTIONS' : ''} + + {!paymentState ? "PAYMENT_OPTIONS" : ""} + - { - // TODO: Fix this type error - // @ts-expect-error - Property 'COMPLETE' does not exist on type 'ResponseScreenStatuses'. - paymentState && paymentState !== ResponseScreenStatuses.COMPLETE ? ( - - ) : ( - - ) - } + {paymentState ? ( + + ) : ( + + )} ); diff --git a/payment_sdk/src/components/ResponseScreen.tsx b/payment_sdk/src/components/ResponseScreen.tsx index 7d08877..f9a8858 100644 --- a/payment_sdk/src/components/ResponseScreen.tsx +++ b/payment_sdk/src/components/ResponseScreen.tsx @@ -1,6 +1,6 @@ import React, { useCallback, useMemo } from "react"; -import { Image, StyleSheet, View } from "react-native"; +import { Image, StyleSheet, View, ImageSourcePropType } from "react-native"; import { ResponseScreenStatuses, ThemeSchemeType } from "@util/types"; @@ -10,8 +10,38 @@ import { useCurrentTheme } from "@theme/useCurrentTheme"; import KomojuText from "./KomojuText"; import SubmitButton from "./SubmitButton"; +type StatusConfig = { + title: string; + defaultMessage: string; + image: ImageSourcePropType; +}; + +// Configuration object for all statuses +const statusConfigs: Partial> = { + [ResponseScreenStatuses.SUCCESS]: { + title: "PAYMENT_SUCCESS", + defaultMessage: "ORDER_THANK_YOU_NOTE", + image: require("../assets/images/success.png"), + }, + [ResponseScreenStatuses.FAILED]: { + title: "PAYMENT_FAILED", + defaultMessage: "PAYMENT_RE_TRY_MSG", + image: require("../assets/images/error.png"), + }, + [ResponseScreenStatuses.CANCELLED]: { + title: "PAYMENT_CANCELLED", + defaultMessage: "PAYMENT_CANCELLED_MSG", + image: require("../assets/images/error.png"), + }, + [ResponseScreenStatuses.COMPLETE]: { + title: "PAYMENT_WAITING", + defaultMessage: "PAYMENT_CANCELLED_MSG", + image: require("../assets/images/awaitingPayment.png"), + }, +}; + type Props = { - status: ResponseScreenStatuses.SUCCESS | ResponseScreenStatuses.FAILED | ResponseScreenStatuses.CANCELLED; + status: ResponseScreenStatuses; message?: string; onPressLabel: string; onPress: () => void; @@ -21,32 +51,22 @@ const ResponseScreen = ({ status, message, onPress, onPressLabel }: Props) => { const theme = useCurrentTheme(); const styles = getStyles(theme); + const statusConfig = statusConfigs[status]; + const renderMessageContent = useMemo(() => { - const title = - status === ResponseScreenStatuses.SUCCESS - ? "PAYMENT_SUCCESS" : status === ResponseScreenStatuses.CANCELLED ? - "PAYMENT_CANCELLED" : "PAYMENT_FAILED"; - const defaultMessage = - status === ResponseScreenStatuses.SUCCESS - ? "ORDER_THANK_YOU_NOTE" : status === ResponseScreenStatuses.CANCELLED ? - "PAYMENT_CANCELLED_MSG" : "PAYMENT_RE_TRY_MSG"; - const msg = message || defaultMessage; + const msg = message || statusConfig?.defaultMessage; return ( - {title} + {statusConfig?.title} {msg} ); - }, [status, message]); + }, [status, message, statusConfig]); const renderIcon = useMemo(() => { - const source = - status === ResponseScreenStatuses.SUCCESS - ? require("../assets/images/success.png") - : require("../assets/images/error.png"); - return ; - }, [status]); + return ; + }, [statusConfig]); const memoizedOnPress = useCallback(onPress, [onPress]); diff --git a/payment_sdk/src/components/Sheet.tsx b/payment_sdk/src/components/Sheet.tsx index dfbc945..04df961 100644 --- a/payment_sdk/src/components/Sheet.tsx +++ b/payment_sdk/src/components/Sheet.tsx @@ -168,11 +168,11 @@ const Sheet: ForwardRefRenderFunction = ( const getCtaText = () => { switch (paymentState) { case ResponseScreenStatuses.SUCCESS: + case ResponseScreenStatuses.COMPLETE: + case ResponseScreenStatuses.CANCELLED: return paymentSuccessCtaText; case ResponseScreenStatuses.FAILED: return paymentFailedCtaText; - case ResponseScreenStatuses.CANCELLED: - return paymentSuccessCtaText; default: return ""; } @@ -181,14 +181,14 @@ const Sheet: ForwardRefRenderFunction = ( const ctaOnPress = () => { switch (paymentState) { case ResponseScreenStatuses.SUCCESS: + case ResponseScreenStatuses.COMPLETE: + case ResponseScreenStatuses.CANCELLED: return closeSheet(false); case ResponseScreenStatuses.FAILED: return dispatch({ type: Actions.SET_PAYMENT_STATE, payload: "", }); - case ResponseScreenStatuses.CANCELLED: - return closeSheet(false); default: return ""; } @@ -218,8 +218,6 @@ const Sheet: ForwardRefRenderFunction = ( !( paymentState === ResponseScreenStatuses.SUCCESS || paymentState === ResponseScreenStatuses.CANCELLED || - // TODO: Fix this type error - // @ts-expect-error - Property 'COMPLETE' does not exist on type 'ResponseScreenStatuses'. paymentState === ResponseScreenStatuses.COMPLETE ) ) @@ -230,18 +228,15 @@ const Sheet: ForwardRefRenderFunction = ( /> - { - // TODO: Fix this type error - paymentState ? ( - - ) : ( - - ) - } + {paymentState ? ( + + ) : ( + + )} ); diff --git a/payment_sdk/src/context/MainStateProvider.tsx b/payment_sdk/src/context/MainStateProvider.tsx index 0e74458..f7b6dac 100644 --- a/payment_sdk/src/context/MainStateProvider.tsx +++ b/payment_sdk/src/context/MainStateProvider.tsx @@ -71,12 +71,15 @@ export const MainStateProvider = (props: KomojuProviderIprops) => { setModalVisible(false); }; - // when payment is success global state is rest and invoking the success screen - const onPaymentSuccess = () => { + const resetGlobalStates = () => dispatch({ type: Actions.RESET_STATES, payload: initialState, }); + + // when payment is success global state is rest and invoking the success screen + const onPaymentSuccess = () => { + resetGlobalStates(); dispatch({ type: Actions.SET_PAYMENT_STATE, payload: ResponseScreenStatuses.SUCCESS, @@ -92,15 +95,21 @@ export const MainStateProvider = (props: KomojuProviderIprops) => { // when payment is cancelled by the user const onPaymentCancelled = () => { + resetGlobalStates(); dispatch({ - type: Actions.RESET_STATES, - payload: initialState, + type: Actions.SET_PAYMENT_STATE, + payload: ResponseScreenStatuses.CANCELLED, }); + }; + + // when payment is completed but awaiting payment + const onPaymentAwaiting = () => { + resetGlobalStates(); dispatch({ type: Actions.SET_PAYMENT_STATE, - payload: ResponseScreenStatuses.CANCELLED, + payload: ResponseScreenStatuses.COMPLETE, }); - } + }; const onUserCancel = async () => { if (onDismissCallback.current) { @@ -200,7 +209,10 @@ export const MainStateProvider = (props: KomojuProviderIprops) => { let sessionResponse = await sessionShow(sessionShowPayload); // Polling until session verification status changes - while (sessionResponse?.status === PaymentStatuses.PENDING && sessionResponse?.payment?.status !== PaymentStatuses.CANCELLED) { + while ( + sessionResponse?.status === PaymentStatuses.PENDING && + sessionResponse?.payment?.status !== PaymentStatuses.CANCELLED + ) { sessionResponse = await sessionShow(sessionShowPayload); } @@ -243,14 +255,13 @@ export const MainStateProvider = (props: KomojuProviderIprops) => { if (response?.status === PaymentStatuses.PENDING) { openURL(response.redirect_url); - } else if ( - response?.status === PaymentStatuses.SUCCESS && - response?.payment?.payment_details?.instructions_url - ) { - openURL(response?.payment?.payment_details?.instructions_url); - onPaymentSuccess(); } else if (response?.status === PaymentStatuses.SUCCESS) { - onPaymentSuccess(); + if (response?.payment?.status === PaymentStatuses.SUCCESS) { + onPaymentSuccess(); + } else if (response?.payment?.payment_details?.instructions_url) { + openURL(response?.payment?.payment_details?.instructions_url); + onPaymentAwaiting(); + } } else { onPaymentFailed(); } @@ -259,10 +270,7 @@ export const MainStateProvider = (props: KomojuProviderIprops) => { const createPayment = useCallback( ({ sessionId, onComplete, onDismiss }: CreatePaymentFuncType) => { - dispatch({ - type: Actions.RESET_STATES, - payload: initialState, - }); + resetGlobalStates(); // setting client provided onComplete callback into a ref // TODO: Fix this type error diff --git a/payment_sdk/src/util/types.ts b/payment_sdk/src/util/types.ts index b95a5b2..0d454c3 100644 --- a/payment_sdk/src/util/types.ts +++ b/payment_sdk/src/util/types.ts @@ -74,7 +74,7 @@ export enum PaymentStatuses { ERROR = "error", SUCCESS = "completed", PENDING = "pending", - CANCELLED = 'cancelled' + CANCELLED = "cancelled", } export enum TokenResponseStatuses { @@ -92,7 +92,7 @@ export enum ResponseScreenStatuses { /** For displaying payment instruction screens and disabling the cancel payment popup */ COMPLETE = "complete", /** For displaying payment instruction screens for cancelled by the user */ - CANCELLED = 'cancelled', + CANCELLED = "cancelled", } export enum CurrencySign { @@ -154,6 +154,7 @@ export type SessionPayResponseType = { status: string; payment: { payment_details: { instructions_url: string }; + status?: string; }; }; @@ -183,7 +184,7 @@ export type SessionShowResponseType = { payment_details: { instructions_url?: string; }; - status?: string + status?: string; }; }; @@ -242,6 +243,7 @@ export type State = CardDetailsType & */ paymentState: | ResponseScreenStatuses.SUCCESS + | ResponseScreenStatuses.COMPLETE | ResponseScreenStatuses.FAILED | ResponseScreenStatuses.CANCELLED | "";