Я почти закончил с книгой Райана Бигга «Мультитенантность с Rails - 2-е издание» и застрял при интеграции моего приложения с 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
Помимо сбоя тестовой спецификации, когда я захожу на subdomain.lvh.me:3000 и прохожу процесс регистрации пользователя + вставки тестовой информации cc, процесс Stripe, кажется, работает - в некоторой степени - но я перенаправлен на эту ошибку:
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]
)
Мой код для контроллера планов выглядит следующим образом:
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
--- Обновление 1 ---
Схемы:
create_table "plans", force: :cascade do |t|
t.string "name"
t.integer "amount"
t.string "stripe_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
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