Class: Pay::Stripe::Billable
- Inherits:
-
Object
- Object
- Pay::Stripe::Billable
- Defined in:
- lib/pay/stripe/billable.rb
Instance Attribute Summary collapse
-
#pay_customer ⇒ Object
readonly
Returns the value of attribute pay_customer.
Class Method Summary collapse
Instance Method Summary collapse
- #add_payment_method(payment_method_id, default: false) ⇒ Object
- #billing_portal(**options) ⇒ Object
- #charge(amount, options = {}) ⇒ Object
- #checkout(**options) ⇒ Object
- #checkout_charge(amount:, name:, quantity: 1, **options) ⇒ Object
- #create_setup_intent ⇒ Object
- #customer ⇒ Object
-
#initialize(pay_customer) ⇒ Billable
constructor
A new instance of Billable.
- #invoice!(options = {}) ⇒ Object
- #processor_subscription(subscription_id, options = {}) ⇒ Object
-
#save_payment_method(payment_method, default:) ⇒ Object
Save the Stripe::PaymentMethod to the database.
- #subscribe(name: Pay.default_product_name, plan: Pay.default_plan_name, **options) ⇒ Object
-
#sync_subscriptions ⇒ Object
Syncs a customer’s subscriptions from Stripe to the database.
- #trial_end_date(stripe_sub) ⇒ Object
- #upcoming_invoice ⇒ Object
- #update_email! ⇒ Object
Constructor Details
#initialize(pay_customer) ⇒ Billable
Returns a new instance of Billable.
21 22 23 |
# File 'lib/pay/stripe/billable.rb', line 21 def initialize(pay_customer) @pay_customer = pay_customer end |
Instance Attribute Details
#pay_customer ⇒ Object (readonly)
Returns the value of attribute pay_customer.
6 7 8 |
# File 'lib/pay/stripe/billable.rb', line 6 def pay_customer @pay_customer end |
Class Method Details
.default_url_options ⇒ Object
17 18 19 |
# File 'lib/pay/stripe/billable.rb', line 17 def self. Rails.application.config.action_mailer. || {} end |
Instance Method Details
#add_payment_method(payment_method_id, default: false) ⇒ Object
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/pay/stripe/billable.rb', line 99 def add_payment_method(payment_method_id, default: false) customer unless processor_id? payment_method = ::Stripe::PaymentMethod.attach(payment_method_id, {customer: processor_id}, ) if default ::Stripe::Customer.update(processor_id, { invoice_settings: { default_payment_method: payment_method.id } }, ) end save_payment_method(payment_method, default: default) rescue ::Stripe::StripeError => e raise Pay::Stripe::Error, e end |
#billing_portal(**options) ⇒ Object
222 223 224 225 226 227 228 229 |
# File 'lib/pay/stripe/billable.rb', line 222 def billing_portal(**) customer unless processor_id? args = { customer: processor_id, return_url: .delete(:return_url) || root_url } ::Stripe::BillingPortal::Session.create(args.merge(), ) end |
#charge(amount, options = {}) ⇒ Object
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/pay/stripe/billable.rb', line 47 def charge(amount, = {}) add_payment_method(payment_method_token, default: true) if payment_method_token? payment_method = pay_customer.default_payment_method args = { amount: amount, confirm: true, confirmation_method: :automatic, currency: "usd", customer: processor_id, payment_method: payment_method&.processor_id }.merge() payment_intent = ::Stripe::PaymentIntent.create(args, ) Pay::Payment.new(payment_intent).validate charge = payment_intent.charges.first Pay::Stripe::Charge.sync(charge.id, object: charge) rescue ::Stripe::StripeError => e raise Pay::Stripe::Error, e end |
#checkout(**options) ⇒ Object
stripe.com/docs/api/checkout/sessions/create
checkout(mode: “payment”) checkout(mode: “setup”) checkout(mode: “subscription”)
checkout(line_items: “price_12345”, quantity: 2) checkout(line_items [{ price: “price_123” }, { price: “price_456” }]) checkout(line_items, “price_12345”, allow_promotion_codes: true)
177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 |
# File 'lib/pay/stripe/billable.rb', line 177 def checkout(**) customer unless processor_id? args = { customer: processor_id, payment_method_types: ["card"], mode: "payment", # These placeholder URLs will be replaced in a following step. success_url: .delete(:success_url) || root_url(session_id: "{CHECKOUT_SESSION_ID}"), cancel_url: .delete(:cancel_url) || root_url(session_id: "{CHECKOUT_SESSION_ID}") } # Line items are optional if (line_items = .delete(:line_items)) args[:line_items] = Array.wrap(line_items).map { |item| if item.is_a? Hash item else {price: item, quantity: .fetch(:quantity, 1)} end } end ::Stripe::Checkout::Session.create(args.merge(), ) end |
#checkout_charge(amount:, name:, quantity: 1, **options) ⇒ Object
stripe.com/docs/api/checkout/sessions/create
checkout_charge(amount: 15_00, name: “T-shirt”, quantity: 2)
206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 |
# File 'lib/pay/stripe/billable.rb', line 206 def checkout_charge(amount:, name:, quantity: 1, **) customer unless processor_id? currency = .delete(:currency) || "usd" checkout( line_items: { price_data: { currency: currency, product_data: {name: name}, unit_amount: amount }, quantity: quantity }, ** ) end |
#create_setup_intent ⇒ Object
148 149 150 |
# File 'lib/pay/stripe/billable.rb', line 148 def create_setup_intent ::Stripe::SetupIntent.create({customer: processor_id, usage: :off_session}, ) end |
#customer ⇒ Object
25 26 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 25 def customer stripe_customer = if processor_id? ::Stripe::Customer.retrieve({id: processor_id}, ) else sc = ::Stripe::Customer.create({email: email, name: customer_name}, ) pay_customer.update!(processor_id: sc.id, stripe_account: stripe_account) sc end if payment_method_token? payment_method = ::Stripe::PaymentMethod.attach(payment_method_token, {customer: stripe_customer.id}, ) pay_payment_method = save_payment_method(payment_method, default: false) pay_payment_method.make_default! pay_customer.payment_method_token = nil end stripe_customer rescue ::Stripe::StripeError => e raise Pay::Stripe::Error, e end |
#invoice!(options = {}) ⇒ Object
139 140 141 142 |
# File 'lib/pay/stripe/billable.rb', line 139 def invoice!( = {}) return unless processor_id? ::Stripe::Invoice.create(.merge(customer: processor_id), ).pay end |
#processor_subscription(subscription_id, options = {}) ⇒ Object
135 136 137 |
# File 'lib/pay/stripe/billable.rb', line 135 def processor_subscription(subscription_id, = {}) ::Stripe::Subscription.retrieve(.merge(id: subscription_id), ) end |
#save_payment_method(payment_method, default:) ⇒ Object
Save the Stripe::PaymentMethod to the database
117 118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/pay/stripe/billable.rb', line 117 def save_payment_method(payment_method, default:) pay_payment_method = pay_customer.payment_methods.where(processor_id: payment_method.id).first_or_initialize attributes = Pay::Stripe::PaymentMethod.extract_attributes(payment_method).merge(default: default) pay_customer.payment_methods.update_all(default: false) if default pay_payment_method.update!(attributes) # Reload the Rails association pay_customer.reload_default_payment_method if default pay_payment_method end |
#subscribe(name: Pay.default_product_name, plan: Pay.default_plan_name, **options) ⇒ Object
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/pay/stripe/billable.rb', line 69 def subscribe(name: Pay.default_product_name, plan: Pay.default_plan_name, **) quantity = .delete(:quantity) || 1 opts = { expand: ["pending_setup_intent", "latest_invoice.payment_intent", "latest_invoice.charge.invoice"], items: [plan: plan, quantity: quantity], off_session: true }.merge() # Inherit trial from plan unless trial override was specified opts[:trial_from_plan] = true unless opts[:trial_period_days] # Load the Stripe customer to verify it exists and update payment method if needed opts[:customer] = customer.id # Create subscription on Stripe stripe_sub = ::Stripe::Subscription.create(opts, ) # Save Pay::Subscription subscription = Pay::Stripe::Subscription.sync(stripe_sub.id, object: stripe_sub, name: name) # No trial, payment method requires SCA if subscription.incomplete? Pay::Payment.new(stripe_sub.latest_invoice.payment_intent).validate end subscription rescue ::Stripe::StripeError => e raise Pay::Stripe::Error, e end |
#sync_subscriptions ⇒ Object
Syncs a customer’s subscriptions from Stripe to the database
158 159 160 161 162 163 164 165 |
# File 'lib/pay/stripe/billable.rb', line 158 def sync_subscriptions subscriptions = ::Stripe::Subscription.list({customer: customer}, ) subscriptions.map do |subscription| Pay::Stripe::Subscription.sync(subscription.id) end rescue ::Stripe::StripeError => e raise Pay::Stripe::Error, e end |
#trial_end_date(stripe_sub) ⇒ Object
152 153 154 155 |
# File 'lib/pay/stripe/billable.rb', line 152 def trial_end_date(stripe_sub) # Times in Stripe are returned in UTC stripe_sub.trial_end.present? ? Time.at(stripe_sub.trial_end) : nil end |
#upcoming_invoice ⇒ Object
144 145 146 |
# File 'lib/pay/stripe/billable.rb', line 144 def upcoming_invoice ::Stripe::Invoice.upcoming({customer: processor_id}, ) end |
#update_email! ⇒ Object
131 132 133 |
# File 'lib/pay/stripe/billable.rb', line 131 def update_email! ::Stripe::Customer.update(processor_id, {email: email, name: customer_name}, ) end |