form_tag does not produce stripeToken upon submit

夙愿已清 提交于 2019-12-13 02:54:16

问题


I am following this tutorial for having customized checkout button

I changed the tutorial for my need, and when I check my params , stripeToken is empty

{"utf8"=>"✓", "authenticity_token"=>"sometokenvalue", "stripeToken"=>"", "amount"=>"40000", "item_id"=>"3"}

I suspect I get this error

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

owing to that.

my code as follows :

<p id="notice"><%= notice %></p>
<div class="container">
  <div class="row">
    <div class="col-md-12"><p>
      <strong>Name:</strong>
        <%= @item.name %>
      </p>  
      <p>
        <strong>Price:</strong>
        <%= @item.price %>
      </p>

       <script src="https://checkout.stripe.com/checkout.js"></script>

      <%= form_tag item_charges_path(@item, amount: @item.price), id: 'paying-form' do %>
          <% if flash[:error].present? %>
            <div id="error_explanation">
              <p><%= flash[:error] %></p>
            </div>
          <% end %>
        <article>
        </article>
        <article>      
          <%= hidden_field_tag :stripeToken  %>
        </article>
        <button id='donateButton' class='btn btn-primary'>Pay</button>
      <% end %>

        <%= link_to 'Edit', edit_item_path(@item) %> |
        <%= link_to 'Back', items_path %>


          <script>
            var handler = StripeCheckout.configure({
              key: '<%= Rails.configuration.stripe[:publishable_key] %>',
              locale: 'auto',
              token: function(token) {   
                $('input#stripeToken').val(token.id);
                $('form').submit();
              }
            });
          </script>
          <script>
          document.getElementById('donateButton').addEventListener('click', function(e) {
              //e.preventDefault();

              $('#error_explanation').html('');

              var amount = "#{@item.price}";
              amount = amount.replace(/\$/g, '').replace(/\,/g, '')

              amount = parseFloat(amount);

              if (isNaN(amount)) {
                $('#error_explanation').html('<p>Please enter a valid amount in USD ($).</p>');
              }
              else {
                amount = amount * 100; // Needs to be an integer!
                handler.open({
                  amount: Math.round(amount)
                })
                e.preventDefault();
              }
            });

            $(window).on('popstate', function() {
              handler.close();
            });

          </script>
    </div>
  </div>
</div>

Note: I put the js codes in the same page for simplicity goals.

Could anyone tell me what is wrong that my form does not produce stripeToken? or May be I am missing some points?

Note: please if more info is needed,let me know so I post Thank you


回答1:


You have a typo in your JS:

var amount = "#{@item.price}";

...should instead be...

var amount = <%= @item.price %>;

Then, move the following code at the top just below the line: addEventListener

e.preventDefault();

Then, remove the following because you don't need it anymore because the @item.price comes directly from your database:

amount = amount.replace(/\$/g, '').replace(/\,/g, '')
amount = parseFloat(amount);

Lastly, because amount is guaranteed to be correct and has an Integer value, then you don't need the following anymore and so remove them:

if (isNaN(amount)) {
  $('#error_explanation').html('<p>Please enter a valid amount in USD ($).</p>');
}

don't forget to remove the dangling } else { } code

Explanation:

  • If my understanding is correct upon looking at your code, whenever you click the "Donate" button, because of the typo, your if (isNaN(amount)) basically evaluates to if (isNaN("#{@item.price}") (which is a STRING!!!), and this is why isNaN("#{@item.price}") always equals true (because it's Not-A-Number!), and therefore the else condition which is...

    handler.open({
      amount: Math.round(amount)
    })
    e.preventDefault();
    

    ...never gets called. Take note that the e.preventDefault() above never gets called! ...which means that your form submits "the normal way" without opening up the "Stripe" modal. If my theory is correct, this is why :stripeToken is empty string because the default value for your hidden_tag :stripeToken is empty-value which means '', instead of the correct way: which is that after you click the Donate button, the Stripe modal should pop up, and after the Stripe transaction has been completed, the token function callback will be called:

    token: function(token) {   
      $('input#stripeToken').val(token.id);
      $('form').submit();
    }
    

    ...of which as you would see above, will update your stripeToken input to have the correct "token" value. And then also as you could see above, the form will then be submitted but now the stripeToken input now has a value because you just updated it.

P.S. Haven't used Stripe per se



来源:https://stackoverflow.com/questions/54448040/form-tag-does-not-produce-stripetoken-upon-submit

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!