This may not be possible and I may be misunderstanding the api but i was looking to submit my Braintree payment via Ajax in Rails 4.
I've got a simple form setup (omitted fields to keep it small) and it is setup to fail in this instance so that i can show an error message
<%= form_tag transactions_path, id: 'braintree-transaction-form', remote: true do %>
<%= text_field_tag :first_name, "", placeholder: 'First Name', required: false %>
<%= text_field_tag :last_name, "", placeholder: 'Last Name', required: false %>
<% end %>
Drop in form JS
braintree.setup(gon.client_token, 'dropin', {
container: 'dropin'
});
Controller
def new
gon.client_token = generate_client_token
end
def create
@result = Braintree::Transaction.sale(
amount: 2500,
payment_method_nonce: params[:payment_method_nonce],
customer: {
first_name: params[:first_name],
last_name: params[:last_name],
options: {
submit_for_settlement: true
}
)
if @result.success?
redirect_to thank_you_path
else
respond_to do |format|
@error_message = BraintreeErrors::Errors.new.error_message(@result)
format.js { flash.now[:error] = @error_message }
end
end
end
When I submit the form I get this in the console
Processing by TransactionsController#create as JS
Parameters: {"utf8"=>"✓", "first_name"=>"", "last_name"=>"", "payment_method_nonce"=>"", "commit"=>"Pay £2500"}
and the response
#<Braintree::Errors transaction:[(91508) Cannot determine payment method.], transaction/credit_card:[(81706) CVV is required.], >
So the card details are not even being submitted to the Braintree servers.
Can I not submit my form via Ajax in this way or do i have to construct the Ajax call using jQuery, adding to the existing braintree.setup
?
Update
So on page load the nonce is not set
<input type="hidden" name="payment_method_nonce" value>
So I remove the data remote: true option and submitted the form and noticed that the nonce is generated on form submission
<input type="hidden" name="payment_method_nonce" value="nonce-value-here">
I then set the form back to remote: true and watched the nonce value be generated again but this time same issue where card details not set.
Some further reading and I have come across this post; it seems like I need to modify my setup script to
braintree.setup(gon.client_token, 'dropin', {
container: 'dropin',
onPaymentMethodReceived: function (paymentMethod) {
$('#braintree-transaction-form').append("<input type='hidden' name='payment_method_nonce' value='" + paymentMethod.nonce + "'></input>");
$('#braintree-transaction-form').submit();
}
});
I notice the docs also state
Note: If
onPaymentMethodReceived
is defined, braintree.js will not add a hidden input to your form, inject the nonce into that hidden input, or submit the form. Upon receiving a nonce, it is up to you to send data to your server as you see fit.
So I've appended the nonce to the form but the form gets submitted twice, once by the first click and then again within the onPaymentMethodReceived
function.
How can I only submit the form through the callback?