ruby-on-rails - Stripe token 未转移到 Controller rails 4

标签 ruby-on-rails ruby-on-rails-4 coffeescript stripe-payments

问题

我已经测试了 CoffeeScript 并且表单调用了 Stripe,使用正确的响应标记设置隐藏字段并提交表单。我的问题是,一旦提交, Controller 似乎无法正确抓取 token 并抛出此错误: Stripe::InvalidRequestError - 您必须提供卡或客户 ID .

接下来,我厌倦了将生成的 token 硬编码到 Controller 中,看看它是否可行。我提交了表格,该表格有效,并且在 Stripes 端收到了付款。我几乎不知道下一步要尝试什么。我想知道我是否忘记了什么或遗漏了什么,因为付款嵌套在分配下。

gem 版本

  • ruby :2.1.0
  • rails :4.0.1
  • Stripe :1.9.9

  • 文件

    /payment/new.html.erb
    <%= form_for([@assignment, @payment]) do |f| %>
      <% if @payment.errors.any? %>
        <div class="error_messages">
          <h2><%= pluralize(@payment.errors.count, "error") %> prohibited this subscription from being saved:</h2>
          <ul>
            <% @payment.errors.full_messages.each do |msg| %>
              <li><%= msg %></li>
            <% end %>
          </ul>
        </div>
      <% end %>
    
      <%= f.hidden_field :stripe_customer_token %>
    
      <% if @payment.stripe_customer_token.present? %>
        <p>This assignment has already been paid for.</p>
      <% else %>
    
        <div class="field">
          <%= label_tag :card_number, "Credit Card Number" %>
          <%= text_field_tag :card_number, nil, name: nil, placeholder: "00000000000000" %>
        </div>
        <div class="row">
          <div class="field card__dates">
            <%= label_tag :card_month, "Card Expiration" %>
            <%= select_month nil, {add_month_numbers: true}, {name: nil, id: "card_month"} %>
            <%= select_year nil, {start_year: Date.today.year, end_year: Date.today.year+15}, {name: nil, id: "card_year"} %>
          </div>
          <div class="field card__cvv">
            <%= label_tag :card_code, "CVV" %>
            <%= text_field_tag :card_code, nil, name: nil, placeholder: "003", required: true, maxlength: 4, minlength: 3 %>
          </div>
        </div>
    
      <% end %>
      <div id="stripe_error">
        <noscript>JavaScript is not enabled and is required for this form. First enable it in your web browser settings.</noscript>
      </div>
      <div class="actions">
        <%= f.submit "Pay " + number_to_currency(@assignment.price.to_s), class: 'btn btn__primary btn__large btn--fill' %>
      </div>
    



    支付 Controller .rb
    class PaymentsController < ApplicationController
      def new
        set_assignment
        @payment = @assignment.build_payment
        @price = @assignment.price
      end
    
      def create
        set_assignment
        @payment = @assignment.build_payment(payment_params)
    
        if save_with_payment
          redirect_to assignments_path, :notice => "Payment received, Thank you!"
    
          # since payment was successful, set assignment paid to true
          Assignment.update(@assignment, assignment_paid: true, project_status: "In Progress")
        else
          render :new
        end
      end
    
      private
    
        def save_with_payment
    
          # Set your secret key: remember to change this to your live secret key in production
          # See your keys here https://manage.stripe.com/account
          Stripe.api_key = Rails.configuration.stripe[:secret_key]
    
          # Get the credit card details submitted by the form
          token = params[:stripe_customer_token]
    
          # How much the assignment costs, which must be converted to cents
          @amount = (@price * 100)
    
          # Create the charge on Stripe's servers - this will charge the user's card
          begin
            charge = Stripe::Charge.create(
              :amount => @amount,
              :currency => "cad",
              :card => token,
              :description => "some description of the product"
            )
          rescue Stripe::CardError => e
            redirect_to @assignment, :notice => "The card has been declined"
          end
        end
    
        def set_assignment
          @assignment = Assignment.friendly.find(params[:assignment_id])
        end
    
        def payment_params
          params.require(:payment).permit(
            :stripe_customer_token
          )
        end
    end
    

    pay.js.coffee
    $ ->
      Stripe.setPublishableKey($('meta[name="stripe-key"]').attr('content'))
      payment.setupForm()
    
    payment =
      setupForm: ->
        $('#new_payment').submit ->
          $('input[type=submit]').attr('disabled', true)
          if $('#card_number').length
            payment.processCard()
            false
          else
            true
    
      processCard: ->
        card =
          number: $('#card_number').val()
          cvc: $('#card_code').val()
          expMonth: $('#card_month').val()
          expYear: $('#card_year').val()
        Stripe.createToken(card, payment.handleStripeResponse)
    
      handleStripeResponse: (status, response) ->
        if status == 200
          console.log response
          $('#payment_stripe_customer_token').val(response.id)
          $('#new_payment')[0].submit()
        else
          $('#stripe_error').text(response.error.message)
          $('input[type=submit]').attr('disabled', false)
    

    付款.rb
    class Payment < ActiveRecord::Base
      belongs_to :assignment
    end
    

    最佳答案

    正如我所见,至少有两个问题。我想在取得进展后可能会有更多。

  • 您无权访问 params#save_with_payment
    问题发生在这一行:
    # Get the credit card details submitted by the form
    token = params[:stripe_customer_token]
    

    params 受 strong_params 保护,您无权访问它。

    修复方法是允许 payment_params 中所有需要的参数并在此方法中重用它。
  • 其实你没有@price#create
    这个问题与问题没有直接关系,但它存在。

    此实例变量 @price#new .和 #create是另一个实例,所以你不能再拥有它。

    修复方法是从 payment_params 获取它
  • 关于ruby-on-rails - Stripe token 未转移到 Controller rails 4,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21065182/

    相关文章:

    javascript - 在 Rails 4 中使用 AJAX 进行搜索、排序和分页

    ruby-on-rails - ruby on rails 二维码实现

    coffeescript 中类似 python 的字符串插值

    javascript - jQuery 循环中的绑定(bind)切换

    ruby-on-rails - 如何让 Rails 异常提供更多信息?

    ruby-on-rails - 模型 "belong_to"可以有两个其他模型并具有嵌套关系吗?

    javascript - Jquery.html 显示文字代码而不是在 application.js 中呈现 html

    ruby-on-rails - 我找不到我的rails line_items Controller 创建操作错误?

    node.js - 语法错误: Unexpected POST_IF error

    ruby-on-rails - 使用 curl 测试 Rails 路由