effective_orders 4.0.0beta5 → 4.0.0beta6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: bd54f1217fe33988f924bf40803efd702916d971
4
- data.tar.gz: 291f290fd3cf4b8636ce5103a86b976760e12122
3
+ metadata.gz: 12e3f1de057495a5b6c3dc1b6cbc8127ef8736bf
4
+ data.tar.gz: d30298b8aac6de0afee57cc5e9af2552b01d5519
5
5
  SHA512:
6
- metadata.gz: 546166ac0b6f8948af732a82bdd2ba8b2e59f11ce6f734d10b1d6dd49350926d764331fe179d71f01a3a9d4510786254dfd6bbfeac0cffb992b821d03ea70c6c
7
- data.tar.gz: 1d1602f8456cbf830c82ca6f298b85ca465b384240a5867479df1280a7384c1693e5b1970ff21e9b353bba3371268da37fb21ae4fb17a82bef993be0c74c5418
6
+ metadata.gz: 9524eb918036d200c9d51f5c383e37a05afd43448dffb67e58d25bb43770a20f01e99ff4e09093f86d25d6506c28f7b859848d2c5bef6fe4ca8211b00d6f3b63
7
+ data.tar.gz: 020f1ae55841895de717445760e905c5e8640101d47ea05e3bc8327a805c5544cb844a02c70402a0d2e1144551de15e55b82edb2666190ababe141e253e0b1db
@@ -1,31 +1,29 @@
1
1
  stripeCustomerChangeCardHandler = (key, form) ->
2
2
  StripeCheckout.configure
3
3
  key: key
4
- closed: -> EffectiveBootstrap.enable(form) unless form.hasClass('stripe-success')
4
+ closed: -> EffectiveForm.reset(form) unless form.hasClass('stripe-success')
5
5
  token: (token, args) ->
6
6
  if token.error
7
- message = "An error ocurred when contacting Stripe. Your card has not been charged. Your subscription has not changed. Please refresh the page and try again. #{token.error.message}"
7
+ message = "An error ocurred when contacting Stripe. Your card has not been charged. Please refresh the page and try again. #{token.error.message}"
8
8
 
9
9
  form.removeClass('stripe-success')
10
- form.find('.effective-orders-customer').find('.invalid-feedback').html(message).show()
10
+ form.find('.invalid-feedback').html(message).show()
11
11
  alert(message)
12
12
  else
13
13
  form.find("input[name$='[stripe_token]']").val('' + token['id'])
14
-
15
- $customer = form.find('.effective-orders-customer')
16
- $customer.find('.payment-status').html("**** **** **** #{token.card.last4} #{token.card.brand} #{token.card.exp_month}/#{token.card.exp_year}")
17
-
18
- if $customer.data('submit')
19
- form.addClass('stripe-success').submit()
14
+ form.addClass('stripe-success').submit() # Submits the form. As this is a remote form, submits via JS
20
15
 
21
16
  # When we click 'Change credit card', make sure the form collects a credit card
22
- $(document).on 'click', '.effective-orders-customer .btn-change-card', (event) ->
23
- event.preventDefault()
24
-
17
+ $(document).on 'click', ".effective-orders-stripe-update-card[type='submit']", (event) ->
25
18
  $form = $(event.currentTarget).closest('form')
26
- stripe = $(event.currentTarget).closest('.effective-orders-customer').data('stripe')
27
19
 
28
- EffectiveBootstrap.submitting($form)
20
+ # Get stripe data payload
21
+ stripe = $form.data('stripe')
22
+ return unless stripe?
23
+
24
+ # Okay, we're good to call stripe
25
+ event.preventDefault()
26
+ EffectiveForm.submitting($form) # Disable and spin while we popup stripe
29
27
 
30
28
  stripeCustomerChangeCardHandler(stripe.key, $form).open
31
29
  image: stripe.image
@@ -1,7 +1,7 @@
1
1
  stripeCheckoutHandler = (key, form) ->
2
2
  StripeCheckout.configure
3
3
  key: key
4
- closed: -> EffectiveBootstrap.enable(form) unless form.hasClass('stripe-success')
4
+ closed: -> EffectiveBootstrap.reset(form) unless form.hasClass('stripe-success')
5
5
  token: (token, args) ->
6
6
  if token.error
7
7
  alert("An error ocurred when contacting Stripe. Your card has not been charged. Please refresh the page and try again. #{token.error.message}")
@@ -1,56 +1,42 @@
1
1
  stripeSubscriptionHandler = (key, form) ->
2
2
  StripeCheckout.configure
3
3
  key: key
4
- closed: -> EffectiveBootstrap.enable(form) unless form.hasClass('stripe-success')
4
+ closed: -> EffectiveForm.reset(form) unless form.hasClass('stripe-success')
5
5
  token: (token, args) ->
6
6
  if token.error
7
- message = "An error ocurred when contacting Stripe. Your card has not been charged. Your subscription has not changed. Please refresh the page and try again. #{token.error.message}"
7
+ message = "An error ocurred when contacting Stripe. Your card has not been charged. Your plan has not changed. Please refresh the page and try again. #{token.error.message}"
8
8
 
9
9
  form.removeClass('stripe-success')
10
- form.find('.effective-orders-stripe-plans').find('.invalid-feedback').html(message).show()
10
+ form.find('.invalid-feedback').html(message).show()
11
11
  alert(message)
12
12
  else
13
13
  form.find("input[name$='[stripe_token]']").val('' + token['id'])
14
- form.addClass('stripe-success').submit()
14
+ form.addClass('stripe-success').submit() # Submits the form. As this is a remote form, submits via JS
15
15
 
16
- # When I submit a for that needs a subscripter token, do the stripe thing.
17
- $(document).on 'click', ".effective-orders-subscripter-token-required[type='submit']", (event) ->
18
- event.preventDefault()
16
+ # Hijack submit and get a stripe token
17
+ $(document).on 'click', ".effective-orders-stripe-token-required[type='submit']", (event) ->
19
18
  $form = $(event.currentTarget).closest('form')
20
19
 
21
- # Get the stripe data
22
- $plans = $form.find('.effective-orders-stripe-plans').first()
23
- selected_plan_id = $plans.find("input[name$='[subscripter][stripe_plan_id]']:checked").val()
24
- return unless $plans.length > 0 && selected_plan_id.length > 0
20
+ # Get stripe data payload
21
+ stripe = $form.data('stripe')
22
+ return unless stripe?
25
23
 
