Class: Pay::StripeMarketplace::Billable
- Inherits:
-
Object
- Object
- Pay::StripeMarketplace::Billable
- Defined in:
- lib/pay/stripe_marketplace/billable.rb
Instance Attribute Summary collapse
-
#billable ⇒ Object
readonly
Returns the value of attribute billable.
Class Method Summary collapse
Instance Method Summary collapse
- #billing_portal(**options) ⇒ Object
-
#charge(amount, options = {}) ⇒ Object
Handles Billable#charge.
- #checkout(**options) ⇒ Object
- #checkout_charge(amount:, name:, quantity: 1, **options) ⇒ Object
- #create_setup_intent ⇒ Object
-
#customer ⇒ Object
Handles Billable#customer.
-
#initialize(billable) ⇒ Billable
constructor
A new instance of Billable.
- #invoice!(options = {}) ⇒ Object
- #processor_subscription(subscription_id, options = {}) ⇒ Object
- #save_pay_charge(object) ⇒ Object
-
#subscribe(name: Pay.default_product_name, plan: Pay.default_plan_name, **options) ⇒ Object
Handles Billable#subscribe.
-
#sync_card_from_stripe ⇒ Object
Used by webhooks when the customer or source changes.
- #trial_end_date(stripe_sub) ⇒ Object
- #upcoming_invoice ⇒ Object
-
#update_card(payment_method_id) ⇒ Object
Handles Billable#update_card.
-
#update_card_on_file(card) ⇒ Object
Save the card to the database as the user’s current card.
- #update_email! ⇒ Object
Constructor Details
#initialize(billable) ⇒ Billable
Returns a new instance of Billable.
21 22 23 |
# File 'lib/pay/stripe_marketplace/billable.rb', line 21 def initialize(billable) @billable = billable end |
Instance Attribute Details
#billable ⇒ Object (readonly)
Returns the value of attribute billable.
6 7 8 |
# File 'lib/pay/stripe_marketplace/billable.rb', line 6 def billable @billable end |
Class Method Details
.default_url_options ⇒ Object
16 17 18 |
# File 'lib/pay/stripe_marketplace/billable.rb', line 16 def Rails.application.config.action_mailer. || {} end |
Instance Method Details
#billing_portal(**options) ⇒ Object
237 238 239 240 241 242 243 |
# File 'lib/pay/stripe_marketplace/billable.rb', line 237 def billing_portal(**) args = { customer: processor_id, return_url: [:return_url] || root_url } ::Stripe::BillingPortal::Session.create(args.merge()) end |
#charge(amount, options = {}) ⇒ Object
Handles Billable#charge
Returns Pay::Charge
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/pay/stripe_marketplace/billable.rb', line 53 def charge(amount, = {}) stripe_customer = customer args = { amount: amount, confirm: true, confirmation_method: :automatic, currency: "usd", customer: stripe_customer.id, payment_method: stripe_customer.invoice_settings.default_payment_method }.merge() payment_intent = ::Stripe::PaymentIntent.create(args) Pay::Payment.new(payment_intent).validate # Create a new charge object save_pay_charge(payment_intent.charges.first) 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)
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 |
# File 'lib/pay/stripe_marketplace/billable.rb', line 195 def checkout(**) args = { customer: processor_id, payment_method_types: ["card"], mode: "payment", # These placeholder URLs will be replaced in a following step. success_url: root_url, cancel_url: root_url } # 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)
223 224 225 226 227 228 229 230 231 232 233 234 235 |
# File 'lib/pay/stripe_marketplace/billable.rb', line 223 def checkout_charge(amount:, name:, quantity: 1, **) checkout( line_items: { price_data: { currency: [:currency] || "usd", product_data: {name: name}, unit_amount: amount }, quantity: quantity }, ** ) end |
#create_setup_intent ⇒ Object
149 150 151 |
# File 'lib/pay/stripe_marketplace/billable.rb', line 149 def create_setup_intent ::Stripe::SetupIntent.create(customer: processor_id, usage: :off_session) end |
#customer ⇒ Object
Handles Billable#customer
Returns Stripe::Customer
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/pay/stripe_marketplace/billable.rb', line 28 def customer if processor_id? ::Stripe::Customer.retrieve(processor_id) else stripe_customer = ::Stripe::Customer.create(email: email, name: customer_name) billable.update(processor: :stripe, processor_id: stripe_customer.id) # Update the user's card on file if a token was passed in if card_token.present? payment_method = ::Stripe::PaymentMethod.attach(card_token, {customer: stripe_customer.id}) stripe_customer.invoice_settings.default_payment_method = payment_method.id stripe_customer.save update_card_on_file ::Stripe::PaymentMethod.retrieve(card_token).card end stripe_customer end rescue ::Stripe::StripeError => e raise Pay::Stripe::Error, e end |
#invoice!(options = {}) ⇒ Object
131 132 133 134 |
# File 'lib/pay/stripe_marketplace/billable.rb', line 131 def invoice!( = {}) return unless processor_id? ::Stripe::Invoice.create(.merge(customer: processor_id)).pay end |
#processor_subscription(subscription_id, options = {}) ⇒ Object
127 128 129 |
# File 'lib/pay/stripe_marketplace/billable.rb', line 127 def processor_subscription(subscription_id, = {}) ::Stripe::Subscription.retrieve(.merge(id: subscription_id)) end |
#save_pay_charge(object) ⇒ Object
170 171 172 173 174 175 176 177 178 179 180 181 182 183 |
# File 'lib/pay/stripe_marketplace/billable.rb', line 170 def save_pay_charge(object) charge = billable.charges.find_or_initialize_by(processor: :stripe, processor_id: object.id) charge.update( amount: object.amount, card_last4: object.payment_method_details.card.last4, card_type: object.payment_method_details.card.brand, card_exp_month: object.payment_method_details.card.exp_month, card_exp_year: object.payment_method_details.card.exp_year, created_at: Time.zone.at(object.created) ) charge end |
#subscribe(name: Pay.default_product_name, plan: Pay.default_plan_name, **options) ⇒ Object
Handles Billable#subscribe
Returns Pay::Subscription
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/pay/stripe_marketplace/billable.rb', line 76 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"], 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] opts[:customer] = customer.id stripe_sub = ::Stripe::Subscription.create(opts) subscription = billable.create_pay_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 |
#sync_card_from_stripe ⇒ Object
Used by webhooks when the customer or source changes
141 142 143 144 145 146 147 |
# File 'lib/pay/stripe_marketplace/billable.rb', line 141 def sync_card_from_stripe if (payment_method_id = customer.invoice_settings.default_payment_method) update_card_on_file ::Stripe::PaymentMethod.retrieve(payment_method_id).card else billable.update(card_type: nil, card_last4: nil) end end |
#trial_end_date(stripe_sub) ⇒ Object
153 154 155 156 |
# File 'lib/pay/stripe_marketplace/billable.rb', line 153 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
136 137 138 |
# File 'lib/pay/stripe_marketplace/billable.rb', line 136 def upcoming_invoice ::Stripe::Invoice.upcoming(customer: processor_id) end |
#update_card(payment_method_id) ⇒ Object
Handles Billable#update_card
Returns true if successful
109 110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/pay/stripe_marketplace/billable.rb', line 109 def update_card(payment_method_id) stripe_customer = customer return true if payment_method_id == stripe_customer.invoice_settings.default_payment_method payment_method = ::Stripe::PaymentMethod.attach(payment_method_id, customer: stripe_customer.id) ::Stripe::Customer.update(stripe_customer.id, invoice_settings: {default_payment_method: payment_method.id}) update_card_on_file(payment_method.card) true rescue ::Stripe::StripeError => e raise Pay::Stripe::Error, e end |
#update_card_on_file(card) ⇒ Object
Save the card to the database as the user’s current card
159 160 161 162 163 164 165 166 167 168 |
# File 'lib/pay/stripe_marketplace/billable.rb', line 159 def update_card_on_file(card) billable.update!( card_type: card.brand.capitalize, card_last4: card.last4, card_exp_month: card.exp_month, card_exp_year: card.exp_year ) billable.card_token = nil end |
#update_email! ⇒ Object
123 124 125 |
# File 'lib/pay/stripe_marketplace/billable.rb', line 123 def update_email! ::Stripe::Customer.update(processor_id, {email: email, name: customer_name}) end |