Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: [IOBP-514] Move authorization creation request upon payment method selection #5419

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
b9579f1
chore: io-ts extensions
mastro993 Jan 18, 2024
ada7a09
chore: `UIWalletInfoDetails`
mastro993 Jan 18, 2024
8c15ed8
refactor: use `UIWalletDetails` type for presentation
mastro993 Jan 18, 2024
68d45e3
fix: argument
mastro993 Jan 18, 2024
fd785b4
chore: update API definitions
mastro993 Jan 19, 2024
9a86f25
chore: `UIWalletInfoDetails`
mastro993 Jan 19, 2024
a9d8794
chore: type update
mastro993 Jan 19, 2024
e519419
chore: update API definitions
mastro993 Jan 19, 2024
ee5e71d
Merge branch 'master' into IOBP-510-new-wallet-payment-details-refact…
mastro993 Jan 19, 2024
e441b81
chore: changed the commit to the corrected swagger
Hantex9 Jan 19, 2024
655cf23
Merge branch 'master' into IOBP-510-new-wallet-payment-details-refact…
Hantex9 Jan 22, 2024
8e28abf
chore: move transaction create upon method selection
mastro993 Jan 22, 2024
f613abb
fix: authorizatio request payload
mastro993 Jan 22, 2024
6330875
Merge branch 'IOBP-510-new-wallet-payment-details-refactoring' into I…
mastro993 Jan 22, 2024
38189ba
chore: add required data in calculate fees request
mastro993 Jan 22, 2024
7f6ab92
chore: remove buttons if no method/psp selected
mastro993 Jan 22, 2024
a067827
fix: tests
mastro993 Jan 22, 2024
a90227d
Merge branch 'master' into IOBP-514-effettuare-chiamata-di-new-transa…
mastro993 Jan 22, 2024
07b2479
fix: buttons
mastro993 Jan 22, 2024
9f57968
Merge branch 'master' into IOBP-514-effettuare-chiamata-di-new-transa…
mastro993 Jan 23, 2024
ff9bba3
Merge branch 'master' into IOBP-514-effettuare-chiamata-di-new-transa…
mastro993 Jan 23, 2024
5d86613
Merge branch 'master' into IOBP-514-effettuare-chiamata-di-new-transa…
Hantex9 Jan 23, 2024
7ad44b9
chore: handle errors in method and psp screens
mastro993 Jan 24, 2024
22ef76b
fix: payment method id
mastro993 Jan 24, 2024
96e1639
chore: updated ecommerce api definitions
Hantex9 Jan 24, 2024
e8778e7
fix: tests
mastro993 Jan 24, 2024
442e5aa
Merge branch 'master' into IOBP-514-effettuare-chiamata-di-new-transa…
mastro993 Jan 24, 2024
ffecef2
Merge branch 'master' into IOBP-514-effettuare-chiamata-di-new-transa…
Hantex9 Jan 25, 2024
d9b34fb
Merge branch 'master' into IOBP-514-effettuare-chiamata-di-new-transa…
forrest57 Jan 25, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"lollipop_api": "https://raw.githubusercontent.com/pagopa/io-backend/v13.25.1-RELEASE/api_lollipop_first_consumer.yaml",
"fast_login_api": "https://raw.githubusercontent.com/pagopa/io-backend/v13.25.1-RELEASE/openapi/generated/api_fast_login.yaml",
"pagopa_api_walletv3": "https://raw.githubusercontent.com/pagopa/pagopa-infra/740e7dcc5ea2ea19639316fea6797bbd504dd0ae/src/domains/wallet-app/api/payment-wallet/v1/_openapi.json.tpl",
"pagopa_api_ecommerce": "https://raw.githubusercontent.com/pagopa/pagopa-infra/5190135ac34791cf66c1986735d4134bcaf4096f/src/domains/ecommerce-app/api/ecommerce-io/v1/_openapi.json.tpl",
"pagopa_api_ecommerce": "https://raw.githubusercontent.com/pagopa/pagopa-infra/a5299db39de86a951d353fdc2bfed48188c0c125/src/domains/ecommerce-app/api/ecommerce-io/v1/_openapi.json.tpl",
"private": true,
"scripts": {
"start": "react-native start",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@ import { PaymentMethodStatusEnum } from "../../../../../../../definitions/pagopa
import { getGenericError } from "../../../../../../utils/errors";
import { readablePrivacyReport } from "../../../../../../utils/reporters";
import { withRefreshApiCall } from "../../../../../fastLogin/saga/utils";
import {
WalletPaymentCalculateFeesPayload,
walletPaymentCalculateFees
} from "../../../store/actions/networking";
import { walletPaymentCalculateFees } from "../../../store/actions/networking";
import { handleWalletPaymentCalculateFees } from "../handleWalletPaymentCalculateFees";
import { CalculateFeeRequest } from "../../../../../../../definitions/pagopa/ecommerce/CalculateFeeRequest";

describe("Test handleWalletPaymentCalculateFees saga", () => {
const calculateFeesPayload: WalletPaymentCalculateFeesPayload = {
walletId: "1234",
paymentAmountInCents: 1234
const calculateFeesPayload: CalculateFeeRequest & {
paymentMethodId: string;
} = {
paymentMethodId: "1234",
paymentAmount: 1234
};

it(`should put ${getType(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import * as O from "fp-ts/lib/Option";

import { call, put, select } from "typed-redux-saga/macro";
import { ActionType } from "typesafe-actions";
import { CalculateFeeRequest } from "../../../../../../definitions/pagopa/ecommerce/CalculateFeeRequest";
import { SagaCallReturnType } from "../../../../../types/utils";
import { getGenericError, getNetworkError } from "../../../../../utils/errors";
import { readablePrivacyReport } from "../../../../../utils/reporters";
Expand All @@ -19,14 +18,10 @@ export function* handleWalletPaymentCalculateFees(
calculateFees: PaymentClient["calculateFees"],
action: ActionType<(typeof walletPaymentCalculateFees)["request"]>
) {
const requestBody: CalculateFeeRequest = {
paymentAmount: action.payload.paymentAmountInCents,
walletId: action.payload.walletId
};

const { paymentMethodId, ...body } = action.payload;
const calculateFeesRequest = calculateFees({
id: action.payload.walletId,
body: requestBody
id: paymentMethodId,
body
});

try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export function* handleWalletPaymentCreateTransaction(
}),
({ status, value }) => {
if (status === 200) {
action.payload.onSucces?.();
return walletPaymentCreateTransaction.success(value);
} else if (status === 400) {
return walletPaymentCreateTransaction.failure({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
VSpacer
} from "@pagopa/io-app-design-system";
import * as pot from "@pagopa/ts-commons/lib/pot";
import { useFocusEffect, useNavigation } from "@react-navigation/native";
import { useNavigation } from "@react-navigation/native";
import { sequenceS } from "fp-ts/lib/Apply";
import * as O from "fp-ts/lib/Option";
import { pipe } from "fp-ts/lib/function";
Expand All @@ -18,22 +18,20 @@ import {
AppParamsList,
IOStackNavigationProp
} from "../../../../navigation/params/AppParamsList";
import { useIODispatch, useIOSelector } from "../../../../store/hooks";
import { useIOSelector } from "../../../../store/hooks";
import { emptyContextualHelp } from "../../../../utils/emptyContextualHelp";
import { WalletPaymentConfirmContent } from "../components/WalletPaymentConfirmContent";
import { useWalletPaymentAuthorizationModal } from "../hooks/useWalletPaymentAuthorizationModal";
import { WalletPaymentRoutes } from "../navigation/routes";
import { walletPaymentCreateTransaction } from "../store/actions/networking";
import {
walletPaymentDetailsSelector,
walletPaymentPickedPaymentMethodSelector,
walletPaymentPickedPspSelector,
walletPaymentTransactionSelector
} from "../store/selectors";
import { WalletPaymentOutcome } from "../types/PaymentOutcomeEnum";
import { useWalletPaymentAuthorizationModal } from "../hooks/useWalletPaymentAuthorizationModal";

const WalletPaymentConfirmScreen = () => {
const dispatch = useIODispatch();
const navigation = useNavigation<IOStackNavigationProp<AppParamsList>>();

const paymentDetailsPot = useIOSelector(walletPaymentDetailsSelector);
Expand All @@ -43,22 +41,13 @@ const WalletPaymentConfirmScreen = () => {
);
const selectedPspOption = useIOSelector(walletPaymentPickedPspSelector);

const isTransactionLoading = pot.isLoading(transactionPot);
const isTransactionError = pot.isError(transactionPot);

useHeaderSecondLevel({
title: "",
contextualHelp: emptyContextualHelp,
faqCategories: ["payment"],
supportRequest: true
});

useFocusEffect(
React.useCallback(() => {
dispatch(walletPaymentCreateTransaction.request({ paymentNotices: [] }));
}, [dispatch])
);

const handleStartPaymentAuthorization = () =>
pipe(
sequenceS(O.Monad)({
Expand Down Expand Up @@ -96,9 +85,8 @@ const WalletPaymentConfirmScreen = () => {
onAuthorizationOutcome: handleAuthorizationOutcome
});

const isLoading =
isTransactionLoading || isAuthUrlLoading || isPendingAuthorization;
const isError = isTransactionError || isAuthUrlError;
const isLoading = isAuthUrlLoading || isPendingAuthorization;
const isError = isAuthUrlError;

if (isError) {
// TODO: Failure handling (https://pagopa.atlassian.net/browse/IOBP-471)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
} from "@pagopa/io-app-design-system";
import * as pot from "@pagopa/ts-commons/lib/pot";
import { useFocusEffect, useNavigation } from "@react-navigation/native";
import { sequenceS } from "fp-ts/lib/Apply";
import { sequenceS, sequenceT } from "fp-ts/lib/Apply";
import * as A from "fp-ts/lib/Array";
import * as O from "fp-ts/lib/Option";
import { pipe } from "fp-ts/lib/function";
Expand All @@ -30,19 +30,24 @@ import { useIODispatch, useIOSelector } from "../../../../store/hooks";
import { ComponentProps } from "../../../../types/react";
import { emptyContextualHelp } from "../../../../utils/emptyContextualHelp";
import { findFirstCaseInsensitive } from "../../../../utils/object";
import { UIWalletInfoDetails } from "../../details/types/UIWalletInfoDetails";
import { WalletPaymentMissingMethodsError } from "../components/WalletPaymentMissingMethodsError";
import { useWalletPaymentGoBackHandler } from "../hooks/useWalletPaymentGoBackHandler";
import { WalletPaymentRoutes } from "../navigation/routes";
import { walletPaymentGetUserWallets } from "../store/actions/networking";
import {
walletPaymentCreateTransaction,
walletPaymentGetUserWallets
} from "../store/actions/networking";
import { walletPaymentPickPaymentMethod } from "../store/actions/orchestration";
import {
walletPaymentAllMethodsSelector,
walletPaymentAmountSelector,
walletPaymentDetailsSelector,
walletPaymentSavedMethodByIdSelector,
walletPaymentTransactionSelector,
walletPaymentUserWalletsSelector
} from "../store/selectors";
import { WalletPaymentMissingMethodsError } from "../components/WalletPaymentMissingMethodsError";
import { useWalletPaymentGoBackHandler } from "../hooks/useWalletPaymentGoBackHandler";
import { UIWalletInfoDetails } from "../../details/types/UIWalletInfoDetails";
import { WalletPaymentOutcomeEnum } from "../types/PaymentOutcomeEnum";

type SavedMethodState = {
kind: "saved";
Expand Down Expand Up @@ -72,6 +77,7 @@ const WalletPaymentPickMethodScreen = () => {
supportRequest: true
});

const paymentDetailsPot = useIOSelector(walletPaymentDetailsSelector);
const transactionPot = useIOSelector(walletPaymentTransactionSelector);
const getSavedtMethodById = useIOSelector(
walletPaymentSavedMethodByIdSelector
Expand All @@ -84,29 +90,37 @@ const WalletPaymentPickMethodScreen = () => {
const alertRef = React.useRef<View>(null);

const isLoading =
pot.isLoading(paymentMethodsPot) ||
pot.isLoading(userWalletsPots) ||
pot.isLoading(transactionPot);
pot.isLoading(paymentMethodsPot) || pot.isLoading(userWalletsPots);
const isLoadingTransaction = pot.isLoading(transactionPot);

const isError =
pot.isError(transactionPot) ||
pot.isError(paymentMethodsPot) ||
pot.isError(userWalletsPots);

const [shouldShowWarningBanner, setShouldShowWarningBanner] =
React.useState<boolean>(false);
const [selectedMethod, setSelectedMethod] =
React.useState<SelectedMethodState>(undefined);

useHeaderSecondLevel({
title: "",
contextualHelp: emptyContextualHelp,
faqCategories: ["payment"],
supportRequest: true
});

useFocusEffect(
React.useCallback(() => {
// dispatch(walletPaymentGetAllMethods.request()); // currently we do not allow onboarding new methods in payment flow
dispatch(walletPaymentGetUserWallets.request());
}, [dispatch])
);

React.useEffect(() => {
if (isError) {
navigation.navigate(WalletPaymentRoutes.WALLET_PAYMENT_MAIN, {
screen: WalletPaymentRoutes.WALLET_PAYMENT_OUTCOME,
params: {
outcome: WalletPaymentOutcomeEnum.GENERIC_ERROR
}
});
}
}, [isError, navigation]);

const paymentAmount = pot.getOrElse(paymentAmountPot, undefined);
const canContinue = selectedMethod !== undefined;

Expand Down Expand Up @@ -152,19 +166,32 @@ const WalletPaymentPickMethodScreen = () => {
};
*/

const navigateToPspSelectionScreen = () => {
navigation.navigate(WalletPaymentRoutes.WALLET_PAYMENT_MAIN, {
screen: WalletPaymentRoutes.WALLET_PAYMENT_PICK_PSP
});
};

const handleContinue = () => {
// todo:: should handle the case where the user
// selects a non saved method
if (selectedMethod?.kind === "saved") {
pipe(
getSavedtMethodById(selectedMethod.walletId),
O.map(walletPaymentPickPaymentMethod),
O.map(dispatch),
O.map(() =>
navigation.navigate(WalletPaymentRoutes.WALLET_PAYMENT_MAIN, {
screen: WalletPaymentRoutes.WALLET_PAYMENT_PICK_PSP
})
)
sequenceT(O.Monad)(
getSavedtMethodById(selectedMethod.walletId),
pot.toOption(paymentDetailsPot)
),
O.map(([method, paymentDetails]) => {
dispatch(walletPaymentPickPaymentMethod(method));
dispatch(
walletPaymentCreateTransaction.request({
paymentNotices: [
{ rptId: paymentDetails.rptId, amount: paymentDetails.amount }
],
onSucces: navigateToPspSelectionScreen
})
);
})
);
}
};
Expand All @@ -185,13 +212,17 @@ const WalletPaymentPickMethodScreen = () => {

return (
<GradientScrollView
primaryActionProps={{
label: I18n.t("global.buttons.continue"),
accessibilityLabel: I18n.t("global.buttons.continue"),
onPress: handleContinue,
disabled: isLoading || !canContinue,
loading: isLoading
}}
primaryActionProps={
canContinue
? {
label: I18n.t("global.buttons.continue"),
accessibilityLabel: I18n.t("global.buttons.continue"),
onPress: handleContinue,
disabled: isLoading || isLoadingTransaction,
loading: isLoading || isLoadingTransaction
}
: undefined
}
>
<H2>{I18n.t("wallet.payment.methodSelection.header")}</H2>
<VSpacer size={16} />
Expand Down
Loading
Loading