pay 2.6.7 → 2.7.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of pay might be problematic. Click here for more details.

Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -0
  3. data/app/models/pay.rb +5 -0
  4. data/app/models/pay/charge.rb +2 -0
  5. data/app/models/pay/subscription.rb +9 -2
  6. data/app/views/pay/stripe/_checkout_button.html.erb +1 -1
  7. data/db/migrate/20200603134434_add_data_to_pay_models.rb +2 -9
  8. data/db/migrate/20210309004259_add_data_to_pay_billable.rb +19 -0
  9. data/db/migrate/20210406215234_add_currency_to_pay_charges.rb +5 -0
  10. data/db/migrate/20210406215506_add_application_fee_to_pay_models.rb +7 -0
  11. data/lib/generators/active_record/templates/migration.rb +1 -1
  12. data/lib/pay.rb +22 -0
  13. data/lib/pay/adapter.rb +13 -0
  14. data/lib/pay/billable.rb +4 -0
  15. data/lib/pay/braintree/billable.rb +11 -2
  16. data/lib/pay/braintree/subscription.rb +4 -0
  17. data/lib/pay/fake_processor/subscription.rb +4 -0
  18. data/lib/pay/merchant.rb +37 -0
  19. data/lib/pay/paddle.rb +7 -0
  20. data/lib/pay/paddle/subscription.rb +7 -0
  21. data/lib/pay/paddle/webhooks/subscription_created.rb +1 -10
  22. data/lib/pay/paddle/webhooks/subscription_payment_succeeded.rb +14 -2
  23. data/lib/pay/stripe.rb +5 -0
  24. data/lib/pay/stripe/billable.rb +46 -34
  25. data/lib/pay/stripe/charge.rb +9 -4
  26. data/lib/pay/stripe/merchant.rb +66 -0
  27. data/lib/pay/stripe/subscription.rb +35 -20
  28. data/lib/pay/stripe/webhooks/account_updated.rb +17 -0
  29. data/lib/pay/stripe/webhooks/subscription_created.rb +2 -1
  30. data/lib/pay/stripe/webhooks/subscription_updated.rb +3 -2
  31. data/lib/pay/version.rb +1 -1
  32. metadata +11 -17
  33. data/lib/pay/stripe_marketplace/billable.rb +0 -246
  34. data/lib/pay/stripe_marketplace/charge.rb +0 -26
  35. data/lib/pay/stripe_marketplace/error.rb +0 -9
  36. data/lib/pay/stripe_marketplace/subscription.rb +0 -83
  37. data/lib/pay/stripe_marketplace/webhooks/charge_refunded.rb +0 -23
  38. data/lib/pay/stripe_marketplace/webhooks/charge_succeeded.rb +0 -24
  39. data/lib/pay/stripe_marketplace/webhooks/customer_deleted.rb +0 -29
  40. data/lib/pay/stripe_marketplace/webhooks/customer_updated.rb +0 -17
  41. data/lib/pay/stripe_marketplace/webhooks/payment_action_required.rb +0 -26
  42. data/lib/pay/stripe_marketplace/webhooks/payment_method_updated.rb +0 -17
  43. data/lib/pay/stripe_marketplace/webhooks/subscription_created.rb +0 -45
  44. data/lib/pay/stripe_marketplace/webhooks/subscription_deleted.rb +0 -19
  45. data/lib/pay/stripe_marketplace/webhooks/subscription_renewing.rb +0 -24
  46. data/lib/pay/stripe_marketplace/webhooks/subscription_updated.rb +0 -38
@@ -3,20 +3,25 @@ module Pay
3
3
  class Charge
4
4
  attr_reader :pay_charge
5
5
 
6
- delegate :processor_id, :owner, to: :pay_charge
6
+ delegate :processor_id, :owner, :stripe_account, to: :pay_charge
7
7
 
8
8
  def initialize(pay_charge)
9
9
  @pay_charge = pay_charge
10
10
  end
11
11
 
12
12
  def charge
13
- ::Stripe::Charge.retrieve(processor_id)
13
+ ::Stripe::Charge.retrieve({id: processor_id, expand: ["customer", "invoice.subscription"]}, {stripe_account: stripe_account})
14
14
  rescue ::Stripe::StripeError => e
15
15
  raise Pay::Stripe::Error, e
16
16
  end
17
17
 
