ruby-on-rails - 将 nonce 传递给服务器并返回到 Braintree SDK
问题描述
以下视图正在生成正确的随机数,如 javascript 代码中的警报所示。
<div class='row'>
<div class='small-12 columns text-center'>
<h4><%= t('proceed_to_payment') %> <%= number_to_currency(@clientorder.payment_amount) %></h4>
<% if !@clientorder.paid? %>
<%= form_tag transacted_clientorders_path(id: @clientorder.id), id: 'checkout' do %>
<input type="hidden" id="nonce" name="payment_method_nonce" />
<div id='dropin-container'></div>
<%= submit_tag t('submit'), id: 'submit-button' %>
<% end %>
<script>
$.ajax({
method: "POST",
url: "/transacted?id=<%= @clientorder.id %>&locale=<%= I18n.locale %>",
data: { payment_method_nonce: payload.nonce }
})
</script>
<script>
var button = document.querySelector('#submit-button');
braintree.dropin.create({
authorization: "<%= @client_token %>",
container: '#dropin-container'
}, function (createErr, instance) {
button.addEventListener('click', function () {
instance.requestPaymentMethod(function (err, payload) {
alert(payload.nonce);
console.log(payload.nonce);
console.log(err);
if (err) {
console.log('Error', err);
return;
}
// Add the nonce to the form and submit
document.querySelector('#nonce').value = payload.nonce;
form.submit();
});
});
});
</script>
<% end %>
</div>
</div>
控制器动作
def transacted
@result = Braintree::Transaction.sale(
amount: @clientorder.payment_amount,
payment_method_nonce: params[:payment_method_nonce],
options: {
submit_for_settlement: true},
)
if @result.transaction.status == "submitted_for_settlement"
[...]
但是不会导致任何进一步的操作。@result
为 nil,因为未提交 nonce,实际上,以下未传递的数量也是记录的请求参数。
{"utf8"=>"✓",
"authenticity_token"=>"qXjwFuI4mNRM+ZFoQ5TwvUBv58fLNVJyQVHJm/FfBdIaArbfhjJP0WirTe+7FnSl+/asJ+fY+d+JPA7xKNLP6Q==",
"payment_method_nonce"=>"",
"commit"=>"Submit",
"id"=>"4",
"locale"=>"en"}
这在哪里偏离了正确的道路?
解决方案
有几件事不对。
- 该位置的 ajax 调用没有得到要处理的随机数
- 以这种方式设置,将对服务器进行 2 次调用:ajax 调用和表单调用本身
- 第 2 项的结果是表单调用将有一个空的 nonce,因此将生成并因此最终应处理
!result.success?
其哈希。result.errors
因此,
<div class='row'>
<div class='small-12 columns text-center'>
<div id="dropin-container"></div>
<button id="submit-button" class='button success'><%= t('proceed_to_payment') %> <%= number_to_currency(@clientorder.payment_amount) %></button>
<script>
var button = document.querySelector('#submit-button');
braintree.dropin.create({
authorization: '<%= @client_token %>',
container: '#dropin-container'
}, function (createErr, instance) {
button.addEventListener('click', function () {
instance.requestPaymentMethod(function (err, payload) {
// Submit payload.nonce to your server
$.ajax({
method: "POST",
url: "<%= transacted_clientorders_path(id: @clientorder.id, locale: I18n.locale) %>",
data: { payment_method_nonce: payload.nonce }
})
if (err) {
console.log('Error', err);
return;
}
// Add the nonce to the form and submit
document.querySelector('#nonce').value = payload.nonce;
form.submit();
});
});
});
</script>
推荐阅读
- python - 腌制部分类
- build - 从“解释到修复”论文构建代码时出错
- python - 如何将 pandas 列拆分为 n 长度的块?
- css - 我试图在列表框中显示我的 findall 方法,只显示数字 1-10
- swift - SwiftUI 中的 iCloud 开关按钮导致崩溃
- linear-programming - 如何在线性规划问题中将多个变量相乘?
- javascript - 在Vue中删除数组中的条目后列表未完全更新
- python - 无法按顺序读取 csv 文件
- flutter - Flutter ARB 本地化抛出“getter was called on null”错误
- r - 如何在 tsibble 中为多个系列应用 boxcox