Adding Bank Account data to stripe not saving to API or database table











up vote
0
down vote

favorite












Issue: The Bank Account data in the form isn't saving to the Stripe API (Stripe::Account), possibly because it's not being correctly or successfully Stripe::Account.retrieve(current_user.stripe_token)



Question: What in my code is causing the retrieve to not work or is the issue something else, such as not having webhooks correctly set up, or incorrect JS?



My Thoughts: I am assuming it's not the controller, but the way the JS is set up as I am not well versed in JS. I found an example application on GitHub using Stripe Connect the way I want it to function and used it as a reference to build my BankAccount controller, view/form, and JS.



This is the sample application for reference I have used to help me set this up: https://stripe-marketplace-demo.herokuapp.com/



How it's set up: I have Users table ; users sign up and get inputted into this User Table. I then have a StripeAccounts table; users (current_user) can create a StripeAccount, the stripe account token is saved as acct_id within StripeAccount >> the user_id (from User table) is associated with the StripeAccount. The stripe_account token is also saved in the User table under stripe_token. Once a stripe_account is created and saved, they are redirected to fill out the BankAccount form << This is where my issues are. The bank account information isn't saving and most likely due to a failure to retrieve. Reasoning below.



Here's the entire Bank Account Controller:



class BankAccountsController < ApplicationController
before_action :authenticate_user!

def new

unless current_user.stripe_token
redirect_to new_user_stripe_account_path and return
end

begin
@stripe_account = Stripe::Account.retrieve(current_user.stripe_token)

rescue Stripe::StripeError => e
handle_error(e.message, 'new')

rescue => e
flash[:error] = e.message
end
end

def create

unless params[:stripeToken] && current_user.stripe_token
redirect_to new_bank_account_path and return
end

begin
stripe_account = Stripe::Account.retrieve(current_user.stripe_token)

stripe_account.external_account = params[:stripeToken]
stripe_account.save

flash[:success] = "Your bank account has been added!"
redirect_to dashboard_path

rescue Stripe::StripeError => e
flash[:error] = e.message


rescue => e
flash[:error] = e.message

end
end
end


I have the stripe_accounts saving correctly with the stripe token saved under "acct_id" in the StripeAccounts table, and the same token saved as "stripe_token" under the Users table in relation to the correct user_id.



I am new to rails (about a month in) and very new to Stripe so the following is only assumption: I am assuming the "@stripe_account = Stripe::Account.retrieve(current_user.stripe_token)" in the new method isn't retrieving anything. Does this rely on webhooks? That I may not have set up correctly? I have tried doing this through ngrok, but to no avail. Although, I receive no errors on page in html.
I would then assume I'm getting stuck at the code in the create method:



  unless params[:stripeToken] && current_user.stripe_token
redirect_to new_bank_account_path and return
end


Because when i press submit, the page simply reloads and nothing saves to the API.



Here's the view/form I am submitting along with the JS:



<%= content_for :page_title, "Add a new bank account" %>
<% content_for(:header) do %>
<script src="https://js.stripe.com/v3/"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.payment/1.4.1/jquery.payment.js"></script>
<script>
// Set your Stripe publishable API key here
// Stripe.setPublishableKey("<%= ENV['PUBLISHABLE_KEY'] %>");
var stripe = Stripe('pk_test_3v1234567896LyWMYKE1f0B8');

$(function() {
var $form = $('#payment-form');
$form.submit(function(event) {
// Clear any errors
$form.find('.has-error').removeClass('has-error');
// Disable the submit button to prevent repeated clicks:
$form.find('.submit').prop('disabled', true).html("<i class='fa fa-spinner fa-spin'></i> Adding bank account...");
// Request a token from Stripe:
Stripe.bankAccount.createToken($form, stripeResponseHandler);


return false;
});
});
function stripeResponseHandler(status, response) {
var $form = $('#payment-form');
if (response.error) {

$form.find('.errors').text(response.error.message).addClass('alert alert-danger');
$form.find('.' + response.error.param).parent('.form-group').addClass('has-error');
$form.find('button').prop('disabled', false).text('Add Bank Account'); // Re-enable submission
}
else { // Token was created!
$form.find('.submit').html("<i class='fa fa-check'></i> Account added");

var token = response.id;

$form.append($('<input type="hidden" name="stripeToken" />').val(token));

$form.get(0).submit();
}
}
</script>
<% end %>

<div class="panel panel-default">
<div class="panel-body">
<form action="/bank_accounts" method="POST" id="payment-form">
<div class="errors"></div>
<div class="row">
<div class="col-md-8">
<div class="form-group">
<label>Country</label>
<select class="form-control input-lg" id="country" data-stripe="country">
<option value="US">United States</option>
</select>
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label>Currency</label>
<select class="form-control input-lg" id="currency" data-stripe="currency">
<option value="usd">USD</option>
</select>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6" id="routing_number_div">
<div class="form-group">
<label id="routing_number_label">Routing Number</label>
<input class="form-control input-lg bank_account" id="routing_number" type="tel" size="12" data-stripe="routing_number" value="110000000" autocomplete="off">
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label id="account_number_label">Account Number</label>
<input class="form-control input-lg bank_account" id="account_number" type="tel" size="20" data-stripe="account_number" value="000123456789" autocomplete="off">
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<button class="btn btn-lg btn-block btn-primary btn-custom submit" type="submit">Add Bank Account</button>
</div>
</div>
<%= hidden_field_tag :authenticity_token, form_authenticity_token -%>
</form>
</div>
</div>


As you see in the JS: // Stripe.setPublishableKey("<%= ENV['PUBLISHABLE_KEY'] %>");
I have tried with that, but apparently it's not up to date anymore. Just for testing purposes, I have simply included the publishable key directly within the JS and not in credentials just yet until I figure it out.



Here is my console when I submit the form:



Started POST "/bank_accounts" for 127.0.0.1 at 2018-11-10 14:32:11 -0500
Processing by BankAccountsController#create as HTML
Parameters: {"authenticity_token"=>"l69UBGkzwcel7JH34+TDbsfQ9Xjkiogu+emWm+8+0iVQfKh9AIxDaXp0yMhjFkUVznHeJYwXeVmdBVSI2XjArg=="}
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ? [["id", 2], ["LIMIT", 1]]
↳ /home/bob/.rvm/gems/ruby-2.5.1/gems/activerecord-5.2.1/lib/active_record/log_subscriber.rb:98
Redirected to http://localhost:3000/bank_accounts/new
Completed 302 Found in 4ms (ActiveRecord: 0.3ms)


Started GET "/bank_accounts/new" for 127.0.0.1 at 2018-11-10 14:32:11 -0500
Processing by BankAccountsController#new as HTML
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ? [["id", 2], ["LIMIT", 1]]
↳ /home/bob/.rvm/gems/ruby-2.5.1/gems/activerecord-5.2.1/lib/active_record/log_subscriber.rb:98
StripeAccount Load (0.2ms) SELECT "stripe_accounts".* FROM "stripe_accounts" WHERE "stripe_accounts"."user_id" = ? LIMIT ? [["user_id", 2], ["LIMIT", 1]]
↳ app/controllers/bank_accounts_controller.rb:6
Rendering bank_accounts/new.html.erb within layouts/application
Rendered bank_accounts/_bank_account_form.html.erb (1.0ms)
Rendered bank_accounts/new.html.erb within layouts/application (4.2ms)
Rendered layouts/_navbar.html.erb (3.0ms)
Rendered layouts/_footer.html.erb (0.3ms)
Completed 200 OK in 218ms (Views: 212.4ms | ActiveRecord: 0.5ms)


