Merge pull request #621 from sharetribe/handle-stripe-postal-code-error

Handle stripe postal code error
This commit is contained in:
Kimmo Puputti 2018-01-08 08:59:41 +02:00 committed by GitHub
commit 2abb4d5848
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 57 additions and 15 deletions

View file

@ -65,11 +65,16 @@ class EditListingPhotosPanel extends Component {
bankAccountToken, bankAccountToken,
address: omitBy(address, isUndefined), address: omitBy(address, isUndefined),
}; };
this.props.onPayoutDetailsSubmit(params).then(() => { this.props
this.setState({ showPayoutDetails: false }); .onPayoutDetailsSubmit(params)
this.props.onManageDisableScrolling('EditListingPhotosPanel.payoutModal', false); .then(() => {
this.props.onSubmit(this.state.submittedValues); this.setState({ showPayoutDetails: false });
}); this.props.onManageDisableScrolling('EditListingPhotosPanel.payoutModal', false);
this.props.onSubmit(this.state.submittedValues);
})
.catch(() => {
// do nothing
});
} }
render() { render() {

View file

@ -15,6 +15,7 @@ import {
TextInputField, TextInputField,
} from '../../components'; } from '../../components';
import * as validators from '../../util/validators'; import * as validators from '../../util/validators';
import { isStripeInvalidPostalCode } from '../../util/errors';
import css from './PayoutDetailsForm.css'; import css from './PayoutDetailsForm.css';
@ -191,11 +192,22 @@ const PayoutDetailsFormComponent = props => {
const submitReady = false; const submitReady = false;
const submitInProgress = submitting || inProgress; const submitInProgress = submitting || inProgress;
const submitDisabled = pristine || invalid || disabled || submitInProgress; const submitDisabled = pristine || invalid || disabled || submitInProgress;
const error = createStripeAccountError ? (
<div className={css.error}> let error = null;
<FormattedMessage id="PayoutDetailsForm.createStripeAccountFailed" />
</div> if (isStripeInvalidPostalCode(createStripeAccountError)) {
) : null; error = (
<div className={css.error}>
<FormattedMessage id="PayoutDetailsForm.createStripeAccountFailedInvalidPostalCode" />
</div>
);
} else if (createStripeAccountError) {
error = (
<div className={css.error}>
<FormattedMessage id="PayoutDetailsForm.createStripeAccountFailed" />
</div>
);
}
return ( return (
<Form className={classes} onSubmit={handleSubmit}> <Form className={classes} onSubmit={handleSubmit}>

View file

@ -380,9 +380,14 @@ export const createStripeAccount = payoutDetails => (dispatch, getState, sdk) =>
.then(() => { .then(() => {
dispatch(stripeAccountCreateSuccess(accountResponse)); dispatch(stripeAccountCreateSuccess(accountResponse));
}) })
.catch(e => { .catch(err => {
dispatch(stripeAccountCreateError(storableError(e))); const e = storableError(err);
log.error(e, 'create-stripe-account-failed'); dispatch(stripeAccountCreateError(e));
const stripeMessage =
e.apiErrors && e.apiErrors.length > 0 && e.apiErrors[0].meta
? e.apiErrors[0].meta.stripe_message
: null;
log.error(err, 'create-stripe-account-failed', { stripeMessage });
throw e; throw e;
}); });
}; };

View file

@ -398,6 +398,7 @@
"PayoutDetailsForm.countryPlaceholder": "Select your country…", "PayoutDetailsForm.countryPlaceholder": "Select your country…",
"PayoutDetailsForm.countryRequired": "This field is required", "PayoutDetailsForm.countryRequired": "This field is required",
"PayoutDetailsForm.createStripeAccountFailed": "Whoops, something went wrong. Please try again.", "PayoutDetailsForm.createStripeAccountFailed": "Whoops, something went wrong. Please try again.",
"PayoutDetailsForm.createStripeAccountFailedInvalidPostalCode": "Whoops, check that the selected country and postal code are correct and try again.",
"PayoutDetailsForm.firstNameLabel": "First name", "PayoutDetailsForm.firstNameLabel": "First name",
"PayoutDetailsForm.firstNamePlaceholder": "John", "PayoutDetailsForm.firstNamePlaceholder": "John",
"PayoutDetailsForm.firstNameRequired": "This field is required", "PayoutDetailsForm.firstNameRequired": "This field is required",

View file

@ -157,6 +157,21 @@ export const isChangeEmailWrongPassword = error => error && error.status === 403
*/ */
export const isChangePasswordWrongPassword = error => error && error.status === 403; export const isChangePasswordWrongPassword = error => error && error.status === 403;
/**
* Check if the given API error (from
* 'sdk.currentUser.createStripeAccount(payoutDetails)') is due to
* invalid postal code in the given country.
*/
export const isStripeInvalidPostalCode = error => {
const msgRe = /^Invalid [A-Z]{2} postal code$/;
return errorAPIErrors(error).some(apiError => {
// Stripe doesn't seem to give an error code for this specific
// case, so we have to recognize it from the message.
const msg = apiError.meta && apiError.meta.stripe_message ? apiError.meta.stripe_message : '';
return msgRe.test(msg);
});
};
export const storableError = error => { export const storableError = error => {
const { name, message, status, statusText } = error; const { name, message, status, statusText } = error;
// Status, statusText, and data.errors are (possibly) added to the error object by SDK // Status, statusText, and data.errors are (possibly) added to the error object by SDK

View file

@ -56,5 +56,6 @@ export const error = (e, code, data) => {
Raven.captureException(e, { tags: { code }, extra: data }); Raven.captureException(e, { tags: { code }, extra: data });
} else { } else {
console.error(e); // eslint-disable-line console.error(e); // eslint-disable-line
console.error('Error code:', code, 'data:', data);
} }
}; };

View file

@ -373,6 +373,7 @@ export const ERROR_CODE_EMAIL_NOT_FOUND = 'email-not-found';
export const ERROR_CODE_EMAIL_NOT_VERIFIED = 'email-unverified'; export const ERROR_CODE_EMAIL_NOT_VERIFIED = 'email-unverified';
export const ERROR_CODE_TOO_MANY_VERIFICATION_REQUESTS = 'email-too-many-verification-requests'; export const ERROR_CODE_TOO_MANY_VERIFICATION_REQUESTS = 'email-too-many-verification-requests';
export const ERROR_CODE_UPLOAD_OVER_LIMIT = 'request-upload-over-limit'; export const ERROR_CODE_UPLOAD_OVER_LIMIT = 'request-upload-over-limit';
export const ERROR_CODE_VALIDATION_INVALID_PARAMS = 'validation-invalid-params';
const ERROR_CODES = [ const ERROR_CODES = [
ERROR_CODE_TRANSACTION_LISTING_NOT_FOUND, ERROR_CODE_TRANSACTION_LISTING_NOT_FOUND,
ERROR_CODE_TRANSACTION_INVALID_TRANSITION, ERROR_CODE_TRANSACTION_INVALID_TRANSITION,
@ -384,6 +385,7 @@ const ERROR_CODES = [
ERROR_CODE_EMAIL_NOT_VERIFIED, ERROR_CODE_EMAIL_NOT_VERIFIED,
ERROR_CODE_TOO_MANY_VERIFICATION_REQUESTS, ERROR_CODE_TOO_MANY_VERIFICATION_REQUESTS,
ERROR_CODE_UPLOAD_OVER_LIMIT, ERROR_CODE_UPLOAD_OVER_LIMIT,
ERROR_CODE_VALIDATION_INVALID_PARAMS,
]; ];
// API error // API error
@ -393,6 +395,7 @@ export const apiError = shape({
status: number.isRequired, status: number.isRequired,
code: oneOf(ERROR_CODES).isRequired, code: oneOf(ERROR_CODES).isRequired,
title: string.isRequired, title: string.isRequired,
meta: object,
}); });
// Storable error prop type. (Error object should not be stored as it is.) // Storable error prop type. (Error object should not be stored as it is.)

View file

@ -7214,9 +7214,9 @@ sharetribe-scripts@1.0.14:
optionalDependencies: optionalDependencies:
fsevents "1.1.2" fsevents "1.1.2"
"sharetribe-sdk@git+ssh://git@github.com/sharetribe/sharetribe-sdk-js#ff76ef91e1e3b1e26b035a04d643d328ea3d1d61": "sharetribe-sdk@git+ssh://git@github.com/sharetribe/sharetribe-sdk-js#267efc4ca52dd1ad54db6bf3c37ab8ebcd8a86ab":
version "0.0.1" version "0.0.1"
resolved "git+ssh://git@github.com/sharetribe/sharetribe-sdk-js#ff76ef91e1e3b1e26b035a04d643d328ea3d1d61" resolved "git+ssh://git@github.com/sharetribe/sharetribe-sdk-js#267efc4ca52dd1ad54db6bf3c37ab8ebcd8a86ab"
dependencies: dependencies:
axios "^0.15.3" axios "^0.15.3"
js-cookie "^2.1.3" js-cookie "^2.1.3"