本文介绍了更新条纹信用卡与咖啡的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我终于找到了如何使用此实现条纹每月结算



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



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

 无法将Symbol转换为String 
app / controllers / subscriptions_controller.rb:38:在'update'中



编辑表格

 <%= 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>更改信用卡< / h4>

< div class =field>
<%= label_tag:card_number,信用卡号码%>
<%= text_field_tag:card_number,nil,name:nil%>
< / div>
< div class =field>
<%= label_tag:card_code,卡上的安全代码(CVV)%>
<%= text_field_tag:card_code,nil,name:nil%>
< / div>

< div class =field>
<%= label_tag:card_month,卡过期%>
<%= 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更改信用卡,:class => btn btn-primary%>

<%end%>

JS.COFFEE

  jQuery  - > 
Stripe.setPublishableKey($('meta [name =stripe-key]')。attr('content'))
subscription.setupForm()
changecard.setupForm b
$ b ###这部分在咖啡脚本中工作得很好。

subscription =
setupForm: - >
$('#new_subscription')。submit - >
$('input [type = submit]')。attr('disabled',true)
如果$('#card_number')长度
subscription.processCard b 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)

###这是我的编辑表单的咖啡。
changecard =
setupForm: - >
$('#update_card')。submit - >
$('input [type = submit]')。attr('disabled',true)
如果$('#card_number')长度
changecard.processCard b 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)

MODEL

  < 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 [email protected]
customer.description =Subscription

###这用于信用卡数据
customer.card = attrs [:stripe_card_token]
customer.save

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

CONTROLLER

  class SubscriptionsController< ApplicationController 

def update
@subscription = current_user.subscription

###我使用方法update_card更新客户的卡
@ subscription.update_card (params [:subscription])

如果@ subscription.update_card
redirect_to edit_subscription_path,
flash [:success] ='信用卡已成功更新'
else
flash.alert ='无法更新卡。
render:edit
end
end

参考:



LOGS

 在2014年为127.0.0.1启动PUT/ subscriptions / 5 -01-30 16:23:20 -0800 
由SubscriptionsController处理#更新为HTML

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

用户加载(0.8ms)SELECTusers。* FROMusers
WHEREusers。remember_token ='xEeu1X6IK9gUAsna9b6Mow'

LIMIT 1
订阅加载(0.5ms)SELECTsubscriptions。*
FROMsubscriptionsWHEREsubscriptions。user_id= 1 LIMIT 1

重定向到
完成500内部服务器错误在1283ms

TypeError(无法将Symbol转换为字符串):
app / controllers / subscriptions_controller。 rb:38:in'update'


解决方案

调用 update_card 以 params 作为参数:

  @ subscription.update_card(params)

和 update_card 希望中的:stripe_card_token :

  def update_card(params)
#...
customer.card = params [:stripe_card_token]

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

 参数:{
...
subscription=> {...stripe_card_token=>tok_103PCo26f8kAprmwHCPjZ6T5},
}

params 结构也符合您的表单结构:

 <%= form_for @subscription,:html => {:id => update_card} do | f | %> 
...
<%= f.hidden_​​field:stripe_card_token%>

form_for @subscription 表单为 X 使用 subscription [X] ,以便 hidden_​​field 将在HTML中具有 name =subscription [stripe_card_token],并转换为 params [:subscription] [:stripe_card_token]



也许你的意思是:

  @ subscription.update_card(params [:subscription])

@ subscription.update_card 没有任何参数。您的整个控制器方法应该看起来更像这样:

  def update 
@subscription = current_user.subscription
if @ subscription.update_card(params [:subscription])
redirect_to edit_subscription_path,:success => 更新卡。
else
flash.alert ='无法更新卡。
render:edit
end
end


I finally figured out how to implement Stripes Monthly Billing using this tutorial

Currently my Submit Button for both my #new_subscription form and edit form creates and sends credit card data to Stripe.

But for some reason I keep getting this error when I update the Credit Card

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

Question: Is this error due to the coffeescript, or is my update_card method in my model causing this problem?

EDIT FORM

<%= 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

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)

MODEL

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 = "[email protected]"
    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

CONTROLLER

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

Reference: Stripe Reference for Ruby

LOGS

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'
解决方案

You're calling update_card with params as the argument:

@subscription.update_card(params)

and update_card is expecting :stripe_card_token in params:

def update_card(params)
  #...
  customer.card = params[:stripe_card_token]

but there is no params[:stripe_card_token], the token is in params[:subscription][:stripe_card_token]:

Parameters: {
  ...
  "subscription"=>{ ... "stripe_card_token"=>"tok_103PCo26f8kAprmwHCPjZ6T5"}, 
}

That params structure also matches your form's structure:

<%= form_for @subscription, :html => { :id => "update_card" } do |f| %>
  ...
  <%= f.hidden_field :stripe_card_token %>

The form_for @subscription will set up the form to use subscription[X] for field X so that hidden_field will have name="subscription[stripe_card_token]" in the HTML and that translates to params[:subscription][:stripe_card_token] in the controller.

Perhaps you mean to say:

@subscription.update_card(params[:subscription])

You also have a stray call to @subscription.update_card without any arguments. Your whole controller method should probably look more like this:

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

这篇关于更新条纹信用卡与咖啡的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-19 13:00