Skip to content

Commit

Permalink
feat: [IOBP-437] Add new wallet payment outcome error handling (#5390)
Browse files Browse the repository at this point in the history
⚠️ Depends on #5378

## Short description
This PR adds the handling of the payment error outcomes.

## List of changes proposed in this pull request
- Added components mapping based on the outcome in
`WalletPaymentOutcomeScreen`
- Added required locales keys
- Refactored `usePaymentFailureSupportModal` to remove the requirement
of passing `RptId` as its argument.

## How to test
Within the **Profile > New Wallet > Payment** playground, using the
`io-dev-api-server`, try to simulate different payment outcomes and
check that the screen and its components are displayed correctly.

## Preview


https://github.com/pagopa/io-app/assets/6160324/cb7c33f1-9c0d-471c-accf-a362efc42264

---------

Co-authored-by: Alessandro Izzo <[email protected]>
Co-authored-by: Mario Perrotta <[email protected]>
  • Loading branch information
3 people authored Jan 12, 2024
1 parent d6d2dc0 commit dff6e61
Show file tree
Hide file tree
Showing 11 changed files with 276 additions and 96 deletions.
8 changes: 4 additions & 4 deletions locales/de/index.yml
Original file line number Diff line number Diff line change
Expand Up @@ -720,7 +720,7 @@ email:
subtitle: "Um die App weiter nutzen zu können, musst du deine E-Mail-Adresse bestätigen"
editButton: "E-Mail-Adresse ändern"
validateButton: "E-Mail-Adresse bestätigen"
header:
header:
title: "IO konfigurieren"
help:
body: "Um die App weiter nutzen zu können, musst du deine E-Mail-Adresse bestätigen"
Expand All @@ -729,7 +729,7 @@ email:
subtitleStart: "Deine E-Mail-Adresse"
subtitleEnd: "wird bereits auf IO verwendet; du musst eine andere eingeben, um die App weiter benutzen zu können."
editButton: "E-Mail-Adresse ändern"
header:
header:
title: "IO konfigurieren"
help:
body: "Deine E-Mail-Adresse wird bereits auf IO verwendet; du musst eine andere eingeben, um die App weiter benutzen zu können."
Expand Down Expand Up @@ -936,7 +936,7 @@ payment:
description: "IO hat keine Zahlungsversuche gespeichert. Hier findest du deine letzten Zahlungsversuche"
title: "Zahlungsversuche"
iuv: "Einheitlicher Zahlungskodex (IUV) {{iuv}}"
confirm:
confirm:
totalAmount: "Zu zahlender Gesamtbetrag"
pay: "Zahle "
payWith: "Zahle mit "
Expand Down Expand Up @@ -1617,7 +1617,7 @@ wallet:
amount: "Nach Betrag"
name: "Nach Name"
outcome:
success:
SUCCESS:
title: "Du hast {{amount}} bezahlt"
button: "OK, schließen"
banner:
Expand Down
46 changes: 35 additions & 11 deletions locales/en/index.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1711,6 +1711,41 @@ wallet:
PAA_PAGAMENTO_SCONOSCIUTO:
title: "Non riusciamo a trovare l’avviso"
subtitle: "L’avviso potrebbe essere stato già pagato. Per ricevere assistenza, contatta l’Ente Creditore che lo ha emesso."
outcome:
SUCCESS:
title: Hai pagato {{amount}}
button: Ok, chiudi
banner:
title: Puoi dirci com’è andata?
content: Raccontaci la tua esperienza con il pagamento e aiutaci a migliorare.
action: Vai al sondaggio
GENERIC_ERROR:
title: Si è verificato un errore imprevisto
subtitle: Non è stato addebitato alcun importo.
AUTH_ERROR:
title: Autorizzazione negata
subtitle: "Non è stato addebitato alcun importo.\nControlla di aver seguito correttamente le istruzioni della tua banca."
INVALID_DATA:
title: I dati del metodo di pagamento non sono corretti
subtitle: Se hai pagato con una carta di debito o credito, assicurati di inserire i dati come riportato sul fronte.
TIMEOUT:
title: La sessione è scaduta
subtitle: Non è stato addebitato alcun importo.\nPer la tua sicurezza, hai a disposizione un tempo limitato per completare l’operazione.
CIRCUIT_ERROR:
title: Il circuito della carta non è supportato
MISSING_FIELDS:
title: Mancano alcuni dati per procedere con il pagamento
INVALID_CARD:
title: Il metodo di pagamento è scaduto o non più valido
subtitle: Per maggiori informazioni, contatta la tua banca.
CANCELED_BY_USER:
title: L’operazione è stata annullata
subtitle: Non è stato addebitato alcun importo.
EXCESSIVE_AMOUNT:
title: Autorizzazione negata
subtitle: Non è stato addebitato alcun importo.\nProbabilmente hai sforato i limiti di spesa previsti dalla tua banca.
INVALID_METHOD:
title: Il metodo di pagamento non è supportato
support:
button: "Contatta l'assistenza"
supportTitle: Contatta l'assistenza
Expand All @@ -1721,17 +1756,6 @@ wallet:
errorCode: Codice errore
noticeNumber: Codice avviso
entityCode: Codice Fiscale Ente
outcome:
cancelled:
title: L’operazione è stata annullata
subtitle: Non è stato addebitato alcun importo.
success:
title: Hai pagato {{amount}}
button: Ok, chiudi
banner:
title: Puoi dirci com’è andata?
content: Raccontaci la tua esperienza con il pagamento e aiutaci a migliorare.
action: Vai al sondaggio
saveCard:
saveCard: Save the card
header: Do you want to save this card?
Expand Down
46 changes: 35 additions & 11 deletions locales/it/index.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1711,6 +1711,41 @@ wallet:
PAA_PAGAMENTO_SCONOSCIUTO:
title: "Non riusciamo a trovare l’avviso"
subtitle: "L’avviso potrebbe essere stato già pagato. Per ricevere assistenza, contatta l’Ente Creditore che lo ha emesso."
outcome:
SUCCESS:
title: Hai pagato {{amount}}
button: Ok, chiudi
banner:
title: Puoi dirci com’è andata?
content: Raccontaci la tua esperienza con il pagamento e aiutaci a migliorare.
action: Vai al sondaggio
GENERIC_ERROR:
title: Si è verificato un errore imprevisto
subtitle: Non è stato addebitato alcun importo.
AUTH_ERROR:
title: Autorizzazione negata
subtitle: "Non è stato addebitato alcun importo.\nControlla di aver seguito correttamente le istruzioni della tua banca."
INVALID_DATA:
title: I dati del metodo di pagamento non sono corretti
subtitle: Se hai pagato con una carta di debito o credito, assicurati di inserire i dati come riportato sul fronte.
TIMEOUT:
title: La sessione è scaduta
subtitle: Non è stato addebitato alcun importo.\nPer la tua sicurezza, hai a disposizione un tempo limitato per completare l’operazione.
CIRCUIT_ERROR:
title: Il circuito della carta non è supportato
MISSING_FIELDS:
title: Mancano alcuni dati per procedere con il pagamento
INVALID_CARD:
title: Il metodo di pagamento è scaduto o non più valido
subtitle: Per maggiori informazioni, contatta la tua banca.
CANCELED_BY_USER:
title: L’operazione è stata annullata
subtitle: Non è stato addebitato alcun importo.
EXCESSIVE_AMOUNT:
title: Autorizzazione negata
subtitle: Non è stato addebitato alcun importo.\nProbabilmente hai sforato i limiti di spesa previsti dalla tua banca.
INVALID_METHOD:
title: Il metodo di pagamento non è supportato
support:
button: "Contatta l'assistenza"
supportTitle: Contatta l'assistenza
Expand All @@ -1721,17 +1756,6 @@ wallet:
errorCode: Codice errore
noticeNumber: Codice avviso
entityCode: Codice Fiscale Ente
outcome:
cancelled:
title: L’operazione è stata annullata
subtitle: Non è stato addebitato alcun importo.
success:
title: Hai pagato {{amount}}
button: Ok, chiudi
banner:
title: Puoi dirci com’è andata?
content: Raccontaci la tua esperienza con il pagamento e aiutaci a migliorare.
action: Vai al sondaggio
saveCard:
saveCard: Salva la carta
header: Vuoi salvare questa carta?
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { useNavigation } from "@react-navigation/native";
import React from "react";
import { FaultCategoryEnum } from "../../../../../definitions/pagopa/ecommerce/FaultCategory";
import { RptId } from "../../../../../definitions/pagopa/ecommerce/RptId";
import { ValidationFaultEnum } from "../../../../../definitions/pagopa/ecommerce/ValidationFault";
import {
OperationResultScreenContent,
Expand All @@ -16,13 +15,12 @@ import { usePaymentFailureSupportModal } from "../hooks/usePaymentFailureSupport
import { WalletPaymentFailure } from "../types/failure";

type Props = {
rptId?: RptId;
failure: WalletPaymentFailure;
};

const WalletPaymentFailureDetail = ({ rptId, failure }: Props) => {
const WalletPaymentFailureDetail = ({ failure }: Props) => {
const navigation = useNavigation<IOStackNavigationProp<AppParamsList>>();
const supportModal = usePaymentFailureSupportModal({ rptId, failure });
const supportModal = usePaymentFailureSupportModal({ failure });

const handleClose = () => {
navigation.pop();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { Banner, VSpacer } from "@pagopa/io-app-design-system";
import { openAuthenticationSession } from "@pagopa/io-react-native-login-utils";
import { default as React } from "react";
import { View } from "react-native";
import I18n from "../../../../i18n";
import { mixpanelTrack } from "../../../../mixpanel";
import { WALLET_PAYMENT_FEEDBACK_URL } from "../utils";

const WalletPaymentFeebackBanner = () => {
const bannerViewRef = React.useRef<View>(null);

const handleBannerPress = () => {
void mixpanelTrack("VOC_USER_EXIT", {
screen_name: "PAYMENT_OUTCOMECODE_MESSAGE"
});

return openAuthenticationSession(WALLET_PAYMENT_FEEDBACK_URL, "");
};

return (
<>
<VSpacer size={24} />
<Banner
color="neutral"
pictogramName="feedback"
size="big"
viewRef={bannerViewRef}
title={I18n.t("wallet.outcomeMessage.payment.success.banner.title")}
content={I18n.t("wallet.outcomeMessage.payment.success.banner.content")}
action={I18n.t("wallet.outcomeMessage.payment.success.banner.action")}
onPress={handleBannerPress}
/>
</>
);
};

export { WalletPaymentFeebackBanner };
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import { pipe } from "fp-ts/lib/function";
import React from "react";
import { Linking } from "react-native";
import { ToolEnum } from "../../../../../definitions/content/AssistanceToolConfig";
import { RptId } from "../../../../../definitions/pagopa/ecommerce/RptId";
import I18n from "../../../../i18n";
import { useIODispatch, useIOSelector } from "../../../../store/hooks";
import { assistanceToolConfigSelector } from "../../../../store/reducers/backendStatus";
Expand All @@ -35,12 +34,17 @@ import {
zendeskSelectedCategory,
zendeskSupportStart
} from "../../../zendesk/store/actions";
import { walletPaymentRptIdSelector } from "../store/selectors";
import {
WalletPaymentOutcome,
getWalletPaymentOutcomeEnumByValue
} from "../types/PaymentOutcomeEnum";
import { WalletPaymentFailure } from "../types/failure";

type PaymentFailureSupportModalParams = {
rptId?: RptId;
failure: WalletPaymentFailure;
withPhoneSupport?: boolean;
failure?: WalletPaymentFailure;
outcome?: WalletPaymentOutcome;
withPhoneAssistance?: boolean;
};

type PaymentFailureSupportModal = {
Expand All @@ -49,16 +53,20 @@ type PaymentFailureSupportModal = {
};

const usePaymentFailureSupportModal = ({
rptId,
failure,
withPhoneSupport = false
outcome,
withPhoneAssistance = false
}: PaymentFailureSupportModalParams): PaymentFailureSupportModal => {
const { faultCodeDetail } = failure;

const assistanceToolConfig = useIOSelector(assistanceToolConfigSelector);
const choosenTool = assistanceToolRemoteConfig(assistanceToolConfig);
const rptId = useIOSelector(walletPaymentRptIdSelector);
const dispatch = useIODispatch();

const faultCodeDetail =
failure?.faultCodeDetail ||
(outcome && getWalletPaymentOutcomeEnumByValue(outcome)) ||
"";

const zendeskAssistanceLogAndStart = () => {
resetCustomFields();
addTicketCustomField(zendeskCategoryId, zendeskPaymentCategory.value);
Expand Down Expand Up @@ -126,7 +134,7 @@ const usePaymentFailureSupportModal = ({
component: (
<>
<ListItemHeader label={I18n.t("wallet.payment.support.supportTitle")} />
{withPhoneSupport && (
{withPhoneAssistance && (
<ListItemAction
label={I18n.t("wallet.payment.support.phone", {
phoneNumber: displayPhoneNumber
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ const WalletPaymentDetailScreen = () => {
faultCodeDetail: GatewayFaultEnum.GENERIC_ERROR
}))
);
return <WalletPaymentFailureDetail rptId={rptId} failure={failure} />;
return <WalletPaymentFailureDetail failure={failure} />;
}

if (pot.isSome(paymentDetailsPot)) {
Expand Down
Loading

0 comments on commit dff6e61

Please sign in to comment.