2015-11-30 4 views
0

Мы получили Stripe для оплаты подписки в нашем приложении rails 4 с использованием подхода Mastering Modern Payments. Теперь мы пытаемся добавить купоны. Мы хотим использовать Stripe для управления купонами (создание купонов на панели инструментов Stripe).Купон на Stripe не отражен в стоимости или сохранен в базе данных для рельсов 4 app

Проблема в том, что когда пользователь платит, купон не уменьшает сумму, начисленную, и не сохраняется в базе данных приложения с информацией о пользователе и подписке. Мы не получаем никаких ошибок.

Что работает: Мы видим код купона в хеше, когда пользователь платит, а купон устанавливается в Stripe. В целом пользователь может зарегистрироваться и заплатить штраф. Мы делаем два шага, создаем пользователя в Devise, а затем платим. Когда они платят свою подписку, активируются в нашем приложении.

Мы знаем, что здесь отсутствуют недостающие куски для купонов, но мы пытаемся выяснить, что это такое и как его реализовать? Я читал о создании виртуального атрибута в рельсах, поэтому, возможно, мы могли бы сделать это для купонов, так как в настоящее время в таблице «Пользователи» пока нет информации о купонах.

Выход выглядит следующим образом пользователь подписывает вверх для подписки (фактические данные заменяются на проводку):

... Started POST "/subscriptions" for 127.0.0.1 at 2015-11-30 10:33:40 -0800 
Processing by SubscriptionsController#create as HTML 
    Parameters: {"utf8"=>"✓", "authenticity_token"=>"XYZ", "plan_id"=>"5", "email_address"=>"[email protected]", "coupon"=>"123", "stripeToken"=>"tok_xyz"} 
    User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT 1 [["id", 52]] 
    Plan Load (0.3ms) SELECT "plans".* FROM "plans" WHERE "plans"."id" = $1 LIMIT 1 [["id", 5]] 
    User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."email" = $1 LIMIT 1 [["email", "[email protected]"]] 
    (0.3ms) BEGIN 
    SQL (0.4ms) UPDATE "users" SET "stripe_customer_id" = $1, "updated_at" = $2 WHERE "users"."id" = $3 [["stripe_customer_id", "cus_7Rq9Kv4nGh6uD2"], ["updated_at", "2015-11-30 18:33:41.930863"], ["id", 52]] 
    SQL (48.6ms) INSERT INTO "subscriptions" ("plan_id", "user_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["plan_id", 5], ["user_id", 52], ["created_at", "2015-11-30 18:33:41.934364"], ["updated_at", "2015-11-30 18:33:41.934364"]] 
DEPRECATION WARNING: `serialized_attributes` is deprecated without replacement, and will be removed in Rails 5.0. (called from serialized_attributes at /usr/local/rvm/gems/ruby-2.2.1/gems/activerecord-4.2.1/lib/active_record/attribute_methods/serialization.rb:56)... 

Схема для пользователей и подписок (купонов столбец в таблице подписки):

схема .rb:

... 
create_table "subscriptions", force: :cascade do |t| 
    t.date  "purchase_date" 
    t.boolean "active" 
    t.datetime "created_at", null: false 
    t.datetime "updated_at", null: false 
    t.integer "user_id" 
    t.integer "plan_id" 
    t.string "stripe_id" 
    t.string "coupon" 
    end 

    add_index "subscriptions", ["plan_id"], name: "index_subscriptions_on_plan_id", using: :btree 
    add_index "subscriptions", ["user_id"], name: "index_subscriptions_on_user_id", using: :btree 

    create_table "users", force: :cascade do |t| 
    t.string "email",     default: "", null: false 
    t.string "encrypted_password",  default: "" 
    t.string "reset_password_token" 
    t.datetime "reset_password_sent_at" 
    t.datetime "remember_created_at" 
    t.integer "sign_in_count",   default: 0,  null: false 
    t.datetime "current_sign_in_at" 
    t.datetime "last_sign_in_at" 
    t.string "current_sign_in_ip" 
    t.string "last_sign_in_ip" 
    t.datetime "created_at" 
    t.datetime "updated_at" 
    t.string "name" 
    t.string "confirmation_token" 
    t.datetime "confirmed_at" 
    t.datetime "confirmation_sent_at" 
    t.string "unconfirmed_email" 
    t.integer "role" 
    t.string "invitation_token" 
    t.datetime "invitation_created_at" 
    t.datetime "invitation_sent_at" 
    t.datetime "invitation_accepted_at" 
    t.integer "invitation_limit" 
    t.integer "invited_by_id" 
    t.string "invited_by_type" 
    t.integer "invitations_count",  default: 0 
    t.boolean "terms_accepted",   default: false 
    t.string "phone_number" 
    t.string "plan_id" 
    t.string "employer" 
    t.string "stripe_customer_id" 
    end 

    add_index "users", ["email"], name: "index_users_on_email", unique: true, using: :btree 
    add_index "users", ["invitation_token"], name: "index_users_on_invitation_token", unique: true, using: :btree 
    add_index "users", ["invitations_count"], name: "index_users_on_invitations_count", using: :btree 
    add_index "users", ["invited_by_id"], name: "index_users_on_invited_by_id", using: :btree 
    add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree 
... 

Купон в Создание подписки службы объекта:

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, 
      coupon: subscription.coupon, 
     ) 
     user.stripe_customer_id = customer.id 
     user.save! 
     stripe_sub = customer.subscriptions.first 
     else 
     customer = Stripe::Customer.retrieve(user.stripe_customer_id) 
     stripe_sub = customer.subscriptions.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 

