diff --git a/src/components/StripeBankAccountTokenInputField/StripeBankAccountTokenInputField.example.js b/src/components/StripeBankAccountTokenInputField/StripeBankAccountTokenInputField.example.js index f0b95162..c791f073 100644 --- a/src/components/StripeBankAccountTokenInputField/StripeBankAccountTokenInputField.example.js +++ b/src/components/StripeBankAccountTokenInputField/StripeBankAccountTokenInputField.example.js @@ -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', +}; diff --git a/src/components/StripeBankAccountTokenInputField/StripeBankAccountTokenInputField.util.js b/src/components/StripeBankAccountTokenInputField/StripeBankAccountTokenInputField.util.js index 83277d0d..60b6d645 100644 --- a/src/components/StripeBankAccountTokenInputField/StripeBankAccountTokenInputField.util.js +++ b/src/components/StripeBankAccountTokenInputField/StripeBankAccountTokenInputField.util.js @@ -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]), diff --git a/src/config.js b/src/config.js index e224fdc4..133971d5 100644 --- a/src/config.js +++ b/src/config.js @@ -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', diff --git a/src/ducks/user.duck.js b/src/ducks/user.duck.js index 48ecc506..b33b9eeb 100644 --- a/src/ducks/user.duck.js +++ b/src/ducks/user.duck.js @@ -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 diff --git a/src/forms/PayoutDetailsForm/PayoutDetailsAddress.js b/src/forms/PayoutDetailsForm/PayoutDetailsAddress.js index b0990d08..0e9ed0e1 100644 --- a/src/forms/PayoutDetailsForm/PayoutDetailsAddress.js +++ b/src/forms/PayoutDetailsForm/PayoutDetailsAddress.js @@ -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 (