Merge pull request #461 from sharetribe/add-info-about-too-low-tx-amount

Show specific error text when tx amount is too low
This commit is contained in:
Kimmo Puputti 2017-10-04 15:05:06 +03:00 committed by GitHub
commit 5da52521e1
4 changed files with 45 additions and 5 deletions

View file

@ -9,7 +9,10 @@ import * as propTypes from '../../util/propTypes';
import { ensureListing, ensureUser, ensureTransaction, ensureBooking } from '../../util/data';
import { withFlattenedRoutes } from '../../util/contextHelpers';
import { createSlug } from '../../util/urlHelpers';
import { isTransactionInitiateListingNotFoundError } from '../../util/errors';
import {
isTransactionInitiateAmountTooLowError,
isTransactionInitiateListingNotFoundError,
} from '../../util/errors';
import {
AvatarMedium,
BookingBreakdown,
@ -212,11 +215,24 @@ export class CheckoutPageComponent extends Component {
<FormattedMessage id="CheckoutPage.errorlistingLinkText" />
</NamedLink>
);
const initiateOrderErrorMessage = !listingNotFound && initiateOrderError
? <p className={css.orderError}>
const isAmountTooLowError = isTransactionInitiateAmountTooLowError(initiateOrderError);
let initiateOrderErrorMessage = null;
if (!listingNotFound && isAmountTooLowError) {
initiateOrderErrorMessage = (
<p className={css.orderError}>
<FormattedMessage id="CheckoutPage.initiateOrderAmountTooLow" />
</p>
);
} else if (!listingNotFound && initiateOrderError) {
initiateOrderErrorMessage = (
<p className={css.orderError}>
<FormattedMessage id="CheckoutPage.initiateOrderError" values={{ listingLink }} />
</p>
: null;
);
}
const speculateTransactionErrorMessage = speculateTransactionError
? <p className={css.speculateError}>
<FormattedMessage id="CheckoutPage.speculateTransactionError" />

View file

@ -74,7 +74,7 @@ export const storedData = storageKey => {
// Dates are expected to be in format: { date: new Date(), _serializedType: 'SerializableDate' }
const reviver = (k, v) => {
// eslint-disable-next-line no-underscore-dangle
if (typeof v === 'object' && v._serializedType === 'SerializableDate') {
if (v && typeof v === 'object' && v._serializedType === 'SerializableDate') {
return new Date(v.date);
}
return types.reviver(k, v);

View file

@ -40,6 +40,7 @@
"CheckoutPage.errorlistingLinkText": "the sauna page",
"CheckoutPage.goToLandingPage": "Go to homepage",
"CheckoutPage.hostedBy": "Hosted by {name}",
"CheckoutPage.initiateOrderAmountTooLow": "Unfortunately we're not able to process this payment, since the payment amount is too low. Please contact the administrators.",
"CheckoutPage.initiateOrderError": "Payment request failed. Please go back to {listingLink} and try again. If the error persists, try refreshing the page or contacting the marketplace admin.",
"CheckoutPage.listingNotFoundError": "Unfortunately the listing is not available anymore.",
"CheckoutPage.loadingData": "Loading checkout data...",

View file

@ -10,6 +10,7 @@
*/
const ERROR_CODE_TRANSITION_PARAMETER_VALIDATION_FAILED = 'transition-parameter-validation-failed';
const ERROR_CODE_PAYMENT_FAILED = 'payment-failed';
const ERROR_CODE_EMAIL_TAKEN = 'email-taken';
const ERROR_CODE_TOO_MANY_VERIFICATION_REQUESTS = 'too-many-verification-requests';
const ERROR_CODE_UPLOAD_OVER_LIMIT = 'upload-over-limit';
@ -96,6 +97,28 @@ export const isTransactionInitiateListingNotFoundError = apiError => {
});
};
/**
* Check if the given API error (from `sdk.transaction.initiate()`) is
* due to the transaction total amount being too low for Stripe.
*/
export const isTransactionInitiateAmountTooLowError = apiError => {
return responseErrors(apiError).some(error => {
const isPaymentFailedError = error.status === 402 && error.code === ERROR_CODE_PAYMENT_FAILED;
let isAmountTooLow = false;
try {
// TODO: This is a temporary solution until a proper error code
// for this specific error is received in the response.
const msg = error.details.msg;
isAmountTooLow = msg.startsWith('Amount must be at least');
} catch (e) {
// Ignore
}
return isPaymentFailedError && isAmountTooLow;
});
};
/**
* Check if the given API error (from `sdk.currentUser.changeEmail(params)`)
* is due to giving wrong password.