Купон на странице получки:

приложение/просмотров/подписок/new.html.haml

= content_for :header do 
    %script{src: 'https://js.stripe.com/v2/', type: 'text/javascript'} 

    :javascript 
     $(function(){ 
      Stripe.setPublishableKey("#{Rails.configuration.stripe[:publishable_key]}"); 
     }); 

    %script{src: '/subscriptions.js', type: 'text/javascript'} 

- unless @subscription.errors.blank? 
    = @subscription.errors.full_messages.to_sentence 
%h2 
    Subscribing to #{@plan.name} 
= form_for @subscription, html: { id: 'payment-form' } do |f| 
    %input{name: 'plan_id', type: 'hidden', value: @plan.id}/ 
    %span.payment-errors 
    .form-row 
     %label 
      %span Email Address 
      %input{name: 'email_address', size: '20', type: 'email', value: @user.email} 
    .form-row 
     %label 
      %span Card Number 
      %input{size: '20', type: 'text', data: {stripe: 'number'}} 
    .form-row 
     %label 
      %span CVC 
      %input{size: '4', type: 'text', data: {stripe: 'cvc'}} 
    .form-row 
     %label 
      %span Expiration (MM/YYYY) 
      %input{size: '2', type: 'text', data: {stripe: 'exp-month'}} 
     %span/
     %input{size: '4', type: 'text', data: {stripe: 'exp-year'}} 
    .form-row 
     %label 
      %span Promo code, if any 
      %input{name: 'coupon', size: '20', type: 'text', value: @coupon} 
    %button{type: 'submit', class: 'btn btn-lg btn-primary'} Pay Now 

И наша модель подписки выглядит следующим образом:

subscription.rb:

class Subscription < ActiveRecord::Base 
     belongs_to :user 
     belongs_to :plan 

     has_paper_trail 

     def inactive? 
     active ? false : true 
     end 

    def active? 
    active 
    end 
end 

Как мы можем получить купонный купон, отраженный в стоимости и сохраненный в нашей базе данных приложений? Спасибо.

+0

Я считаю, что вижу проблему, но могу ли вы сначала опубликовать свой контроллер подписок? –

ответ

0

Ваш CreateSubscription сервис не предоставляет вам возможности для передачи вашего купонного кода.

Вам нужно будет добавить новый параметр для этого, например.

class CreateSubscription 
    def self.call(plan, email_address, token, coupon = nil) 
    # ... 
    subscription = Subscription.new(
     plan: plan, 
     user: user, 
     coupon: coupon 
    ) 
    # ... 
    end 
end 

Кроме того, есть несколько других вещей, чтобы быть в курсе с кодом вы предоставили:

customer = Stripe::Customer.create(
    source: token, 
    email: user.email, 
    plan: plan.stripe_id, 
    coupon: subscription.coupon 
) 

Стипе позволяет установить coupon на обоих клиентов и подписок. При выставлении счетов скидка, применяемая к подписке, отменяет скидку, применяемую на основе всего клиента.См. https://stripe.com/docs/api#subscription_object

Так что, если ваш клиент отменяет свою подписку или имеет другие (несколько) подписки. Они потенциально могут получить скидку, применимую к этим, в зависимости от настроек вашего купона.

Так что, в зависимости от того, что вы хотите совершить, вы можете только передать купон на Stripe::Subscription, а не на Stripe::Customer.

+0

Спасибо Марк Мерфи, мы попробуем это предложение. Отличная идея. – Iggy

 Смежные вопросы

  • Нет связанных вопросов^_^