diff --git a/lib/coprl/presenters/plugins/stripe/components/credit_card_form.rb b/lib/coprl/presenters/plugins/stripe/components/credit_card_form.rb index 2f9a2d4..6b75e1f 100644 --- a/lib/coprl/presenters/plugins/stripe/components/credit_card_form.rb +++ b/lib/coprl/presenters/plugins/stripe/components/credit_card_form.rb @@ -9,12 +9,14 @@ class CreditCardForm < DSL::Components::EventBase attr_reader :stripe_publishable_key, :address_config, + :required_fields, :currency, :form_type def initialize(stripe_publishable_key, **attribs, &block) @stripe_publishable_key = stripe_publishable_key @address_config = attribs.delete(:address_config){ {} } + @required_fields = attribs.delete(:required_fields){ [] } @currency = attribs.delete(:currency){ 'usd' } @form_type = attribs[:form_type] || :multi_line diff --git a/views/assets/js/credit_card_form.js b/views/assets/js/credit_card_form.js index 284b949..90b3304 100644 --- a/views/assets/js/credit_card_form.js +++ b/views/assets/js/credit_card_form.js @@ -69,9 +69,10 @@ } stripeTokenData() { - let data = {currency: this.data.currency} + let data = {currency: this.data.currency, missing: []} if (this.data.addressConfig && this.formType !== 'single_line') { const config = JSON.parse(this.data.addressConfig); + const requiredFields = JSON.parse(this.data.requiredFields); for (let field in config) { let value = config[field] if (Array.isArray(value)) { @@ -82,6 +83,9 @@ else{ data[field] = document.getElementsByName(value)[0] ? document.getElementsByName(value)[0].value : ''; } + if (requiredFields.includes(field) && !data[field]) { + data['missing'].push(field); + } } } return data; @@ -95,33 +99,55 @@ if (plugin && plugin.vPlugin) { plugin = plugin.vPlugin targetComponent.disable(); - plugin.stripe.createToken(plugin.cardNumber, plugin.stripeTokenData()).then(function (response) { - if (response.token) { - const result = {action: 'tokenize_credit_card', content: {onetime_token: response.token.id}, statusCode: 200}; - result.content = JSON.stringify(result.content); - results.push(result); - resolve(results); - } else { - const message = response.error.message; - const bad_result = { - action: 'tokenize_credit_card', - contentType: 'application/json', - content: {errors: message}, - statusCode: 400 - }; - bad_result.content = JSON.stringify(bad_result.content); - results.push(bad_result); - targetComponent.enable(); - reject(results); - } - }); + let tokenData = plugin.stripeTokenData(); + if (tokenData['missing'].length === 0) { // Don't attempt to tokenize if any required field is missing + delete tokenData['missing']; + plugin.stripe.createToken(plugin.cardNumber, tokenData).then(function (response) { + if (response.token) { + const result = { + action: 'tokenize_credit_card', + content: { + onetime_token: response.token.id, + card: response.token.card, + client_ip: response.token.client_ip + }, + statusCode: 200 + }; + result.content = JSON.stringify(result.content); + results.push(result); + resolve(results); + } else { + results.push(errorResult(response.error.message)); + targetComponent.enable(); + reject(results); + } + }); + } else { + results.push(emptyResult()); + resolve(results); + } } else { - results.push({action: 'tokenize_credit_card', content: JSON.stringify({onetime_token: ''}), statusCode: 200}) + results.push(emptyResult()); resolve(results); } }); } + function errorResult(message) { + const bad_result = { + action: 'tokenize_credit_card', + contentType: 'application/json', + content: {errors: message}, + statusCode: 400 + }; + bad_result.content = JSON.stringify(bad_result.content); + return bad_result; + } + + function emptyResult() { + return {action: 'tokenize_credit_card', content: JSON.stringify({onetime_token: ''}), statusCode: 200} + } + function handleElementChange(event, element) { const mdcTextField = element.closest('.mdc-text-field'); const inputHintElement = element.closest('.v-column').querySelector('.mdc-text-field-helper-text'); diff --git a/views/components/application/_credit_card_form.erb b/views/components/application/_credit_card_form.erb index ebcee44..6150cf8 100644 --- a/views/components/application/_credit_card_form.erb +++ b/views/components/application/_credit_card_form.erb @@ -5,6 +5,7 @@ data-form-type="<%= comp.form_type %>" data-currency="<%= comp.currency %>" <% if comp.address_config %>data-address-config=<%= comp.address_config.to_json %><% end %> + <% if comp.required_fields %>data-required-fields=<%= comp.required_fields.to_json %><% end %> > <% if comp.form_type == :single_line %> <%= raw File.read(File.expand_path('_credit_card_form_single_line.html', __dir__) ) %>