Ruby on rails Stripe and Rails 5-Stripe::InvalidRequestError:没有这样的计划:starter

Ruby on rails Stripe and Rails 5-Stripe::InvalidRequestError:没有这样的计划:starter,ruby-on-rails,stripe-payments,Ruby On Rails,Stripe Payments,我几乎看完了Ryan Bigg的《Rails多租户-第二版》一书,发现自己在将应用程序与Stripe集成时陷入了困境。特别是,我遇到了这个问题: 测试失败如下所示: Failures: 1) Subscriptions can be cancelled Failure/Error: subscription = customer.subscriptions.create(plan: "starter") Stripe::InvalidRequestError: No suc

我几乎看完了Ryan Bigg的《Rails多租户-第二版》一书,发现自己在将应用程序与Stripe集成时陷入了困境。特别是,我遇到了这个问题:

测试失败如下所示:

Failures:

1) Subscriptions can be cancelled
     Failure/Error: subscription = customer.subscriptions.create(plan: "starter")

 Stripe::InvalidRequestError:
   No such plan: starter
 # ./spec/features/accounts/subscriptions_spec.rb:20:in `block (2 levels) in <top (required)>'
 # ./spec/rails_helper.rb:40:in `block (3 levels) in <top (required)>'
 # ./spec/rails_helper.rb:39:in `block (2 levels) in <top (required)>'
 # ------------------
 # --- Caused by: ---
 # RestClient::BadRequest:
 #   400 Bad Request
 #   ./spec/features/accounts/subscriptions_spec.rb:20:in `block (2 levels) in <top (required)>'

Finished in 1.42 seconds (files took 5.1 seconds to load)
1 example, 1 failure

Failed examples:

rspec ./spec/features/accounts/subscriptions_spec.rb:30 # Subscriptions can be cancelled
require "rails_helper"
require "stripe_plan_fetcher"

describe StripePlanFetcher do
  let(:faux_plan) do
    double("plan",
              id: "starter",
              nickname: "Starter",
              amount: 995)
  end

  it "fetches and stores plans" do
    expect(Stripe::Plan).to receive(:all).and_return([faux_plan])
    expect(Plan).to receive(:create).with({
      stripe_id: "starter",
      name: "Starter",
      amount: 995
      })

      StripePlanFetcher.store_locally
  end

  it "checks and updates plans" do
    expect(Stripe::Plan).to receive(:all).and_return([faux_plan])
    expect(Plan).to receive(:find_by).
                                with(stripe_id: faux_plan.id).
                                and_return(plan = double)
    expect(plan).to receive(:update).with({
      name: "Starter",
      amount: 995
      })

    expect(Plan).to_not receive(:create)

    StripePlanFetcher.store_locally
  end
end
class Accounts::PlansController < Accounts::BaseController
  skip_before_action :subscription_required!

  def choose
    @plans = Plan.order(:amount)
  end

  def chosen
    customer = Stripe::Customer.retrieve(current_account.stripe_customer_id)
    plan = Plan.find(params[:account][:plan_id])
    subscription = customer.subscriptions.create(
      plan: plan.stripe_id,
      source: params[:token]
    )

    current_account.plan = plan
    current_account.stripe_subscription_id = subscription.id
    current_account.stripe_subscription_status = "active"
    current_account.save
    flash[:notice] = "Your account has been created."
    redirect_to root_url(subdomain: current_account.subdomain)
  end

  def cancel
    customer = Stripe::Customer.retrieve(current_account.stripe_customer_id)
    subscription = customer.subscriptions.retrieve(current_account.stripe_subscription_id).delete
    if subscription.status == "canceled"
      current_account.update_column(:stripe_subscription_id, nil)
      flash[:notice] = "Your subscription to Twist has been cancelled."
      redirect_to root_url(subdomain: nil)
    end
  end
end
除了测试规范失败之外,当我访问subdomain.lvh.me:3000并经历注册用户+输入测试cc信息的过程时,条带过程似乎在一定程度上正常工作,但我被重定向到以下错误:

Stripe::InvalidRequestError in Accounts::PlansController#chosen
Received unknown parameter: source

customer = Stripe::Customer.retrieve(current_account.stripe_customer_id)
plan = Plan.find(params[:account][:plan_id])
subscription = customer.subscriptions.create(
  plan: plan.stripe_id,
  source: params[:token]
)
我的Plans Controller代码如下所示:

Failures:

1) Subscriptions can be cancelled
     Failure/Error: subscription = customer.subscriptions.create(plan: "starter")

 Stripe::InvalidRequestError:
   No such plan: starter
 # ./spec/features/accounts/subscriptions_spec.rb:20:in `block (2 levels) in <top (required)>'
 # ./spec/rails_helper.rb:40:in `block (3 levels) in <top (required)>'
 # ./spec/rails_helper.rb:39:in `block (2 levels) in <top (required)>'
 # ------------------
 # --- Caused by: ---
 # RestClient::BadRequest:
 #   400 Bad Request
 #   ./spec/features/accounts/subscriptions_spec.rb:20:in `block (2 levels) in <top (required)>'

Finished in 1.42 seconds (files took 5.1 seconds to load)
1 example, 1 failure

Failed examples:

rspec ./spec/features/accounts/subscriptions_spec.rb:30 # Subscriptions can be cancelled
require "rails_helper"
require "stripe_plan_fetcher"

describe StripePlanFetcher do
  let(:faux_plan) do
    double("plan",
              id: "starter",
              nickname: "Starter",
              amount: 995)
  end

  it "fetches and stores plans" do
    expect(Stripe::Plan).to receive(:all).and_return([faux_plan])
    expect(Plan).to receive(:create).with({
      stripe_id: "starter",
      name: "Starter",
      amount: 995
      })

      StripePlanFetcher.store_locally
  end

  it "checks and updates plans" do
    expect(Stripe::Plan).to receive(:all).and_return([faux_plan])
    expect(Plan).to receive(:find_by).
                                with(stripe_id: faux_plan.id).
                                and_return(plan = double)
    expect(plan).to receive(:update).with({
      name: "Starter",
      amount: 995
      })

    expect(Plan).to_not receive(:create)

    StripePlanFetcher.store_locally
  end
end
class Accounts::PlansController < Accounts::BaseController
  skip_before_action :subscription_required!

  def choose
    @plans = Plan.order(:amount)
  end

  def chosen
    customer = Stripe::Customer.retrieve(current_account.stripe_customer_id)
    plan = Plan.find(params[:account][:plan_id])
    subscription = customer.subscriptions.create(
      plan: plan.stripe_id,
      source: params[:token]
    )

    current_account.plan = plan
    current_account.stripe_subscription_id = subscription.id
    current_account.stripe_subscription_status = "active"
    current_account.save
    flash[:notice] = "Your account has been created."
    redirect_to root_url(subdomain: current_account.subdomain)
  end

  def cancel
    customer = Stripe::Customer.retrieve(current_account.stripe_customer_id)
    subscription = customer.subscriptions.retrieve(current_account.stripe_subscription_id).delete
    if subscription.status == "canceled"
      current_account.update_column(:stripe_subscription_id, nil)
      flash[:notice] = "Your subscription to Twist has been cancelled."
      redirect_to root_url(subdomain: nil)
    end
  end
end
架构帐户:

create_table "accounts", force: :cascade do |t|
    t.string   "name"
    t.datetime "created_at",             null: false
    t.datetime "updated_at",             null: false
    t.integer  "owner_id"
    t.string   "subdomain"
    t.string   "stripe_customer_id"
    t.integer  "plan_id"
    t.string   "stripe_subscription_id"
    t.index ["plan_id"], name: "index_accounts_on_plan_id", using: :btree
    t.index ["subdomain"], name: "index_accounts_on_subdomain", using: :btree
  end
条带计划获取程序

class StripePlanFetcher
  def self.store_locally
    Stripe::Plan.all.each do |plan|
      if local_plan = Plan.find_by(stripe_id: plan.id)
        local_plan.update(
          name: plan.nickname,
          amount: plan.amount
        )
      else
        Plan.create(
          name: plan.nickname,
          amount: plan.amount,
          stripe_id: plan.id
        )
      end
    end
  end
end

问题在于,您试图创建一个具有属性的订阅,但“计划”不是订阅的属性,而是对计划记录的引用。最有可能的是订阅有一个名为
plan\u id
的属性(在将来发布所有模式-在这种情况下,了解订阅的模式会很有帮助)

因此,在这种情况下,您可能需要声明
plan
是什么样的:

@plan=plan.find_by(name:'starter')


customer.subscriptions.create(plan:@plan)

您也可以发布模型的模式吗?问题是您正在使用属性
plan='starter'
创建订阅。我猜
starter
类似于
plan.id
plan.name
。它应该是这样的:
customer.subscriptions.create(plan\u id:1)
@gwalshington刚刚发布在上面。感谢您的帮助/想法。我不确定这是否会改变您的答案/想法,但我设置它的方式是,我在stripe中创建了计划,并使用stripe\u plan\u fetcher.rb检索我在stripe中创建的计划。其中一个计划名为“启动者”(不过这是一个昵称)。不过,上面更新“starter”中的条带计划获取程序代码不是
id
。这是
名称
。查看并可能应该将
计划
作为
项目
列表传递