the e.message reads as follows:



Invalid external_account object: must be a dictionary or a non-empty string. See API docs at https://stripe.com/docs'


but the e.message only appears on page reload and not when the form is submitted. Only once I submit, and then reload the page, it appears.



I having nothing set up within the BankAccount model, either does the example app i used as a reference.



Extra information: For Users and StripeAccount, I have them nested, which is why you will see new_user_stripe_account_path... BankAccount isn't nested to anything.



Message from Browser Console:



Error: The selector you specified (#card-element) applies to no DOM elements that are currently on the page.
Make sure the element exists on the page before calling mount(). v3:1:10186
t
https://js.stripe.com/v3/:1:10186
oi/this.mount<
https://js.stripe.com/v3/:1:79868
Gt/<
https://js.stripe.com/v3/:1:23367
<anonymous>
http://localhost:3000/assets/stripejs.self-8c2ad75855f867e5280e1a173e994f83fb5afc997847456669b8cbe0b24fae1f.js:31:1
[Exception... "Component returned failure code: 0x80040111 (NS_ERROR_NOT_AVAILABLE) [nsIContentSniffer.getMIMETypeFromContent]" nsresult: "0x80040111 (NS_ERROR_NOT_AVAILABLE)" location: "JS frame :: resource:///modules/FaviconLoader.jsm :: onStopRequest :: line 181" data: no]
onStopRequest
resource:///modules/FaviconLoader.jsm:181:16
InterpretGeneratorResume self-hosted:1257:8 next self-hosted:1212:9









share|improve this question
























  • Because you are getting an error like "must be a dictionary or a non-empty string" , I suspect your bank account token is never getting passed to your back-end at all --- in fact i don't see it in the log you shared Parameters: {"authenticity_token"=>"l69UBGkzwcel7JH34+TDbsfQ9Xjkiogu+emWm+8+0iVQfKh9AIxDaXp0yMhjFkUVznHeJYwXeVmdBVSI2XjArg=="} --- try adding some debugging to your JS --- console.logs in your stripeResponseHandler, a breakpoint before the form submit (check that a hidden stripeToken input really exists in your form using browser dev tools inspector)
    – duck
    Nov 11 at 19:54










  • I added the Browser Console when i press submit. Other than that, do you think the rest of the code is okay?
    – uno
    Nov 11 at 23:56










  • BTW, "check that a hidden stripetoken input exists"... is that something I'll see in the Browser console...? and in the update, it's not there if so?
    – uno
    Nov 12 at 0:20










  • So it looks like, from what i understand, is the JS is for Stripe V2 and not Stripe V3 you can see the differences here: V2:stripe.com/docs/stripe-js/v2#collecting-bank-account-details ----V3:stripe.com/docs/stripe-js/… ----- so im trying to migrate it over to v3
    – uno
    Nov 12 at 2:53

















up vote
0
down vote

favorite












Issue: The Bank Account data in the form isn't saving to the Stripe API (Stripe::Account), possibly because it's not being correctly or successfully Stripe::Account.retrieve(current_user.stripe_token)



Question: What in my code is causing the retrieve to not work or is the issue something else, such as not having webhooks correctly set up, or incorrect JS?



My Thoughts: I am assuming it's not the controller, but the way the JS is set up as I am not well versed in JS. I found an example application on GitHub using Stripe Connect the way I want it to function and used it as a reference to build my BankAccount controller, view/form, and JS.



This is the sample application for reference I have used to help me set this up: https://stripe-marketplace-demo.herokuapp.com/



How it's set up: I have Users table ; users sign up and get inputted into this User Table. I then have a StripeAccounts table; users (current_user) can create a StripeAccount, the stripe account token is saved as acct_id within StripeAccount >> the user_id (from User table) is associated with the StripeAccount. The stripe_account token is also saved in the User table under stripe_token. Once a stripe_account is created and saved, they are redirected to fill out the BankAccount form << This is where my issues are. The bank account information isn't saving and most likely due to a failure to retrieve. Reasoning below.



Here's the entire Bank Account Controller:



class BankAccountsController < ApplicationController
before_action :authenticate_user!

def new

unless current_user.stripe_token
redirect_to new_user_stripe_account_path and return
end

begin
@stripe_account = Stripe::Account.retrieve(current_user.stripe_token)

rescue Stripe::StripeError => e
handle_error(e.message, 'new')

rescue => e
flash[:error] = e.message
end
end

def create

unless params[:stripeToken] && current_user.stripe_token
redirect_to new_bank_account_path and return
end

begin
stripe_account = Stripe::Account.retrieve(current_user.stripe_token)

stripe_account.external_account = params[:stripeToken]
stripe_account.save

flash[:success] = "Your bank account has been added!"
redirect_to dashboard_path

rescue Stripe::StripeError => e
flash[:error] = e.message


rescue => e
flash[:error] = e.message

end
end
end


I have the stripe_accounts saving correctly with the stripe token saved under "acct_id" in the StripeAccounts table, and the same token saved as "stripe_token" under the Users table in relation to the correct user_id.



I am new to rails (about a month in) and very new to Stripe so the following is only assumption: I am assuming the "@stripe_account = Stripe::Account.retrieve(current_user.stripe_token)" in the new method isn't retrieving anything. Does this rely on webhooks? That I may not have set up correctly? I have tried doing this through ngrok, but to no avail. Although, I receive no errors on page in html.
I would then assume I'm getting stuck at the code in the create method:



  unless params[:stripeToken] && current_user.stripe_token
redirect_to new_bank_account_path and return
end


Because when i press submit, the page simply reloads and nothing saves to the API.



Here's the view/form I am submitting along with the JS:



<%= content_for :page_title, "Add a new bank account" %>
<% content_for(:header) do %>
<script src="https://js.stripe.com/v3/"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.payment/1.4.1/jquery.payment.js"></script>
<script>
// Set your Stripe publishable API key here
// Stripe.setPublishableKey("<%= ENV['PUBLISHABLE_KEY'] %>");
var stripe = Stripe('pk_test_3v1234567896LyWMYKE1f0B8');

$(function() {
var $form = $('#payment-form');
$form.submit(function(event) {
// Clear any errors
$form.find('.has-error').removeClass('has-error');
// Disable the submit button to prevent repeated clicks:
$form.find('.submit').prop('disabled', true).html("<i class='fa fa-spinner fa-spin'></i> Adding bank account...");
// Request a token from Stripe:
Stripe.bankAccount.createToken($form, stripeResponseHandler);


return false;
});
});
function stripeResponseHandler(status, response) {
var $form = $('#payment-form');
if (response.error) {

$form.find('.errors').text(response.error.message).addClass('alert alert-danger');
$form.find('.' + response.error.param).parent('.form-group').addClass('has-error');
$form.find('button').prop('disabled', false).text('Add Bank Account'); // Re-enable submission
}
else { // Token was created!
$form.find('.submit').html("<i class='fa fa-check'></i> Account added");

var token = response.id;

$form.append($('<input type="hidden" name="stripeToken" />').val(token));

$form.get(0).submit();
}
}
</script>
<% end %>

<div class="panel panel-default">
<div class="panel-body">
<form action="/bank_accounts" method="POST" id="payment-form">
<div class="errors"></div>
<div class="row">
<div class="col-md-8">
<div class="form-group">
<label>Country</label>
<select class="form-control input-lg" id="country" data-stripe="country">
<option value="US">United States</option>
</select>
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label>Currency</label>
<select class="form-control input-lg" id="currency" data-stripe="currency">
<option value="usd">USD</option>
</select>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6" id="routing_number_div">
<div class="form-group">
<label id="routing_number_label">Routing Number</label>
<input class="form-control input-lg bank_account" id="routing_number" type="tel" size="12" data-stripe="routing_number" value="110000000" autocomplete="off">
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label id="account_number_label">Account Number</label>
<input class="form-control input-lg bank_account" id="account_number" type="tel" size="20" data-stripe="account_number" value="000123456789" autocomplete="off">
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<button class="btn btn-lg btn-block btn-primary btn-custom submit" type="submit">Add Bank Account</button>
</div>
</div>
<%= hidden_field_tag :authenticity_token, form_authenticity_token -%>
</form>
</div>
</div>


As you see in the JS: // Stripe.setPublishableKey("<%= ENV['PUBLISHABLE_KEY'] %>");
I have tried with that, but apparently it's not up to date anymore. Just for testing purposes, I have simply included the publishable key directly within the JS and not in credentials just yet until I figure it out.



Here is my console when I submit the form:



Started POST "/bank_accounts" for 127.0.0.1 at 2018-11-10 14:32:11 -0500
Processing by BankAccountsController#create as HTML
Parameters: {"authenticity_token"=>"l69UBGkzwcel7JH34+TDbsfQ9Xjkiogu+emWm+8+0iVQfKh9AIxDaXp0yMhjFkUVznHeJYwXeVmdBVSI2XjArg=="}
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ? [["id", 2], ["LIMIT", 1]]
↳ /home/bob/.rvm/gems/ruby-2.5.1/gems/activerecord-5.2.1/lib/active_record/log_subscriber.rb:98
Redirected to http://localhost:3000/bank_accounts/new
Completed 302 Found in 4ms (ActiveRecord: 0.3ms)


Started GET "/bank_accounts/new" for 127.0.0.1 at 2018-11-10 14:32:11 -0500
Processing by BankAccountsController#new as HTML
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ? [["id", 2], ["LIMIT", 1]]
↳ /home/bob/.rvm/gems/ruby-2.5.1/gems/activerecord-5.2.1/lib/active_record/log_subscriber.rb:98
StripeAccount Load (0.2ms) SELECT "stripe_accounts".* FROM "stripe_accounts" WHERE "stripe_accounts"."user_id" = ? LIMIT ? [["user_id", 2], ["LIMIT", 1]]
↳ app/controllers/bank_accounts_controller.rb:6
Rendering bank_accounts/new.html.erb within layouts/application
Rendered bank_accounts/_bank_account_form.html.erb (1.0ms)
Rendered bank_accounts/new.html.erb within layouts/application (4.2ms)
Rendered layouts/_navbar.html.erb (3.0ms)
Rendered layouts/_footer.html.erb (0.3ms)
Completed 200 OK in 218ms (Views: 212.4ms | ActiveRecord: 0.5ms)


the e.message reads as follows:



Invalid external_account object: must be a dictionary or a non-empty string. See API docs at https://stripe.com/docs'


but the e.message only appears on page reload and not when the form is submitted. Only once I submit, and then reload the page, it appears.



I having nothing set up within the BankAccount model, either does the example app i used as a reference.



Extra information: For Users and StripeAccount, I have them nested, which is why you will see new_user_stripe_account_path... BankAccount isn't nested to anything.



Message from Browser Console:



Error: The selector you specified (#card-element) applies to no DOM elements that are currently on the page.
Make sure the element exists on the page before calling mount(). v3:1:10186
t
https://js.stripe.com/v3/:1:10186
oi/this.mount<
https://js.stripe.com/v3/:1:79868
Gt/<
https://js.stripe.com/v3/:1:23367
<anonymous>
http://localhost:3000/assets/stripejs.self-8c2ad75855f867e5280e1a173e994f83fb5afc997847456669b8cbe0b24fae1f.js:31:1
[Exception... "Component returned failure code: 0x80040111 (NS_ERROR_NOT_AVAILABLE) [nsIContentSniffer.getMIMETypeFromContent]" nsresult: "0x80040111 (NS_ERROR_NOT_AVAILABLE)" location: "JS frame :: resource:///modules/FaviconLoader.jsm :: onStopRequest :: line 181" data: no]
onStopRequest
resource:///modules/FaviconLoader.jsm:181:16
InterpretGeneratorResume self-hosted:1257:8 next self-hosted:1212:9









share|improve this question
























  • Because you are getting an error like "must be a dictionary or a non-empty string" , I suspect your bank account token is never getting passed to your back-end at all --- in fact i don't see it in the log you shared Parameters: {"authenticity_token"=>"l69UBGkzwcel7JH34+TDbsfQ9Xjkiogu+emWm+8+0iVQfKh9AIxDaXp0yMhjFkUVznHeJYwXeVmdBVSI2XjArg=="} --- try adding some debugging to your JS --- console.logs in your stripeResponseHandler, a breakpoint before the form submit (check that a hidden stripeToken input really exists in your form using browser dev tools inspector)
    – duck
    Nov 11 at 19:54










  • I added the Browser Console when i press submit. Other than that, do you think the rest of the code is okay?
    – uno
    Nov 11 at 23:56










  • BTW, "check that a hidden stripetoken input exists"... is that something I'll see in the Browser console...? and in the update, it's not there if so?
    – uno
    Nov 12 at 0:20










  • So it looks like, from what i understand, is the JS is for Stripe V2 and not Stripe V3 you can see the differences here: V2:stripe.com/docs/stripe-js/v2#collecting-bank-account-details ----V3:stripe.com/docs/stripe-js/… ----- so im trying to migrate it over to v3
    – uno
    Nov 12 at 2:53















up vote
0
down vote

favorite









up vote
0
down vote

favorite











Issue: The Bank Account data in the form isn't saving to the Stripe API (Stripe::Account), possibly because it's not being correctly or successfully Stripe::Account.retrieve(current_user.stripe_token)



Question: What in my code is causing the retrieve to not work or is the issue something else, such as not having webhooks correctly set up, or incorrect JS?



My Thoughts: I am assuming it's not the controller, but the way the JS is set up as I am not well versed in JS. I found an example application on GitHub using Stripe Connect the way I want it to function and used it as a reference to build my BankAccount controller, view/form, and JS.



This is the sample application for reference I have used to help me set this up: https://stripe-marketplace-demo.herokuapp.com/



How it's set up: I have Users table ; users sign up and get inputted into this User Table. I then have a StripeAccounts table; users (current_user) can create a StripeAccount, the stripe account token is saved as acct_id within StripeAccount >> the user_id (from User table) is associated with the StripeAccount. The stripe_account token is also saved in the User table under stripe_token. Once a stripe_account is created and saved, they are redirected to fill out the BankAccount form << This is where my issues are. The bank account information isn't saving and most likely due to a failure to retrieve. Reasoning below.



Here's the entire Bank Account Controller:



class BankAccountsController < ApplicationController
before_action :authenticate_user!

def new

unless current_user.stripe_token
redirect_to new_user_stripe_account_path and return
end

begin
@stripe_account = Stripe::Account.retrieve(current_user.stripe_token)

rescue Stripe::StripeError => e
handle_error(e.message, 'new')

rescue => e
flash[:error] = e.message
end
end

def create

unless params[:stripeToken] && current_user.stripe_token
redirect_to new_bank_account_path and return
end

begin
stripe_account = Stripe::Account.retrieve(current_user.stripe_token)

stripe_account.external_account = params[:stripeToken]
stripe_account.save

flash[:success] = "Your bank account has been added!"
redirect_to dashboard_path

rescue Stripe::StripeError => e
flash[:error] = e.message


rescue => e
flash[:error] = e.message

end
end
end


I have the stripe_accounts saving correctly with the stripe token saved under "acct_id" in the StripeAccounts table, and the same token saved as "stripe_token" under the Users table in relation to the correct user_id.



I am new to rails (about a month in) and very new to Stripe so the following is only assumption: I am assuming the "@stripe_account = Stripe::Account.retrieve(current_user.stripe_token)" in the new method isn't retrieving anything. Does this rely on webhooks? That I may not have set up correctly? I have tried doing this through ngrok, but to no avail. Although, I receive no errors on page in html.
I would then assume I'm getting stuck at the code in the create method:



  unless params[:stripeToken] && current_user.stripe_token
redirect_to new_bank_account_path and return
end


Because when i press submit, the page simply reloads and nothing saves to the API.



Here's the view/form I am submitting along with the JS:



<%= content_for :page_title, "Add a new bank account" %>
<% content_for(:header) do %>
<script src="https://js.stripe.com/v3/"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.payment/1.4.1/jquery.payment.js"></script>
<script>
// Set your Stripe publishable API key here
// Stripe.setPublishableKey("<%= ENV['PUBLISHABLE_KEY'] %>");
var stripe = Stripe('pk_test_3v1234567896LyWMYKE1f0B8');

$(function() {
var $form = $('#payment-form');
$form.submit(function(event) {
// Clear any errors
$form.find('.has-error').removeClass('has-error');
// Disable the submit button to prevent repeated clicks:
$form.find('.submit').prop('disabled', true).html("<i class='fa fa-spinner fa-spin'></i> Adding bank account...");
// Request a token from Stripe:
Stripe.bankAccount.createToken($form, stripeResponseHandler);


return false;
});
});
function stripeResponseHandler(status, response) {
var $form = $('#payment-form');
if (response.error) {

$form.find('.errors').text(response.error.message).addClass('alert alert-danger');
$form.find('.' + response.error.param).parent('.form-group').addClass('has-error');
$form.find('button').prop('disabled', false).text('Add Bank Account'); // Re-enable submission
}
else { // Token was created!
$form.find('.submit').html("<i class='fa fa-check'></i> Account added");

var token = response.id;

$form.append($('<input type="hidden" name="stripeToken" />').val(token));

$form.get(0).submit();
}
}
</script>
<% end %>

<div class="panel panel-default">
<div class="panel-body">
<form action="/bank_accounts" method="POST" id="payment-form">
<div class="errors"></div>
<div class="row">
<div class="col-md-8">
<div class="form-group">
<label>Country</label>
<select class="form-control input-lg" id="country" data-stripe="country">
<option value="US">United States</option>
</select>
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label>Currency</label>
<select class="form-control input-lg" id="currency" data-stripe="currency">
<option value="usd">USD</option>
</select>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6" id="routing_number_div">
<div class="form-group">
<label id="routing_number_label">Routing Number</label>
<input class="form-control input-lg bank_account" id="routing_number" type="tel" size="12" data-stripe="routing_number" value="110000000" autocomplete="off">
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label id="account_number_label">Account Number</label>
<input class="form-control input-lg bank_account" id="account_number" type="tel" size="20" data-stripe="account_number" value="000123456789" autocomplete="off">
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<button class="btn btn-lg btn-block btn-primary btn-custom submit" type="submit">Add Bank Account</button>
</div>
</div>
<%= hidden_field_tag :authenticity_token, form_authenticity_token -%>
</form>
</div>
</div>


As you see in the JS: // Stripe.setPublishableKey("<%= ENV['PUBLISHABLE_KEY'] %>");
I have tried with that, but apparently it's not up to date anymore. Just for testing purposes, I have simply included the publishable key directly within the JS and not in credentials just yet until I figure it out.



Here is my console when I submit the form:



Started POST "/bank_accounts" for 127.0.0.1 at 2018-11-10 14:32:11 -0500
Processing by BankAccountsController#create as HTML
Parameters: {"authenticity_token"=>"l69UBGkzwcel7JH34+TDbsfQ9Xjkiogu+emWm+8+0iVQfKh9AIxDaXp0yMhjFkUVznHeJYwXeVmdBVSI2XjArg=="}
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ? [["id", 2], ["LIMIT", 1]]
↳ /home/bob/.rvm/gems/ruby-2.5.1/gems/activerecord-5.2.1/lib/active_record/log_subscriber.rb:98
Redirected to http://localhost:3000/bank_accounts/new
Completed 302 Found in 4ms (ActiveRecord: 0.3ms)


Started GET "/bank_accounts/new" for 127.0.0.1 at 2018-11-10 14:32:11 -0500
Processing by BankAccountsController#new as HTML
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ? [["id", 2], ["LIMIT", 1]]
↳ /home/bob/.rvm/gems/ruby-2.5.1/gems/activerecord-5.2.1/lib/active_record/log_subscriber.rb:98
StripeAccount Load (0.2ms) SELECT "stripe_accounts".* FROM "stripe_accounts" WHERE "stripe_accounts"."user_id" = ? LIMIT ? [["user_id", 2], ["LIMIT", 1]]
↳ app/controllers/bank_accounts_controller.rb:6
Rendering bank_accounts/new.html.erb within layouts/application
Rendered bank_accounts/_bank_account_form.html.erb (1.0ms)
Rendered bank_accounts/new.html.erb within layouts/application (4.2ms)
Rendered layouts/_navbar.html.erb (3.0ms)
Rendered layouts/_footer.html.erb (0.3ms)
Completed 200 OK in 218ms (Views: 212.4ms | ActiveRecord: 0.5ms)


the e.message reads as follows:



Invalid external_account object: must be a dictionary or a non-empty string. See API docs at https://stripe.com/docs'


but the e.message only appears on page reload and not when the form is submitted. Only once I submit, and then reload the page, it appears.



I having nothing set up within the BankAccount model, either does the example app i used as a reference.



Extra information: For Users and StripeAccount, I have them nested, which is why you will see new_user_stripe_account_path... BankAccount isn't nested to anything.



Message from Browser Console:



Error: The selector you specified (#card-element) applies to no DOM elements that are currently on the page.
Make sure the element exists on the page before calling mount(). v3:1:10186
t
https://js.stripe.com/v3/:1:10186
oi/this.mount<
https://js.stripe.com/v3/:1:79868
Gt/<
https://js.stripe.com/v3/:1:23367
<anonymous>
http://localhost:3000/assets/stripejs.self-8c2ad75855f867e5280e1a173e994f83fb5afc997847456669b8cbe0b24fae1f.js:31:1
[Exception... "Component returned failure code: 0x80040111 (NS_ERROR_NOT_AVAILABLE) [nsIContentSniffer.getMIMETypeFromContent]" nsresult: "0x80040111 (NS_ERROR_NOT_AVAILABLE)" location: "JS frame :: resource:///modules/FaviconLoader.jsm :: onStopRequest :: line 181" data: no]
onStopRequest
resource:///modules/FaviconLoader.jsm:181:16
InterpretGeneratorResume self-hosted:1257:8 next self-hosted:1212:9









share|improve this question















Issue: The Bank Account data in the form isn't saving to the Stripe API (Stripe::Account), possibly because it's not being correctly or successfully Stripe::Account.retrieve(current_user.stripe_token)



Question: What in my code is causing the retrieve to not work or is the issue something else, such as not having webhooks correctly set up, or incorrect JS?



My Thoughts: I am assuming it's not the controller, but the way the JS is set up as I am not well versed in JS. I found an example application on GitHub using Stripe Connect the way I want it to function and used it as a reference to build my BankAccount controller, view/form, and JS.



This is the sample application for reference I have used to help me set this up: https://stripe-marketplace-demo.herokuapp.com/



How it's set up: I have Users table ; users sign up and get inputted into this User Table. I then have a StripeAccounts table; users (current_user) can create a StripeAccount, the stripe account token is saved as acct_id within StripeAccount >> the user_id (from User table) is associated with the StripeAccount. The stripe_account token is also saved in the User table under stripe_token. Once a stripe_account is created and saved, they are redirected to fill out the BankAccount form << This is where my issues are. The bank account information isn't saving and most likely due to a failure to retrieve. Reasoning below.



Here's the entire Bank Account Controller:



class BankAccountsController < ApplicationController
before_action :authenticate_user!

def new

unless current_user.stripe_token
redirect_to new_user_stripe_account_path and return
end

begin
@stripe_account = Stripe::Account.retrieve(current_user.stripe_token)

rescue Stripe::StripeError => e
handle_error(e.message, 'new')

rescue => e
flash[:error] = e.message
end
end

def create

unless params[:stripeToken] && current_user.stripe_token
redirect_to new_bank_account_path and return
end

begin
stripe_account = Stripe::Account.retrieve(current_user.stripe_token)

stripe_account.external_account = params[:stripeToken]
stripe_account.save

flash[:success] = "Your bank account has been added!"
redirect_to dashboard_path

rescue Stripe::StripeError => e
flash[:error] = e.message


rescue => e
flash[:error] = e.message

end
end
end


I have the stripe_accounts saving correctly with the stripe token saved under "acct_id" in the StripeAccounts table, and the same token saved as "stripe_token" under the Users table in relation to the correct user_id.



I am new to rails (about a month in) and very new to Stripe so the following is only assumption: I am assuming the "@stripe_account = Stripe::Account.retrieve(current_user.stripe_token)" in the new method isn't retrieving anything. Does this rely on webhooks? That I may not have set up correctly? I have tried doing this through ngrok, but to no avail. Although, I receive no errors on page in html.
I would then assume I'm getting stuck at the code in the create method:



  unless params[:stripeToken] && current_user.stripe_token
redirect_to new_bank_account_path and return
end


Because when i press submit, the page simply reloads and nothing saves to the API.



Here's the view/form I am submitting along with the JS:



<%= content_for :page_title, "Add a new bank account" %>
<% content_for(:header) do %>
<script src="https://js.stripe.com/v3/"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.payment/1.4.1/jquery.payment.js"></script>
<script>
// Set your Stripe publishable API key here
// Stripe.setPublishableKey("<%= ENV['PUBLISHABLE_KEY'] %>");
var stripe = Stripe('pk_test_3v1234567896LyWMYKE1f0B8');

$(function() {
var $form = $('#payment-form');
$form.submit(function(event) {
// Clear any errors
$form.find('.has-error').removeClass('has-error');
// Disable the submit button to prevent repeated clicks:
$form.find('.submit').prop('disabled', true).html("<i class='fa fa-spinner fa-spin'></i> Adding bank account...");
// Request a token from Stripe:
Stripe.bankAccount.createToken($form, stripeResponseHandler);


return false;
});
});
function stripeResponseHandler(status, response) {
var $form = $('#payment-form');
if (response.error) {

$form.find('.errors').text(response.error.message).addClass('alert alert-danger');
$form.find('.' + response.error.param).parent('.form-group').addClass('has-error');
$form.find('button').prop('disabled', false).text('Add Bank Account'); // Re-enable submission
}
else { // Token was created!
$form.find('.submit').html("<i class='fa fa-check'></i> Account added");

var token = response.id;

$form.append($('<input type="hidden" name="stripeToken" />').val(token));

$form.get(0).submit();
}
}
</script>
<% end %>

<div class="panel panel-default">
<div class="panel-body">
<form action="/bank_accounts" method="POST" id="payment-form">
<div class="errors"></div>
<div class="row">
<div class="col-md-8">
<div class="form-group">
<label>Country</label>
<select class="form-control input-lg" id="country" data-stripe="country">
<option value="US">United States</option>
</select>
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label>Currency</label>
<select class="form-control input-lg" id="currency" data-stripe="currency">
<option value="usd">USD</option>
</select>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6" id="routing_number_div">
<div class="form-group">
<label id="routing_number_label">Routing Number</label>
<input class="form-control input-lg bank_account" id="routing_number" type="tel" size="12" data-stripe="routing_number" value="110000000" autocomplete="off">
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label id="account_number_label">Account Number</label>
<input class="form-control input-lg bank_account" id="account_number" type="tel" size="20" data-stripe="account_number" value="000123456789" autocomplete="off">
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<button class="btn btn-lg btn-block btn-primary btn-custom submit" type="submit">Add Bank Account</button>
</div>
</div>
<%= hidden_field_tag :authenticity_token, form_authenticity_token -%>
</form>
</div>
</div>


As you see in the JS: // Stripe.setPublishableKey("<%= ENV['PUBLISHABLE_KEY'] %>");
I have tried with that, but apparently it's not up to date anymore. Just for testing purposes, I have simply included the publishable key directly within the JS and not in credentials just yet until I figure it out.



Here is my console when I submit the form:



Started POST "/bank_accounts" for 127.0.0.1 at 2018-11-10 14:32:11 -0500
Processing by BankAccountsController#create as HTML
Parameters: {"authenticity_token"=>"l69UBGkzwcel7JH34+TDbsfQ9Xjkiogu+emWm+8+0iVQfKh9AIxDaXp0yMhjFkUVznHeJYwXeVmdBVSI2XjArg=="}
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ? [["id", 2], ["LIMIT", 1]]
↳ /home/bob/.rvm/gems/ruby-2.5.1/gems/activerecord-5.2.1/lib/active_record/log_subscriber.rb:98
Redirected to http://localhost:3000/bank_accounts/new
Completed 302 Found in 4ms (ActiveRecord: 0.3ms)


Started GET "/bank_accounts/new" for 127.0.0.1 at 2018-11-10 14:32:11 -0500
Processing by BankAccountsController#new as HTML
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ? [["id", 2], ["LIMIT", 1]]
↳ /home/bob/.rvm/gems/ruby-2.5.1/gems/activerecord-5.2.1/lib/active_record/log_subscriber.rb:98
StripeAccount Load (0.2ms) SELECT "stripe_accounts".* FROM "stripe_accounts" WHERE "stripe_accounts"."user_id" = ? LIMIT ? [["user_id", 2], ["LIMIT", 1]]
↳ app/controllers/bank_accounts_controller.rb:6
Rendering bank_accounts/new.html.erb within layouts/application
Rendered bank_accounts/_bank_account_form.html.erb (1.0ms)
Rendered bank_accounts/new.html.erb within layouts/application (4.2ms)
Rendered layouts/_navbar.html.erb (3.0ms)
Rendered layouts/_footer.html.erb (0.3ms)
Completed 200 OK in 218ms (Views: 212.4ms | ActiveRecord: 0.5ms)


the e.message reads as follows:



Invalid external_account object: must be a dictionary or a non-empty string. See API docs at https://stripe.com/docs'


but the e.message only appears on page reload and not when the form is submitted. Only once I submit, and then reload the page, it appears.



I having nothing set up within the BankAccount model, either does the example app i used as a reference.



Extra information: For Users and StripeAccount, I have them nested, which is why you will see new_user_stripe_account_path... BankAccount isn't nested to anything.



Message from Browser Console:



Error: The selector you specified (#card-element) applies to no DOM elements that are currently on the page.
Make sure the element exists on the page before calling mount(). v3:1:10186
t
https://js.stripe.com/v3/:1:10186
oi/this.mount<
https://js.stripe.com/v3/:1:79868
Gt/<
https://js.stripe.com/v3/:1:23367
<anonymous>
http://localhost:3000/assets/stripejs.self-8c2ad75855f867e5280e1a173e994f83fb5afc997847456669b8cbe0b24fae1f.js:31:1
[Exception... "Component returned failure code: 0x80040111 (NS_ERROR_NOT_AVAILABLE) [nsIContentSniffer.getMIMETypeFromContent]" nsresult: "0x80040111 (NS_ERROR_NOT_AVAILABLE)" location: "JS frame :: resource:///modules/FaviconLoader.jsm :: onStopRequest :: line 181" data: no]
onStopRequest
resource:///modules/FaviconLoader.jsm:181:16
InterpretGeneratorResume self-hosted:1257:8 next self-hosted:1212:9






javascript ruby-on-rails ruby stripe-payments






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 11 at 23:55

























asked Nov 11 at 7:57









uno

579




579












  • Because you are getting an error like "must be a dictionary or a non-empty string" , I suspect your bank account token is never getting passed to your back-end at all --- in fact i don't see it in the log you shared Parameters: {"authenticity_token"=>"l69UBGkzwcel7JH34+TDbsfQ9Xjkiogu+emWm+8+0iVQfKh9AIxDaXp0yMhjFkUVznHeJYwXeVmdBVSI2XjArg=="} --- try adding some debugging to your JS --- console.logs in your stripeResponseHandler, a breakpoint before the form submit (check that a hidden stripeToken input really exists in your form using browser dev tools inspector)
    – duck
    Nov 11 at 19:54










  • I added the Browser Console when i press submit. Other than that, do you think the rest of the code is okay?
    – uno
    Nov 11 at 23:56










  • BTW, "check that a hidden stripetoken input exists"... is that something I'll see in the Browser console...? and in the update, it's not there if so?
    – uno
    Nov 12 at 0:20










  • So it looks like, from what i understand, is the JS is for Stripe V2 and not Stripe V3 you can see the differences here: V2:stripe.com/docs/stripe-js/v2#collecting-bank-account-details ----V3:stripe.com/docs/stripe-js/… ----- so im trying to migrate it over to v3
    – uno
    Nov 12 at 2:53




















  • Because you are getting an error like "must be a dictionary or a non-empty string" , I suspect your bank account token is never getting passed to your back-end at all --- in fact i don't see it in the log you shared Parameters: {"authenticity_token"=>"l69UBGkzwcel7JH34+TDbsfQ9Xjkiogu+emWm+8+0iVQfKh9AIxDaXp0yMhjFkUVznHeJYwXeVmdBVSI2XjArg=="} --- try adding some debugging to your JS --- console.logs in your stripeResponseHandler, a breakpoint before the form submit (check that a hidden stripeToken input really exists in your form using browser dev tools inspector)
    – duck
    Nov 11 at 19:54










  • I added the Browser Console when i press submit. Other than that, do you think the rest of the code is okay?
    – uno
    Nov 11 at 23:56










  • BTW, "check that a hidden stripetoken input exists"... is that something I'll see in the Browser console...? and in the update, it's not there if so?
    – uno
    Nov 12 at 0:20










  • So it looks like, from what i understand, is the JS is for Stripe V2 and not Stripe V3 you can see the differences here: V2:stripe.com/docs/stripe-js/v2#collecting-bank-account-details ----V3:stripe.com/docs/stripe-js/… ----- so im trying to migrate it over to v3
    – uno
    Nov 12 at 2:53


















Because you are getting an error like "must be a dictionary or a non-empty string" , I suspect your bank account token is never getting passed to your back-end at all --- in fact i don't see it in the log you shared Parameters: {"authenticity_token"=>"l69UBGkzwcel7JH34+TDbsfQ9Xjkiogu+emWm+8+0iVQfKh9AIxDaXp0yMhjFkUVznHeJYwXeVmdBVSI2XjArg=="} --- try adding some debugging to your JS --- console.logs in your stripeResponseHandler, a breakpoint before the form submit (check that a hidden stripeToken input really exists in your form using browser dev tools inspector)
– duck
Nov 11 at 19:54




Because you are getting an error like "must be a dictionary or a non-empty string" , I suspect your bank account token is never getting passed to your back-end at all --- in fact i don't see it in the log you shared Parameters: {"authenticity_token"=>"l69UBGkzwcel7JH34+TDbsfQ9Xjkiogu+emWm+8+0iVQfKh9AIxDaXp0yMhjFkUVznHeJYwXeVmdBVSI2XjArg=="} --- try adding some debugging to your JS --- console.logs in your stripeResponseHandler, a breakpoint before the form submit (check that a hidden stripeToken input really exists in your form using browser dev tools inspector)
– duck
Nov 11 at 19:54












I added the Browser Console when i press submit. Other than that, do you think the rest of the code is okay?
– uno
Nov 11 at 23:56




I added the Browser Console when i press submit. Other than that, do you think the rest of the code is okay?
– uno
Nov 11 at 23:56












BTW, "check that a hidden stripetoken input exists"... is that something I'll see in the Browser console...? and in the update, it's not there if so?
– uno
Nov 12 at 0:20




BTW, "check that a hidden stripetoken input exists"... is that something I'll see in the Browser console...? and in the update, it's not there if so?
– uno
Nov 12 at 0:20












So it looks like, from what i understand, is the JS is for Stripe V2 and not Stripe V3 you can see the differences here: V2:stripe.com/docs/stripe-js/v2#collecting-bank-account-details ----V3:stripe.com/docs/stripe-js/… ----- so im trying to migrate it over to v3
– uno
Nov 12 at 2:53






So it looks like, from what i understand, is the JS is for Stripe V2 and not Stripe V3 you can see the differences here: V2:stripe.com/docs/stripe-js/v2#collecting-bank-account-details ----V3:stripe.com/docs/stripe-js/… ----- so im trying to migrate it over to v3
– uno
Nov 12 at 2:53














1 Answer
1






active

oldest

votes

















up vote
0
down vote



accepted










So it looks like the JS was to blame. It was somewhat wrong and out of date, and a few things weren't matched up with my controller.



Here's the correct JS for S v3
JS on view page (i believe this NEEDS TO BE UNDER the form; could be wrong):



var stripe = Stripe('pk_test_WUSo123456789PWU8kh');

function setOutcome(result) {
var successElement = document.querySelector('.success');
var errorElement = document.querySelector('.error');
successElement.classList.remove('visible');
errorElement.classList.remove('visible');

if (result.token) {
// In this example, we're simply displaying the token
successElement.querySelector('.token').textContent = result.token.id;
successElement.classList.add('visible');

// In a real integration, you'd submit the form with the token to your backend server
var form = document.querySelector('form');
form.querySelector('input[name="token"]').setAttribute('value', result.token.id);
form.submit();

} else {
errorElement.textContent = result.error.message;
errorElement.classList.add('visible');
}
}

document.querySelector('form').addEventListener('submit', function(e) {
e.preventDefault();

var bankAccountParams = {
country: document.getElementById('country').value,
currency: document.getElementById('currency').value,
account_number: document.getElementById('account-number').value,
account_holder_name: document.getElementById('account-holder-name').value,
account_holder_type: document.getElementById('account-holder-type').value,
}
if (document.getElementById('routing-number').value != '') {
bankAccountParams['routing_number'] = document.getElementById('routing-number').value;
}

stripe.createToken('bank_account', bankAccountParams).then(setOutcome);
});


And the correct Create for the BankAccount controller:
(or this at least works, i may be fixing this up a bit after this)



def create
unless params[:token] && current_user.stripe_token
redirect_to new_bank_account_path and return
end
begin
token = params[:token]
stripe_account.external_account = params[:token]
stripe_account.save
flash[:success] = "Your bank account has been added!"
redirect_to dashboard_path
rescue Stripe::StripeError => e
# handler_for_rescue(e.message, 'new')
flash[:error] = e.message
# Handle any other exceptions
rescue => e
# handle_error(e.message, 'new')
flash[:error] = e.message
end
end
end


In the form, I also pass the following which may or may not be needed, I will do testing on this later on after i post this.:



<%= hidden_field_tag :authenticity_token, form_authenticity_token -%>
<%= hidden_field_tag :stripeToken, current_user.stripe_token -%>


I don't believe :stripeToken is needed... but auth is






share|improve this answer





















    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53246837%2fadding-bank-account-data-to-stripe-not-saving-to-api-or-database-table%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    0
    down vote



    accepted










    So it looks like the JS was to blame. It was somewhat wrong and out of date, and a few things weren't matched up with my controller.



    Here's the correct JS for S v3
    JS on view page (i believe this NEEDS TO BE UNDER the form; could be wrong):



    var stripe = Stripe('pk_test_WUSo123456789PWU8kh');

    function setOutcome(result) {
    var successElement = document.querySelector('.success');
    var errorElement = document.querySelector('.error');
    successElement.classList.remove('visible');
    errorElement.classList.remove('visible');

    if (result.token) {
    // In this example, we're simply displaying the token
    successElement.querySelector('.token').textContent = result.token.id;
    successElement.classList.add('visible');

    // In a real integration, you'd submit the form with the token to your backend server
    var form = document.querySelector('form');
    form.querySelector('input[name="token"]').setAttribute('value', result.token.id);
    form.submit();

    } else {
    errorElement.textContent = result.error.message;
    errorElement.classList.add('visible');
    }
    }

    document.querySelector('form').addEventListener('submit', function(e) {
    e.preventDefault();

    var bankAccountParams = {
    country: document.getElementById('country').value,
    currency: document.getElementById('currency').value,
    account_number: document.getElementById('account-number').value,
    account_holder_name: document.getElementById('account-holder-name').value,
    account_holder_type: document.getElementById('account-holder-type').value,
    }
    if (document.getElementById('routing-number').value != '') {
    bankAccountParams['routing_number'] = document.getElementById('routing-number').value;
    }

    stripe.createToken('bank_account', bankAccountParams).then(setOutcome);
    });


    And the correct Create for the BankAccount controller:
    (or this at least works, i may be fixing this up a bit after this)



    def create
    unless params[:token] && current_user.stripe_token
    redirect_to new_bank_account_path and return
    end
    begin
    token = params[:token]
    stripe_account.external_account = params[:token]
    stripe_account.save
    flash[:success] = "Your bank account has been added!"
    redirect_to dashboard_path
    rescue Stripe::StripeError => e
    # handler_for_rescue(e.message, 'new')
    flash[:error] = e.message
    # Handle any other exceptions
    rescue => e
    # handle_error(e.message, 'new')
    flash[:error] = e.message
    end
    end
    end


    In the form, I also pass the following which may or may not be needed, I will do testing on this later on after i post this.:



    <%= hidden_field_tag :authenticity_token, form_authenticity_token -%>
    <%= hidden_field_tag :stripeToken, current_user.stripe_token -%>


    I don't believe :stripeToken is needed... but auth is






    share|improve this answer

























      up vote
      0
      down vote



      accepted










      So it looks like the JS was to blame. It was somewhat wrong and out of date, and a few things weren't matched up with my controller.



      Here's the correct JS for S v3
      JS on view page (i believe this NEEDS TO BE UNDER the form; could be wrong):



      var stripe = Stripe('pk_test_WUSo123456789PWU8kh');

      function setOutcome(result) {
      var successElement = document.querySelector('.success');
      var errorElement = document.querySelector('.error');
      successElement.classList.remove('visible');
      errorElement.classList.remove('visible');

      if (result.token) {
      // In this example, we're simply displaying the token
      successElement.querySelector('.token').textContent = result.token.id;
      successElement.classList.add('visible');

      // In a real integration, you'd submit the form with the token to your backend server
      var form = document.querySelector('form');
      form.querySelector('input[name="token"]').setAttribute('value', result.token.id);
      form.submit();

      } else {
      errorElement.textContent = result.error.message;
      errorElement.classList.add('visible');
      }
      }

      document.querySelector('form').addEventListener('submit', function(e) {
      e.preventDefault();

      var bankAccountParams = {
      country: document.getElementById('country').value,
      currency: document.getElementById('currency').value,
      account_number: document.getElementById('account-number').value,
      account_holder_name: document.getElementById('account-holder-name').value,
      account_holder_type: document.getElementById('account-holder-type').value,
      }
      if (document.getElementById('routing-number').value != '') {
      bankAccountParams['routing_number'] = document.getElementById('routing-number').value;
      }

      stripe.createToken('bank_account', bankAccountParams).then(setOutcome);
      });


      And the correct Create for the BankAccount controller:
      (or this at least works, i may be fixing this up a bit after this)



      def create
      unless params[:token] && current_user.stripe_token
      redirect_to new_bank_account_path and return
      end
      begin
      token = params[:token]
      stripe_account.external_account = params[:token]
      stripe_account.save
      flash[:success] = "Your bank account has been added!"
      redirect_to dashboard_path
      rescue Stripe::StripeError => e
      # handler_for_rescue(e.message, 'new')
      flash[:error] = e.message
      # Handle any other exceptions
      rescue => e
      # handle_error(e.message, 'new')
      flash[:error] = e.message
      end
      end
      end


      In the form, I also pass the following which may or may not be needed, I will do testing on this later on after i post this.:



      <%= hidden_field_tag :authenticity_token, form_authenticity_token -%>
      <%= hidden_field_tag :stripeToken, current_user.stripe_token -%>


      I don't believe :stripeToken is needed... but auth is






      share|improve this answer























        up vote
        0
        down vote



        accepted







        up vote
        0
        down vote



        accepted






        So it looks like the JS was to blame. It was somewhat wrong and out of date, and a few things weren't matched up with my controller.



        Here's the correct JS for S v3
        JS on view page (i believe this NEEDS TO BE UNDER the form; could be wrong):



        var stripe = Stripe('pk_test_WUSo123456789PWU8kh');

        function setOutcome(result) {
        var successElement = document.querySelector('.success');
        var errorElement = document.querySelector('.error');
        successElement.classList.remove('visible');
        errorElement.classList.remove('visible');

        if (result.token) {
        // In this example, we're simply displaying the token
        successElement.querySelector('.token').textContent = result.token.id;
        successElement.classList.add('visible');

        // In a real integration, you'd submit the form with the token to your backend server
        var form = document.querySelector('form');
        form.querySelector('input[name="token"]').setAttribute('value', result.token.id);
        form.submit();

        } else {
        errorElement.textContent = result.error.message;
        errorElement.classList.add('visible');
        }
        }

        document.querySelector('form').addEventListener('submit', function(e) {
        e.preventDefault();

        var bankAccountParams = {
        country: document.getElementById('country').value,
        currency: document.getElementById('currency').value,
        account_number: document.getElementById('account-number').value,
        account_holder_name: document.getElementById('account-holder-name').value,
        account_holder_type: document.getElementById('account-holder-type').value,
        }
        if (document.getElementById('routing-number').value != '') {
        bankAccountParams['routing_number'] = document.getElementById('routing-number').value;
        }

        stripe.createToken('bank_account', bankAccountParams).then(setOutcome);
        });


        And the correct Create for the BankAccount controller:
        (or this at least works, i may be fixing this up a bit after this)



        def create
        unless params[:token] && current_user.stripe_token
        redirect_to new_bank_account_path and return
        end
        begin
        token = params[:token]
        stripe_account.external_account = params[:token]
        stripe_account.save
        flash[:success] = "Your bank account has been added!"
        redirect_to dashboard_path
        rescue Stripe::StripeError => e
        # handler_for_rescue(e.message, 'new')
        flash[:error] = e.message
        # Handle any other exceptions
        rescue => e
        # handle_error(e.message, 'new')
        flash[:error] = e.message
        end
        end
        end


        In the form, I also pass the following which may or may not be needed, I will do testing on this later on after i post this.:



        <%= hidden_field_tag :authenticity_token, form_authenticity_token -%>
        <%= hidden_field_tag :stripeToken, current_user.stripe_token -%>


        I don't believe :stripeToken is needed... but auth is






        share|improve this answer












        So it looks like the JS was to blame. It was somewhat wrong and out of date, and a few things weren't matched up with my controller.



        Here's the correct JS for S v3
        JS on view page (i believe this NEEDS TO BE UNDER the form; could be wrong):



        var stripe = Stripe('pk_test_WUSo123456789PWU8kh');

        function setOutcome(result) {
        var successElement = document.querySelector('.success');
        var errorElement = document.querySelector('.error');
        successElement.classList.remove('visible');
        errorElement.classList.remove('visible');

        if (result.token) {
        // In this example, we're simply displaying the token
        successElement.querySelector('.token').textContent = result.token.id;
        successElement.classList.add('visible');

        // In a real integration, you'd submit the form with the token to your backend server
        var form = document.querySelector('form');
        form.querySelector('input[name="token"]').setAttribute('value', result.token.id);
        form.submit();

        } else {
        errorElement.textContent = result.error.message;
        errorElement.classList.add('visible');
        }
        }

        document.querySelector('form').addEventListener('submit', function(e) {
        e.preventDefault();

        var bankAccountParams = {
        country: document.getElementById('country').value,
        currency: document.getElementById('currency').value,
        account_number: document.getElementById('account-number').value,
        account_holder_name: document.getElementById('account-holder-name').value,
        account_holder_type: document.getElementById('account-holder-type').value,
        }
        if (document.getElementById('routing-number').value != '') {
        bankAccountParams['routing_number'] = document.getElementById('routing-number').value;
        }

        stripe.createToken('bank_account', bankAccountParams).then(setOutcome);
        });


        And the correct Create for the BankAccount controller:
        (or this at least works, i may be fixing this up a bit after this)



        def create
        unless params[:token] && current_user.stripe_token
        redirect_to new_bank_account_path and return
        end
        begin
        token = params[:token]
        stripe_account.external_account = params[:token]
        stripe_account.save
        flash[:success] = "Your bank account has been added!"
        redirect_to dashboard_path
        rescue Stripe::StripeError => e
        # handler_for_rescue(e.message, 'new')
        flash[:error] = e.message
        # Handle any other exceptions
        rescue => e
        # handle_error(e.message, 'new')
        flash[:error] = e.message
        end
        end
        end


        In the form, I also pass the following which may or may not be needed, I will do testing on this later on after i post this.:



        <%= hidden_field_tag :authenticity_token, form_authenticity_token -%>
        <%= hidden_field_tag :stripeToken, current_user.stripe_token -%>


        I don't believe :stripeToken is needed... but auth is







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 12 at 8:40









        uno

        579




        579






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53246837%2fadding-bank-account-data-to-stripe-not-saving-to-api-or-database-table%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Guess what letter conforming each word

            Port of Spain

            Run scheduled task as local user group (not BUILTIN)