18
- def refund!(amount_to_refund)
19
- ::Stripe::Refund.create(charge: processor_id, amount: amount_to_refund)
18
+ # https://stripe.com/docs/api/refunds/create
19
+ #
20
+ # refund!
21
+ # refund!(5_00)
22
+ # refund!(5_00, refund_application_fee: true)
23
+ def refund!(amount_to_refund, **options)
24
+ ::Stripe::Refund.create(options.merge(charge: processor_id, amount: amount_to_refund), {stripe_account: stripe_account})
20
25
  pay_charge.update(amount_refunded: amount_to_refund)
21
26
  rescue ::Stripe::StripeError => e
22
27
  raise Pay::Stripe::Error, e
@@ -0,0 +1,66 @@
1
+ module Pay
2
+ module Stripe
3
+ class Merchant
4
+ attr_reader :merchant
5
+
6
+ delegate :stripe_connect_account_id,
7
+ to: :merchant
8
+
9
+ def initialize(merchant)
10
+ @merchant = merchant
11
+ end
12
+
13
+ def create_account(**options)
14
+ defaults = {
15
+ type: "express",
16
+ capabilities: {
17
+ card_payments: {requested: true},
18
+ transfers: {requested: true}
19
+ }
20
+ }
21
+
22
+ stripe_account = ::Stripe::Account.create(defaults.merge(options))
23
+ merchant.update(stripe_connect_account_id: stripe_account.id)
24
+ stripe_account
25
+ rescue ::Stripe::StripeError => e
26
+ raise Pay::Stripe::Error, e
27
+ end
28
+
29
+ def account
30
+ ::Stripe::Account.retrieve(stripe_connect_account_id)
31
+ rescue ::Stripe::StripeError => e
32
+ raise Pay::Stripe::Error, e
33
+ end
34
+
35
+ def account_link(refresh_url:, return_url:, type: "account_onboarding", **options)
36
+ ::Stripe::AccountLink.create({
37
+ account: stripe_connect_account_id,
38
+ refresh_url: refresh_url,
39
+ return_url: return_url,
40
+ type: type
41
+ })
42
+ rescue ::Stripe::StripeError => e
43
+ raise Pay::Stripe::Error, e
44
+ end
45
+
46
+ # A single-use login link for Express accounts to access their Stripe dashboard
47
+ def login_link(**options)
48
+ ::Stripe::Account.create_login_link(stripe_connect_account_id)
49
+ rescue ::Stripe::StripeError => e
50
+ raise Pay::Stripe::Error, e
51
+ end
52
+
53
+ # Transfer money from the platform to this connected account
54
+ # https://stripe.com/docs/connect/charges-transfers#transfer-availability
55
+ def transfer(amount:, currency: "usd", **options)
56
+ ::Stripe::Transfer.create({
57
+ amount: amount,
58
+ currency: currency,
59
+ destination: stripe_connect_account_id
60
+ }.merge(options))
61
+ rescue ::Stripe::StripeError => e
62
+ raise Pay::Stripe::Error, e
63
+ end
64
+ end
65
+ end
66
+ end
@@ -16,6 +16,7 @@ module Pay
16
16
  :prorate?,
17
17
  :quantity,
18
18
  :quantity?,
19
+ :stripe_account,
19
20
  :trial_ends_at,
20
21
  to: :pay_subscription
21
22
 
@@ -23,20 +24,26 @@ module Pay
23
24
  @pay_subscription = pay_subscription
24
25
  end
25
26
 
26
- def cancel
27
- subscription = processor_subscription
28
- subscription.cancel_at_period_end = true
29
- subscription.save
27
+ def subscription(**options)
28
+ ::Stripe::Subscription.retrieve(options.merge(id: processor_id))
29
+ end
30
30
 
31
- new_ends_at = on_trial? ? trial_ends_at : Time.at(subscription.current_period_end)
32
- pay_subscription.update(ends_at: new_ends_at)
31
+ def cancel
32
+ stripe_sub = ::Stripe::Subscription.update(processor_id, {cancel_at_period_end: true}, {stripe_account: stripe_account})
33
+ pay_subscription.update(ends_at: (on_trial? ? trial_ends_at : Time.at(stripe_sub.current_period_end)))
33
34
  rescue ::Stripe::StripeError => e
34
35
  raise Pay::Stripe::Error, e
35
36
  end
36
37
 
37
38
  def cancel_now!
