pay 2.7.0 → 3.0.1
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.
- checksums.yaml +4 -4
- data/README.md +35 -696
- data/app/controllers/pay/webhooks/braintree_controller.rb +10 -3
- data/app/controllers/pay/webhooks/paddle_controller.rb +7 -8
- data/app/controllers/pay/webhooks/stripe_controller.rb +6 -3
- data/app/jobs/pay/{email_sync_job.rb → customer_sync_job.rb} +3 -4
- data/app/models/pay/application_record.rb +1 -5
- data/app/models/pay/charge.rb +31 -18
- data/app/models/pay/customer.rb +87 -0
- data/app/models/pay/merchant.rb +19 -0
- data/app/models/pay/payment_method.rb +41 -0
- data/app/models/pay/subscription.rb +42 -30
- data/app/models/pay/webhook.rb +36 -0
- data/app/views/layouts/pay/application.html.erb +2 -3
- data/app/views/pay/payments/show.html.erb +109 -81
- data/app/views/pay/user_mailer/receipt.html.erb +2 -2
- data/app/views/pay/user_mailer/refund.html.erb +2 -2
- data/config/locales/en.yml +1 -1
- data/db/migrate/1_create_pay_tables.rb +72 -0
- data/lib/generators/active_record/billable_generator.rb +44 -0
- data/lib/generators/active_record/merchant_generator.rb +44 -0
- data/lib/generators/active_record/templates/billable_migration.rb +17 -0
- data/lib/generators/active_record/templates/merchant_migration.rb +12 -0
- data/lib/generators/pay/{pay_generator.rb → billable_generator.rb} +2 -3
- data/lib/generators/pay/merchant_generator.rb +17 -0
- data/lib/generators/pay/orm_helpers.rb +10 -6
- data/lib/pay/adapter.rb +9 -0
- data/lib/pay/attributes.rb +74 -0
- data/lib/pay/billable/sync_customer.rb +30 -0
- data/lib/pay/braintree/billable.rb +133 -110
- data/lib/pay/braintree/payment_method.rb +42 -0
- data/lib/pay/braintree/subscription.rb +9 -12
- data/lib/pay/braintree/webhooks/subscription_canceled.rb +1 -1
- data/lib/pay/braintree/webhooks/subscription_charged_successfully.rb +4 -4
- data/lib/pay/braintree/webhooks/subscription_charged_unsuccessfully.rb +1 -1
- data/lib/pay/braintree/webhooks/subscription_expired.rb +1 -1
- data/lib/pay/braintree/webhooks/subscription_trial_ended.rb +2 -2
- data/lib/pay/braintree/webhooks/subscription_went_active.rb +1 -1
- data/lib/pay/braintree/webhooks/subscription_went_past_due.rb +1 -1
- data/lib/pay/braintree.rb +3 -2
- data/lib/pay/engine.rb +6 -1
- data/lib/pay/env.rb +8 -0
- data/lib/pay/fake_processor/billable.rb +45 -21
- data/lib/pay/fake_processor/payment_method.rb +21 -0
- data/lib/pay/fake_processor/subscription.rb +11 -8
- data/lib/pay/fake_processor.rb +2 -1
- data/lib/pay/nano_id.rb +13 -0
- data/lib/pay/paddle/billable.rb +18 -48
- data/lib/pay/paddle/charge.rb +5 -5
- data/lib/pay/paddle/payment_method.rb +60 -0
- data/lib/pay/paddle/response.rb +0 -0
- data/lib/pay/paddle/subscription.rb +49 -8
- data/lib/pay/paddle/webhooks/subscription_cancelled.rb +6 -3
- data/lib/pay/paddle/webhooks/subscription_created.rb +1 -40
- data/lib/pay/paddle/webhooks/subscription_payment_refunded.rb +3 -3
- data/lib/pay/paddle/webhooks/subscription_payment_succeeded.rb +26 -28
- data/lib/pay/paddle/webhooks/subscription_updated.rb +2 -2
- data/lib/pay/paddle.rb +7 -3
- data/lib/pay/payment.rb +1 -1
- data/lib/pay/receipts.rb +35 -7
- data/lib/pay/stripe/billable.rb +80 -102
- data/lib/pay/stripe/charge.rb +59 -3
- data/lib/pay/stripe/merchant.rb +10 -10
- data/lib/pay/stripe/payment_method.rb +61 -0
- data/lib/pay/stripe/subscription.rb +70 -8
- data/lib/pay/stripe/webhooks/account_updated.rb +2 -3
- data/lib/pay/stripe/webhooks/charge_refunded.rb +2 -7
- data/lib/pay/stripe/webhooks/charge_succeeded.rb +2 -8
- data/lib/pay/stripe/webhooks/checkout_session_async_payment_succeeded.rb +15 -0
- data/lib/pay/stripe/webhooks/checkout_session_completed.rb +15 -0
- data/lib/pay/stripe/webhooks/customer_deleted.rb +7 -15
- data/lib/pay/stripe/webhooks/customer_updated.rb +10 -3
- data/lib/pay/stripe/webhooks/payment_action_required.rb +2 -2
- data/lib/pay/stripe/webhooks/payment_intent_succeeded.rb +6 -14
- data/lib/pay/stripe/webhooks/payment_method_attached.rb +15 -0
- data/lib/pay/stripe/webhooks/payment_method_detached.rb +12 -0
- data/lib/pay/stripe/webhooks/payment_method_updated.rb +10 -4
- data/lib/pay/stripe/webhooks/subscription_created.rb +1 -36
- data/lib/pay/stripe/webhooks/subscription_deleted.rb +2 -9
- data/lib/pay/stripe/webhooks/subscription_renewing.rb +14 -6
- data/lib/pay/stripe/webhooks/subscription_updated.rb +1 -29
- data/lib/pay/stripe.rb +12 -3
- data/lib/pay/version.rb +1 -1
- data/lib/pay/webhooks/delegator.rb +4 -0
- data/lib/pay/webhooks/process_job.rb +9 -0
- data/lib/pay/webhooks.rb +1 -0
- data/lib/pay.rb +7 -78
- data/lib/tasks/pay.rake +20 -0
- metadata +31 -39
- data/app/models/pay.rb +0 -5
- data/db/migrate/20170205020145_create_pay_subscriptions.rb +0 -17
- data/db/migrate/20170727235816_create_pay_charges.rb +0 -18
- data/db/migrate/20190816015720_add_status_to_pay_subscriptions.rb +0 -14
- data/db/migrate/20200603134434_add_data_to_pay_models.rb +0 -15
- data/db/migrate/20210309004259_add_data_to_pay_billable.rb +0 -19
- data/db/migrate/20210406215234_add_currency_to_pay_charges.rb +0 -5
- data/db/migrate/20210406215506_add_application_fee_to_pay_models.rb +0 -7
- data/lib/generators/active_record/pay_generator.rb +0 -58
- data/lib/generators/active_record/templates/migration.rb +0 -9
- data/lib/pay/billable/sync_email.rb +0 -40
- data/lib/pay/billable.rb +0 -172
data/lib/pay/paddle.rb
CHANGED
@@ -2,8 +2,9 @@ module Pay
|
|
2
2
|
module Paddle
|
3
3
|
autoload :Billable, "pay/paddle/billable"
|
4
4
|
autoload :Charge, "pay/paddle/charge"
|
5
|
-
autoload :Subscription, "pay/paddle/subscription"
|
6
5
|
autoload :Error, "pay/paddle/error"
|
6
|
+
autoload :PaymentMethod, "pay/paddle/payment_method"
|
7
|
+
autoload :Subscription, "pay/paddle/subscription"
|
7
8
|
|
8
9
|
module Webhooks
|
9
10
|
autoload :SignatureVerifier, "pay/paddle/webhooks/signature_verifier"
|
@@ -44,9 +45,12 @@ module Pay
|
|
44
45
|
options.merge(owner_sgid: owner.to_sgid.to_s).to_json
|
45
46
|
end
|
46
47
|
|
48
|
+
def self.parse_passthrough(passthrough)
|
49
|
+
JSON.parse(passthrough)
|
50
|
+
end
|
51
|
+
|
47
52
|
def self.owner_from_passthrough(passthrough)
|
48
|
-
|
49
|
-
GlobalID::Locator.locate_signed(passthrough_json["owner_sgid"])
|
53
|
+
GlobalID::Locator.locate_signed parse_passthrough(passthrough)["owner_sgid"]
|
50
54
|
rescue JSON::ParserError
|
51
55
|
nil
|
52
56
|
end
|
data/lib/pay/payment.rb
CHANGED
@@ -2,7 +2,7 @@ module Pay
|
|
2
2
|
class Payment
|
3
3
|
attr_reader :intent
|
4
4
|
|
5
|
-
delegate :id, :amount, :client_secret, :status, :confirm, to: :intent
|
5
|
+
delegate :id, :amount, :client_secret, :customer, :status, :confirm, to: :intent
|
6
6
|
|
7
7
|
def self.from_id(id)
|
8
8
|
intent = id.start_with?("seti_") ? ::Stripe::SetupIntent.retrieve(id) : ::Stripe::PaymentIntent.retrieve(id)
|
data/lib/pay/receipts.rb
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
module Pay
|
2
2
|
module Receipts
|
3
|
-
def filename
|
4
|
-
"receipt-#{created_at.strftime("%Y-%m-%d")}.pdf"
|
5
|
-
end
|
6
|
-
|
7
3
|
def product
|
8
4
|
Pay.application_name
|
9
5
|
end
|
10
6
|
|
11
|
-
|
7
|
+
def receipt_filename
|
8
|
+
"receipt-#{created_at.strftime("%Y-%m-%d")}.pdf"
|
9
|
+
end
|
10
|
+
alias_method :filename, :receipt_filename
|
11
|
+
|
12
12
|
def receipt
|
13
13
|
receipt_pdf.render
|
14
14
|
end
|
@@ -26,15 +26,43 @@ module Pay
|
|
26
26
|
)
|
27
27
|
end
|
28
28
|
|
29
|
+
def invoice_filename
|
30
|
+
"invoice-#{created_at.strftime("%Y-%m-%d")}.pdf"
|
31
|
+
end
|
32
|
+
|
33
|
+
def invoice
|
34
|
+
invoice_pdf.render
|
35
|
+
end
|
36
|
+
|
37
|
+
def invoice_pdf
|
38
|
+
::Receipts::Invoice.new(
|
39
|
+
id: id,
|
40
|
+
issue_date: created_at,
|
41
|
+
due_date: created_at,
|
42
|
+
status: "<b><color rgb='#5eba7d'>PAID</color></b>",
|
43
|
+
bill_to: [
|
44
|
+
customer.customer_name,
|
45
|
+
customer.email
|
46
|
+
].compact,
|
47
|
+
product: product,
|
48
|
+
company: {
|
49
|
+
name: Pay.business_name,
|
50
|
+
address: Pay.business_address,
|
51
|
+
email: Pay.support_email
|
52
|
+
},
|
53
|
+
line_items: line_items
|
54
|
+
)
|
55
|
+
end
|
56
|
+
|
29
57
|
def line_items
|
30
58
|
line_items = [
|
31
59
|
[I18n.t("receipt.date"), created_at.to_s],
|
32
|
-
[I18n.t("receipt.account_billed"), "#{
|
60
|
+
[I18n.t("receipt.account_billed"), "#{customer.customer_name} (#{customer.email})"],
|
33
61
|
[I18n.t("receipt.product"), product],
|
34
62
|
[I18n.t("receipt.amount"), ActionController::Base.helpers.number_to_currency(amount / 100.0)],
|
35
63
|
[I18n.t("receipt.charged_to"), charged_to]
|
36
64
|
]
|
37
|
-
line_items << [I18n.t("receipt.additional_info"), owner.extra_billing_info] if owner.extra_billing_info?
|
65
|
+
line_items << [I18n.t("receipt.additional_info"), customer.owner.extra_billing_info] if customer.owner.extra_billing_info?
|
38
66
|
line_items
|
39
67
|
end
|
40
68
|
end
|
data/lib/pay/stripe/billable.rb
CHANGED
@@ -3,43 +3,40 @@ module Pay
|
|
3
3
|
class Billable
|
4
4
|
include Rails.application.routes.url_helpers
|
5
5
|
|
6
|
-
attr_reader :
|
6
|
+
attr_reader :pay_customer
|
7
7
|
|
8
8
|
delegate :processor_id,
|
9
9
|
:processor_id?,
|
10
10
|
:email,
|
11
11
|
:customer_name,
|
12
|
-
:
|
12
|
+
:payment_method_token,
|
13
|
+
:payment_method_token?,
|
13
14
|
:stripe_account,
|
14
|
-
to: :
|
15
|
+
to: :pay_customer
|
15
16
|
|
16
|
-
|
17
|
-
|
18
|
-
Rails.application.config.action_mailer.default_url_options || {}
|
19
|
-
end
|
17
|
+
def self.default_url_options
|
18
|
+
Rails.application.config.action_mailer.default_url_options || {}
|
20
19
|
end
|
21
20
|
|
22
|
-
def initialize(
|
23
|
-
@
|
21
|
+
def initialize(pay_customer)
|
22
|
+
@pay_customer = pay_customer
|
24
23
|
end
|
25
24
|
|
26
|
-
# Handles Billable#customer
|
27
|
-
#
|
28
|
-
# Returns Stripe::Customer
|
29
25
|
def customer
|
30
26
|
stripe_customer = if processor_id?
|
31
|
-
::Stripe::Customer.retrieve(
|
27
|
+
::Stripe::Customer.retrieve({id: processor_id}, stripe_options)
|
32
28
|
else
|
33
|
-
sc = ::Stripe::Customer.create({email: email, name: customer_name},
|
34
|
-
|
29
|
+
sc = ::Stripe::Customer.create({email: email, name: customer_name}, stripe_options)
|
30
|
+
pay_customer.update!(processor_id: sc.id, stripe_account: stripe_account)
|
35
31
|
sc
|
36
32
|
end
|
37
33
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
34
|
+
if payment_method_token?
|
35
|
+
payment_method = ::Stripe::PaymentMethod.attach(payment_method_token, {customer: stripe_customer.id}, stripe_options)
|
36
|
+
pay_payment_method = save_payment_method(payment_method, default: false)
|
37
|
+
pay_payment_method.make_default!
|
38
|
+
|
39
|
+
pay_customer.payment_method_token = nil
|
43
40
|
end
|
44
41
|
|
45
42
|
stripe_customer
|
@@ -47,36 +44,32 @@ module Pay
|
|
47
44
|
raise Pay::Stripe::Error, e
|
48
45
|
end
|
49
46
|
|
50
|
-
# Handles Billable#charge
|
51
|
-
#
|
52
|
-
# Returns Pay::Charge
|
53
47
|
def charge(amount, options = {})
|
54
|
-
|
48
|
+
add_payment_method(payment_method_token, default: true) if payment_method_token?
|
49
|
+
|
50
|
+
payment_method = pay_customer.default_payment_method
|
55
51
|
args = {
|
56
52
|
amount: amount,
|
57
53
|
confirm: true,
|
58
54
|
confirmation_method: :automatic,
|
59
55
|
currency: "usd",
|
60
|
-
customer:
|
61
|
-
payment_method:
|
56
|
+
customer: processor_id,
|
57
|
+
payment_method: payment_method&.processor_id
|
62
58
|
}.merge(options)
|
63
59
|
|
64
|
-
payment_intent = ::Stripe::PaymentIntent.create(args,
|
60
|
+
payment_intent = ::Stripe::PaymentIntent.create(args, stripe_options)
|
65
61
|
Pay::Payment.new(payment_intent).validate
|
66
62
|
|
67
|
-
|
68
|
-
|
63
|
+
charge = payment_intent.charges.first
|
64
|
+
Pay::Stripe::Charge.sync(charge.id, object: charge)
|
69
65
|
rescue ::Stripe::StripeError => e
|
70
66
|
raise Pay::Stripe::Error, e
|
71
67
|
end
|
72
68
|
|
73
|
-
# Handles Billable#subscribe
|
74
|
-
#
|
75
|
-
# Returns Pay::Subscription
|
76
69
|
def subscribe(name: Pay.default_product_name, plan: Pay.default_plan_name, **options)
|
77
70
|
quantity = options.delete(:quantity) || 1
|
78
71
|
opts = {
|
79
|
-
expand: ["pending_setup_intent", "latest_invoice.payment_intent"],
|
72
|
+
expand: ["pending_setup_intent", "latest_invoice.payment_intent", "latest_invoice.charge.invoice"],
|
80
73
|
items: [plan: plan, quantity: quantity],
|
81
74
|
off_session: true
|
82
75
|
}.merge(options)
|
@@ -84,19 +77,18 @@ module Pay
|
|
84
77
|
# Inherit trial from plan unless trial override was specified
|
85
78
|
opts[:trial_from_plan] = true unless opts[:trial_period_days]
|
86
79
|
|
87
|
-
# Load the Stripe customer to verify it exists and update
|
80
|
+
# Load the Stripe customer to verify it exists and update payment method if needed
|
88
81
|
opts[:customer] = customer.id
|
89
82
|
|
90
|
-
|
91
|
-
|
83
|
+
# Create subscription on Stripe
|
84
|
+
stripe_sub = ::Stripe::Subscription.create(opts, stripe_options)
|
92
85
|
|
93
|
-
#
|
86
|
+
# Save Pay::Subscription
|
87
|
+
subscription = Pay::Stripe::Subscription.sync(stripe_sub.id, object: stripe_sub, name: name)
|
88
|
+
|
89
|
+
# No trial, payment method requires SCA
|
94
90
|
if subscription.incomplete?
|
95
91
|
Pay::Payment.new(stripe_sub.latest_invoice.payment_intent).validate
|
96
|
-
|
97
|
-
# Trial, card requires SCA
|
98
|
-
elsif subscription.on_trial? && stripe_sub.pending_setup_intent
|
99
|
-
Pay::Payment.new(stripe_sub.pending_setup_intent).validate
|
100
92
|
end
|
101
93
|
|
102
94
|
subscription
|
@@ -104,51 +96,57 @@ module Pay
|
|
104
96
|
raise Pay::Stripe::Error, e
|
105
97
|
end
|
106
98
|
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
def update_card(payment_method_id)
|
111
|
-
stripe_customer = customer
|
112
|
-
|
113
|
-
return true if payment_method_id == stripe_customer.invoice_settings.default_payment_method
|
99
|
+
def add_payment_method(payment_method_id, default: false)
|
100
|
+
customer unless processor_id?
|
101
|
+
payment_method = ::Stripe::PaymentMethod.attach(payment_method_id, {customer: processor_id}, stripe_options)
|
114
102
|
|
115
|
-
|
116
|
-
|
103
|
+
if default
|
104
|
+
::Stripe::Customer.update(processor_id, {
|
105
|
+
invoice_settings: {
|
106
|
+
default_payment_method: payment_method.id
|
107
|
+
}
|
108
|
+
}, stripe_options)
|
109
|
+
end
|
117
110
|
|
118
|
-
|
119
|
-
true
|
111
|
+
save_payment_method(payment_method, default: default)
|
120
112
|
rescue ::Stripe::StripeError => e
|
121
113
|
raise Pay::Stripe::Error, e
|
122
114
|
end
|
123
115
|
|
116
|
+
# Save the Stripe::PaymentMethod to the database
|
117
|
+
def save_payment_method(payment_method, default:)
|
118
|
+
pay_payment_method = pay_customer.payment_methods.where(processor_id: payment_method.id).first_or_initialize
|
119
|
+
|
120
|
+
attributes = Pay::Stripe::PaymentMethod.extract_attributes(payment_method).merge(default: default)
|
121
|
+
|
122
|
+
pay_customer.payment_methods.update_all(default: false) if default
|
123
|
+
pay_payment_method.update!(attributes)
|
124
|
+
|
125
|
+
# Reload the Rails association
|
126
|
+
pay_customer.reload_default_payment_method if default
|
127
|
+
|
128
|
+
pay_payment_method
|
129
|
+
end
|
130
|
+
|
124
131
|
def update_email!
|
125
|
-
::Stripe::Customer.update(processor_id, {email: email, name: customer_name},
|
132
|
+
::Stripe::Customer.update(processor_id, {email: email, name: customer_name}, stripe_options)
|
126
133
|
end
|
127
134
|
|
128
135
|
def processor_subscription(subscription_id, options = {})
|
129
|
-
::Stripe::Subscription.retrieve(options.merge(id: subscription_id),
|
136
|
+
::Stripe::Subscription.retrieve(options.merge(id: subscription_id), stripe_options)
|
130
137
|
end
|
131
138
|
|
132
139
|
def invoice!(options = {})
|
133
140
|
return unless processor_id?
|
134
|
-
::Stripe::Invoice.create(options.merge(customer: processor_id),
|
141
|
+
::Stripe::Invoice.create(options.merge(customer: processor_id), stripe_options).pay
|
135
142
|
end
|
136
143
|
|
137
144
|
def upcoming_invoice
|
138
|
-
::Stripe::Invoice.upcoming({customer: processor_id},
|
139
|
-
end
|
140
|
-
|
141
|
-
# Used by webhooks when the customer or source changes
|
142
|
-
def sync_card_from_stripe
|
143
|
-
if (payment_method_id = customer.invoice_settings.default_payment_method)
|
144
|
-
update_card_on_file ::Stripe::PaymentMethod.retrieve(payment_method_id, {stripe_account: stripe_account}).card
|
145
|
-
else
|
146
|
-
billable.update(card_type: nil, card_last4: nil)
|
147
|
-
end
|
145
|
+
::Stripe::Invoice.upcoming({customer: processor_id}, stripe_options)
|
148
146
|
end
|
149
147
|
|
150
148
|
def create_setup_intent
|
151
|
-
::Stripe::SetupIntent.create({customer: processor_id, usage: :off_session},
|
149
|
+
::Stripe::SetupIntent.create({customer: processor_id, usage: :off_session}, stripe_options)
|
152
150
|
end
|
153
151
|
|
154
152
|
def trial_end_date(stripe_sub)
|
@@ -156,41 +154,14 @@ module Pay
|
|
156
154
|
stripe_sub.trial_end.present? ? Time.at(stripe_sub.trial_end) : nil
|
157
155
|
end
|
158
156
|
|
159
|
-
#
|
160
|
-
def
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
card_exp_month: card.exp_month,
|
165
|
-
card_exp_year: card.exp_year
|
166
|
-
)
|
167
|
-
|
168
|
-
billable.card_token = nil
|
169
|
-
end
|
170
|
-
|
171
|
-
def save_pay_charge(object)
|
172
|
-
charge = billable.charges.find_or_initialize_by(processor: :stripe, processor_id: object.id)
|
173
|
-
|
174
|
-
attrs = {
|
175
|
-
amount: object.amount,
|
176
|
-
card_last4: object.payment_method_details.card.last4,
|
177
|
-
card_type: object.payment_method_details.card.brand,
|
178
|
-
card_exp_month: object.payment_method_details.card.exp_month,
|
179
|
-
card_exp_year: object.payment_method_details.card.exp_year,
|
180
|
-
created_at: Time.zone.at(object.created),
|
181
|
-
currency: object.currency,
|
182
|
-
stripe_account: stripe_account,
|
183
|
-
application_fee_amount: object.application_fee_amount
|
184
|
-
}
|
185
|
-
|
186
|
-
# Associate charge with subscription if we can
|
187
|
-
if object.invoice
|
188
|
-
invoice = (object.invoice.is_a?(::Stripe::Invoice) ? object.invoice : ::Stripe::Invoice.retrieve(object.invoice))
|
189
|
-
attrs[:subscription] = Pay::Subscription.find_by(processor: :stripe, processor_id: invoice.subscription)
|
157
|
+
# Syncs a customer's subscriptions from Stripe to the database
|
158
|
+
def sync_subscriptions
|
159
|
+
subscriptions = ::Stripe::Subscription.list({customer: customer}, stripe_options)
|
160
|
+
subscriptions.map do |subscription|
|
161
|
+
Pay::Stripe::Subscription.sync(subscription.id)
|
190
162
|
end
|
191
|
-
|
192
|
-
|
193
|
-
charge
|
163
|
+
rescue ::Stripe::StripeError => e
|
164
|
+
raise Pay::Stripe::Error, e
|
194
165
|
end
|
195
166
|
|
196
167
|
# https://stripe.com/docs/api/checkout/sessions/create
|
@@ -224,7 +195,7 @@ module Pay
|
|
224
195
|
}
|
225
196
|
end
|
226
197
|
|
227
|
-
::Stripe::Checkout::Session.create(args.merge(options),
|
198
|
+
::Stripe::Checkout::Session.create(args.merge(options), stripe_options)
|
228
199
|
end
|
229
200
|
|
230
201
|
# https://stripe.com/docs/api/checkout/sessions/create
|
@@ -251,7 +222,14 @@ module Pay
|
|
251
222
|
customer: processor_id,
|
252
223
|
return_url: options.delete(:return_url) || root_url
|
253
224
|
}
|
254
|
-
::Stripe::BillingPortal::Session.create(args.merge(options),
|
225
|
+
::Stripe::BillingPortal::Session.create(args.merge(options), stripe_options)
|
226
|
+
end
|
227
|
+
|
228
|
+
private
|
229
|
+
|
230
|
+
# Options for Stripe requests
|
231
|
+
def stripe_options
|
232
|
+
{stripe_account: stripe_account}.compact
|
255
233
|
end
|
256
234
|
end
|
257
235
|
end
|
data/lib/pay/stripe/charge.rb
CHANGED
@@ -3,14 +3,63 @@ module Pay
|
|
3
3
|
class Charge
|
4
4
|
attr_reader :pay_charge
|
5
5
|
|
6
|
-
delegate :processor_id, :
|
6
|
+
delegate :processor_id, :stripe_account, to: :pay_charge
|
7
|
+
|
8
|
+
def self.sync(charge_id, object: nil, stripe_account: nil, try: 0, retries: 1)
|
9
|
+
# Skip loading the latest charge details from the API if we already have it
|
10
|
+
object ||= ::Stripe::Charge.retrieve(charge_id, {stripe_account: stripe_account}.compact)
|
11
|
+
|
12
|
+
pay_customer = Pay::Customer.find_by(processor: :stripe, processor_id: object.customer)
|
13
|
+
return unless pay_customer
|
14
|
+
|
15
|
+
payment_method = object.payment_method_details.send(object.payment_method_details.type)
|
16
|
+
attrs = {
|
17
|
+
amount: object.amount,
|
18
|
+
amount_refunded: object.amount_refunded,
|
19
|
+
application_fee_amount: object.application_fee_amount,
|
20
|
+
created_at: Time.at(object.created),
|
21
|
+
currency: object.currency,
|
22
|
+
stripe_account: pay_customer.stripe_account,
|
23
|
+
metadata: object.metadata,
|
24
|
+
payment_method_type: object.payment_method_details.type,
|
25
|
+
brand: payment_method.try(:brand)&.capitalize,
|
26
|
+
last4: payment_method.try(:last4).to_s,
|
27
|
+
exp_month: payment_method.try(:exp_month).to_s,
|
28
|
+
exp_year: payment_method.try(:exp_year).to_s,
|
29
|
+
bank: payment_method.try(:bank_name) || payment_method.try(:bank) # eps, fpx, ideal, p24, acss_debit, etc
|
30
|
+
}
|
31
|
+
|
32
|
+
# Associate charge with subscription if we can
|
33
|
+
if object.invoice
|
34
|
+
invoice = (object.invoice.is_a?(::Stripe::Invoice) ? object.invoice : ::Stripe::Invoice.retrieve(object.invoice, {stripe_account: stripe_account}.compact))
|
35
|
+
attrs[:subscription] = pay_customer.subscriptions.find_by(processor_id: invoice.subscription)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Update or create the charge
|
39
|
+
if (pay_charge = pay_customer.charges.find_by(processor_id: object.id))
|
40
|
+
pay_charge.with_lock do
|
41
|
+
pay_charge.update!(attrs)
|
42
|
+
end
|
43
|
+
pay_charge
|
44
|
+
else
|
45
|
+
pay_customer.charges.create!(attrs.merge(processor_id: object.id))
|
46
|
+
end
|
47
|
+
rescue ActiveRecord::RecordInvalid
|
48
|
+
try += 1
|
49
|
+
if try <= retries
|
50
|
+
sleep 0.1
|
51
|
+
retry
|
52
|
+
else
|
53
|
+
raise
|
54
|
+
end
|
55
|
+
end
|
7
56
|
|
8
57
|
def initialize(pay_charge)
|
9
58
|
@pay_charge = pay_charge
|
10
59
|
end
|
11
60
|
|
12
61
|
def charge
|
13
|
-
::Stripe::Charge.retrieve({id: processor_id, expand: ["customer", "invoice.subscription"]},
|
62
|
+
::Stripe::Charge.retrieve({id: processor_id, expand: ["customer", "invoice.subscription"]}, stripe_options)
|
14
63
|
rescue ::Stripe::StripeError => e
|
15
64
|
raise Pay::Stripe::Error, e
|
16
65
|
end
|
@@ -21,11 +70,18 @@ module Pay
|
|
21
70
|
# refund!(5_00)
|
22
71
|
# refund!(5_00, refund_application_fee: true)
|
23
72
|
def refund!(amount_to_refund, **options)
|
24
|
-
::Stripe::Refund.create(options.merge(charge: processor_id, amount: amount_to_refund),
|
73
|
+
::Stripe::Refund.create(options.merge(charge: processor_id, amount: amount_to_refund), stripe_options)
|
25
74
|
pay_charge.update(amount_refunded: amount_to_refund)
|
26
75
|
rescue ::Stripe::StripeError => e
|
27
76
|
raise Pay::Stripe::Error, e
|
28
77
|
end
|
78
|
+
|
79
|
+
private
|
80
|
+
|
81
|
+
# Options for Stripe requests
|
82
|
+
def stripe_options
|
83
|
+
{stripe_account: stripe_account}.compact
|
84
|
+
end
|
29
85
|
end
|
30
86
|
end
|
31
87
|
end
|