26
- EffectiveBootstrap.submitting($form)
24
+ # Make sure there is a plan selected
25
+ selected_plan_id = $form.find("input[name$='[stripe_plan_id]']:checked").val() || ''
26
+ return unless selected_plan_id.length > 0
27
27
 
28
- stripe = $plans.data('stripe')
28
+ # Match plan
29
29
  plan = stripe.plans.find (plan, _) => plan.id == selected_plan_id
30
+ return unless plan?
31
+
32
+ # Okay, we're good to call stripe
33
+ event.preventDefault()
34
+ EffectiveForm.submitting($form) # Disable and spin while we popup stripe
30
35
 
31
36
  stripeSubscriptionHandler(stripe.key, $form).open
32
37
  image: stripe.image
33
38
  name: stripe.name
34
- description: plan.name
35
39
  email: stripe.email
40
+ description: plan.name
36
41
  amount: plan.amount
37
- panelLabel: "{{amount}}#{plan.occurrence} Go!"
38
-
39
- # When I click on a stripe plan ID radio button, add .effective-orders-subscripter-token-required to the form if required
40
- $(document).on 'change', "input[name$='[subscripter][stripe_plan_id]']", (event) ->
41
- $plan = $(event.currentTarget)
42
- return unless $plan.is(':checked')
43
-
44
- selected_plan_id = $plan.val()
45
-
46
- $plans = $plan.closest('.effective-orders-stripe-plans').first()
47
- plan = $plans.data('stripe').plans.find (plan, _) => plan.id == selected_plan_id
48
-
49
- token_required = $plans.data('stripe').token_required
50
-
51
- if (plan.amount || 0) > 0 && token_required
52
- $plans.closest('form').find("input[type='submit'],button[type='submit']").addClass('effective-orders-subscripter-token-required')
53
- else
54
- $plans.closest('form').find("input[type='submit'],button[type='submit']").removeClass('effective-orders-subscripter-token-required')
55
-
56
- true
42
+ panelLabel: "{{amount}}/#{plan.interval} Go!"
@@ -2,42 +2,24 @@ module Effective
2
2
  class CustomersController < ApplicationController
3
3
  layout (EffectiveOrders.layout.kind_of?(Hash) ? EffectiveOrders.layout[:customers] : EffectiveOrders.layout)
4
4
 
5
- before_action :authenticate_user!
5
+ include Effective::CrudController
6
6
 
7
- # Get here by visiting /customer/settings
8
- def edit
9
- @customer = Effective::Customer.where(user: current_user).first!
10
- EffectiveOrders.authorize!(self, :edit, @customer)
7
+ submit :save, 'Save', redirect: :back, success: -> { 'Successfully updated card.' }
8
+ page_title 'Customer Settings'
11
9
 
12
- @subscripter = Effective::Subscripter.new(customer: @customer, user: @customer.user)
13
-
14
- @page_title ||= "Customer #{current_user.to_s}"
10
+ def resource
11
+ @customer ||= Effective::Customer.where(user: current_user).first!
12
+ @subscripter ||= Effective::Subscripter.new(customer: @customer, user: @customer.user)
15
13
  end
16
14
 
17
- def update
18
- @customer = Effective::Customer.where(user: current_user).first!
19
- EffectiveOrders.authorize!(self, :update, @customer)
20
-
21
- @subscripter = Effective::Subscripter.new(customer: @customer, user: @customer.user)
22
- @subscripter.assign_attributes(subscripter_params)
23
-
24
- @page_title ||= "Customer #{current_user.to_s}"
25
-
26
- if (@subscripter.save! rescue false)
27
- flash[:success] = "Successfully updated customer settings"
28
- redirect_to(effective_orders.customer_settings_path)
29
- else
30
- flash.now[:danger] = "Unable to update customer settings: #{@subscripter.errors.full_messages.to_sentence}"
31
- render :edit
32
- end
15
+ # I don't want save_resource to wrap my save in a transaction
16
+ def save_resource(resource, action)
17
+ resource.save!
33
18
  end
34
19
 
35
- private
36
-
37
20
  # StrongParameters
38
- def subscripter_params
21
+ def customer_params
39
22
  params.require(:effective_subscripter).permit(:stripe_token)
40
23
  end
41
-
42
24
  end
43
25
  end
@@ -0,0 +1,23 @@
1
+ module Effective
2
+ class SubscripterController < ApplicationController
3
+ layout (EffectiveOrders.layout.kind_of?(Hash) ? EffectiveOrders.layout[:subscriptions] : EffectiveOrders.layout)
4
+
5
+ include Effective::CrudController
6
+
7
+ submit :save, 'Save', redirect: :back, success: -> { 'Successfully updated plan.' }
8
+
9
+ def resource
10
+ @subscripter ||= Effective::Subscripter.new(user: current_user)
11
+ end
12
+
13
+ # I don't want save_resource to wrap my save in a transaction
14
+ def save_resource(resource, action)
15
+ resource.save!
16
+ end
17
+
18
+ # StrongParameters
19
+ def subscripter_params
20
+ params.require(:effective_subscripter).permit!
21
+ end
22
+ end
23
+ end
@@ -26,18 +26,19 @@ module Effective
26
26
 
27
27
  when 'invoice.payment_succeeded'
28
28
  customer = Effective::Customer.where(stripe_customer_id: @event.data.object.customer).first!
29
- customer.update_attributes!(status: 'active')
29
+ customer.update_attributes!(status: EffectiveOrders::ACTIVE)
30
30
 
31
31
  send_email(:subscription_payment_succeeded, customer)
32
32
  when 'invoice.payment_failed'
33
33
  customer = Effective::Customer.where(stripe_customer_id: @event.data.object.customer).first!
34
- customer.update_attributes!(status: 'past_due')
34
+ customer.update_attributes!(status: EffectiveOrders::PAST_DUE)
35
35
 
36
36
  send_email(:subscription_payment_failed, customer)
37
37
  when 'customer.subscription.deleted'
38
38
  customer = Effective::Customer.where(stripe_customer_id: @event.data.object.customer).first!
39
39
  Effective::Subscription.where(customer: customer).destroy_all
40
40
  customer.update_attributes!(stripe_subscription_id: nil, status: nil, active_card: nil)
41
+ customer.subscriptions.delete_all
41
42
 
42
43
  send_email(:subscription_canceled, customer)
