diff --git a/app/components/payments/bank-account.js b/app/components/payments/bank-account.js index 76d93a3cc..d9024dc0e 100644 --- a/app/components/payments/bank-account.js +++ b/app/components/payments/bank-account.js @@ -10,8 +10,8 @@ export default Component.extend({ classNameBindings: ['statusClass'], classNames: ['bank-account', 'account-setup__section'], - accountNumber: '000123456789', - routingNumber: '110000000', + accountNumber: null, + routingNumber: null, status: computed.alias('stripeConnectAccount.bankAccountStatus'), diff --git a/app/components/payments/funds-recipient/details-form.js b/app/components/payments/funds-recipient/details-form.js index 97720add5..738ed9fd0 100644 --- a/app/components/payments/funds-recipient/details-form.js +++ b/app/components/payments/funds-recipient/details-form.js @@ -1,55 +1,40 @@ import Ember from 'ember'; const { - assign, Component, computed: { equal }, get, - getProperties, set } = Ember; -const BUSINESS_PROPERTIES = ['businessName', 'businessEin']; - -const INDIVIDUAL_PROPERTIES = [ - 'recipientType', - 'firstName', 'lastName', - 'dobDay', 'dobMonth', 'dobYear', - 'address1', 'address2', 'city', 'state', 'zip', 'country', - 'ssnLast4' -]; - export default Component.extend({ classNames: ['details-form'], tagName: 'section', - isBusiness: equal('recipientType', 'business'), - isIndividual: equal('recipientType', 'individual'), + isBusiness: equal('stripeConnectAccount.legalEntityType', 'business'), + isIndividual: equal('stripeConnectAccount.legalEntityType', 'individual'), init() { - let recipientType = get(this, 'stripeConnnectAccount.recipientType') || 'individual'; - set(this, 'recipientType', recipientType); this._super(...arguments); + let stripeConnectAccount = get(this, 'stripeConnectAccount'); + if (get(stripeConnectAccount, 'legalEntityType') === null) { + set(this, 'stripeConnectAccount.legalEntityType', 'individual'); + } }, actions: { submit() { - let details = this._collectIndividualProperties(); + let stripeConnectAccount = get(this, 'stripeConnectAccount'); - if (get(this, 'isBusiness')) { - assign(details, this._collectBusinessProperties()); + if (get(this, 'isIndividual')) { + stripeConnectAccount.setProperties({ + legalEntityBusinessName: null, + legalEntityBusinessTaxId: null + }); } let onSubmit = get(this, 'onSubmit'); - onSubmit(details); + onSubmit(); } - }, - - _collectBusinessProperties() { - return getProperties(this, ...BUSINESS_PROPERTIES); - }, - - _collectIndividualProperties() { - return getProperties(this, ...INDIVIDUAL_PROPERTIES); } }); diff --git a/app/controllers/project/settings/donations/payments.js b/app/controllers/project/settings/donations/payments.js index 2f62863c5..d47ea4c8f 100644 --- a/app/controllers/project/settings/donations/payments.js +++ b/app/controllers/project/settings/donations/payments.js @@ -2,18 +2,19 @@ import Ember from 'ember'; import FriendlyError from 'code-corps-ember/utils/friendly-error'; const { + computed: { alias }, Controller, get, inject: { service }, RSVP, - set, - setProperties + set } = Ember; const ACCOUNT_CREATION_ERROR = 'There was a problem with creating your account. Please check your input and try again.'; const ACCOUNT_UPDATE_ERROR = 'There was a problem with your account information. Please check your input and try again.'; const BANK_ACCOUNT_TOKEN_CREATION_ERROR = 'There was a problem in using your bank account information. Please check your input and try again.'; const BANK_ACCOUNT_ADDING_ERROR = 'There was a problem submitting your bank account information.'; +const PERSONAL_ID_NUMBER_TOKEN_CREATION_ERROR = 'There was a problem in using your personal ID number. Please check your input and try again.'; const VERIFICATION_DOCUMENT_ERROR = 'There was a problem with attaching your document. Please try again.'; export default Controller.extend({ @@ -21,6 +22,8 @@ export default Controller.extend({ store: service(), stripe: service(), + stripeConnectAccount: alias('project.organization.stripeConnectAccount'), + actions: { onCreateStripeConnectAccount(country) { set(this, 'isBusy', true); @@ -31,11 +34,11 @@ export default Controller.extend({ .finally(() => set(this, 'isBusy', false)); }, - onRecipientDetailsSubmitted(recipientInformation) { + onRecipientDetailsSubmitted() { set(this, 'isBusy', true); get(this, 'stripeConnectAccount') - .then((stripeConnectAccount) => this._updateRecipientDetails(stripeConnectAccount, recipientInformation)) + .then((stripeConnectAccount) => this._updateRecipientDetails(stripeConnectAccount)) .catch((reason) => this._handleError(reason)) .finally(() => set(this, 'isBusy', false)); }, @@ -63,13 +66,18 @@ export default Controller.extend({ .finally(() => set(this, 'isBusy', false)); }, - onPersonalIdNumberSubmitted(personalIdNumber) { + onLegalEntityPersonalIdNumberSubmitted(legalEntityPersonalIdNumber) { set(this, 'isBusy', true); - get(this, 'stripeConnectAccount') - .then((account) => this._assignPersonalIdNumber(account, personalIdNumber)) - .catch((response) => this._handleError(response)) - .finally(() => set(this, 'isBusy', false)); + let promises = { + tokenData: this._createPersonalIdNumberToken(legalEntityPersonalIdNumber), + stripeConnectAccount: get(this, 'stripeConnectAccount') + }; + + RSVP.hash(promises) + .then(({ tokenData, stripeConnectAccount }) => this._assignLegalEntityPersonalIdNumber(tokenData, stripeConnectAccount)) + .catch((response) => this._handleError(response)) + .finally(() => set(this, 'isBusy', false)); } }, @@ -85,9 +93,7 @@ export default Controller.extend({ // udating recipient info - _updateRecipientDetails(stripeConnectAccount, recipientDetails) { - setProperties(stripeConnectAccount, recipientDetails); - + _updateRecipientDetails(stripeConnectAccount) { return stripeConnectAccount .save() .then(RSVP.resolve) @@ -97,7 +103,7 @@ export default Controller.extend({ // uploading and assigning an id verification document _assignIdentityVerificationDocument(stripeConnectAccount, stripeFileUploadId) { - set(stripeConnectAccount, 'identityDocumentId', stripeFileUploadId); + set(stripeConnectAccount, 'legalEntityVerificationDocument', stripeFileUploadId); return stripeConnectAccount .save() @@ -107,8 +113,8 @@ export default Controller.extend({ // assigning a personal id number - _assignPersonalIdNumber(stripeConnectAccount, personalIdNumber) { - set(stripeConnectAccount, 'personalIdNumber', personalIdNumber); + _assignLegalEntityPersonalIdNumber(tokenData, stripeConnectAccount) { + set(stripeConnectAccount, 'legalEntityPersonalIdNumber', tokenData.id); return stripeConnectAccount .save() @@ -116,6 +122,14 @@ export default Controller.extend({ .catch(() => this._wrapError(ACCOUNT_UPDATE_ERROR)); }, + _createPersonalIdNumberToken(personalIdNumber) { + let stripe = get(this, 'stripe'); + + return stripe.piiData.createToken({ personalIdNumber }) + .then((stripeResponse) => RSVP.resolve(stripeResponse)) + .catch(() => this._wrapError(PERSONAL_ID_NUMBER_TOKEN_CREATION_ERROR)); + }, + // bank account - token step _createAccountToken(accountNumber, routingNumber) { @@ -123,8 +137,8 @@ export default Controller.extend({ let params = this._bankAccountTokenParams(accountNumber, routingNumber); return stripe.bankAccount.createToken(params) - .then((stripeResponse) => RSVP.resolve(stripeResponse)) - .catch(() => this._wrapError(BANK_ACCOUNT_TOKEN_CREATION_ERROR)); + .then((stripeResponse) => RSVP.resolve(stripeResponse)) + .catch(() => this._wrapError(BANK_ACCOUNT_TOKEN_CREATION_ERROR)); }, _bankAccountTokenParams(accountNumber, routingNumber) { diff --git a/app/models/stripe-connect-account.js b/app/models/stripe-connect-account.js index 1f2023936..19ebdaf1f 100644 --- a/app/models/stripe-connect-account.js +++ b/app/models/stripe-connect-account.js @@ -3,33 +3,65 @@ import attr from 'ember-data/attr'; import { belongsTo } from 'ember-data/relationships'; export default Model.extend({ - address1: attr(), - address2: attr(), - businessEin: attr(), + bankAccountStatus: attr(), businessName: attr(), - businessType: attr(), + businessUrl: attr(), canAcceptDonations: attr(), chargesEnabled: attr(), - city: attr(), country: attr(), + defaultCurrency: attr(), + detailsSubmitted: attr(), displayName: attr(), - dobDay: attr(), - dobMonth: attr(), - dobYear: attr(), email: attr(), - firstName: attr(), - identityDocumentId: attr(), - idFromStripe: attr(), + externalAccount: attr(), insertedAt: attr(), - lastName: attr(), + legalEntityAddressCity: attr(), + legalEntityAddressCountry: attr(), + legalEntityAddressLine1: attr(), + legalEntityAddressLine2: attr(), + legalEntityAddressPostalCode: attr(), + legalEntityAddressState: attr(), + legalEntityBusinessName: attr(), + legalEntityBusinessTaxId: attr(), + legalEntityBusinessTaxIdProvided: attr(), + legalEntityBusinessVatId: attr(), + legalEntityBusinessVatIdProvided: attr(), + legalEntityDobDay: attr('number'), + legalEntityDobMonth: attr('number'), + legalEntityDobYear: attr('number'), + legalEntityFirstName: attr(), + legalEntityLastName: attr(), + legalEntityGender: attr(), + legalEntityMaidenName: attr(), + legalEntityPersonalAddressCity: attr(), + legalEntityPersonalAddressCountry: attr(), + legalEntityPersonalAddressLine1: attr(), + legalEntityPersonalAddressLine2: attr(), + legalEntityPersonalAddressPostalCode: attr(), + legalEntityPersonalAddressState: attr(), + legalEntityPhoneNumber: attr(), + legalEntityPersonalIdNumber: attr(), + legalEntityPersonalIdNumberProvided: attr(), + legalEntitySsnLast4: attr(), + legalEntitySsnLast4Provided: attr(), + legalEntityType: attr(), + legalEntityVerificationDetails: attr(), + legalEntityVerificationDetailsCode: attr(), + legalEntityVerificationDocument: attr(), + legalEntityVerificationStatus: attr(), + idFromStripe: attr(), + managed: attr(), + personalIdNumberStatus: attr(), recipientStatus: attr(), - recipientType: attr(), - ssnLast4: attr(), - state: attr(), + supportEmail: attr(), + supportPhone: attr(), + supportUrl: attr(), + transfersEnabled: attr(), updatedAt: attr(), + verificationDisabledReason: attr(), verificationDocumentStatus: attr(), + verificationDueBy: attr(), verificationFieldsNeeded: attr(), - zip: attr(), organization: belongsTo('organization', { async: true }) }); diff --git a/app/serializers/stripe-connect-account.js b/app/serializers/stripe-connect-account.js new file mode 100644 index 000000000..98d851f6b --- /dev/null +++ b/app/serializers/stripe-connect-account.js @@ -0,0 +1,8 @@ +import ApplicationSerializer from './application'; + +export default ApplicationSerializer.extend({ + attrs: { + legalEntitySsnLast4: { key: 'legal-entity-ssn-last-4' }, + legalEntitySsnLast4Provided: { key: 'legal-entity-ssn-last-4-provided' } + } +}); diff --git a/app/styles/_icons.scss b/app/styles/_icons.scss index 171cd9ade..8096b9f82 100644 --- a/app/styles/_icons.scss +++ b/app/styles/_icons.scss @@ -59,7 +59,7 @@ $calendar: 20px 20px $spriteURL -42px -268px $spritex2URL; $task-small: 16px 16px $spriteURL 0px -288px $spritex2URL; $issue-small: 16px 16px $spriteURL -16px -288px $spritex2URL; $idea-small: 16px 16px $spriteURL -32px -288px $spritex2URL; -$tick-green-large: 20px 24px $spriteURL 0px -304px $spritex2URL; +$tick-green-large: 24px 20px $spriteURL 0px -304px $spritex2URL; .box-icon { @include sprite($box); diff --git a/app/styles/components/payments/account-setup.scss b/app/styles/components/payments/account-setup.scss index f8460e0d5..308948a3a 100644 --- a/app/styles/components/payments/account-setup.scss +++ b/app/styles/components/payments/account-setup.scss @@ -44,6 +44,10 @@ background-color: $light-green-background; border-color: $green; + p { + color: $green; + } + aside h1:before { content: ""; display: block; diff --git a/app/templates/components/payments/account-setup.hbs b/app/templates/components/payments/account-setup.hbs index fea9576ee..d0382100d 100644 --- a/app/templates/components/payments/account-setup.hbs +++ b/app/templates/components/payments/account-setup.hbs @@ -9,9 +9,9 @@ {{payments/funds-recipient isBusy=isBusy + onLegalEntityPersonalIdNumberSubmitted=(action onLegalEntityPersonalIdNumberSubmitted) onRecipientDetailsSubmitted=(action onRecipientDetailsSubmitted) onVerificationDocumentSubmitted=(action onVerificationDocumentSubmitted) - onPersonalIdNumberSubmitted=(action onPersonalIdNumberSubmitted) stripeConnectAccount=stripeConnectAccount }} diff --git a/app/templates/components/payments/funds-recipient.hbs b/app/templates/components/payments/funds-recipient.hbs index bae3a1017..78c80cdb7 100644 --- a/app/templates/components/payments/funds-recipient.hbs +++ b/app/templates/components/payments/funds-recipient.hbs @@ -13,24 +13,27 @@ {{payments/funds-recipient/verification-document isBusy=isBusy onVerificationDocumentSubmitted=(action onVerificationDocumentSubmitted) - stripeConnectAccount=stripeConnectAccount}} + stripeConnectAccount=stripeConnectAccount + }} + {{payments/funds-recipient/personal-id-number isBusy=isBusy stripeConnectAccount=stripeConnectAccount - submit=(action onPersonalIdNumberSubmitted)}} + submit=(action onLegalEntityPersonalIdNumberSubmitted) + }} {{/if}} {{#if (eq status 'verified')}}
-

{{stripeConnectAccount.individualName}}

+

{{stripeConnectAccount.legalEntityFirstName}} {{stripeConnectAccount.legalEntityLastName}}

- {{#if (eq stripeConnectAccount.recipientType 'business')}} + {{#if (eq stripeConnectAccount.legalEntityType 'business')}}
-

{{stripeConnectAccount.businessName}}

+

{{stripeConnectAccount.legalEntityBusinessName}}

{{/if}}
diff --git a/app/templates/components/payments/funds-recipient/details-form.hbs b/app/templates/components/payments/funds-recipient/details-form.hbs index 9cb345b62..d26d460f9 100644 --- a/app/templates/components/payments/funds-recipient/details-form.hbs +++ b/app/templates/components/payments/funds-recipient/details-form.hbs @@ -1,24 +1,24 @@

Tell us whether a person or an organization will be running this project. Once your turn on donations, you cannot change your information.

- {{#radio-button class="details-form__recipient-type" value="individual" groupValue=recipientType}} + {{#radio-button class="details-form__recipient-type" value="individual" groupValue=stripeConnectAccount.legalEntityType}} Individual {{/radio-button}} - {{#radio-button class="details-form__recipient-type" value="business" groupValue=recipientType}} + {{#radio-button class="details-form__recipient-type" value="business" groupValue=stripeConnectAccount.legalEntityType}} Legal entity (company or organization) {{/radio-button}}
-{{#if (eq recipientType 'business')}} +{{#if (eq stripeConnectAccount.legalEntityType 'business')}}
Legal entity
- - {{input type="text" name="business-name" value=businessName}} + + {{input type="text" name="legal-entity-business-name" value=stripeConnectAccount.legalEntityBusinessName}}
- - {{input type="text" name="business-ein" value=businessEin}} + + {{input type="text" name="legal-entity-business-tax-id" value=stripeConnectAccount.legalEntityBusinessTaxId}}
@@ -31,12 +31,12 @@
Your name
- - {{input type="text" name="first-name" value=firstName}} + + {{input type="text" name="legal-entity-first-name" value=stripeConnectAccount.legalEntityFirstName}}
- - {{input type="text" name="last-name" value=lastName}} + + {{input type="text" name="legal-entity-last-name" value=stripeConnectAccount.legalEntityLastName}}
@@ -45,7 +45,7 @@
Birthdate
- {{select/birth-date day=dobDay month=dobMonth year=dobYear}} + {{select/birth-date day=stripeConnectAccount.legalEntityDobDay month=stripeConnectAccount.legalEntityDobMonth year=stripeConnectAccount.legalEntityDobYear}}
@@ -54,30 +54,30 @@
Address
- - {{input type="text" name="address-1" value=address1}} + + {{input type="text" name="legal-entity-address-1" value=stripeConnectAccount.legalEntityAddressLine1}}
- - {{input type="text" name="address-2" value=address2}} + + {{input type="text" name="legal-entity-address-2" value=stripeConnectAccount.legalEntityAddressLine2}}
- {{input type="text" name="city" value=city}} + {{input type="text" name="legal-entity-address-city" value=stripeConnectAccount.legalEntityAddressCity}}
- - {{select/state-select state=state}} + + {{select/state-select state=stripeConnectAccount.legalEntityAddressState}}
- {{input type="text" name="zip" value=zip}} + {{input type="text" name="legal-entity-address-postal-code" value=stripeConnectAccount.legalEntityAddressPostalCode}}
- {{select/country-select country=country}} + {{select/country-select country=stripeConnectAccount.legalEntityAddressCountry}}
@@ -86,7 +86,7 @@
SSN Last 4
- {{input type="text" name="ssn-last4" value=ssnLast4}} + {{input type="text" name="legal-entity-ssn-last-4" value=stripeConnectAccount.legalEntitySsnLast4}}
diff --git a/app/templates/components/payments/funds-recipient/personal-id-number.hbs b/app/templates/components/payments/funds-recipient/personal-id-number.hbs index 1be8b4546..ee7e73950 100644 --- a/app/templates/components/payments/funds-recipient/personal-id-number.hbs +++ b/app/templates/components/payments/funds-recipient/personal-id-number.hbs @@ -1,16 +1,16 @@ {{#if (eq status 'required')}}
-
We need your full personal ID number
+
We need your full personal ID number.
- {{input type="text" name="personal-id-number" value=personalIdNumber disabled=isBusy}} + {{input type="text" name="legal-entity-personal-id-number" value=legalEntityPersonalIdNumber disabled=isBusy}}
- + {{/if}} {{#if (eq status 'verifying')}} - We're verifying your ID number -{{/if}} \ No newline at end of file +

We're verifying your ID number.

+{{/if}} diff --git a/app/templates/components/payments/funds-recipient/verification-document.hbs b/app/templates/components/payments/funds-recipient/verification-document.hbs index 81c1db4f3..94e498615 100644 --- a/app/templates/components/payments/funds-recipient/verification-document.hbs +++ b/app/templates/components/payments/funds-recipient/verification-document.hbs @@ -1,10 +1,11 @@ {{#if (eq status 'required')}} {{#if isBusy}} - Processing... +

Processing...

{{else if isUploading}} {{progressMessage}} {{else}} -
we need you to upload a scan of your ID (form + submit)
+

We need you to upload a copy of your personal ID to verify your identity.

+

Please upload either a PNG or JPG image. Your file should be less than 8MB.

{{payments/funds-recipient/identity-document-file-upload isBusy=isBusy @@ -20,6 +21,7 @@ {{/if}} {{/if}} {{/if}} + {{#if (eq status 'verifying')}} - Please be patient while we review the document you provided. +

Please be patient while we review the document you provided.

{{/if}} diff --git a/app/templates/project/settings/donations/payments.hbs b/app/templates/project/settings/donations/payments.hbs index a0136b713..c2f14add9 100644 --- a/app/templates/project/settings/donations/payments.hbs +++ b/app/templates/project/settings/donations/payments.hbs @@ -3,11 +3,11 @@ isBusy=isBusy onBankAccountInformationSubmitted=(action 'onBankAccountInformationSubmitted') onCreateStripeConnectAccount=(action 'onCreateStripeConnectAccount') - onPersonalIdNumberSubmitted=(action 'onPersonalIdNumberSubmitted') + onLegalEntityPersonalIdNumberSubmitted=(action 'onLegalEntityPersonalIdNumberSubmitted') onRecipientDetailsSubmitted=(action 'onRecipientDetailsSubmitted') onVerificationDocumentSubmitted=(action 'onVerificationDocumentSubmitted') organizationName=project.organization.name - stripeConnectAccount=project.organization.stripeConnectAccount + stripeConnectAccount=stripeConnectAccount }} {{#if error}} diff --git a/mirage/config.js b/mirage/config.js index 05f1976d5..217d40654 100644 --- a/mirage/config.js +++ b/mirage/config.js @@ -1,4 +1,9 @@ import Mirage from 'ember-cli-mirage'; +import Ember from 'ember'; + +const { + isEmpty +} = Ember; function generateCommentMentions(schema, comment) { let body = comment.body || ''; @@ -71,6 +76,9 @@ const routes = [ ]; export default function() { + this.passthrough('https://api.stripe.com/**'); + this.passthrough('https://uploads.stripe.com/**'); + /** * Categories */ @@ -396,9 +404,46 @@ export default function() { * Stripe connect accounts */ - this.post('/stripe-connect-accounts'); + this.post('/stripe-connect-accounts', function(schema) { + let { country } = this.normalizedRequestAttrs(); + let stripeConnectAccount = schema.create('stripeConnectAccount', { + country, + recipientStatus: 'required' + }); + return stripeConnectAccount; + }); + this.get('/stripe-connect-accounts/:id'); + this.patch('/stripe-connect-accounts/:id', function(schema) { + let attrs = this.normalizedRequestAttrs(); + + if (!isEmpty(attrs.legalEntityAddressCity)) { + attrs.recipientStatus = 'verifying'; + attrs.personalIdNumberStatus = 'required'; + } + + if (!isEmpty(attrs.legalEntityPersonalIdNumber)) { + attrs.personalIdNumberStatus = 'verified'; + attrs.verificationDocumentStatus = 'required'; + } + + if (!isEmpty(attrs.legalEntityVerificationDocument)) { + attrs.recipientStatus = 'verified'; + attrs.verificationDocumentStatus = 'verified'; + attrs.bankAccountStatus = 'required'; + } + + if (!isEmpty(attrs.externalAccount)) { + attrs.bankAccountStatus = 'verified'; + } + + let stripeConnectAccount = schema.stripeConnectAccounts.find(attrs.id); + stripeConnectAccount.attrs = attrs; + stripeConnectAccount.save(); + return stripeConnectAccount; + }); + /** * Stripe plans */ diff --git a/mirage/models/project.js b/mirage/models/project.js index 333fad709..1c07856c2 100644 --- a/mirage/models/project.js +++ b/mirage/models/project.js @@ -3,9 +3,9 @@ import { Model, belongsTo, hasMany } from 'ember-cli-mirage'; export default Model.extend({ donationGoals: hasMany(), organization: belongsTo(), - taskLists: hasMany(), - tasks: hasMany(), projectCategories: hasMany(), projectSkills: hasMany(), - stripeConnectPlan: belongsTo() + stripeConnectPlan: belongsTo(), + taskLists: hasMany(), + tasks: hasMany() }); diff --git a/mirage/scenarios/default.js b/mirage/scenarios/default.js index ea73e3f4e..8534af274 100644 --- a/mirage/scenarios/default.js +++ b/mirage/scenarios/default.js @@ -289,13 +289,6 @@ export default function(server) { server.create('project-category', { category, project }); }); - let stripeConnectAccount = server.create('stripe-connect-account', { - organization, - recipientStatus: 'required' - }); - organization.stripeConnectAccount = stripeConnectAccount; - organization.save(); - project.createStripeConnectPlan(); server.create('stripe-platform-customer', { user: owner }); diff --git a/tests/integration/components/payments/account-setup-test.js b/tests/integration/components/payments/account-setup-test.js index 86eca77e6..d5a570759 100644 --- a/tests/integration/components/payments/account-setup-test.js +++ b/tests/integration/components/payments/account-setup-test.js @@ -15,14 +15,14 @@ function setHandlers(context, { onCreateStripeConnectAccount = K, onRecipientDetailsSubmitted = K, onVerificationDocumentSubmitted = K, - onPersonalIdNumberSubmitted = K, + onLegalEntityPersonalIdNumberSubmitted = K, onBankAccountInformationSubmitted = K } = {}) { context.setProperties({ onCreateStripeConnectAccount, onRecipientDetailsSubmitted, onVerificationDocumentSubmitted, - onPersonalIdNumberSubmitted, + onLegalEntityPersonalIdNumberSubmitted, onBankAccountInformationSubmitted }); } @@ -36,7 +36,7 @@ function renderPage() { onCreateStripeConnectAccount=onCreateStripeConnectAccount onRecipientDetailsSubmitted=onRecipientDetailsSubmitted onVerificationDocumentSubmitted=onVerificationDocumentSubmitted - onPersonalIdNumberSubmitted=onPersonalIdNumberSubmitted + onLegalEntityPersonalIdNumberSubmitted=onLegalEntityPersonalIdNumberSubmitted onBankAccountInformationSubmitted=onBankAccountInformationSubmitted organizationName=project.organization.name }} diff --git a/tests/integration/components/payments/funds-recipient-test.js b/tests/integration/components/payments/funds-recipient-test.js index b9a644470..f0d342ad0 100644 --- a/tests/integration/components/payments/funds-recipient-test.js +++ b/tests/integration/components/payments/funds-recipient-test.js @@ -19,7 +19,7 @@ function renderPage() { stripeConnectAccount=stripeConnectAccount onRecipientDetailsSubmitted=detailsHandler onVerificationDocumentSubmitted=documentHandler - onPersonalIdNumberSubmitted=idHandler + onLegalEntityPersonalIdNumberSubmitted=idHandler }} `); } @@ -68,7 +68,7 @@ test('it renders correctly when "verifying" and document status "required"', fun assert.ok(page.rendersVerifying, 'Component is rendered in verifying mode.'); assert.ok(page.rendersVerificationDocument, 'Component renders the verification document subcomponent.'); - assert.ok(page.rendersPersonalIdNumber, 'Component renders the personal id number subcomponent.'); + assert.ok(page.renderslegalEntityPersonalIdNumber, 'Component renders the personal id number subcomponent.'); }); test('it renders correctly when "verified"', function(assert) { @@ -76,7 +76,8 @@ test('it renders correctly when "verified"', function(assert) { let stripeConnectAccount = { recipientStatus: 'verified', - individualName: 'Joe Individual' + legalEntityFirstName: 'Joe', + legalEntityLastName: 'Individual' }; this.set('stripeConnectAccount', stripeConnectAccount); @@ -91,9 +92,10 @@ test('it renders correctly when "verified" for business', function(assert) { let stripeConnectAccount = { recipientStatus: 'verified', - individualName: 'Joe Individual', - businessName: 'Company Inc.', - recipientType: 'business' + legalEntityFirstName: 'Joe', + legalEntityLastName: 'Individual', + legalEntityBusinessName: 'Company Inc.', + legalEntityType: 'business' }; this.set('stripeConnectAccount', stripeConnectAccount); @@ -101,7 +103,7 @@ test('it renders correctly when "verified" for business', function(assert) { assert.ok(page.rendersVerified, 'Component is rendered in verified mode.'); assert.ok(page.individualNameText, 'Joe Individual', 'Component renders the name of the registered individual.'); - assert.ok(page.businessNameText, 'Company Inc.', 'Component renders the name of the registered business.'); + assert.ok(page.legalEntityBusinessNameText, 'Company Inc.', 'Component renders the name of the registered business.'); }); test('it passes out submit action from details subcomponent', function(assert) { @@ -151,5 +153,5 @@ test('it passes out submit action from personal id number subcomponent', functio renderPage(); - page.personalIdNumber.clickSubmit(); + page.legalEntityPersonalIdNumber.clickSubmit(); }); diff --git a/tests/integration/components/payments/funds-recipient/details-form-test.js b/tests/integration/components/payments/funds-recipient/details-form-test.js index c68957f49..4b74bdfa5 100644 --- a/tests/integration/components/payments/funds-recipient/details-form-test.js +++ b/tests/integration/components/payments/funds-recipient/details-form-test.js @@ -1,6 +1,12 @@ import { moduleForComponent, test } from 'ember-qunit'; import hbs from 'htmlbars-inline-precompile'; import PageObject from 'ember-cli-page-object'; +import Ember from 'ember'; + +const { + get, + Object +} = Ember; import detailsFormComponent from 'code-corps-ember/tests/pages/components/payments/funds-recipient/details-form'; @@ -8,7 +14,7 @@ let page = PageObject.create(detailsFormComponent); function renderPage() { page.render( - hbs`{{payments/funds-recipient/details-form account=account onSubmit=onSubmit}}` + hbs`{{payments/funds-recipient/details-form stripeConnectAccount=stripeConnectAccount onSubmit=onSubmit}}` ); } @@ -22,92 +28,98 @@ moduleForComponent('payments/funds-recipient/details-form', 'Integration | Compo } }); -test('it sends out correct properties when submitting in business mode', function(assert) { +test('it keeps the business properties when submitting in business mode', function(assert) { assert.expect(1); - let expectedProperties = { - businessName: 'Test Business', - businessEin: '1234', - recipientType: 'business', - firstName: 'Joe', - lastName: 'Regular', - dobDay: 6, - dobMonth: 12, - dobYear: 1986, - address1: 'Some street 42', - address2: 'PO 21', - city: 'Town', - state: 'AL', - zip: '11111', - country: 'US', - ssnLast4: '5555' - }; - - this.set('onSubmit', (properties) => { - assert.deepEqual(properties, expectedProperties, 'Correct properties were submitted'); + let account = Object.create({ + legalEntityType: 'business', + legalEntityBusinessName: 'Test Business', + legalEntityBusinessTaxId: '1234', + legalEntityFirstName: 'Joe', + legalEntityLastName: 'Regular', + legalEntityDobDay: 6, + legalEntityDobMonth: 12, + legalEntityDobYear: 1986, + legalEntityAddressLine1: 'Some street 42', + legalEntityAddressLine2: 'PO 21', + legalEntityAddressCity: 'Town', + legalEntityAddressState: 'AL', + legalEntityAddressPostalCode: '11111', + legalEntityAddressCountry: 'US', + legalEntitySsnLast4: '5555' + }); + + this.set('onSubmit', () => { + assert.equal(get(account, 'legalEntityBusinessName'), 'Test Business'); }); + this.set('stripeConnectAccount', account); + renderPage(); page.selectBusiness() - .businessName(expectedProperties.businessName) - .businessEin(expectedProperties.businessEin) - .firstName(expectedProperties.firstName) - .lastName(expectedProperties.lastName) - .address1(expectedProperties.address1) - .address2(expectedProperties.address2) - .city(expectedProperties.city) - .zip(expectedProperties.zip) - .ssnLast4(expectedProperties.ssnLast4); - - page.state.fillIn(expectedProperties.state); - page.country.fillIn(expectedProperties.country); - page.birthDate.day.fillIn(expectedProperties.dobDay); - page.birthDate.month.fillIn(expectedProperties.dobMonth); - page.birthDate.year.fillIn(expectedProperties.dobYear); + .legalEntityBusinessName(account.legalEntityBusinessName) + .legalEntityBusinessTaxId(account.legalEntityBusinessTaxId) + .legalEntityFirstName(account.legalEntityFirstName) + .legalEntityLastName(account.legalEntityLastName) + .legalEntityAddressLine1(account.legalEntityAddressLine1) + .legalEntityAddressLine2(account.legalEntityAddressLine2) + .legalEntityAddressCity(account.legalEntityAddressCity) + .legalEntityAddressPostalCode(account.legalEntityAddressPostalCode) + .legalEntitySsnLast4(account.legalEntitySsnLast4); + + page.state.fillIn(account.legalEntityAddressState); + page.country.fillIn(account.legalEntityAddressCountry); + page.birthDate.day.fillIn(account.legalEntityDobDay); + page.birthDate.month.fillIn(account.legalEntityDobMonth); + page.birthDate.year.fillIn(account.legalEntityDobYear); page.clickSubmit(); }); -test('it sends out correct properties when submitting in individual mode', function(assert) { +test('it unsets the business properties when submitting in individual mode', function(assert) { assert.expect(1); - let expectedProperties = { - recipientType: 'individual', - firstName: 'Joe', - lastName: 'Regular', - dobDay: 6, - dobMonth: 12, - dobYear: 1986, - address1: 'Some street 42', - address2: 'PO 21', - city: 'Town', - state: 'AL', - zip: '11111', - country: 'US', - ssnLast4: '5555' - }; - - this.set('onSubmit', (properties) => { - assert.deepEqual(properties, expectedProperties, 'Correct properties were submitted'); + let account = Object.create({ + legalEntityType: 'individual', + legalEntityBusinessName: 'Test Business', + legalEntityBusinessTaxId: '1234', + legalEntityFirstName: 'Joe', + legalEntityLastName: 'Regular', + legalEntityDobDay: 6, + legalEntityDobMonth: 12, + legalEntityDobYear: 1986, + legalEntityAddressLine1: 'Some street 42', + legalEntityAddressLine2: 'PO 21', + legalEntityAddressCity: 'Town', + legalEntityAddressState: 'AL', + legalEntityAddressPostalCode: '11111', + legalEntityAddressCountry: 'US', + legalEntitySsnLast4: '5555' }); + this.set('onSubmit', () => { + assert.equal(get(account, 'legalEntityBusinessName'), null); + }); + + this.set('stripeConnectAccount', account); + renderPage(); page.selectIndividual() - .firstName(expectedProperties.firstName) - .lastName(expectedProperties.lastName) - .address1(expectedProperties.address1) - .address2(expectedProperties.address2) - .city(expectedProperties.city) - .zip(expectedProperties.zip) - .ssnLast4(expectedProperties.ssnLast4); - - page.state.fillIn(expectedProperties.state); - page.country.fillIn(expectedProperties.country); - page.birthDate.day.fillIn(expectedProperties.dobDay); - page.birthDate.month.fillIn(expectedProperties.dobMonth); - page.birthDate.year.fillIn(expectedProperties.dobYear); + .legalEntityFirstName(account.legalEntityFirstName) + .legalEntityLastName(account.legalEntityLastName) + .legalEntityAddressLine1(account.legalEntityAddressLine1) + .legalEntityAddressLine2(account.legalEntityAddressLine2) + .legalEntityAddressCity(account.legalEntityAddressCity) + .legalEntityAddressPostalCode(account.legalEntityAddressPostalCode) + .legalEntitySsnLast4(account.legalEntitySsnLast4); + + page.state.fillIn(account.legalEntityAddressState); + page.country.fillIn(account.legalEntityAddressCountry); + page.birthDate.day.fillIn(account.legalEntityDobDay); + page.birthDate.month.fillIn(account.legalEntityDobMonth); + page.birthDate.year.fillIn(account.legalEntityDobYear); page.clickSubmit(); }); diff --git a/tests/integration/components/payments/funds-recipient/personal-id-number-test.js b/tests/integration/components/payments/funds-recipient/personal-id-number-test.js index 970960e76..cb73f654e 100644 --- a/tests/integration/components/payments/funds-recipient/personal-id-number-test.js +++ b/tests/integration/components/payments/funds-recipient/personal-id-number-test.js @@ -3,9 +3,9 @@ import { moduleForComponent, test } from 'ember-qunit'; import hbs from 'htmlbars-inline-precompile'; import PageObject from 'ember-cli-page-object'; -import personalIdNumberComponent from 'code-corps-ember/tests/pages/components/payments/funds-recipient/personal-id-number'; +import legalEntityPersonalIdNumberComponent from 'code-corps-ember/tests/pages/components/payments/funds-recipient/personal-id-number'; -let page = PageObject.create(personalIdNumberComponent); +let page = PageObject.create(legalEntityPersonalIdNumberComponent); const { set, @@ -55,7 +55,7 @@ test('it renders correctly for "required" status', function(assert) { renderPage(); - assert.ok(page.rendersPersonalIdNumberField, 'Component renders the account number field.'); + assert.ok(page.renderslegalEntityPersonalIdNumberField, 'Component renders the account number field.'); assert.ok(page.rendersSubmitButton, 'Component renders the submit button.'); }); @@ -67,7 +67,7 @@ test('it renders correctly for "verifying" status', function(assert) { renderPage(); - assert.equal(page.text, "We're verifying your ID number"); + assert.equal(page.text, "We're verifying your ID number."); }); test('it renders correctly for "verified" status', function(assert) { @@ -87,14 +87,14 @@ test('it sends properties with submit action', function(assert) { let stripeConnectAccount = { personalIdNumberStatus: 'required' }; set(this, 'stripeConnectAccount', stripeConnectAccount); - let personalIdNumber = '123456'; + let legalEntityPersonalIdNumber = '123456'; setHandler(this, (number) => { - assert.equal(personalIdNumber, number, 'Correct parameter was sent out with action.'); + assert.equal(legalEntityPersonalIdNumber, number, 'Correct parameter was sent out with action.'); }); renderPage(); - page.personalIdNumber(personalIdNumber).clickSubmit(); + page.legalEntityPersonalIdNumber(legalEntityPersonalIdNumber).clickSubmit(); }); test('it disables controls when busy', function(assert) { @@ -106,6 +106,6 @@ test('it disables controls when busy', function(assert) { renderPage(); - assert.ok(page.personalIdNumberFieldIsDisabled, 'Personal ID number field is disabled when busy.'); + assert.ok(page.legalEntityPersonalIdNumberFieldIsDisabled, 'Personal ID number field is disabled when busy.'); assert.ok(page.submitButtonIsDisabled, 'Submit button is disabled when busy.'); }); diff --git a/tests/pages/components/payments/funds-recipient.js b/tests/pages/components/payments/funds-recipient.js index cd3dcb8ef..e579e3662 100644 --- a/tests/pages/components/payments/funds-recipient.js +++ b/tests/pages/components/payments/funds-recipient.js @@ -2,7 +2,7 @@ import { hasClass, isVisible, text } from 'ember-cli-page-object'; import detailsForm from './funds-recipient/details-form'; import verificationDocument from './funds-recipient/verification-document'; -import personalIdNumber from './funds-recipient/personal-id-number'; +import legalEntityPersonalIdNumber from './funds-recipient/personal-id-number'; export default { scope: '.funds-recipient', @@ -14,12 +14,12 @@ export default { rendersDetailsForm: isVisible('.details-form'), rendersVerificationDocument: isVisible('.verification-document'), - rendersPersonalIdNumber: isVisible('.personal-id-number'), + renderslegalEntityPersonalIdNumber: isVisible('.personal-id-number'), individualNameText: text('.funds-recipient__individual-name p'), - businessNameText: text('.funds-recipient__business-name p'), + legalEntityBusinessNameText: text('.funds-recipient__business-name p'), detailsForm, verificationDocument, - personalIdNumber + legalEntityPersonalIdNumber }; diff --git a/tests/pages/components/payments/funds-recipient/details-form.js b/tests/pages/components/payments/funds-recipient/details-form.js index 8fde6f795..a38572c62 100644 --- a/tests/pages/components/payments/funds-recipient/details-form.js +++ b/tests/pages/components/payments/funds-recipient/details-form.js @@ -9,22 +9,22 @@ export default { selectIndividual: clickable('input[value="individual"]'), selectBusiness: clickable('input[value="business"]'), - businessName: fillable('input[name=business-name]'), - businessEin: fillable('input[name=business-ein]'), + legalEntityBusinessName: fillable('input[name=legal-entity-business-name]'), + legalEntityBusinessTaxId: fillable('input[name=legal-entity-business-tax-id]'), - firstName: fillable('input[name=first-name]'), - lastName: fillable('input[name=last-name]'), + legalEntityFirstName: fillable('input[name=legal-entity-first-name]'), + legalEntityLastName: fillable('input[name=legal-entity-last-name]'), birthDate, - address1: fillable('input[name=address-1]'), - address2: fillable('input[name=address-2]'), - city: fillable('input[name=city]'), + legalEntityAddressLine1: fillable('input[name=legal-entity-address-1]'), + legalEntityAddressLine2: fillable('input[name=legal-entity-address-2]'), + legalEntityAddressCity: fillable('input[name=legal-entity-address-city]'), state, - zip: fillable('input[name=zip]'), + legalEntityAddressPostalCode: fillable('input[name=legal-entity-address-postal-code]'), country, - ssnLast4: fillable('input[name=ssn-last4]'), + legalEntitySsnLast4: fillable('input[name=legal-entity-ssn-last-4]'), clickSubmit: clickable('input[type=submit]') }; diff --git a/tests/pages/components/payments/funds-recipient/personal-id-number.js b/tests/pages/components/payments/funds-recipient/personal-id-number.js index cd6745fa7..cb81e02a6 100644 --- a/tests/pages/components/payments/funds-recipient/personal-id-number.js +++ b/tests/pages/components/payments/funds-recipient/personal-id-number.js @@ -5,10 +5,10 @@ export default { clickSubmit: clickable('button'), - personalIdNumber: fillable('input[type=text]'), - personalIdNumberFieldIsDisabled: is(':disabled', 'input[type=text]'), + legalEntityPersonalIdNumber: fillable('input[type=text]'), + legalEntityPersonalIdNumberFieldIsDisabled: is(':disabled', 'input[type=text]'), - rendersPersonalIdNumberField: isVisible('input[type=text]'), + renderslegalEntityPersonalIdNumberField: isVisible('input[type=text]'), rendersSubmitButton: isVisible('button'), submitButtonIsDisabled: is(':disabled', 'button') diff --git a/tests/unit/models/stripe-connect-account-test.js b/tests/unit/models/stripe-connect-account-test.js index 8b6007700..d42d1ea77 100644 --- a/tests/unit/models/stripe-connect-account-test.js +++ b/tests/unit/models/stripe-connect-account-test.js @@ -12,32 +12,64 @@ test('it exists', function(assert) { }); testForAttributes('stripe-connect-account', [ - 'address1', - 'address2', - 'businessEin', + 'bankAccountStatus', 'businessName', - 'businessType', + 'businessUrl', 'canAcceptDonations', 'chargesEnabled', - 'city', 'country', + 'defaultCurrency', + 'detailsSubmitted', 'displayName', - 'dobDay', - 'dobMonth', - 'dobYear', 'email', - 'firstName', - 'identityDocumentId', - 'idFromStripe', + 'externalAccount', 'insertedAt', - 'lastName', + 'legalEntityAddressCity', + 'legalEntityAddressCountry', + 'legalEntityAddressLine1', + 'legalEntityAddressLine2', + 'legalEntityAddressPostalCode', + 'legalEntityAddressState', + 'legalEntityBusinessName', + 'legalEntityBusinessTaxId', + 'legalEntityBusinessTaxIdProvided', + 'legalEntityBusinessVatId', + 'legalEntityBusinessVatIdProvided', + 'legalEntityDobDay', + 'legalEntityDobMonth', + 'legalEntityDobYear', + 'legalEntityFirstName', + 'legalEntityLastName', + 'legalEntityGender', + 'legalEntityMaidenName', + 'legalEntityPersonalAddressCity', + 'legalEntityPersonalAddressCountry', + 'legalEntityPersonalAddressLine1', + 'legalEntityPersonalAddressLine2', + 'legalEntityPersonalAddressPostalCode', + 'legalEntityPersonalAddressState', + 'legalEntityPhoneNumber', + 'legalEntityPersonalIdNumber', + 'legalEntityPersonalIdNumberProvided', + 'legalEntitySsnLast4', + 'legalEntitySsnLast4Provided', + 'legalEntityType', + 'legalEntityVerificationDetails', + 'legalEntityVerificationDetailsCode', + 'legalEntityVerificationDocument', + 'legalEntityVerificationStatus', + 'idFromStripe', + 'managed', + 'personalIdNumberStatus', 'recipientStatus', - 'recipientType', - 'ssnLast4', - 'state', + 'supportEmail', + 'supportPhone', + 'supportUrl', + 'transfersEnabled', 'updatedAt', + 'verificationDisabledReason', 'verificationDocumentStatus', - 'verificationFieldsNeeded', - 'zip' + 'verificationDueBy', + 'verificationFieldsNeeded' ]); testForBelongsTo('stripe-connect-account', 'organization');