[英]Adding Bank Account data to stripe not saving to API or database table
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) 问题:表单中的银行帐户数据未保存到Stripe API(Stripe :: Account),可能是因为数据未正确或未成功存储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? 问题:在我的代码中是什么导致检索无法正常工作或其他问题(例如,没有正确设置webhooks或不正确的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. 我的想法:我假设它不是控制器,而是JS的设置方式,因为我不熟悉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.
我在GitHub上使用Stripe Connect以我希望其运行的方式找到了一个示例应用程序,并将其用作构建BankAccount控制器,视图/表单和JS的参考。
This is the sample application for reference I have used to help me set this up: https://stripe-marketplace-demo.herokuapp.com/ 这是我用来帮助我进行设置的示例应用程序参考: https : //stripe-marketplace-demo.herokuapp.com/
How it's set up: I have Users table ; 设置方式:我有Users表; users sign up and get inputted into this User Table.
用户注册并输入此用户表。 I then have a StripeAccounts table;
然后,我有了一个StripeAccounts表; 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.
用户(current_user)可以创建StripeAccount,该条带化帐户令牌被保存为StripeAccount中的acct_id >> >> user_id(来自User表)与StripeAccount关联。 The stripe_account token is also saved in the User table under stripe_token.
stripe_account令牌也保存在User表中的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.
创建并保存了stripe_account后,会将它们重定向以填写BankAccount表单<<这是我的问题所在。 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. 我将stripe_accounts正确保存,并将Stripe令牌保存在StripeAccounts表的“ acct_id”下,并将相同的令牌另存为“ stripe_token”,保存在Users表下,与正确的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. 我是Rails的新手(大约一个月),而Stripe的新手,因此以下只是假设:我假设新方法中的“ @stripe_account = Stripe :: Account.retrieve(current_user.stripe_token)”不是检索任何东西。 Does this rely on webhooks?
这是否依赖于webhooks? That I may not have set up correctly?
我可能没有正确设置? I have tried doing this through ngrok, but to no avail.
我曾尝试通过ngrok进行此操作,但无济于事。 Although, I receive no errors on page in html.
虽然,我在html页面上没有收到任何错误。 I would then assume I'm getting stuck at the code in the create method:
然后,我假设我陷入了create方法中的代码:
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. 因为当我按提交时,页面只是重新加载而没有任何内容保存到API。
Here's the view/form I am submitting along with the JS: 这是我与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'] %>");
如您在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.
仅出于测试目的,我只是将可发布的密钥直接包含在JS中,而尚未将其包含在凭据中,直到我弄清楚了。
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: 该e.message内容如下:
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. 但是e.message仅在重新加载页面时显示,而在提交表单时不显示。 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. 我在BankAccount模型中没有任何设置,我用作参考的示例应用程序也没有。
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. 额外信息:对于用户和StripeAccount,我将它们嵌套,这就是为什么您会看到new_user_stripe_account_path ... BankAccount未嵌套到任何东西的原因。
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
So it looks like the JS was to blame. 因此,似乎要怪JS。 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): 这是视图页面上适用于S v3 JS的正确JS(我相信此需求必须在表单下;可能是错误的):
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) 并为BankAccount控制器正确创建:(或至少可以,在此之后我可能会对其进行修复)
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 我不认为:stripeToken是必需的...但是auth是
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.