43
44
  else
@@ -1,32 +1,19 @@
1
1
  module EffectiveSubscriptionsHelper
2
2
 
3
- def effective_customer_fields(form, submit: true)
3
+ def stripe_plans_collection(form)
4
4
  raise 'expected an Effective::FormBuilder object' unless form.class.name == 'Effective::FormBuilder'
5
- raise 'form object must be an Effective::Subscripter object' unless form.object.class.name == 'Effective::Subscripter'
6
5
 
7
- render(
8
- partial: 'effective/customers/fields',
9
- locals: {
10
- f: form,
11
- submit: submit,
12
- stripe: {
13
- email: form.object.customer.user.email,
14
- image: stripe_site_image_url,
15
- key: EffectiveOrders.stripe[:publishable_key],
16
- name: EffectiveOrders.stripe[:site_title],
17
- }
18
- }
19
- )
20
- end
6
+ subscripter = form.object
7
+ raise 'form object must be a subscripter object' unless subscripter.class.name == 'Effective::Subscripter'
21
8
 
22
- def stripe_plans_collection(form, include_trial: nil)
23
- raise 'expected an Effective::FormBuilder object' unless form.class.name == 'Effective::FormBuilder'
24
- raise 'form object must be an acts_as_subscribable object' unless form.object.subscribable.subscripter.present?
25
-
26
- include_trial = form.object.subscribable.trialing? if include_trial.nil?
9
+ plans = EffectiveOrders.stripe_plans.values.sort do |x, y|
10
+ amount = (x[:amount] <=> y[:amount])
11
+ (amount != 0) ? amount : x[:name] <=> y[:name]
12
+ end
27
13
 
28
- plans = include_trial ? EffectiveOrders.stripe_plans : EffectiveOrders.stripe_plans.except('trial')
29
- plans = plans.values.sort { |x, y| (amount = x[:amount] <=> y[:amount]) != 0 ? amount : x[:name] <=> y[:name] }
14
+ if (existing = subscripter.customer.stripe_subscription_interval).present?
15
+ plans.select! { |plan| plan[:interval] == existing }
16
+ end
30
17
 
31
18
  plans.map do |plan|
