Update PayPal cancel handling

Co-authored-by: ayumi-signal <143036029+ayumi-signal@users.noreply.github.com>
This commit is contained in:
automated-signal
2026-02-02 18:39:16 -06:00
committed by GitHub
parent ee1a7689ce
commit 804368b598
5 changed files with 41 additions and 30 deletions

View File

@@ -10050,6 +10050,10 @@
"messageformat": "You have a donation in progress that requires confirmation.",
"description": "Shown when the user is not on the Preferences/Donations screen, and donation verification is needed. Like when resuming from startup."
},
"icu:Donations__Toast__PaypalConfirmationNeeded": {
"messageformat": "You have a donation in progress that requires confirmation.",
"description": "Shown when the user is not on the Preferences/Donations screen, and donation verification of a PayPal donation is needed. Like when resuming from startup."
},
"icu:Donations__Toast__PaypalCanceled": {
"messageformat": "PayPal donation canceled",
"description": "Shown when the user cancels a PayPal payment and they are not on the Preferences/Donations screen."

View File

@@ -134,6 +134,8 @@ function getToast(toastType: ToastType): AnyToast {
return { toastType: ToastType.DonationCompleted };
case ToastType.DonationConfirmationNeeded:
return { toastType: ToastType.DonationConfirmationNeeded };
case ToastType.DonationPaypalConfirmationNeeded:
return { toastType: ToastType.DonationPaypalConfirmationNeeded };
case ToastType.DonationError:
return { toastType: ToastType.DonationError };
case ToastType.DonationPaypalCanceled:

View File

@@ -413,6 +413,7 @@ export function renderToast({
toastType === ToastType.DonationConfirmationNeeded ||
toastType === ToastType.DonationError ||
toastType === ToastType.DonationPaypalCanceled ||
toastType === ToastType.DonationPaypalConfirmationNeeded ||
toastType === ToastType.DonationPaypalError ||
toastType === ToastType.DonationVerificationFailed ||
toastType === ToastType.DonationVerificationNeeded
@@ -428,6 +429,9 @@ export function renderToast({
[ToastType.DonationPaypalCanceled]: i18n(
'icu:Donations__Toast__PaypalCanceled'
),
[ToastType.DonationPaypalConfirmationNeeded]: i18n(
'icu:Donations__Toast__PaypalConfirmationNeeded'
),
[ToastType.DonationPaypalError]: i18n(
'icu:Donations__Toast__PaypalError'
),
@@ -439,6 +443,11 @@ export function renderToast({
),
};
const pageRedirect =
toastType === ToastType.DonationPaypalConfirmationNeeded
? SettingsPage.DonationsDonateFlow
: SettingsPage.Donations;
const text = mapping[toastType];
return (
@@ -451,7 +460,7 @@ export function renderToast({
changeLocation({
tab: NavTab.Settings,
details: {
page: SettingsPage.Donations,
page: pageRedirect,
},
});
},

View File

@@ -120,13 +120,10 @@ export async function initialize(): Promise<void> {
return;
}
if (
workflow.type === donationStateSchema.Enum.INTENT_METHOD ||
workflow.type === donationStateSchema.Enum.PAYPAL_INTENT
) {
if (workflow.type === donationStateSchema.Enum.INTENT_METHOD) {
if (shouldShowToast) {
log.info(
`initialize: Showing confirmation toast, workflow is at ${workflow.type}.`
'initialize: Showing confirmation toast, workflow is at INTENT_METHOD.'
);
window.reduxActions.toast.showToast({
toastType: ToastType.DonationConfirmationNeeded,
@@ -137,6 +134,20 @@ export async function initialize(): Promise<void> {
return;
}
if (workflow.type === donationStateSchema.Enum.PAYPAL_INTENT) {
if (shouldShowToast) {
log.info(
'initialize: Showing confirmation toast, workflow is at PAYPAL_INTENT.'
);
window.reduxActions.toast.showToast({
toastType: ToastType.DonationPaypalConfirmationNeeded,
});
}
// Note that we are not starting the workflow here
return;
}
if (shouldShowToast) {
log.info(
'initialize: We resumed at startup and donation page not visible. Showing processing toast.'
@@ -277,35 +288,18 @@ export async function approvePaypalPayment({
await _saveAndRunWorkflow(workflow);
}
export async function cancelPaypalPayment(returnToken: string): Promise<void> {
// The cancel flow happens when the user views the PayPal payment form and clicks the
// link "Return to Signal". We handle this by focusing the app donations PayPal page,
// where the user can take action to abandon the flow.
export async function cancelPaypalPayment(_returnToken: string): Promise<void> {
const logId = 'cancelPaypalPayment';
log.info(`${logId}: Canceling workflow after user visited cancel URI`);
log.info(`${logId}: User visited PayPal cancel URI, showing donate flow`);
const existing = _getWorkflowFromRedux();
if (!existing) {
throw new Error(`${logId}: Cannot finish nonexistent workflow!`);
}
if (existing.type !== donationStateSchema.Enum.PAYPAL_INTENT) {
throw new Error(`${logId}: Workflow not type PAYPAL_INTENT`);
}
// This case will happen if the user initiated 2 PayPal requests but cancels the
// older one. We interpret this case as an intention to cancel. If the user then
// approves the more recent payment, we will show an error and ask them to try again.
if (returnToken !== existing.returnToken) {
log.warn(
`${logId}: The provided token did not match saved token. Canceling anyway.`
);
}
await failDonation(donationErrorTypeSchema.Enum.PaypalCanceled);
if (isDonationsDonateFlowVisible()) {
if (!isDonationPageVisible()) {
window.reduxActions.nav.changeLocation({
tab: NavTab.Settings,
details: {
page: SettingsPage.Donations,
page: SettingsPage.DonationsDonateFlow,
},
});
}

View File

@@ -42,6 +42,7 @@ export enum ToastType {
DonationConfirmationNeeded = 'DonationConfirmationNeeded',
DonationError = 'DonationError',
DonationPaypalCanceled = 'DonationPaypalCanceled',
DonationPaypalConfirmationNeeded = 'DonationPaypalConfirmationNeeded',
DonationPaypalError = 'DonationPaypalError',
DonationProcessing = 'DonationProcessing',
DonationVerificationNeeded = 'DonationVerificationNeeded',
@@ -163,6 +164,7 @@ export type AnyToast =
| { toastType: ToastType.DonationConfirmationNeeded }
| { toastType: ToastType.DonationError }
| { toastType: ToastType.DonationPaypalCanceled }
| { toastType: ToastType.DonationPaypalConfirmationNeeded }
| { toastType: ToastType.DonationPaypalError }
| { toastType: ToastType.DonationProcessing }
| { toastType: ToastType.DonationVerificationFailed }