Class: Pay::Stripe::Customer
- Inherits:
-
Customer
- Object
- ApplicationRecord
- Customer
- Pay::Stripe::Customer
- Includes:
- Routing
- Defined in:
- app/models/pay/stripe/customer.rb
Instance Method Summary collapse
- #add_payment_method(payment_method_id, default: false) ⇒ Object
- #api_record(expand: ["tax", "invoice_credit_balance"]) ⇒ Object
-
#api_record_attributes ⇒ Object
Returns a hash of attributes for the Stripe::Customer object.
- #authorize(amount, options = {}) ⇒ Object
- #billing_portal(**options) ⇒ Object
-
#charge(amount, options = {}) ⇒ Object
Charges an amount to the customer’s default payment method.
- #checkout(**options) ⇒ Object
- #checkout_charge(amount:, name:, quantity: 1, **options) ⇒ Object
-
#create_meter_event(event_name, payload: {}, **options) ⇒ Object
Creates a meter event to bill for usage.
-
#create_payment_intent(amount, options = {}) ⇒ Object
Creates and returns a Stripe::PaymentIntent.
- #create_setup_intent(options = {}) ⇒ Object
- #customer_session(**options) ⇒ Object
- #invoice!(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(**options) ⇒ Object
Syncs a customer’s subscriptions from Stripe to the database.
-
#terminal_charge(amount, options = {}) ⇒ Object
Used for creating Stripe Terminal charges.
- #upcoming_invoice ⇒ Object
- #update_api_record(**attributes) ⇒ Object
Methods included from Routing
Methods inherited from Customer
#active?, #customer_name, #deleted?, #has_incomplete_payment?, #on_generic_trial?, #on_trial?, #on_trial_or_subscribed?, #retry_past_due_subscriptions!, #subscribed?, #subscription, #update_payment_method
Instance Method Details
#add_payment_method(payment_method_id, default: false) ⇒ Object
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'app/models/pay/stripe/customer.rb', line 84 def add_payment_method(payment_method_id, default: false) api_record 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 |
#api_record(expand: ["tax", "invoice_credit_balance"]) ⇒ Object
26 27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'app/models/pay/stripe/customer.rb', line 26 def api_record(expand: ["tax", "invoice_credit_balance"]) with_lock do if processor_id? ::Stripe::Customer.retrieve({id: processor_id, expand: }, ) else ::Stripe::Customer.create(api_record_attributes.merge(expand: ), ).tap do |customer| update!(processor_id: customer.id, stripe_account: stripe_account) end end end rescue ::Stripe::StripeError => e raise Pay::Stripe::Error, e end |
#api_record_attributes ⇒ Object
Returns a hash of attributes for the Stripe::Customer object
12 13 14 15 16 17 18 19 20 21 22 23 24 |
# File 'app/models/pay/stripe/customer.rb', line 12 def api_record_attributes attributes = case owner.class.pay_stripe_customer_attributes when Symbol owner.send(owner.class.pay_stripe_customer_attributes, self) when Proc owner.class.pay_stripe_customer_attributes.call(self) end # Guard against attributes being returned nil attributes ||= {} {email: email, name: customer_name}.merge(attributes) end |
#authorize(amount, options = {}) ⇒ Object
241 242 243 |
# File 'app/models/pay/stripe/customer.rb', line 241 def (amount, = {}) charge(amount, .merge(capture_method: :manual)) end |
#billing_portal(**options) ⇒ Object
226 227 228 229 230 231 232 233 |
# File 'app/models/pay/stripe/customer.rb', line 226 def billing_portal(**) api_record 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
Charges an amount to the customer’s default payment method
46 47 48 49 50 51 52 53 54 55 56 |
# File 'app/models/pay/stripe/customer.rb', line 46 def charge(amount, = {}) args = {confirm: true, payment_method: default_payment_method&.processor_id}.merge() payment_intent = create_payment_intent(amount, args) Pay::Payment.new(payment_intent).validate charge = payment_intent.latest_charge 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)
170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 |
# File 'app/models/pay/stripe/customer.rb', line 170 def checkout(**) api_record unless processor_id? args = { customer: processor_id, mode: "payment" } # Hosted (the default) checkout sessions require a success_url and cancel_url if ["", "hosted"].include? [:ui_mode].to_s args[:success_url] = merge_session_id_param(.delete(:success_url) || root_url) args[:cancel_url] = merge_session_id_param(.delete(:cancel_url) || root_url) end if [:return_url] args[:return_url] = merge_session_id_param(.delete(:return_url)) end # Line items are optional if (line_items = .delete(:line_items)) quantity = .delete(:quantity) || 1 args[:line_items] = Array.wrap(line_items).map { |item| if item.is_a? Hash item else { price: item, quantity: quantity } 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)
210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 |
# File 'app/models/pay/stripe/customer.rb', line 210 def checkout_charge(amount:, name:, quantity: 1, **) api_record 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_meter_event(event_name, payload: {}, **options) ⇒ Object
Creates a meter event to bill for usage
create_meter_event(:api_request, value: 1) create_meter_event(:api_request, token: 7)
249 250 251 252 253 254 255 |
# File 'app/models/pay/stripe/customer.rb', line 249 def create_meter_event(event_name, payload: {}, **) api_record unless processor_id? ::Stripe::Billing::MeterEvent.create({ event_name: event_name, payload: {stripe_customer_id: processor_id}.merge(payload) }.merge()) end |
#create_payment_intent(amount, options = {}) ⇒ Object
Creates and returns a Stripe::PaymentIntent
120 121 122 123 124 125 126 127 128 129 130 |
# File 'app/models/pay/stripe/customer.rb', line 120 def create_payment_intent(amount, = {}) args = { amount: amount, currency: "usd", customer: processor_id || api_record.id, expand: ["latest_charge.refunds"], return_url: root_url }.merge() ::Stripe::PaymentIntent.create(args, ) end |
#create_setup_intent(options = {}) ⇒ Object
137 138 139 |
# File 'app/models/pay/stripe/customer.rb', line 137 def create_setup_intent( = {}) ::Stripe::SetupIntent.create({customer: processor_id || api_record.id, usage: :off_session}.merge(), ) end |
#customer_session(**options) ⇒ Object
235 236 237 238 239 |
# File 'app/models/pay/stripe/customer.rb', line 235 def customer_session(**) api_record unless processor_id? args = {customer: processor_id} ::Stripe::CustomerSession.create(args.merge(), ) end |
#invoice!(options = {}) ⇒ Object
141 142 143 |
# File 'app/models/pay/stripe/customer.rb', line 141 def invoice!( = {}) ::Stripe::Invoice.create(.merge(customer: processor_id || api_record.id), ).pay end |
#save_payment_method(payment_method, default:) ⇒ Object
Save the Stripe::PaymentMethod to the database
102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
# File 'app/models/pay/stripe/customer.rb', line 102 def save_payment_method(payment_method, default:) pay_payment_method = payment_methods.where(processor_id: payment_method.id).first_or_initialize attributes = Pay::Stripe::PaymentMethod.extract_attributes(payment_method).merge(default: default) # Ignore the payment method if it's already in the database payment_methods.where.not(id: pay_payment_method.id).update_all(default: false) if default pay_payment_method.update!(attributes) # Reload the Rails association reload_default_payment_method pay_payment_method end |
#subscribe(name: Pay.default_product_name, plan: Pay.default_plan_name, **options) ⇒ Object
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 |
# File 'app/models/pay/stripe/customer.rb', line 58 def subscribe(name: Pay.default_product_name, plan: Pay.default_plan_name, **) quantity = .delete(:quantity) opts = { expand: ["pending_setup_intent", "latest_invoice.payment_intent", "latest_invoice.charge"], items: [plan: plan, quantity: quantity] }.merge() # Load the Stripe customer to verify it exists and update payment method if needed opts[:customer] = processor_id || api_record.id # Create subscription on Stripe stripe_sub = ::Stripe::Subscription.create(opts.merge(Pay::Stripe::Subscription.), ) # Save Pay::Subscription subscription = Pay::Stripe::Subscription.sync(stripe_sub.id, object: stripe_sub, name: name) # No trial, payment method requires SCA if [:payment_behavior].to_s != "default_incomplete" && 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(**options) ⇒ Object
Syncs a customer’s subscriptions from Stripe to the database. Note that by default canceled subscriptions are NOT returned by Stripe. In order to include them, use ‘sync_subscriptions(status: “all”)`.
151 152 153 154 155 156 157 158 |
# File 'app/models/pay/stripe/customer.rb', line 151 def sync_subscriptions(**) subscriptions = ::Stripe::Subscription.list(.with_defaults(customer: processor_id), ) subscriptions.map do |subscription| Pay::Stripe::Subscription.sync(subscription.id) end rescue ::Stripe::StripeError => e raise Pay::Stripe::Error, e end |
#terminal_charge(amount, options = {}) ⇒ Object
Used for creating Stripe Terminal charges
133 134 135 |
# File 'app/models/pay/stripe/customer.rb', line 133 def terminal_charge(amount, = {}) create_payment_intent(amount, .merge(payment_method_types: ["card_present"], capture_method: "manual")) end |
#upcoming_invoice ⇒ Object
145 146 147 |
# File 'app/models/pay/stripe/customer.rb', line 145 def upcoming_invoice ::Stripe::Invoice.upcoming({customer: processor_id || api_record.id}, ) end |
#update_api_record(**attributes) ⇒ Object
40 41 42 43 |
# File 'app/models/pay/stripe/customer.rb', line 40 def update_api_record(**attributes) api_record unless processor_id? ::Stripe::Customer.update(processor_id, api_record_attributes.merge(attributes), ) end |