32
19
  partial = (
@@ -49,27 +36,34 @@ module EffectiveSubscriptionsHelper
49
36
  end
50
37
  end
51
38
 
52
- def effective_subscription_fields(form, label: false, required: true, include_trial: nil)
53
- raise 'expected an Effective::FormBuilder object' unless form.class.name == 'Effective::FormBuilder'
54
- raise 'form object must be an acts_as_subscribable object' unless form.object.subscripter.present?
55
-
56
- render(
57
- partial: 'effective/subscriptions/fields',
58
- locals: {
59
- form: form,
60
- label: label,
61
- required: required,
62
- include_trial: include_trial,
63
- stripe: {
64
- email: form.object.subscribable_buyer.email,
65
- image: stripe_site_image_url,
66
- key: EffectiveOrders.stripe[:publishable_key],
67
- name: EffectiveOrders.stripe[:site_title],
68
- plans: EffectiveOrders.stripe_plans.values,
69
- token_required: form.object.subscripter.token_required?
70
- },
71
- }
72
- )
39
+ def subscribable_form_with(subscribable)
40
+ raise 'form object must be an acts_as_subscribable object' unless subscribable.respond_to?(:subscripter)
41
+
42
+ subscripter = subscribable.subscripter
43
+ raise 'subscribable.subscribable_buyer must match current_user' unless subscripter.user == current_user
44
+
45
+ render('effective/subscripter/form', subscripter: subscripter)
73
46
  end
74
47
 
48
+ def customer_form_with(customer)
49
+ raise 'form object must be an Effective::Customer object' unless customer.kind_of?(Effective::Customer)
50
+ raise 'expected customer user to match current user' if customer.user != current_user
51
+
52
+ subscripter = Effective::Subscripter.new(customer: customer, user: customer.user)
53
+
54
+ render('effective/customers/form', subscripter: subscripter)
55
+ end
56
+
57
+ def subscripter_stripe_data(subscripter)
58
+ {
59
+ email: current_user.email,
60
+ image: stripe_site_image_url,
61
+ key: EffectiveOrders.stripe[:publishable_key],
62
+ name: EffectiveOrders.stripe[:site_title],
63
+ plans: EffectiveOrders.stripe_plans.values
64
+ }
65
+ end
66
+
67
+
68
+
75
69
  end
@@ -27,8 +27,6 @@ module ActsAsSubscribable
27
27
  validates :trialing_until, presence: true, if: -> { EffectiveOrders.trial? }
28
28
  validates :subscription_status, inclusion: { allow_nil: true, in: EffectiveOrders::STATUSES.keys }
29
29
 
30
- validates :subscripter, associated: true
31
-
32
30
  scope :trialing, -> { where(subscription_status: nil).where('trialing_until > ?', Time.zone.now) }
33
31
  scope :trial_past_due, -> { where(subscription_status: nil).where('trialing_until < ?', Time.zone.now) }
34
32
  scope :not_trialing, -> { where.not(subscription_status: nil) }
@@ -45,10 +43,6 @@ module ActsAsSubscribable
45
43
  @_effective_subscripter ||= Effective::Subscripter.new(subscribable: self, user: subscribable_buyer)
46
44
  end
47
45
 
48
- def subscripter=(atts)
49
- subscripter.assign_attributes(atts)
50
- end
51
-
52
46
  def subscribed?(stripe_plan_id = nil)
53
47
  return false if subscription_status.blank?
54
48
  stripe_plan_id ? (subscription&.stripe_plan_id == stripe_plan_id) : true
@@ -5,26 +5,23 @@ module Effective
5
5
  attr_accessor :stripe_customer, :stripe_subscription
6
6
 
7
7
  belongs_to :user
8
- has_many :subscribables, as: :subscribable
9
-
10
- has_many :subscriptions, class_name: 'Effective::Subscription', foreign_key: 'customer_id'
11
- has_many :subscribables, through: :subscriptions, source: :subscribable
12
-
13
- #accepts_nested_attributes_for :subscriptions
8
+ has_many :subscriptions, -> { includes(:subscribable) }, class_name: 'Effective::Subscription', foreign_key: 'customer_id'
9
+ accepts_nested_attributes_for :subscriptions
14
10
 
15
11
  # Attributes
16
12
  # stripe_customer_id :string # cus_xja7acoa03
17
13
  # active_card :string # **** **** **** 4242 Visa 05/12
18
14
 
19
15
  # stripe_subscription_id :string # Each user gets one stripe subscription object, which can contain many items
16
+ # stripe_subscription_interval :string
20
17
  # status :string
21
18
 
22
19
  # timestamps
23
20
 
24
21
  scope :deep, -> { includes(subscriptions: :subscribable) }
25
22
 
26
- before_validation do
27
- subscriptions.each { |subscription| subscription.status = status }
23
+ after_commit(if: -> { stripe_subscription_id.present? }) do
24
+ subscriptions.each { |subscription| subscription.subscribable.update_column(:subscription_status, status) }
28
25
  end
29
26
 
30
27
  validates :user, presence: true
@@ -67,14 +64,13 @@ module Effective
67
64
  def payment_status
68
65
  if status == 'past_due'
69
66
  'We ran into an error processing your last payment. Please update or confirm your card details to continue.'
70
- elsif active_card.present? && token_required?
71
- 'Please update or confirm your card details to continue.'
72
- elsif active_card.present?
73
- 'Thanks for your support! The card we have on file is'
74
- else
67
+ elsif status == 'active'
68
+ "Your payment is in good standing. Thanks so much for your support!"
69
+ elsif active_card.blank?
75
70
  'No credit card on file. Please add a card.'
71
+ else
72
+ 'Please update or confirm your card details to continue.'
76
73
  end.html_safe
77
74
  end
78
-
79
75
  end
80
76
  end
@@ -5,36 +5,46 @@ module Effective
5
5
  include ActiveModel::Model
6
6
 
7
7
  attr_accessor :user, :subscribable, :customer
8
- attr_accessor :stripe_plan_id, :stripe_token
8
+ attr_accessor :subscribable_global_id, :stripe_token, :stripe_plan_id, :include_trial
9
9
 
10
10
  validates :user, presence: true
11
- validates :subscribable, presence: true, if: -> { stripe_plan_id }
12
- validates :stripe_plan_id, inclusion: { allow_blank: true, in: EffectiveOrders.stripe_plans.keys, message: 'unknown plan' }
11
+ validates :subscribable, presence: true, if: -> { stripe_plan_id.present? }
12
+ validates :customer, presence: true
13
13
 
14
- validate(if: -> { stripe_plan_id && plan && subscribable }) do
15
- if plan[:amount] > 0 && stripe_token.blank? && token_required?
16
- self.errors.add(:stripe_token, 'updated payment card required')
17
- customer.errors.add(:stripe_token, 'updated payment card required')
18
- end
19
- end
14
+ validates :stripe_plan_id, inclusion: { allow_blank: true, in: EffectiveOrders.stripe_plans.keys, message: 'unknown plan' }
20
15
 
21
- validate(if: -> { subscribable }) do
22
- subscribable.errors.add(:subscripter, errors.messages.values.flatten.to_sentence) if self.errors.present?
16
+ validate(if: -> { stripe_plan_id && plan && plan[:amount] > 0 }) do
17
+ self.errors.add(:stripe_token, 'updated payment card required') if stripe_token.blank? && token_required?
23
18
  end
24
19
 
25
20
  def customer
26
21
  @customer ||= Effective::Customer.deep.where(user: user).first_or_initialize
27
22
  end
28
23
 
24
+ def subscribable_global_id
25
+ subscribable&.to_global_id
26
+ end
27
+
28
+ def subscribable_global_id=(global_id)
29
+ @subscribable = GlobalID::Locator.locate(global_id)
30
+ end
31
+
32
+ def user_id=(id)
33
+ @user = User.find(id)
34
+ end
35
+
29
36
  def current_plan
30
- return nil unless subscribable
31
- subscribable.subscription.blank? ? EffectiveOrders.stripe_plans['trial'] : subscribable.subscription.plan
37
+ subscribable&.subscription&.plan
32
38
  end
33
39
 
34
40
  def plan
35
41
  EffectiveOrders.stripe_plans[stripe_plan_id]
36
42
  end
37
43
 
44
+ def stripe_plan_id
45
+ @stripe_plan_id || (current_plan[:id] if current_plan)
46
+ end
47
+
38
48
  def token_required?
39
49
  customer.token_required?
40
50
  end
@@ -44,71 +54,27 @@ module Effective
44
54
 
45
55
  raise 'is invalid' unless valid?
46
56
 
47
- begin
48
- build! && sync! && customer.save!
49
- rescue => e
50
- reload!
51
-
52
- self.errors.add(:base, e.message)
53
- raise e
54
- end
55
- end
56
-
57
- def subscribe!(stripe_plan_id)
58
- self.stripe_plan_id = stripe_plan_id
59
- save!
60
- end
61
-
62
- def destroy!
63
- return true unless subscription && subscription.persisted? && customer.stripe_subscription.present?
64
-
65
- raise 'is invalid' unless valid?
66
-
67
- subscription.destroy!
68
- customer.subscriptions.reload
69
-
70
- sync! && customer.save!
71
- end
72
-
73
- def reload!
74
- @stripe_token = nil
75
- @stripe_plan_id = nil
76
- @customer = nil
77
- @subscription = nil
78
- end
79
-
80
- private
81
-
82
- def subscription
83
- return nil unless subscribable
84
- @subscription ||= (
85
- customer.subscriptions.find { |sub| sub.subscribable == subscribable } ||
86
- customer.subscriptions.build(subscribable: subscribable, customer: customer)
87
- )
57
+ create_customer!
58
+ create_stripe_token!
59
+ build_subscription!
60
+ sync_subscription!
61
+ true
88
62
  end
89
63
 
90
- def build!
91
- # Check for an existing customer created within the last hour with this email
92
- # This catches an edge case in which a stripe customer is created twice when a first time customer is using a declined card
93
- if customer.stripe_customer.blank?
94
- Rails.logger.info "STRIPE CUSTOMER CHECK FOR EXISTING: #{user.email}"
95
-
96
- customers = Stripe::Customer.list(created: { gt: (user.created_at - 1.hour).to_i } ).data
97
-
98
- if (existing = customers.find { |cus| cus.email == user.email && (cus.metadata || {})[:user_id] == user.id.to_s })
99
- customer.stripe_customer = existing
100
- customer.stripe_customer_id = existing.id
101
- end
102
- end
64
+ protected
103
65
 
104
- # Create customer
66
+ # This should work even if the rest of the form doesn't. Careful with our transactions...
67
+ def create_customer!
105
68
  if customer.stripe_customer.blank?
106
69
  Rails.logger.info "STRIPE CUSTOMER CREATE: #{user.email}"
107
70
  customer.stripe_customer = Stripe::Customer.create(email: user.email, description: user.to_s, metadata: { user_id: user.id })
108
71
  customer.stripe_customer_id = customer.stripe_customer.id
72
+ customer.save!
109
73
  end
74
+ end
110
75
 
111
- # Update stripe customer card
76
+ # Update stripe customer card
77
+ def create_stripe_token!
112
78
  if stripe_token.present?
113
79
  Rails.logger.info "STRIPE CUSTOMER SOURCE UPDATE #{stripe_token}"
114
80
  customer.stripe_customer.source = stripe_token
@@ -117,34 +83,46 @@ module Effective
117
83
  if customer.stripe_customer.default_source.present?
118
84
  card = customer.stripe_customer.sources.retrieve(customer.stripe_customer.default_source)
119
85
  customer.active_card = "**** **** **** #{card.last4} #{card.brand} #{card.exp_month}/#{card.exp_year}"
86
+ customer.save!
120
87
  end
121
88
  end
89
+ end
122
90
 
123
- # Assign stripe plan
124
- if plan
125
- subscription.stripe_plan_id = plan[:id]
91
+ def build_subscription!
92
+ return unless plan.present?
93
+ subscription.stripe_plan_id = plan[:id]
94
+ end
126
95
 
127
- # Ensure stripe subscription exists
128
- if customer.stripe_subscription.blank?
129
- Rails.logger.info "STRIPE SUBSCRIPTION CREATE: #{items(metadata: false)}"
130
- customer.stripe_subscription = Stripe::Subscription.create(customer: customer.stripe_customer_id, items: items(metadata: false), metadata: metadata)
131
- customer.stripe_subscription_id = customer.stripe_subscription.id
132
- end
133
- end
96
+ def sync_subscription!
97
+ return unless plan.present?
98
+ customer.stripe_subscription.blank? ? create_subscription! : update_subscription!
134
99
 
135
- true
100
+ customer.save!
101
+ end
102
+
103
+ def create_subscription!
104
+ return unless plan.present?
105
+ return if customer.stripe_subscription.present?
106
+
107
+ Rails.logger.info "STRIPE SUBSCRIPTION CREATE: #{items(metadata: false)}"
108
+ customer.stripe_subscription = Stripe::Subscription.create(customer: customer.stripe_customer_id, items: items(metadata: false), metadata: metadata)
109
+ customer.stripe_subscription_id = customer.stripe_subscription.id
110
+
111
+ customer.status = customer.stripe_subscription.status
112
+ customer.stripe_subscription_interval = customer.stripe_subscription.plan.interval
136
113
  end
137
114
 
138
- def sync!
139
- return true unless plan && customer.stripe_subscription
115
+ def update_subscription!
116
+ return unless plan.present?
117
+ return if customer.stripe_subscription.blank?
140
118
 
141
119
  Rails.logger.info "STRIPE SUBSCRIPTION SYNC: #{customer.stripe_subscription_id} #{items}"
142
120
 
143
121
  if items.length == 0
144
122
  customer.stripe_subscription.delete
145
123
  customer.stripe_subscription_id = nil
146
- customer.status = nil
147
- return true
124
+ customer.status = EffectiveOrders::CANCELED
125
+ return
148
126
  end
149
127
 
150
128
  # Update stripe subscription items
@@ -189,14 +167,32 @@ module Effective
189
167
  # Stripe::Invoice.create(customer: customer.stripe_customer_id).pay rescue false
190
168
  # end
191
169
 
192
- # Sync status
193
170
  customer.status = customer.stripe_subscription.status
171
+ end
194
172
 
195
- true
173
+ def subscribe!(stripe_plan_id)
174
+ self.stripe_plan_id = stripe_plan_id
175
+ save!
196
176
  end
197
177
 
178
+ # def destroy!
179
+ # return true unless subscription && subscription.persisted? && customer.stripe_subscription.present?
180
+
181
+ # raise 'is invalid' unless valid?
182
+
183
+ # subscription.destroy!
184
+ # customer.subscriptions.reload
185
+
186
+ # sync! && customer.save!
187
+ # end
188
+
198
189
  private
199
190
 
191
+ def subscription
192
+ return nil unless subscribable
193
+ customer.subscriptions.find { |sub| sub.subscribable == subscribable } || customer.subscriptions.build(subscribable: subscribable, customer: customer)
194
+ end
195
+
200
196
  def items(metadata: true)
201
197
  customer.subscriptions.group_by { |sub| sub.stripe_plan_id }.map do |plan, subscriptions|
202
198
  if metadata
@@ -20,7 +20,7 @@ module Effective
20
20
  validates :customer, presence: true
21
21
  validates :subscribable, presence: true
22
22
 
23
- validates :stripe_plan_id, presence: true, inclusion: { in: EffectiveOrders.stripe_plans.except('trial').keys }
23
+ validates :stripe_plan_id, presence: true, inclusion: { in: EffectiveOrders.stripe_plans.keys }
24
24
  validates :name, presence: true
25
25
 
26
26
  def to_s
@@ -1,145 +1,134 @@
1
- %h3.effective-heading Customer
2
-
3
- %table.table
4
- %tbody
5
- %tr
6
- %th Id
7
- %td= customer.stripe_customer.id
8
- %tr
9
- %th Email
10
- %td= customer.stripe_customer.email
11
- %tr
12
- %th Card
13
- %td
14
- - if customer.stripe_customer.default_source.present?
15
- - card = customer.stripe_customer.sources.retrieve(customer.stripe_customer.default_source)
16
- = "**** **** **** #{card.last4} #{card.brand} #{card.exp_month}/#{card.exp_year}"
17
- - else
18
- None
19
-
20
- - if customer.stripe_customer.currency.present?
21
- %tr
22
- %th Currency
23
- %td= customer.stripe_customer.currency.to_s.upcase
24
-
25
- - if customer.stripe_customer.account_balance.to_i > 0
26
- %tr
27
- %th Balance
28
- %td= price_to_currency(customer.stripe_customer.account_balance.to_i)
29
-
30
- = yield if block_given?
31
-
32
1
  - if customer.stripe_subscription.present?
33
- %h3.effective-heading Subscription
34
-
35
- %table.table
36
- %tbody
37
- %tr
38
- %th Status
39
- %td= customer.stripe_subscription.status.presence || 'unknown'
40
-
41
- - if customer.stripe_subscription.discount.present?
42
- %tr
43
- %th Coupon
44
- %td= stripe_coupon_description(customer.stripe_subscription.discount.coupon)
45
-
46
- - if customer.stripe_subscription.start.present?
47
- %tr
48
- %th Started
49
- %td= Time.zone.at(customer.stripe_subscription.start).strftime('%F')
50
-
51
- - if customer.stripe_subscription.ended_at.present?
52
- %tr
53
- %th Ended
54
- %td= Time.zone.at(customer.stripe_subscription.ended_at).strftime('%F')
55
-
56
- - if customer.stripe_subscription.canceled_at.present?
57
- %tr
58
- %th Cancelled
59
- %td= Time.zone.at(customer.stripe_subscription.canceled_at).strftime('%F')
60
-
61
- - if customer.stripe_subscription.current_period_start.present?
62
- %tr
63
- %th Current Period Start
64
- %td= Time.zone.at(customer.stripe_subscription.current_period_start).strftime('%F')
65
-
66
- - if customer.stripe_subscription.current_period_end.present?
67
- %tr
68
- %th Current Period End
69
- %td= Time.zone.at(customer.stripe_subscription.current_period_end).strftime('%F')
70
-
71
- - if customer.stripe_subscription.metadata.present? && false
72
- %tr
73
- %th Metadata
74
- %td= tableize_hash(customer.stripe_subscription.metadata.to_h, th: false)
75
-
76
- - if customer.stripe_subscription.items.present?
77
- %tr
78
- %th Plans
79
- %td= tableize_hash(customer.stripe_subscription.items.inject({}) { |h, item| h[item.plan.nickname] = item.quantity; h }, th: false)
80
-
81
- - if customer.subscriptions.present?
82
- %table.table
83
- %thead
84
- %tr
85
- %th Subscribed
86
- %th Plan
87
- %th
88
- %tbody
89
- - customer.subscriptions.each do |sub|
2
+ .card.my-4
3
+ .card-header Subscription
4
+ .card-body
5
+ %table.table
6
+ %tbody
7
+ %tr
8
+ %th Status
9
+ %td= customer.stripe_subscription.status.presence || 'unknown'
10
+
90
11
  %tr
91
- %td= sub.subscribable
92
- %td= sub
93
- %td= link_to 'change', edit_polymorphic_path(sub.subscribable)
12
+ %th Email
13
+ %td= customer.stripe_customer.email
94
14
 
95
- - if customer.stripe_subscription.blank?
96
- %h3.effective-heading Subscription
97
- %p No current subscriptions
15
+ %tr
16
+ %th Card
17
+ %td
18
+ - if customer.stripe_customer.default_source.present?
19
+ - card = customer.stripe_customer.sources.retrieve(customer.stripe_customer.default_source)
20
+ = "**** **** **** #{card.last4} #{card.brand} #{card.exp_month}/#{card.exp_year}"
21
+ - else
22
+ None
23
+
24
+ %tr
25
+ %th Currency
26
+ %td= customer.stripe_customer.currency.to_s.upcase
27
+
28
+ - if customer.stripe_subscription.discount.present?
29
+ %tr
30
+ %th Coupon
31
+ %td= stripe_coupon_description(customer.stripe_subscription.discount.coupon)
32
+
33
+ - if customer.stripe_subscription.start.present?
34
+ %tr
35
+ %th Started
36
+ %td= Time.zone.at(customer.stripe_subscription.start).strftime('%F')
37
+
38
+ - if customer.stripe_subscription.ended_at.present?
39
+ %tr
40
+ %th Ended
41
+ %td= Time.zone.at(customer.stripe_subscription.ended_at).strftime('%F')
42
+
43
+ - if customer.stripe_subscription.canceled_at.present?
44
+ %tr
45
+ %th Cancelled
46
+ %td= Time.zone.at(customer.stripe_subscription.canceled_at).strftime('%F')
47
+
48
+ - if customer.stripe_subscription.current_period_start.present?
49
+ %tr
50
+ %th Current Period Start
51
+ %td= Time.zone.at(customer.stripe_subscription.current_period_start).strftime('%F')
52
+
53
+ - if customer.stripe_subscription.current_period_end.present?
54
+ %tr
55
+ %th Current Period End
56
+ %td= Time.zone.at(customer.stripe_subscription.current_period_end).strftime('%F')
57
+
58
+ - if customer.stripe_subscription.metadata.present? && false
59
+ %tr
60
+ %th Metadata
61
+ %td= tableize_hash(customer.stripe_subscription.metadata.to_h, th: false)
62
+
63
+ - if customer.stripe_subscription.items.present?
64
+ %tr
65
+ %th Plans
66
+ %td= tableize_hash(customer.stripe_subscription.items.inject({}) { |h, item| h[item.plan.nickname] = item.quantity; h }, th: false)
67
+
68
+ - if customer.subscriptions.present?
69
+ .card.my-4
70
+ .card-header Subscribed
71
+ .card-body
72
+ %table.table
73
+ %thead
74
+ %tr
75
+ %th Name
76
+ %th Plan
77
+ %th
78
+ %tbody
79
+ - customer.subscriptions.each do |sub|
80
+ %tr
81
+ %td= sub.subscribable
82
+ %td= sub
98
83
 
99
84
  - if customer.stripe_customer.invoices.present?
100
- %h3.effective-heading Invoices
101
-
102
- %table.table
103
- %thead
104
- %tr
105
- %th Date
106
- %th Number
107
- %th Period
108
- %th Items
109
- %th Total
110
- %tbody
111
- - customer.stripe_customer.invoices.each do |invoice|
112
- %tr
113
- %td= Time.zone.at(invoice.date).strftime('%F')
114
- %td= invoice.id
115
- %td
116
- = Time.zone.at(invoice.lines.first.period.start).strftime('%F')
117
- to
118
- = Time.zone.at(invoice.lines.first.period.end).strftime('%F')
119
- %td
120
- - invoice.lines.each do |line|
121
- %p= line.description
122
-
123
- %td= price_to_currency(invoice.total)
85
+ .card.my-4
86
+ .card-header Invoices
87
+ .card-body
88
+ %table.table
89
+ %thead
90
+ %tr
91
+ %th Date
92
+ %th Invoice
93
+ %th Total
94
+ %tbody
95
+ - customer.stripe_customer.invoices.each do |invoice|
96
+ %tr
97
+ %td= Time.zone.at(invoice.date).strftime('%F')
98
+ %td
99
+ %p
100
+ = invoice.id
101
+ %br
102
+ = Time.zone.at(invoice.lines.first.period.start).strftime('%F')
103
+ to
104
+ = Time.zone.at(invoice.lines.first.period.end).strftime('%F')
105
+
106
+ %p
107
+ - invoice.lines.each do |line|
108
+ = line.description
109
+ %br
110
+
111
+ %td= price_to_currency(invoice.total)
124
112
 
125
113
  - if customer.upcoming_invoice.present?
126
- %p Upcoming Invoice:
127
-
128
- %table.table
129
- %tbody
130
- %tr
131
- %th Date
132
- %td= Time.zone.at(customer.upcoming_invoice.date).strftime('%F')
133
- %tr
134
- %th Items
135
- %td
136
- %table.table
137
- %tbody
138
- - customer.upcoming_invoice.lines.each do |line|
139
- %tr
140
- %td #{Time.zone.at(line.period.start).strftime('%F')} to #{Time.zone.at(line.period.end).strftime('%F')}
141
- %td= line.description
142
- %td= price_to_currency(line.amount)
143
- %tr
144
- %th Total
145
- %td= price_to_currency(customer.upcoming_invoice.total)
114
+ .card.my-4
115
+ .card-header Upcoming Invoice
116
+ .card-body
117
+ %table.table
118
+ %tbody
119
+ %tr
120
+ %th Date
121
+ %td= Time.zone.at(customer.upcoming_invoice.date).strftime('%F')
122
+ %tr
123
+ %th Items
124
+ %td
125
+ %table.table
126
+ %tbody
127
+ - customer.upcoming_invoice.lines.each do |line|
128
+ %tr
129
+ %td #{Time.zone.at(line.period.start).strftime('%F')} to #{Time.zone.at(line.period.end).strftime('%F')}
130
+ %td= line.description
131
+ %td= price_to_currency(line.amount)
132
+ %tr
133
+ %th Total
134
+ %td= price_to_currency(customer.upcoming_invoice.total)
@@ -1,12 +1,21 @@
1
1
  = javascript_include_tag 'https://checkout.stripe.com/checkout.js'
2
2
 
3
- = effective_form_with(model: subscripter, url: effective_orders.customer_settings_path, method: :put) do |f|
4
- = f.hidden_field :stripe_token, value: nil
3
+ .card
4
+ .card-header Customer Summary
5
+ .card-body
6
+ = effective_form_with(model: subscripter, url: effective_orders.customer_settings_path, remote: true, data: { stripe: subscripter_stripe_data(subscripter) }) do |f|
7
+ = f.hidden_field :stripe_token, value: nil
8
+ = f.error :stripe_token
5
9
 
6
- = render(f.object.customer) do
7
- %h3.effective-heading Card
8
- = effective_customer_fields(f)
10
+ %p
11
+ All subscription and billing notifications are sent to:
12
+ %strong= f.object.user.email
9
13
 
10
- = f.submit
14
+ - if f.object.customer.active_card.present?
15
+ %p
16
+ All charges are made to
17
+ %strong= f.object.customer.active_card
11
18
 
19
+ %p= f.object.customer.payment_status
12
20
 
21
+ = f.submit 'Update Card', border: false, left: true, class: 'effective-orders-stripe-update-card'
@@ -1,3 +1,4 @@
1
1
  %h1.effective-heading= @page_title
2
2
 
3
3
  = render 'effective/customers/form', subscripter: @subscripter
4
+ = render 'effective/customers/customer', customer: @customer
@@ -0,0 +1,5 @@
1
+ <% resource = (@_effective_resource || Effective::Resource.new(controller_path)) %>
2
+ <% @resource = instance_variable_get('@' + resource.name) if resource.name %>
3
+
4
+ EffectiveForm.remote_form_payload = $("<div><%= j render_resource_form(resource, subscripter: @subscripter) %></div>");
5
+ EffectiveForm.remote_form_flash = <%= raw flash.to_json %>;
@@ -0,0 +1,11 @@
1
+ = javascript_include_tag 'https://checkout.stripe.com/checkout.js'
2
+
3
+ = effective_form_with(model: subscripter, url: effective_orders.subscripter_path, remote: true, data: { stripe: subscripter_stripe_data(subscripter) }) do |f|
4
+ = f.hidden_field :user_id, value: current_user.id
5
+ = f.hidden_field :subscribable_global_id
6
+ = f.hidden_field :stripe_token, value: nil
7
+ = f.error :stripe_token
8
+
9
+ = f.radios :stripe_plan_id, stripe_plans_collection(f), cards: true, label: false, required: true
10
+
11
+ = f.submit 'Choose this Plan', center: true, class: ('effective-orders-stripe-token-required' if f.object.token_required?)
@@ -0,0 +1,3 @@
1
+ .effective-radios.card-deck
2
+ .card.active
3
+ = render 'effective/subscriptions/plan', plan: subscription.plan, subscribed: true
data/config/routes.rb CHANGED
@@ -25,8 +25,10 @@ EffectiveOrders::Engine.routes.draw do
25
25
  post 'orders/:id', to: 'orders#update'
26
26
 
27
27
  if EffectiveOrders.subscriptions?
28
+ match 'subscribe', to: 'subscripter#update', via: :post, as: :subscripter
29
+
28
30
  match 'customer/settings', to: 'customers#edit', as: :customer_settings, via: [:get]
29
- match 'customer/settings', to: 'customers#update', via: [:patch, :put]
31
+ match 'customer/settings', to: 'customers#update', via: [:patch, :put, :post]
30
32
  match 'webhooks/stripe', to: 'webhooks#stripe', via: [:post, :put]
31
33
  end
32
34
 
@@ -75,6 +75,7 @@ class CreateEffectiveOrders < ActiveRecord::Migration[4.2]
75
75
  t.string :active_card
76
76
 
77
77
  t.string :stripe_subscription_id
78
+ t.string :stripe_subscription_interval
78
79
  t.string :status
79
80
 
80
81
  t.integer :subscriptions_count, :default => 0
@@ -13,8 +13,9 @@ module EffectiveOrders
13
13
  # Subscription statuses (as per stripe)
14
14
  ACTIVE = 'active'.freeze
15
15
  PAST_DUE = 'past_due'.freeze
16
+ CANCELED = 'canceled'.freeze
16
17
 
17
- STATUSES = { ACTIVE => ACTIVE, PAST_DUE => PAST_DUE }
18
+ STATUSES = { ACTIVE => ACTIVE, PAST_DUE => PAST_DUE, CANCELED => CANCELED }
18
19
 
19
20
  # The following are all valid config keys
20
21
  mattr_accessor :orders_table_name
@@ -83,7 +84,7 @@ module EffectiveOrders
83
84
  end
84
85
 
85
86
  def self.authorize!(controller, action, resource)
86
- raise Effective::AccessDenied unless authorized?(controller, action, resource)
87
+ raise Effective::AccessDenied.new('Access Denied', action, resource) unless authorized?(controller, action, resource)
87
88
  end
88
89
 
89
90
  def self.permitted_params
@@ -175,35 +176,18 @@ module EffectiveOrders
175
176
  #{ }"tiers":null,"tiers_mode":null,"transform_usage":null,"trial_period_days":null,"usage_type":"licensed"},
176
177
 
177
178
  plans = Stripe::Plan.all.inject({}) do |h, plan|
178
- occurrence = case plan.interval
179
- when 'daily' ; '/day'
180
- when 'weekly' ; '/week'
181
- when 'monthly' ; '/month'
182
- when 'yearly' ; '/year'
183
- when 'day' ; plan.interval_count == 1 ? '/day' : " every #{plan.interval_count} days"
184
- when 'week' ; plan.interval_count == 1 ? '/week' : " every #{plan.interval_count} weeks"
185
- when 'month' ; plan.interval_count == 1 ? '/month' : " every #{plan.interval_count} months"
186
- when 'year' ; plan.interval_count == 1 ? '/year' : " every #{plan.interval_count} years"
187
- else ; plan.interval
188
- end
189
-
190
179
  h[plan.id] = {
191
180
  id: plan.id,
192
181
  product_id: plan.product,
193
182
  name: plan.nickname,
194
183
  amount: plan.amount,
195
184
  currency: plan.currency,
196
- description: "$#{'%0.2f' % (plan.amount / 100.0)} #{plan.currency.upcase}#{occurrence}",
197
- occurrence: "#{occurrence}",
185
+ description: "$#{'%0.2f' % (plan.amount / 100.0)} #{plan.currency.upcase}/#{plan.interval}",
198
186
  interval: plan.interval,
199
187
  interval_count: plan.interval_count
200
188
  }; h
201
189
  end
202
190
 
203
- if trial?
204
- plans['trial'] = { id: 'trial', amount: 0, name: trial.fetch(:name), description: trial.fetch(:description) }
205
- end
206
-
207
191
  plans
208
192
  )
