Skip to content

Commit

Permalink
🚧
Browse files Browse the repository at this point in the history
  • Loading branch information
josemigallas committed Oct 19, 2022
1 parent 2940931 commit f162381
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 79 deletions.
35 changes: 35 additions & 0 deletions app/javascript/packs/braintree_edit_form.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// @flow
// TODO: we can probably re-use BraintreeForm here
/* eslint-disable no-unused-expressions */

import braintree from 'braintree-web'
import { createBraintreeClient, createHostedFieldsInstance, hostedFieldOptions } from 'PaymentGateways/braintree/braintree'
import { error } from 'utilities/alert'

document.addEventListener('DOMContentLoaded', async () => {
const submit = document.querySelector('button[type="submit"]')
const data = document.querySelector('#braintree_data')
const form = document.querySelector('form#new_customer')

if (!submit || !data || !form) {
throw new Error('Required Element not found')
}
const authorization = data.dataset?.authorization || ''

const client = await createBraintreeClient(braintree.client, authorization)
const instance = await createHostedFieldsInstance(braintree.hostedFields, client, hostedFieldOptions)

submit.removeAttribute('disabled')
form.addEventListener('submit', (event: Event) => {
event.preventDefault()
event.stopPropagation()
instance.tokenize((tokenizeErr, payload) => {
if (tokenizeErr) {
error('Some of the credit card details are wrong. Please update them.')
} else {
document.querySelector('input#braintree_nonce')?.setAttribute('value', payload.nonce)
;((form: any): HTMLFormElement).submit()
}
})
})
})
20 changes: 12 additions & 8 deletions app/javascript/src/PaymentGateways/braintree/braintree.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,20 +85,24 @@ const createHostedFieldsInstance = (
hostedFields: any,
clientInstance: any,
hostedFieldOptions: HostedFieldsOptions,
setIsCardValid: (cardValid: boolean) => void,
setCardError: (err: string | null) => void
setIsCardValid?: (cardValid: boolean) => void,
setCardError?: (err: string | null) => void
): any => {
return hostedFields.create({
...hostedFieldOptions,
client: clientInstance
})
.then((hostedFieldsInstance) => {
hostedFieldsInstance.on('validityChange', () => {
const state = hostedFieldsInstance.getState()
const cardValid = Object.keys(state.fields).every((key) => state.fields[key].isValid)
setIsCardValid(cardValid)
})
hostedFieldsInstance.on('focus', () => setCardError(null))
if (setIsCardValid) {
hostedFieldsInstance.on('validityChange', () => {
const state = hostedFieldsInstance.getState()
const cardValid = Object.keys(state.fields).every((key) => state.fields[key].isValid)
setIsCardValid(cardValid)
})
}
if (setCardError) {
hostedFieldsInstance.on('focus', () => setCardError(null))
}
return hostedFieldsInstance
})
.catch(error => console.error(error))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,74 +92,7 @@ p

= render partial: '/shared/legal_terms_for_cc_details'
= form.actions do
= form.commit_button 'Save credit card'
= form.commit_button 'Save credit card', button_html: { disabled: true }

/ TODO: All is duplicated. Move this into a pack and use braintree from node_modules
script src="https://js.braintreegateway.com/web/3.69.0/js/client.min.js"
script src="https://js.braintreegateway.com/web/3.69.0/js/hosted-fields.min.js"
javascript:
const form = document.querySelector('form#new_customer');
const submit = document.querySelector('button[type="submit"]');
if (typeof braintree !== 'undefined') {
braintree.client.create({
authorization: '#{j @braintree_authorization}'
}, function(clientErr, clientInstance) {
if (clientErr) {
console.error(clientErr);
return;
}
// This example shows Hosted Fields, but you can also use this
// client instance to create additional components here, such as:qa
// PayPal or Data Collector.
braintree.hostedFields.create({
client: clientInstance,
styles: {
'input': {
'font-size': '14px'
},
'input.invalid': {
'color': 'red'
},
'input.valid': {
'color': 'green'
}
},
fields: {
number: {
selector: '#customer_credit_card_number',
placeholder: '4111 1111 1111 1111'
},
cvv: {
selector: '#customer_credit_card_cvv',
placeholder: '123'
},
expirationDate: {
selector: '#customer_credit_card_expiration_date',
placeholder: 'MM/YY'
}
}
}, function(hostedFieldsErr, hostedFieldsInstance) {
if (hostedFieldsErr) {
console.error(hostedFieldsErr);
return;
}
submit.removeAttribute('disabled');
form.addEventListener('submit', function(event) {
event.preventDefault();
event.stopPropagation();
hostedFieldsInstance.tokenize(function(tokenizeErr, payload) {
if (tokenizeErr) {
console.error(tokenizeErr);
return;
}
document.querySelector('input#braintree_nonce').setAttribute('value', payload.nonce);
form.submit();
});
});
});
})
}
span#braintree_data data-authorization="#{j @braintree_authorization}"
= javascript_pack_tag 'braintree_edit_form'
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
@javascript
Feature: Credit card details
In order to pay for the service
As a provider
Expand Down
2 changes: 1 addition & 1 deletion features/step_definitions/credit_card_steps.rb
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@
# TODO: Would be better to not rely on this kind of variables
if @javascript
page.evaluate_script("document.querySelector('#braintree_nonce').value = 'some_braintree_nonce'")
page.evaluate_script("document.querySelector('.btn-primary').disabled = false")
page.evaluate_script("document.querySelector('input[type=\"submit\"]').disabled = false")
else
find(:css, '#braintree_nonce', visible: :hidden).set('some_braintree_nonce')
end
Expand Down
6 changes: 6 additions & 0 deletions features/support/hooks.rb
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,12 @@
end

Before '@braintree' do
stub_request(:get, 'https://payments.sandbox.braintree-api.com/graphql')
.to_return(status: 200, body: '', headers: {})
stub_request(:post, %r{https://origin-analytics-sand.sandbox.braintree-api.com/.+})
.to_return(status: 200, body: '', headers: {})
stub_request(:get, %r{https://api.sandbox.braintreegateway.com:443/merchants/.+/client_api/v1/})
.to_return(status: 200, body: '', headers: {})
stub_request(:delete, %r{@sandbox.braintreegateway.com/merchants/.+/customers/valid_code})
.to_return(status: 200, body: '', headers: {})
end
Expand Down

0 comments on commit f162381

Please sign in to comment.