条带订阅和Rails 4:当新用户尝试购买

时间:2015-11-09 21:15:00

标签: ruby-on-rails ruby-on-rails-4 devise stripe-payments subscriptions

我正在向现有的Rails 4应用添加订阅,我们使用Devise。这是遵循掌握现代支付方法。

我可以从我的rails控制台成功创建一个计划(ID为1)并将其显示在Stripe中。所以我知道基本握手没问题。

作为用户,当我转到付款页面并填写所有信息并单击提交时,我收到错误:路由错误:没有路由匹配[POST]“/ subscriptions”。

我想购买的用户付费页面是 本地主机:3000 /订阅/新plan_id的数据类型= 1

看起来像这样: 订阅/ new.html.erb

<% unless @subscription.errors.blank? %>
    <%= @subscription.errors.full_messages.to_sentence %>
<% end %>

<h2>Subscribing to <%= @plan.name %></h2>

<%= form_for @subscription, html: { id: 'payment-form' } do |f| %>
    <input type="hidden" name="plan_id" value="<%= @plan.id %>" />
    <span class="payment-errors"></span>

    <div class="form-row">
      <label>
        <span>Email Address</span>
        <input type="email" size="20" name="email_address"/>
      </label>
    </div>

    <div class="form-row">
      <label>
        <span>Card Number</span>
        <input type="text" size="20" data-stripe="number"/>
      </label>
    </div>

    <div class="form-row">
      <label>
        <span>CVC</span>
        <input type="text" size="4" data-stripe="cvc"/>
      </label>
    </div>

    <div class="form-row">
      <label>
        <span>Expiration (MM/YYYY)</span>
        <input type="text" size="2" data-stripe="exp-month"/>
      </label>
      <span> / </span>
      <input type="text" size="4" data-stripe="exp-year"/>
    </div>

    <button type="submit">Pay Now</button>
<% end %>

我们有这些路线:

Helper  HTTP Verb   Path    Controller#Action
Path / Url      
Path Match
subscriptions_index_path    GET /subscriptions/index(.:format)  subscriptions#index
subscriptions_new_path  GET /subscriptions/new(.:format)    subscriptions#new
subscriptions_create_path   GET /subscriptions/create(.:format) subscriptions#create
subscriptions_show_path GET /subscriptions/show(.:format)   subscriptions#show
subscriptions_plans_path    GET /subscriptions/plans(.:format)  subscriptions#plans
subscriptions_update_path   GET /subscriptions/update(.:format) subscriptions#update
subscriptions_destroy_path  GET /subscriptions/destroy(.:format)    subscriptions#destroy
plans_index_path    GET /plans/index(.:format)  plans#index
plans_show_path GET /plans/show(.:format)   plans#show
stripe_checkout_path    POST    /stripe_checkout(.:format)  subscription#stripe_checkout
subscription_checkout_path  POST    /subscription_checkout(.:format)    subscription#subscription_checkout
new_user_session_path   GET /users/sign_in(.:format)    devise/sessions#new
user_session_path   POST    /users/sign_in(.:format)    devise/sessions#create
destroy_user_session_path   DELETE  /users/sign_out(.:format)   devise/sessions#destroy
user_password_path  POST    /users/password(.:format)   devise/passwords#create
new_user_password_path  GET /users/password/new(.:format)   devise/passwords#new
edit_user_password_path GET /users/password/edit(.:format)  devise/passwords#edit
PATCH   /users/password(.:format)   devise/passwords#update
PUT /users/password(.:format)   devise/passwords#update
cancel_user_registration_path   GET /users/cancel(.:format) users#cancel
user_registration_path  POST    /users(.:format)    users#create
new_user_registration_path  GET /users/sign_up(.:format)    users#new
edit_user_registration_path GET /users/edit(.:format)   users#edit
PATCH   /users(.:format)    users#update
PUT /users(.:format)    users#update
DELETE  /users(.:format)    users#destroy
accept_user_invitation_path GET /users/invitation/accept(.:format)  devise/invitations#edit
remove_user_invitation_path GET /users/invitation/remove(.:format)  devise/invitations#destroy
user_invitation_path    POST    /users/invitation(.:format) devise/invitations#create
new_user_invitation_path    GET /users/invitation/new(.:format) devise/invitations#new
PATCH   /users/invitation(.:format) devise/invitations#update
PUT /users/invitation(.:format) devise/invitations#update
users_path  GET /users(.:format)    users#index
POST    /users(.:format)    users#create
new_user_path   GET /users/new(.:format)    users#new
edit_user_path  GET /users/:id/edit(.:format)   users#edit
user_path   GET /users/:id(.:format)    users#show
PATCH   /users/:id(.:format)    users#update
PUT /users/:id(.:format)    users#update
DELETE  /users/:id(.:format)    users#destroy
entries_path    POST    /entries(.:format)  entries#create
new_entry_path  GET /entries/new(.:format)  entries#new
edit_entry_path GET /entries/:id/edit(.:format) entries#edit
entry_path  GET /entries/:id(.:format)  entries#show
PATCH   /entries/:id(.:format)  entries#update
PUT /entries/:id(.:format)  entries#update
DELETE  /entries/:id(.:format)  entries#destroy
orders_path GET /orders(.:format)   orders#index
POST    /orders(.:format)   orders#create
new_order_path  GET /orders/new(.:format)   orders#new
edit_order_path GET /orders/:id/edit(.:format)  orders#edit
order_path  GET /orders/:id(.:format)   orders#show
PATCH   /orders/:id(.:format)   orders#update
PUT /orders/:id(.:format)   orders#update
DELETE  /orders/:id(.:format)   orders#destroy
last24_s1_events_path   GET /s1_events/last24(.:format) s1_events#last24
s1_event_subscriptions_path GET /s1_events/:s1_event_id/subscriptions(.:format) subscriptions#index
POST    /s1_events/:s1_event_id/subscriptions(.:format) subscriptions#create
new_s1_event_subscription_path  GET /s1_events/:s1_event_id/subscriptions/new(.:format) subscriptions#new
s1_events_path  GET /s1_events(.:format)    s1_events#index
upmin_path      /admin  Upmin::Engine
root_path   GET /   dashboard#index
income_path GET /income(.:format)   dashboard#income
liquidity_path  GET /liquidity(.:format)    dashboard#liquidity
time_horizon_path   GET /time-horizon(.:format) dashboard#time_horizon
get_feed_path   GET /get-feed(.:format) pages#get_feed
get_updates_path    GET /get-updates(.:format)  pages#get_updates
subscriptions_path  GET /subscriptions(.:format)    pages#subscriptions
api_path    GET /api(.:format)  pages#api
icons_path  GET /icons(.:format)    pages#icons
contact_us_path GET /contact_us(.:format)   contacts#new
s1_qa_path  GET /s1-qa(.:format)    pages#s1_qa
contacts_path   POST    /contacts(.:format) contacts#create
Routes for Upmin::Engine
root_path   GET /   upmin/models#dashboard
upmin_dashboard_path    GET /   upmin/models#dashboard
upmin_search_path   GET|POST    /m/:klass(.:format) upmin/models#search
upmin_new_model_path    GET /m/:klass/new(.:format) upmin/models#new
upmin_create_model_path POST    /m/:klass/new(.:format) upmin/models#create
upmin_model_path    GET /m/:klass/i/:id(.:format)   upmin/models#show
PUT /m/:klass/i/:id(.:format)   upmin/models#update
upmin_action_path   POST    /m/:klass/i/:id/:method(.:format)   upmin/models#action

我们的routes.rb文件如下所示:

Rails.application.routes.draw do

  get 'subscriptions/index'

  get 'subscriptions/new'

  get 'subscriptions/create'

  get 'subscriptions/show'

  get 'subscriptions/plans'

  get 'subscriptions/update'

  get 'subscriptions/destroy'

  get 'plans/index'

  get 'plans/show'

  post 'stripe_checkout' => 'subscription#stripe_checkout'
  post 'subscription_checkout' => 'subscription#subscription_checkout'


  devise_for :users, :controllers => { registrations: 'users' }
  resources :users
  resources :entries, except: [:index]
  resources :orders
  resources :s1_events, only: [:index] do
    get 'last24', on: :collection
  resources :subscriptions, only: [:index, :new, :create]
  end

  mount Upmin::Engine => '/admin'

  root to: 'dashboard#index'
  get 'income', to: 'dashboard#income'
  get 'liquidity', to: 'dashboard#liquidity'
  get 'time-horizon', to: 'dashboard#time_horizon'
  get 'get-feed', to: 'pages#get_feed'
  get 'get-updates', to: 'pages#get_updates'
  get 'subscriptions', to: 'pages#subscriptions'
  get 'api', to: 'pages#api'
  get 'icons', to: 'pages#icons'
  get 'contact_us', to: 'contacts#new'
  get 's1-qa', to: 'pages#s1_qa'
  resources 'contacts', only: [:create]
end

我们有一个CreateSubscription服务对象: create_subscription.rb

class CreateSubscription
  def self.call(plan, email_address, token)
    user, raw_token = CreateUser.call(email_address)

    subscription = Subscription.new(
        plan: plan,
        user: user
    )

    begin
      stripe_sub = nil
      if user.stripe_customer_id.blank?
        customer = Stripe::Customer.create(
            source: token,
            email: user.email,
            plan: plan.stripe_id,
        )
        user.stripe_customer_id = customer.id
        user.save!
        stripe_sub = customer.subscriptions_choices.first
      else
        customer = Stripe::Customer.retrieve(user.stripe_customer_id)
        stripe_sub = customer.subscriptions_choices.create(
            plan: plan.stripe_id
        )
      end

      subscription.stripe_id = stripe_sub.id

      subscription.save!
    rescue Stripe::StripeError => e
      subscription.errors[:base] << e.message
    end

    subscription
  end
end

这里指的是CreateUser服务对象: create_user.rb

class CreateUser
  def self.call(email_address)

    user = User.find_by(email: email_address)

    return user if user.present?

    raw_token, enc_token = Devise.token_generator.generate(
        User, :reset_password_token)
    password = SecureRandom.hex(32)

    user = User.create!(
        email: email_address,
        password: password,
        password_confirmation: password,
        reset_password_token: enc_token,
        reset_password_sent_at: Time.now
    )

    return user, raw_token
  end
end

这些应该合作的方式是在Devise之后。意思是,如果用户已存在,则会向其添加付款。如果没有,请创建一个新用户。所以Devise在这里不应该有任何问题。

有关如何解决此错误以及让我的用户购买订阅的任何建议都非常感谢。

1 个答案:

答案 0 :(得分:0)

错误信息非常简单。您没有POST /subscriptions路线。

您还有很多其他内容,例如get 'subscriptions/create'POST /s1_events/:s1_event_id/subscriptions

我建议你先清理你的路线。

get 'subscriptions/index'
get 'subscriptions/new'
get 'subscriptions/create'
get 'subscriptions/show'
get 'subscriptions/plans'
get 'subscriptions/update'
get 'subscriptions/destroy'

不要这样做。 GET操作应始终为idempotent。您还违反了Rails REST约定:

GET    '/subscriptions'     => index
POST   '/subscriptions'     => create
GET    '/subscriptions/:id' => show
PATCH  '/subscriptions/:id' => update
DELETE '/subscriptions/:id' => destroy

除非你subscriptions/update,否则那些GET subscriptions/update?id=foo&bar=baz和销毁路径将无效。呸。

resources :subscriptions

http://guides.rubyonrails.org/routing.html#resource-routing-the-rails-default