209
193
  end
@@ -1,3 +1,3 @@
1
1
  module EffectiveOrders
2
- VERSION = '4.0.0beta5'.freeze
2
+ VERSION = '4.0.0beta6'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: effective_orders
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.0beta5
4
+ version: 4.0.0beta6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Code and Effect
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-04-19 00:00:00.000000000 Z
11
+ date: 2018-04-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -140,6 +140,7 @@ files:
140
140
  - app/controllers/effective/providers/pretend.rb
141
141
  - app/controllers/effective/providers/refund.rb
142
142
  - app/controllers/effective/providers/stripe.rb
143
+ - app/controllers/effective/subscripter_controller.rb
143
144
  - app/controllers/effective/webhooks_controller.rb
144
145
  - app/datatables/effective_customers_datatable.rb
145
146
  - app/datatables/effective_order_items_datatable.rb
@@ -183,9 +184,9 @@ files:
183
184
  - app/views/effective/carts/_cart_actions.html.haml
184
185
  - app/views/effective/carts/show.html.haml
185
186
  - app/views/effective/customers/_customer.html.haml
186
- - app/views/effective/customers/_fields.html.haml
187
187
  - app/views/effective/customers/_form.html.haml
188
188
  - app/views/effective/customers/edit.html.haml
189
+ - app/views/effective/customers/update.js.erb
189
190
  - app/views/effective/orders/_checkout_actions.html.haml