38
- processor_subscription.delete
39
- pay_subscription.update(ends_at: Time.zone.now, status: :canceled)
39
+ ::Stripe::Subscription.delete(processor_id, {stripe_account: stripe_account})
40
+ pay_subscription.update(ends_at: Time.current, status: :canceled)
41
+ rescue ::Stripe::StripeError => e
42
+ raise Pay::Stripe::Error, e
43
+ end
44
+
45
+ def change_quantity(quantity)
46
+ ::Stripe::Subscription.update(processor_id, quantity: quantity)
40
47
  rescue ::Stripe::StripeError => e
41
48
  raise Pay::Stripe::Error, e
42
49
  end
@@ -58,23 +65,31 @@ module Pay
58
65
  raise StandardError, "You can only resume subscriptions within their grace period."
59
66
  end
60
67
 
61
- subscription = processor_subscription
62
- subscription.plan = processor_plan
63
- subscription.trial_end = on_trial? ? trial_ends_at.to_i : "now"
64
- subscription.cancel_at_period_end = false
65
- subscription.save
68
+ ::Stripe::Subscription.update(
69
+ processor_id,
70
+ {
71
+ plan: processor_plan,
72
+ trial_end: (on_trial? ? trial_ends_at.to_i : "now"),
73
+ cancel_at_period_end: false
74
+ },
75
+ {stripe_account: stripe_account}
76
+ )
66
77
  rescue ::Stripe::StripeError => e
67
78
  raise Pay::Stripe::Error, e
68
79
  end
69
80
 
70
81
  def swap(plan)
71
- subscription = processor_subscription
72
- subscription.cancel_at_period_end = false
73
- subscription.plan = plan
74
- subscription.proration_behavior = (prorate ? "create_prorations" : "none")
75
- subscription.trial_end = on_trial? ? trial_ends_at.to_i : "now"
76
- subscription.quantity = quantity if quantity?
77
- subscription.save
82
+ ::Stripe::Subscription.update(
83
+ processor_id,
84
+ {
85
+ cancel_at_period_end: false,
86
+ plan: plan,
87
+ proration_behavior: (prorate ? "create_prorations" : "none"),
88
+ trial_end: (on_trial? ? trial_ends_at.to_i : "now"),
89
+ quantity: quantity
90
+ },
91
+ {stripe_account: stripe_account}
92
+ )
78
93
  rescue ::Stripe::StripeError => e
79
94
  raise Pay::Stripe::Error, e
80
95
  end
@@ -0,0 +1,17 @@
1
+ module Pay
2
+ module Stripe
3
+ module Webhooks
4
+ class AccountUpdated
5
+ def call(event)
6
+ object = event.data.object
7
+
8
+ merchant = Pay.find_merchant("stripe_connect_account_id", object.id)
9
+
10
+ return unless merchant.present?
11
+
12
+ merchant.update(onboarding_complete: object.charges_enabled)
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -21,9 +21,10 @@ module Pay
21
21
  subscription = Pay.subscription_model.new(name: Pay.default_product_name, owner: owner, processor: :stripe, processor_id: object.id)
22
22
  end
23
23
 
24
+ subscription.application_fee_percent = object.application_fee_percent
25
+ subscription.processor_plan = object.plan.id
24
26
  subscription.quantity = object.quantity
25
27
  subscription.status = object.status
26
- subscription.processor_plan = object.plan.id
27
28
  subscription.trial_ends_at = Time.at(object.trial_end) if object.trial_end.present?
28
29
 
29
30
  # If user was on trial, their subscription ends at the end of the trial
@@ -14,9 +14,10 @@ module Pay
14
14
  return
15
15
  end
16
16
 
17
- subscription.status = object.status
18
- subscription.quantity = object.quantity
17
+ subscription.application_fee_percent = object.application_fee_percent
19
18
  subscription.processor_plan = object.plan.id
19
+ subscription.quantity = object.quantity
20
+ subscription.status = object.status
20
21
  subscription.trial_ends_at = Time.at(object.trial_end) if object.trial_end.present?
21
22
 
22
23
  # If user was on trial, their subscription ends at the end of the trial
data/lib/pay/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Pay
2
- VERSION = "2.6.7"
2
+ VERSION = "2.7.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pay
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.6.7
4
+ version: 2.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jason Charnes
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2021-04-07 00:00:00.000000000 Z
12
+ date: 2021-05-19 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -125,6 +125,7 @@ files:
125
125
  - app/jobs/pay/email_sync_job.rb
