Add Stripe support for Canada

This commit is contained in:
Jenni Nurmi 2018-12-05 13:59:17 +02:00
parent fe1082e5e5
commit 45e00d2241
6 changed files with 136 additions and 3 deletions

View file

@ -104,3 +104,20 @@ export const AU_AUD = {
},
group: 'custom inputs',
};
// CA
export const CA_CAD = {
component: formComponent('CA'),
props: {
formName: 'CA_CAD',
onChange: formState => {
if (formState.dirty) {
console.log('form values changed to:', formState.values);
}
},
onSubmit: values => {
console.log('values submitted:', values);
},
},
group: 'custom inputs',
};

View file

@ -6,6 +6,10 @@ import config from '../../config';
export const ACCOUNT_NUMBER = 'accountNumber';
// Australian equivalent for routing number
export const BSB = 'bsb';
// Needed for creating full routing number in Canada
export const INSTITUTION_NUMBER = 'institutionNumber';
// Needed for creating full routing number in Canada
export const TRANSIT_NUMBER = 'transitNumber';
// International bank account number (e.g. EU countries use this)
export const IBAN = 'iban';
// Routing number to separate bank account in different areas
@ -15,7 +19,15 @@ export const SORT_CODE = 'sortCode';
// Currently supported bank account inputs
// the order here matters: account number input is asked after routing number and its equivalents
export const BANK_ACCOUNT_INPUTS = [BSB, SORT_CODE, ROUTING_NUMBER, ACCOUNT_NUMBER, IBAN];
export const BANK_ACCOUNT_INPUTS = [
BSB,
TRANSIT_NUMBER,
INSTITUTION_NUMBER,
SORT_CODE,
ROUTING_NUMBER,
ACCOUNT_NUMBER,
IBAN,
];
export const supportedCountries = config.stripe.supportedCountries.map(c => c.code);
@ -117,7 +129,7 @@ export const translateStripeError = (country, intl, stripeError) => {
*
* @return {Object} key - value in Object literal.
*/
export const mapInputsToStripeAccountKeys = (country, inputsNeeded, values) => {
export const mapInputsToStripeAccountKeys = (country, values) => {
// Stripe documentation speaks about actual bank account terms of different countries
// (like BSB, sort code, routing number), but all of those get mapped to one of
// the two different request keys: routing_number or account_number
@ -149,6 +161,13 @@ export const mapInputsToStripeAccountKeys = (country, inputsNeeded, values) => {
routing_number: cleanedString(values[BSB]),
account_number: cleanedString(values[ACCOUNT_NUMBER]),
};
case 'CA':
return {
routing_number: cleanedString(values[TRANSIT_NUMBER]).concat(
cleanedString(values[INSTITUTION_NUMBER])
),
account_number: cleanedString(values[ACCOUNT_NUMBER]),
};
case 'GB':
return {
routing_number: cleanedString(values[SORT_CODE]),

View file

@ -127,6 +127,22 @@ const stripeSupportedCountries = [
iban: true,
},
},
{
// Canada
code: 'CA',
currency: 'CAD',
addressConfig: {
addressLine: true,
city: true,
postalCode: true,
province: true,
},
accountConfig: {
transitNumber: true,
institutionNumber: true,
accountNumber: true,
},
},
{
// Denmark
code: 'DK',

View file

@ -398,14 +398,18 @@ export const createStripeAccount = payoutDetails => (dispatch, getState, sdk) =>
postalCode,
city,
state,
province,
bankAccountToken,
personalIdNumber,
} = payoutDetails;
const hasProvince = province && !state;
const address = {
city,
line1: streetAddress,
postal_code: postalCode,
state: hasProvince ? province : state,
};
// Params for Stripe SDK

View file

@ -1,11 +1,27 @@
import React from 'react';
import { bool, object, string } from 'prop-types';
import { FieldTextInput } from '../../components';
import { FieldSelect, FieldTextInput } from '../../components';
import * as validators from '../../util/validators';
import { stripeCountryConfigs } from './PayoutDetailsForm';
import css from './PayoutDetailsForm.css';
const CANADIAN_PROVINCES = [
'AB',
'BC',
'MB',
'NB',
'NL',
'NS',
'NT',
'NU',
'ON',
'PE',
'QC',
'SK',
'YT',
];
const PayoutDetailsAddress = props => {
const { country, intl, disabled, form } = props;
const countryConfig = country ? stripeCountryConfigs(country).addressConfig : null;
@ -60,6 +76,18 @@ const PayoutDetailsAddress = props => {
})
);
const showProvince = country && isRequired(countryConfig, 'province');
const provinceLabel = intl.formatMessage({ id: 'PayoutDetailsForm.canadianProvinceLabel' });
const provincePlaceholder = intl.formatMessage({
id: 'PayoutDetailsForm.canadianProvincePlaceholder',
});
const provinceRequired = validators.required(
intl.formatMessage({
id: 'PayoutDetailsForm.canadianProvinceRequired',
})
);
return (
<div>
{showAddressLine ? (
@ -120,6 +148,27 @@ const PayoutDetailsAddress = props => {
onUnmount={() => form.change('state', undefined)}
/>
) : null}
{showProvince ? (
<FieldSelect
id="province"
name="province"
disabled={disabled}
className={css.selectCountry}
autoComplete="province"
label={provinceLabel}
validate={provinceRequired}
>
<option disabled value="">
{provincePlaceholder}
</option>
{CANADIAN_PROVINCES.map(p => (
<option key={p} value={p}>
{intl.formatMessage({ id: `PayoutDetailsForm.canadianProvinceNames.${p}` })}
</option>
))}
</FieldSelect>
) : null}
</div>
);
};

View file

@ -445,6 +445,22 @@
"PayoutDetailsForm.birthdayMonthPlaceholder": "mm",
"PayoutDetailsForm.birthdayRequired": "Birthday is required and must be a valid date.",
"PayoutDetailsForm.birthdayYearPlaceholder": "yyyy",
"PayoutDetailsForm.canadianProvinceLabel": "Province",
"PayoutDetailsForm.canadianProvinceNames.AB": "Alberta",
"PayoutDetailsForm.canadianProvinceNames.BC": "British Columbia",
"PayoutDetailsForm.canadianProvinceNames.MB": "Manitoba",
"PayoutDetailsForm.canadianProvinceNames.NB": "New Brunswick",
"PayoutDetailsForm.canadianProvinceNames.NL": "Newfoundland and Labrador",
"PayoutDetailsForm.canadianProvinceNames.NS": "Nova Scotia",
"PayoutDetailsForm.canadianProvinceNames.NT": "Northwest Territories",
"PayoutDetailsForm.canadianProvinceNames.NU": "Nunavut",
"PayoutDetailsForm.canadianProvinceNames.ON": "Ontario",
"PayoutDetailsForm.canadianProvinceNames.PE": "Prince Edward Island",
"PayoutDetailsForm.canadianProvinceNames.QC": "Quebec",
"PayoutDetailsForm.canadianProvinceNames.SK": "Saskatchewan",
"PayoutDetailsForm.canadianProvinceNames.YT": "Yukon",
"PayoutDetailsForm.canadianProvincePlaceholder": "Province",
"PayoutDetailsForm.canadianProvinceRequired": "This field is required",
"PayoutDetailsForm.cityLabel": "City",
"PayoutDetailsForm.cityPlaceholder": "Helsinki",
"PayoutDetailsForm.cityRequired": "This field is required",
@ -452,6 +468,7 @@
"PayoutDetailsForm.countryNames.AT": "Austria",
"PayoutDetailsForm.countryNames.AU": "Australia",
"PayoutDetailsForm.countryNames.BE": "Belgium",
"PayoutDetailsForm.countryNames.CA": "Canada",
"PayoutDetailsForm.countryNames.DE": "Germany",
"PayoutDetailsForm.countryNames.DK": "Denmark",
"PayoutDetailsForm.countryNames.ES": "Spain",
@ -478,6 +495,9 @@
"PayoutDetailsForm.lastNameRequired": "This field is required",
"PayoutDetailsForm.personalDetailsTitle": "Personal details",
"PayoutDetailsForm.personalIdNumberTitle": "Personal id number",
"PayoutDetailsForm.personalIdNumberLabel.HK": "Hong Kong Identity Card Number (HKID)",
"PayoutDetailsForm.personalIdNumberLabel.US": "Last 4 digits of social security number (SSN)",
"PayoutDetailsForm.personalIdNumberPlaceholder.HK": "XY123456",
"PayoutDetailsForm.personalIdNumberRequired": "This field is required",
"PayoutDetailsForm.postalCodeLabel": "Postal code",
"PayoutDetailsForm.postalCodePlaceholder": "00100",
@ -644,6 +664,10 @@
"StripeBankAccountTokenInputField.iban.label": "Bank account number (IBAN)",
"StripeBankAccountTokenInputField.iban.placeholder": "DE89 3704 0044 0532 0130 00",
"StripeBankAccountTokenInputField.iban.required": "Bank account number (IBAN) is required",
"StripeBankAccountTokenInputField.institutionNumber.inline": "institution number",
"StripeBankAccountTokenInputField.institutionNumber.label": "Institution number",
"StripeBankAccountTokenInputField.institutionNumber.placeholder": "Type in institution number",
"StripeBankAccountTokenInputField.institutionNumber.required": "Institution number is required",
"StripeBankAccountTokenInputField.routingNumber.inline": "routing number",
"StripeBankAccountTokenInputField.routingNumber.label": "Routing number",
"StripeBankAccountTokenInputField.routingNumber.placeholder": "Type in routing number…",
@ -653,6 +677,10 @@
"StripeBankAccountTokenInputField.sortCode.placeholder": "Type in sort code…",
"StripeBankAccountTokenInputField.sortCode.required": "Sort code is required",
"StripeBankAccountTokenInputField.unsupportedCountry": "Country not supported: {country}",
"StripeBankAccountTokenInputField.transitNumber.inline": "transit number",
"StripeBankAccountTokenInputField.transitNumber.label": "Transit number",
"StripeBankAccountTokenInputField.transitNumber.placeholder": "Type in transit number",
"StripeBankAccountTokenInputField.transitNumber.required": "Transit number is required",
"StripePaymentForm.creditCardDetails": "Credit card details",
"StripePaymentForm.genericError": "Could not handle payment data. Please try again.",
"StripePaymentForm.messageHeading": "Message",