首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用记录更新Stripe信用卡

用记录更新Stripe信用卡
EN

Stack Overflow用户
提问于 2014-01-30 08:14:53
回答 2查看 484关注 0票数 1

我终于想出了如何用这个教程实现条子每月计费

目前,我的提交按钮为我的#new_subscription表单和编辑表单创建并发送信用卡数据到Stripe。

,但由于某些原因,我在更新信用卡时一直收到此错误

代码语言:javascript
复制
can't convert Symbol into String
app/controllers/subscriptions_controller.rb:38:in `update'

问题:这个错误是由于coffeescript引起的,还是我的模型中的update_card方法导致了这个问题?

编辑表格

代码语言:javascript
复制
<%= form_for @subscription, :html => { :id => "update_card" } do |f| %>
  <%= render 'shared/error_messages', object: f.object %>

  <%= f.hidden_field :plan_id %>
  <%= f.hidden_field :user_id %>
  <%= f.hidden_field :stripe_card_token %>

  <h4>Change Credit Card</h4>

   <div class="field">
     <%= label_tag :card_number, "Credit Card Number" %>
     <%= text_field_tag :card_number, nil, name: nil %>
   </div>
   <div class="field">
     <%= label_tag :card_code, "Security Code on Card (CVV)" %>
     <%= text_field_tag :card_code, nil, name: nil %>
   </div>

   <div class="field">
     <%= 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>

   <%= f.submit "Change Credit Card", :class => "btn btn-primary" %>

<% end %>

JS.COFFEE

代码语言:javascript
复制
jQuery ->
  Stripe.setPublishableKey($('meta[name="stripe-key"]').attr('content'))
  subscription.setupForm()
  changecard.setupForm()

###That part is working great in the coffee script.

subscription =
  setupForm: ->
    $('#new_subscription').submit ->
      $('input[type=submit]').attr('disabled', true)
      if $('#card_number').length
        subscription.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, subscription.handleStripeResponse)

  handleStripeResponse: (status, response) ->
    if status == 200
      $('#subscription_stripe_card_token').val(response.id)
      $('#new_subscription')[0].submit()
    else
      $('#stripe_error').text(response.error.message)
      $('input[type=submit]').attr('disabled', false)

###This is the Coffee for my Edit Form..
changecard =
  setupForm: ->
    $('#update_card').submit ->
      $('input[type=submit]').attr('disabled', true)
      if $('#card_number').length
        changecard.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, changecard.handleStripeResponse)

  handleStripeResponse: (status, response) ->
    if status == 200
      $('#subscription_stripe_card_token').val(response.id)
      $('#update_card')[0].submit()
    else
      $('#stripe_error').text(response.error.message)
      $('input[type=submit]').attr('disabled', false)

模型

代码语言:javascript
复制
class Subscription < ActiveRecord::Base
  attr_accessible :plan_id, :user_id, :email, :stripe_customer_token, :last_4_digits,
              :card_token, :card_name, :exp_month, :exp_year, :stripe_card_token

  attr_accessor :stripe_card_token

  def update_card(attrs)
    customer = Stripe::Customer.retrieve(stripe_customer_token)
    customer.email = "myemail@gmail.com"
    customer.description = "Subscription"

    ###This is being used for the credit card data
    customer.card = attrs[:stripe_card_token]
    customer.save

  rescue Stripe::StripeError => e 
    logger.error "Stripe Error: " + e.message 
    errors.add :base, "#{e.message}." 
    false
  end

控制器

代码语言:javascript
复制
class SubscriptionsController < ApplicationController

  def update
    @subscription = current_user.subscription

    ### I use the method update_card to update the customer's card
    @subscription.update_card(params[:subscription])  

     if @subscription.update_card
      redirect_to edit_subscription_path, 
      flash[:success] = 'Credit Card was Succesfully Updated.' 
    else
      flash.alert = 'Unable to update card.'
      render :edit 
    end
  end

参考资料:Ruby的条带引用

日志

代码语言:javascript
复制
Started PUT "/subscriptions/5" for 127.0.0.1 at 2014-01-30 16:23:20 -0800
Processing by SubscriptionsController#update as HTML

Parameters: {"utf8"=>"✓", "authenticity_token"=>"ehyUD17CbH7MMOe98s+Kqkh+wGghntWkG4OpoqbnQaA=", 
"subscription"=>{"plan_id"=>"1", "user_id"=>"1", 
"stripe_card_token"=>"tok_103PJj26f8kAprmwvAtoZFRq"}, "id"=>"5"}

User Load (0.8ms)  SELECT "users".* FROM "users" 
WHERE "users"."remember_token" = 'xEeu1X6IK9gUAsna9b6Mow' 

LIMIT 1
Subscription Load (0.5ms)  SELECT "subscriptions".* 
FROM "subscriptions" WHERE "subscriptions"."user_id" = 1 LIMIT 1

Redirected to 
Completed 500 Internal Server Error in 1283ms

TypeError (can't convert Symbol into String):
app/controllers/subscriptions_controller.rb:38:in `update'
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-01-30 22:46:20

您使用params作为参数调用params

代码语言:javascript
复制
@subscription.update_card(params)

update_card期待着:stripe_card_tokenparams

代码语言:javascript
复制
def update_card(params)
  #...
  customer.card = params[:stripe_card_token]

但是没有params[:stripe_card_token],令牌在params[:subscription][:stripe_card_token]

代码语言:javascript
复制
Parameters: {
  ...
  "subscription"=>{ ... "stripe_card_token"=>"tok_103PCo26f8kAprmwHCPjZ6T5"}, 
}

params结构也与表单的结构相匹配:

代码语言:javascript
复制
<%= form_for @subscription, :html => { :id => "update_card" } do |f| %>
  ...
  <%= f.hidden_field :stripe_card_token %>

form_for @subscription将设置使用subscription[X]进行字段X的表单,以便hidden_field在HTML中具有name="subscription[stripe_card_token]",并在控制器中转换为params[:subscription][:stripe_card_token]

也许你是想说:

代码语言:javascript
复制
@subscription.update_card(params[:subscription])

您还可以在没有任何参数的情况下对@subscription.update_card进行错误调用。您的整个控制器方法可能看起来更像这样:

代码语言:javascript
复制
def update
  @subscription = current_user.subscription
  if @subscription.update_card(params[:subscription])
    redirect_to edit_subscription_path, :success => 'Updated Card.' 
  else
    flash.alert = 'Unable to update card.'
    render :edit 
  end
end
票数 2
EN

Stack Overflow用户

发布于 2014-01-30 11:29:20

我想这是个错误,你写的是'subscription.processCard()‘而不是'changecard.processCard()’

代码语言:javascript
复制
changecard =
  setupForm: ->
    $('#update_card').submit ->
      $('input[type=submit]').attr('disabled', true)
      if $('#card_number').length
        changecard.processCard()
        false
      else
        true
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21450993

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档