126
126
  - app/mailers/pay/application_mailer.rb
127
127
  - app/mailers/pay/user_mailer.rb
128
+ - app/models/pay.rb
128
129
  - app/models/pay/application_record.rb
129
130
  - app/models/pay/charge.rb
130
131
  - app/models/pay/subscription.rb
@@ -141,6 +142,9 @@ files:
141
142
  - db/migrate/20170727235816_create_pay_charges.rb
142
143
  - db/migrate/20190816015720_add_status_to_pay_subscriptions.rb
143
144
  - db/migrate/20200603134434_add_data_to_pay_models.rb
145
+ - db/migrate/20210309004259_add_data_to_pay_billable.rb
146
+ - db/migrate/20210406215234_add_currency_to_pay_charges.rb
147
+ - db/migrate/20210406215506_add_application_fee_to_pay_models.rb
144
148
  - lib/generators/active_record/pay_generator.rb
145
149
  - lib/generators/active_record/templates/migration.rb
146
150
  - lib/generators/pay/email_views_generator.rb
@@ -148,6 +152,7 @@ files:
148
152
  - lib/generators/pay/pay_generator.rb
149
153
  - lib/generators/pay/views_generator.rb
150
154
  - lib/pay.rb
155
+ - lib/pay/adapter.rb
151
156
  - lib/pay/billable.rb
152
157
  - lib/pay/billable/sync_email.rb
153
158
  - lib/pay/braintree.rb
@@ -171,6 +176,7 @@ files:
171
176
  - lib/pay/fake_processor/charge.rb
172
177
  - lib/pay/fake_processor/error.rb
173
178
  - lib/pay/fake_processor/subscription.rb
179
+ - lib/pay/merchant.rb
174
180
  - lib/pay/paddle.rb
175
181
  - lib/pay/paddle/billable.rb
176
182
  - lib/pay/paddle/charge.rb
@@ -188,7 +194,9 @@ files:
188
194
  - lib/pay/stripe/billable.rb
189
195
  - lib/pay/stripe/charge.rb
190
196
  - lib/pay/stripe/error.rb
197
+ - lib/pay/stripe/merchant.rb
191
198
  - lib/pay/stripe/subscription.rb
199
+ - lib/pay/stripe/webhooks/account_updated.rb
192
200
  - lib/pay/stripe/webhooks/charge_refunded.rb
193
201
  - lib/pay/stripe/webhooks/charge_succeeded.rb
194
202
  - lib/pay/stripe/webhooks/customer_deleted.rb
@@ -200,20 +208,6 @@ files:
200
208
  - lib/pay/stripe/webhooks/subscription_deleted.rb
201
209
  - lib/pay/stripe/webhooks/subscription_renewing.rb
202
210
  - lib/pay/stripe/webhooks/subscription_updated.rb
203
- - lib/pay/stripe_marketplace/billable.rb
204
- - lib/pay/stripe_marketplace/charge.rb
205
- - lib/pay/stripe_marketplace/error.rb
206
- - lib/pay/stripe_marketplace/subscription.rb
207
- - lib/pay/stripe_marketplace/webhooks/charge_refunded.rb
208
- - lib/pay/stripe_marketplace/webhooks/charge_succeeded.rb
209
- - lib/pay/stripe_marketplace/webhooks/customer_deleted.rb
210
- - lib/pay/stripe_marketplace/webhooks/customer_updated.rb
211
- - lib/pay/stripe_marketplace/webhooks/payment_action_required.rb
212
- - lib/pay/stripe_marketplace/webhooks/payment_method_updated.rb
213
- - lib/pay/stripe_marketplace/webhooks/subscription_created.rb
214
- - lib/pay/stripe_marketplace/webhooks/subscription_deleted.rb
215
- - lib/pay/stripe_marketplace/webhooks/subscription_renewing.rb
216
- - lib/pay/stripe_marketplace/webhooks/subscription_updated.rb
217
211
  - lib/pay/version.rb
218
212
  - lib/pay/webhooks.rb
219
213
  - lib/pay/webhooks/delegator.rb
@@ -236,7 +230,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
236
230
  - !ruby/object:Gem::Version
237
231
  version: '0'
238
232
  requirements: []
239
- rubygems_version: 3.2.3
233
+ rubygems_version: 3.2.15
240
234
  signing_key:
