Skip to content

Commit

Permalink
chore: [IOBP-704] Add payed rptid into state entities on payment succ…
Browse files Browse the repository at this point in the history
…ess (#5914)

## Short description
This PR adds the rptId when a payment is successfully made within the
state.entities to display the "Paid" badge in the message list.

## List of changes proposed in this pull request
- Added an additional orchestration action `paymentCompletedSuccess` to
the new payment flow checkout;
- Dispatched the above action when showing the successful outcome;
- Added the action handler into `ts/store/reducers/entities/payments.ts`
file

## How to test
- Enable the new wallet landing page FF;
- Start a payment from the new payment landing;
- When you reach the success outcome, you should be able to see the
dispatched action with the rptId paid.

## Preview

https://github.com/pagopa/io-app/assets/34343582/ebf23085-8549-49b1-9987-5c7de3a04c75

---------

Co-authored-by: Andrea <[email protected]>
  • Loading branch information
Hantex9 and Vangaorth authored Jun 28, 2024
1 parent e130cd1 commit 56bc826
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ import {
} from "../../../../navigation/params/AppParamsList";
import { usePaymentFailureSupportModal } from "../hooks/usePaymentFailureSupportModal";
import { WalletPaymentFailure } from "../types/WalletPaymentFailure";
import { useOnFirstRender } from "../../../../utils/hooks/useOnFirstRender";
import { paymentCompletedSuccess } from "../store/actions/orchestration";
import { useIODispatch, useIOSelector } from "../../../../store/hooks";
import { selectOngoingPaymentHistory } from "../../history/store/selectors";

type Props = {
failure: WalletPaymentFailure;
Expand All @@ -19,6 +23,8 @@ type Props = {
const WalletPaymentFailureDetail = ({ failure }: Props) => {
const navigation = useNavigation<IOStackNavigationProp<AppParamsList>>();
const supportModal = usePaymentFailureSupportModal({ failure });
const paymentOngoingHistory = useIOSelector(selectOngoingPaymentHistory);
const dispatch = useIODispatch();

const handleClose = () => {
navigation.pop();
Expand Down Expand Up @@ -115,6 +121,20 @@ const WalletPaymentFailureDetail = ({ failure }: Props) => {
}
};

useOnFirstRender(() => {
if (
paymentOngoingHistory?.rptId &&
failure.faultCodeCategory === "PAYMENT_DUPLICATED"
) {
dispatch(
paymentCompletedSuccess({
rptId: paymentOngoingHistory.rptId,
kind: "DUPLICATED"
})
);
}
});

const contentProps = getPropsFromFailure(failure);

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
} from "../../../../components/screens/OperationResultScreenContent";
import I18n from "../../../../i18n";
import { useIONavigation } from "../../../../navigation/params/AppParamsList";
import { useIOSelector } from "../../../../store/hooks";
import { useIODispatch, useIOSelector } from "../../../../store/hooks";
import { profileEmailSelector } from "../../../../store/reducers/profile";
import { formatNumberCentsToAmount } from "../../../../utils/stringBuilder";
import { useAvoidHardwareBackButton } from "../../../../utils/useAvoidHardwareBackButton";
Expand All @@ -26,6 +26,9 @@ import {
} from "../types/PaymentOutcomeEnum";
import ROUTES from "../../../../navigation/routes";
import { PaymentsOnboardingRoutes } from "../../onboarding/navigation/routes";
import { useOnFirstRender } from "../../../../utils/hooks/useOnFirstRender";
import { selectOngoingPaymentHistory } from "../../history/store/selectors";
import { paymentCompletedSuccess } from "../store/actions/orchestration";

type WalletPaymentOutcomeScreenNavigationParams = {
outcome: WalletPaymentOutcome;
Expand All @@ -39,18 +42,34 @@ type WalletPaymentOutcomeRouteProps = RouteProp<
const WalletPaymentOutcomeScreen = () => {
useAvoidHardwareBackButton();

const dispatch = useIODispatch();
const { params } = useRoute<WalletPaymentOutcomeRouteProps>();
const { outcome } = params;

const navigation = useIONavigation();
const paymentDetailsPot = useIOSelector(walletPaymentDetailsSelector);
const onSuccessAction = useIOSelector(walletPaymentOnSuccessActionSelector);
const profileEmailOption = useIOSelector(profileEmailSelector);
const paymentOngoingHistory = useIOSelector(selectOngoingPaymentHistory);

const supportModal = usePaymentFailureSupportModal({
outcome
});

useOnFirstRender(() => {
const kind =
outcome === WalletPaymentOutcomeEnum.SUCCESS
? "COMPLETED"
: outcome === WalletPaymentOutcomeEnum.DUPLICATE_ORDER
? "DUPLICATED"
: undefined;
const rptId = paymentOngoingHistory?.rptId;

if (kind && rptId) {
dispatch(paymentCompletedSuccess({ rptId, kind }));
}
});

// TODO: This is a workaround to disable swipe back gesture on this screen
// .. it should be removed as soon as the migration to react-navigation v6 is completed (https://pagopa.atlassian.net/browse/IOBP-522)
React.useEffect(() => {
Expand Down
13 changes: 12 additions & 1 deletion ts/features/payments/checkout/store/actions/orchestration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Bundle } from "../../../../../../definitions/pagopa/ecommerce/Bundle";
import { PaymentStartOrigin, WalletPaymentStepEnum } from "../../types";
import { WalletInfo } from "../../../../../../definitions/pagopa/ecommerce/WalletInfo";
import { PaymentMethodResponse } from "../../../../../../definitions/pagopa/ecommerce/PaymentMethodResponse";
import { RptId } from "../../../../../../definitions/pagopa/ecommerce/RptId";

export const walletPaymentSetCurrentStep = createStandardAction(
"WALLET_PAYMENT_SET_CURRENT_STEP"
Expand All @@ -15,6 +16,11 @@ export type PaymentInitStateParams = {
onSuccess?: OnPaymentSuccessAction;
};

export type PaymentCompletedSuccessPayload = {
rptId: RptId;
kind: "COMPLETED" | "DUPLICATED";
};

/**
* Action to initialize the state of a payment, optionally you can specify the route to go back to
* after the payment is completed or cancelled (default is the popToTop route)
Expand All @@ -31,8 +37,13 @@ export const selectPaymentPspAction = createStandardAction(
"PAYMENTS_SELECT_PAYMENT_PSP"
)<Bundle>();

export const paymentCompletedSuccess = createStandardAction(
"PAYMENTS_PAYMENT_COMPLETED_SUCCESS"
)<PaymentCompletedSuccessPayload>();

export type PaymentsCheckoutOrchestrationActions =
| ActionType<typeof walletPaymentSetCurrentStep>
| ActionType<typeof initPaymentStateAction>
| ActionType<typeof selectPaymentMethodAction>
| ActionType<typeof selectPaymentPspAction>;
| ActionType<typeof selectPaymentPspAction>
| ActionType<typeof paymentCompletedSuccess>;
15 changes: 13 additions & 2 deletions ts/store/reducers/entities/payments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
import { getType } from "typesafe-actions";
import { RptIdFromString } from "@pagopa/io-pagopa-commons/lib/pagopa";
import { Action } from "../../actions/types";
import { paymentCompletedSuccess } from "../../actions/wallet/payment";
import { paymentCompletedSuccess as legacyPaymentCompletedSuccess } from "../../actions/wallet/payment";
import { paymentCompletedSuccess } from "../../../features/payments/checkout/store/actions/orchestration";
import { GlobalState } from "../types";
import { differentProfileLoggedIn } from "../../actions/crossSessions";

Expand Down Expand Up @@ -36,7 +37,7 @@ export const paymentByRptIdReducer = (
action: Action
): PaymentByRptIdState => {
switch (action.type) {
case getType(paymentCompletedSuccess):
case getType(legacyPaymentCompletedSuccess):
// Use the ID as object key
const rptIdString: string = RptIdFromString.encode(action.payload.rptId);
return {
Expand All @@ -51,6 +52,16 @@ export const paymentByRptIdReducer = (
kind: "DUPLICATED"
}
};
// New payment flow completed
case getType(paymentCompletedSuccess):
return {
...state,
[action.payload.rptId]: {
kind: action.payload.kind,
// The transaction ID is not available with the PM, it will be added when migrated to the NPG that will support it
transactionId: undefined
}
};
// clear state if the current profile is different from the previous one
case getType(differentProfileLoggedIn):
return INITIAL_STATE;
Expand Down

0 comments on commit 56bc826

Please sign in to comment.