1

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?

halfer
  • 19,824
  • 17
  • 99
  • 186
Richlewis
  • 15,070
  • 37
  • 122
  • 283

0 Answers0