190
191
  - app/views/effective/orders/_checkout_step1.html.haml
191
192
  - app/views/effective/orders/_checkout_step2.html.haml
@@ -226,8 +227,9 @@ files:
226
227
  - app/views/effective/orders_mailer/subscription_payment_succeeded.html.haml
227
228
  - app/views/effective/orders_mailer/subscription_trial_expired.html.haml
228
229
  - app/views/effective/orders_mailer/subscription_trial_expiring.html.haml
229
- - app/views/effective/subscriptions/_fields.html.haml
230
+ - app/views/effective/subscripter/_form.html.haml
230
231
  - app/views/effective/subscriptions/_plan.html.haml
232
+ - app/views/effective/subscriptions/_subscription.html.haml
231
233
  - app/views/layouts/effective_orders_mailer_layout.html.haml
232
234
  - config/effective_orders.rb
233
235
  - config/routes.rb
@@ -1,9 +0,0 @@
1
- .effective-orders-customer{ data: { stripe: stripe.to_json, submit: submit.to_json } }
2
- .card
3
- .card-header Credit Card
4
- .card-body
5
- = f.static_field :stripe_token, label: false, class: 'payment-status', value: f.object.customer.payment_status
6
-
7
- %p= link_to 'Update Card Details', '#', class: 'btn btn-primary btn-change-card'
8
-
9
- %p.invalid-feedback
@@ -1,12 +0,0 @@
1
- = javascript_include_tag 'https://checkout.stripe.com/checkout.js'
2
-
3
- = form.fields_for :subscripter, form.object.subscripter do |fs|
4
- = fs.hidden_field :stripe_token, value: nil
5
-
6
- - fs.object.stripe_plan_id ||= (fs.object.current_plan || {})[:id]
7
-
8
- = fs.radios :stripe_plan_id, stripe_plans_collection(fs, include_trial: include_trial),
9
- label: label,
10
- required: required,
11
- cards: true,
12
- wrapper: { class: 'effective-orders-stripe-plans', data: { stripe: stripe } }