Module: Pay::Stripe::Billable

Defined in:
lib/pay/stripe/billable.rb

Instance Method Summary collapse

Instance Method Details

#create_setup_intent ⇒ Object



17
18
19
20
21
22
# File 'lib/pay/stripe/billable.rb', line 17

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



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/pay/stripe/billable.rb', line 27

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 Error, e.message
end

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

Handles Billable#subscribe

Returns Pay::Subscription



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/pay/stripe/billable.rb', line 50

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 Error, e.message
end

#stripe_customer ⇒ Object

Handles Billable#customer

Returns Stripe::Customer



7
8
9
10
11
12
13
14
15
# File 'lib/pay/stripe/billable.rb', line 7

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

#stripe_invoice!(options = {}) ⇒ Object



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

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

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



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

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

#stripe_upcoming_invoice ⇒ Object



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

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

#sync_card_from_stripe ⇒ Object

Used by webhooks when the customer or source changes



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/pay/stripe/billable.rb', line 118

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



83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/pay/stripe/billable.rb', line 83

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 Error, e.message
end

#update_stripe_email! ⇒ Object



97
98
99
100
101
102
# File 'lib/pay/stripe/billable.rb', line 97

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