241
235
  specification_version: 4
242
236
  summary: Payments engine for Ruby on Rails
@@ -1,246 +0,0 @@
1
- module Pay
2
- module StripeMarketplace
3
- class Billable
4
- include Rails.application.routes.url_helpers
5
-
6
- attr_reader :billable
7
-
8
- delegate :processor_id,
9
- :processor_id?,
10
- :email,
11
- :customer_name,
12
- :card_token,
13
- to: :billable
14
-
15
- class << self
16
- def default_url_options
17
- Rails.application.config.action_mailer.default_url_options || {}
18
- end
19
- end
20
-
21
- def initialize(billable)
22
- @billable = billable
23
- end
24
-
25
- # Handles Billable#customer
26
- #
27
- # Returns Stripe::Customer
28
- def customer
29
- if processor_id?
30
- ::Stripe::Customer.retrieve(processor_id)
31
- else
32
- stripe_customer = ::Stripe::Customer.create(email: email, name: customer_name)
33
- billable.update(processor: :stripe, processor_id: stripe_customer.id)
34
-
35
- # Update the user's card on file if a token was passed in
36
- if card_token.present?
37
- payment_method = ::Stripe::PaymentMethod.attach(card_token, {customer: stripe_customer.id})
38
- stripe_customer.invoice_settings.default_payment_method = payment_method.id
39
- stripe_customer.save
40
-
41
- update_card_on_file ::Stripe::PaymentMethod.retrieve(card_token).card
42
- end
43
-
44
- stripe_customer
45
- end
46
- rescue ::Stripe::StripeError => e
47
- raise Pay::Stripe::Error, e
48
- end
49
-
50
- # Handles Billable#charge
51
- #
52
- # Returns Pay::Charge
53
- def charge(amount, options = {})
54
- stripe_customer = customer
55
- args = {
56
- amount: amount,
57
- confirm: true,
58
- confirmation_method: :automatic,
59
- currency: "usd",
60
- customer: stripe_customer.id,
61
- payment_method: stripe_customer.invoice_settings.default_payment_method
62
- }.merge(options)
63
-
64
- payment_intent = ::Stripe::PaymentIntent.create(args)
65
- Pay::Payment.new(payment_intent).validate
66
-
67
- # Create a new charge object
68
- save_pay_charge(payment_intent.charges.first)
69
- rescue ::Stripe::StripeError => e
70
- raise Pay::Stripe::Error, e
71
- end
72
-
73
- # Handles Billable#subscribe
74
- #
75
- # Returns Pay::Subscription
76
- def subscribe(name: Pay.default_product_name, plan: Pay.default_plan_name, **options)
77
- quantity = options.delete(:quantity) || 1
78
- opts = {
79
- expand: ["pending_setup_intent", "latest_invoice.payment_intent"],
80
- items: [plan: plan, quantity: quantity],
81
- off_session: true
82
- }.merge(options)
83
-
84
- # Inherit trial from plan unless trial override was specified
85
- opts[:trial_from_plan] = true unless opts[:trial_period_days]
86
-
87
- opts[:customer] = customer.id
88
-
89
- stripe_sub = ::Stripe::Subscription.create(opts)
90
- subscription = billable.create_pay_subscription(stripe_sub, "stripe", name, plan, status: stripe_sub.status, quantity: quantity)
91
-
92
- # No trial, card requires SCA
93
- if subscription.incomplete?
94
- Pay::Payment.new(stripe_sub.latest_invoice.payment_intent).validate
95
-
96
- # Trial, card requires SCA
97
- elsif subscription.on_trial? && stripe_sub.pending_setup_intent
98
- Pay::Payment.new(stripe_sub.pending_setup_intent).validate
99
- end
100
-
101
- subscription
102
- rescue ::Stripe::StripeError => e
103
- raise Pay::Stripe::Error, e
104
- end
105
-
106
- # Handles Billable#update_card
107
- #
108
- # Returns true if successful
109
- def update_card(payment_method_id)
110
- stripe_customer = customer
111
-
112
- return true if payment_method_id == stripe_customer.invoice_settings.default_payment_method
113
-
114
- payment_method = ::Stripe::PaymentMethod.attach(payment_method_id, customer: stripe_customer.id)
115
- ::Stripe::Customer.update(stripe_customer.id, invoice_settings: {default_payment_method: payment_method.id})
116
-
117
- update_card_on_file(payment_method.card)
118
- true
119
- rescue ::Stripe::StripeError => e
120
- raise Pay::Stripe::Error, e
121
- end
122
-
123
- def update_email!
124
- ::Stripe::Customer.update(processor_id, {email: email, name: customer_name})
125
- end
126
-
127
- def processor_subscription(subscription_id, options = {})
128
- ::Stripe::Subscription.retrieve(options.merge(id: subscription_id))
129
- end
130
-
131
- def invoice!(options = {})
132
- return unless processor_id?
133
- ::Stripe::Invoice.create(options.merge(customer: processor_id)).pay
134
- end
135
-
136
- def upcoming_invoice
137
- ::Stripe::Invoice.upcoming(customer: processor_id)
138
- end
139
-
140
- # Used by webhooks when the customer or source changes
141
- def sync_card_from_stripe
142
- if (payment_method_id = customer.invoice_settings.default_payment_method)
143
- update_card_on_file ::Stripe::PaymentMethod.retrieve(payment_method_id).card
144
- else
145
- billable.update(card_type: nil, card_last4: nil)
146
- end
147
- end
148
-
149
- def create_setup_intent
150
- ::Stripe::SetupIntent.create(customer: processor_id, usage: :off_session)
151
- end
152
-
153
- def trial_end_date(stripe_sub)
154
- # Times in Stripe are returned in UTC
155
- stripe_sub.trial_end.present? ? Time.at(stripe_sub.trial_end) : nil
156
- end
157
-
158
- # Save the card to the database as the user's current card
159
- def update_card_on_file(card)
160
- billable.update!(
161
- card_type: card.brand.capitalize,
162
- card_last4: card.last4,
163
- card_exp_month: card.exp_month,
164
- card_exp_year: card.exp_year
165
- )
166
-
167
- billable.card_token = nil
168
- end
169
-
170
- def save_pay_charge(object)
171
- charge = billable.charges.find_or_initialize_by(processor: :stripe, processor_id: object.id)
172
-
173
- charge.update(
174
- amount: object.amount,
175
- card_last4: object.payment_method_details.card.last4,
176
- card_type: object.payment_method_details.card.brand,
177
- card_exp_month: object.payment_method_details.card.exp_month,
178
- card_exp_year: object.payment_method_details.card.exp_year,
179
- created_at: Time.zone.at(object.created)
180
- )
181
-
182
- charge
183
- end
184
-
185
- # https://stripe.com/docs/api/checkout/sessions/create
186
- #
187
- # checkout(mode: "payment")
188
- # checkout(mode: "setup")
189
- # checkout(mode: "subscription")
190
- #
191
- # checkout(line_items: "price_12345", quantity: 2)
192
- # checkout(line_items [{ price: "price_123" }, { price: "price_456" }])
193
- # checkout(line_items, "price_12345", allow_promotion_codes: true)
194
- #
195
- def checkout(**options)
196
- args = {
197
- customer: processor_id,
198
- payment_method_types: ["card"],
199
- mode: "payment",
200
- # These placeholder URLs will be replaced in a following step.
201
- success_url: root_url,
202
- cancel_url: root_url
203
- }
204
-
205
- # Line items are optional
206
- if (line_items = options.delete(:line_items))
207
- args[:line_items] = Array.wrap(line_items).map { |item|
208
- if item.is_a? Hash
209
- item
210
- else
211
- {price: item, quantity: options.fetch(:quantity, 1)}
212
- end
213
- }
214
- end
215
-
216
- ::Stripe::Checkout::Session.create(args.merge(options))
217
- end
218
-
219
- # https://stripe.com/docs/api/checkout/sessions/create
220
- #
221
- # checkout_charge(amount: 15_00, name: "T-shirt", quantity: 2)
222
- #
223
- def checkout_charge(amount:, name:, quantity: 1, **options)
224
- checkout(
225
- line_items: {
226
- price_data: {
227
- currency: options[:currency] || "usd",
228
- product_data: {name: name},
229
- unit_amount: amount
230
- },
231
- quantity: quantity
232
- },
233
- **options
234
- )
235
- end
236
-
237
- def billing_portal(**options)
238
- args = {
239
- customer: processor_id,
240
- return_url: options[:return_url] || root_url
241
- }
242
- ::Stripe::BillingPortal::Session.create(args.merge(options))
243
- end
244
- end
245
- end
246
- end