Module: Pay::Stripe::Billable

Extended by:
ActiveSupport::Concern
Defined in:
lib/pay/stripe/billable.rb

Instance Method Summary collapse

Instance Method Details

#create_setup_intentObject



23
24
25
26
27
28
# File 'lib/pay/stripe/billable.rb', line 23

def create_setup_intent
  ::Stripe::SetupIntent.create(
    customer: processor_id,
    usage: :off_session
  )
end

#create_stripe_charge(amount, options = {}) ⇒ Object

Handles Billable#charge

Returns Pay::Charge



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/pay/stripe/billable.rb', line 33

def create_stripe_charge(amount, options = {})
  customer = stripe_customer
  args = {
    amount: amount,
    confirm: true,
    confirmation_method: :automatic,
    currency: "usd",
    customer: customer.id,
    payment_method: customer.invoice_settings.default_payment_method
  }.merge(options)

  payment_intent = ::Stripe::PaymentIntent.create(args)
  Pay::Payment.new(payment_intent).validate

  # Create a new charge object
  Stripe::Webhooks::ChargeSucceeded.new.create_charge(self, payment_intent.charges.first)
rescue ::Stripe::StripeError => e
  raise Pay::Stripe::Error, e
end

#create_stripe_subscription(name, plan, options = {}) ⇒ Object

Handles Billable#subscribe

Returns Pay::Subscription



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/pay/stripe/billable.rb', line 56

def create_stripe_subscription(name, plan, options = {})
  quantity = options.delete(:quantity) || 1
  opts = {
    expand: ["pending_setup_intent", "latest_invoice.payment_intent"],
    items: [plan: plan, quantity: quantity],
    off_session: true
  }.merge(options)

  # Inherit trial from plan unless trial override was specified
  opts[:trial_from_plan] = true unless opts[:trial_period_days]

  opts[:customer] = stripe_customer.id

  stripe_sub = ::Stripe::Subscription.create(opts)
  subscription = create_subscription(stripe_sub, "stripe", name, plan, status: stripe_sub.status, quantity: quantity)

  # No trial, card requires SCA
  if subscription.incomplete?
    Pay::Payment.new(stripe_sub.latest_invoice.payment_intent).validate

  # Trial, card requires SCA
  elsif subscription.on_trial? && stripe_sub.pending_setup_intent
    Pay::Payment.new(stripe_sub.pending_setup_intent).validate
  end

  subscription
rescue ::Stripe::StripeError => e
  raise Pay::Stripe::Error, e
end

#stripe_customerObject

Handles Billable#customer

Returns Stripe::Customer



13
14
15
16
17
18
19
20
21
# File 'lib/pay/stripe/billable.rb', line 13

def stripe_customer
  if processor_id?
    ::Stripe::Customer.retrieve(processor_id)
  else
    create_stripe_customer
  end
rescue ::Stripe::StripeError => e
  raise Pay::Stripe::Error, e
end

#stripe_invoice!(options = {}) ⇒ Object



114
115
116
117
# File 'lib/pay/stripe/billable.rb', line 114

def stripe_invoice!(options = {})
  return unless processor_id?
  ::Stripe::Invoice.create(options.merge(customer: processor_id)).pay
end

#stripe_subscription(subscription_id, options = {}) ⇒ Object



110
111
112
# File 'lib/pay/stripe/billable.rb', line 110

def stripe_subscription(subscription_id, options = {})
  ::Stripe::Subscription.retrieve(options.merge(id: subscription_id))
end

#stripe_upcoming_invoiceObject



119
120
121
# File 'lib/pay/stripe/billable.rb', line 119

def stripe_upcoming_invoice
  ::Stripe::Invoice.upcoming(customer: processor_id)
end

#sync_card_from_stripeObject

Used by webhooks when the customer or source changes



124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/pay/stripe/billable.rb', line 124

def sync_card_from_stripe
  stripe_cust = stripe_customer
  default_payment_method_id = stripe_cust.invoice_settings.default_payment_method

  if default_payment_method_id.present?
    payment_method = ::Stripe::PaymentMethod.retrieve(default_payment_method_id)
    update(
      card_type: payment_method.card.brand,
      card_last4: payment_method.card.last4,
      card_exp_month: payment_method.card.exp_month,
      card_exp_year: payment_method.card.exp_year
    )

  # Customer has no default payment method
  else
    update(card_type: nil, card_last4: nil)
  end
end

#update_stripe_card(payment_method_id) ⇒ Object

Handles Billable#update_card

Returns true if successful



89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/pay/stripe/billable.rb', line 89

def update_stripe_card(payment_method_id)
  customer = stripe_customer

  return true if payment_method_id == customer.invoice_settings.default_payment_method

  payment_method = ::Stripe::PaymentMethod.attach(payment_method_id, customer: customer.id)
  ::Stripe::Customer.update(customer.id, invoice_settings: {default_payment_method: payment_method.id})

  update_stripe_card_on_file(payment_method.card)
  true
rescue ::Stripe::StripeError => e
  raise Pay::Stripe::Error, e
end

#update_stripe_email!Object



103
104
105
106
107
108
# File 'lib/pay/stripe/billable.rb', line 103

def update_stripe_email!
  customer = stripe_customer
  customer.email = email
  customer.name = customer_name
  customer.save
end