solidus_stripe 5.0.0.alpha.1 → 5.0.0.rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.circleci/config.yml +15 -8
- data/README.md +94 -52
- data/app/models/solidus_stripe/gateway.rb +21 -23
- data/app/models/solidus_stripe/payment_intent.rb +27 -14
- data/app/subscribers/solidus_stripe/webhook/charge_subscriber.rb +3 -3
- data/app/subscribers/solidus_stripe/webhook/payment_intent_subscriber.rb +5 -5
- data/app/views/spree/admin/payments/source_forms/existing_payment/_stripe.html.erb +6 -1
- data/db/migrate/20230306105520_create_solidus_stripe_payment_intents.rb +6 -2
- data/db/migrate/20230308122414_create_solidus_stripe_slug_entries.rb +12 -0
- data/db/migrate/20230313150008_create_solidus_stripe_customers.rb +2 -3
- data/lib/generators/solidus_stripe/install/templates/app/javascript/controllers/solidus_stripe_payment_controller.js +3 -3
- data/lib/generators/solidus_stripe/install/templates/app/views/checkouts/existing_payment/_stripe.html.erb +6 -1
- data/lib/generators/solidus_stripe/install/templates/app/views/checkouts/payment/_stripe.html.erb +49 -14
- data/lib/generators/solidus_stripe/install/templates/app/views/orders/payment_info/_stripe.html.erb +15 -3
- data/lib/solidus_stripe/refunds_synchronizer.rb +26 -24
- data/lib/solidus_stripe/testing_support/factories.rb +18 -18
- data/lib/solidus_stripe/version.rb +1 -1
- data/lib/solidus_stripe/webhook/event.rb +6 -5
- data/solidus_stripe.gemspec +1 -1
- data/spec/lib/solidus_stripe/refunds_synchronizer_spec.rb +47 -47
- data/spec/lib/solidus_stripe/webhook/event_spec.rb +10 -10
- data/spec/models/solidus_stripe/customer_spec.rb +3 -3
- data/spec/models/solidus_stripe/gateway_spec.rb +52 -54
- data/spec/models/solidus_stripe/payment_intent_spec.rb +62 -1
- data/spec/models/solidus_stripe/payment_method_spec.rb +16 -16
- data/spec/models/solidus_stripe/payment_source_spec.rb +3 -3
- data/spec/requests/solidus_stripe/intents_controller_spec.rb +2 -2
- data/spec/requests/solidus_stripe/webhooks_controller/charge/refunded_spec.rb +1 -1
- data/spec/requests/solidus_stripe/webhooks_controller/payment_intent/canceled_spec.rb +1 -1
- data/spec/requests/solidus_stripe/webhooks_controller/payment_intent/payment_failed_spec.rb +1 -1
- data/spec/requests/solidus_stripe/webhooks_controller/payment_intent/succeeded_spec.rb +1 -1
- data/spec/requests/solidus_stripe/webhooks_controller_spec.rb +8 -4
- data/spec/subscribers/solidus_stripe/webhook/charge_subscriber_spec.rb +1 -1
- data/spec/subscribers/solidus_stripe/webhook/payment_intent_subscriber_spec.rb +12 -12
- data/spec/support/solidus_stripe/backend_test_helper.rb +17 -42
- data/spec/support/solidus_stripe/checkout_test_helper.rb +27 -1
- data/spec/support/solidus_stripe/webhook/event_with_context_factory.rb +1 -1
- data/spec/system/backend/solidus_stripe/orders/payments_spec.rb +47 -21
- data/spec/system/frontend/solidus_stripe/checkout_spec.rb +19 -0
- metadata +6 -11
- data/db/migrate/20230303154931_create_solidus_stripe_setup_intent.rb +0 -10
- data/db/migrate/20230308122414_create_solidus_stripe_webhook_endpoints.rb +0 -10
- data/db/migrate/20230310152615_add_payment_method_reference_to_stripe_intents.rb +0 -6
- data/db/migrate/20230310171444_normalize_stripe_intent_id_attributes.rb +0 -6
- data/db/migrate/20230323154931_drop_solidus_stripe_setup_intent.rb +0 -13
- data/db/migrate/20230403094916_rename_webhook_endpoint_to_payment_method_slug_entries.rb +0 -5
@@ -8,7 +8,7 @@ RSpec.describe SolidusStripe::Customer, type: :model do
|
|
8
8
|
it 'returns the customer_id' do
|
9
9
|
user = create(:user)
|
10
10
|
order = create(:order, user: user)
|
11
|
-
customer = create(:
|
11
|
+
customer = create(:solidus_stripe_customer, stripe_id: 'cus_123', source: user)
|
12
12
|
|
13
13
|
expect(customer.source).to be_a(Spree::User)
|
14
14
|
expect(
|
@@ -21,7 +21,7 @@ RSpec.describe SolidusStripe::Customer, type: :model do
|
|
21
21
|
it 'creates the customer from a user' do
|
22
22
|
user = create(:user, email: 'registered@example.com')
|
23
23
|
order = create(:order, user: user)
|
24
|
-
payment_method = create(:
|
24
|
+
payment_method = create(:solidus_stripe_payment_method)
|
25
25
|
|
26
26
|
stripe_customer = Stripe::Customer.construct_from(id: 'cus_123')
|
27
27
|
allow(Stripe::Customer).to receive(:create).with(email: 'registered@example.com').and_return(stripe_customer)
|
@@ -32,7 +32,7 @@ RSpec.describe SolidusStripe::Customer, type: :model do
|
|
32
32
|
end
|
33
33
|
|
34
34
|
it 'creates the customer from a guest order' do
|
35
|
-
payment_method = create(:
|
35
|
+
payment_method = create(:solidus_stripe_payment_method)
|
36
36
|
order = create(:order, user: nil, email: 'guest@example.com')
|
37
37
|
|
38
38
|
stripe_customer = Stripe::Customer.construct_from(id: 'cus_123')
|
@@ -5,36 +5,34 @@ require 'solidus_stripe_spec_helper'
|
|
5
5
|
RSpec.describe SolidusStripe::Gateway do
|
6
6
|
describe '#authorize' do
|
7
7
|
it 'confirms the Stripe payment' do
|
8
|
-
stripe_payment_method = Stripe::PaymentMethod.construct_from(id: "pm_123")
|
8
|
+
stripe_payment_method = Stripe::PaymentMethod.construct_from(id: "pm_123", type: 'card')
|
9
9
|
stripe_customer = Stripe::Customer.construct_from(id: 'cus_123')
|
10
10
|
stripe_payment_intent = Stripe::PaymentIntent.construct_from(id: "pi_123")
|
11
11
|
|
12
|
-
payment_method = build(:
|
12
|
+
payment_method = build(:solidus_stripe_payment_method)
|
13
13
|
gateway = payment_method.gateway
|
14
|
-
order = create(:
|
14
|
+
order = create(:solidus_stripe_order,
|
15
15
|
amount: 123.45,
|
16
16
|
payment_method: payment_method,
|
17
17
|
stripe_payment_method_id: stripe_payment_method.id)
|
18
18
|
payment = order.payments.last
|
19
19
|
|
20
20
|
allow(Stripe::Customer).to receive(:create).and_return(stripe_customer)
|
21
|
-
[:create, :
|
21
|
+
[:create, :retrieve].each do |method|
|
22
22
|
allow(Stripe::PaymentIntent).to receive(method).and_return(stripe_payment_intent)
|
23
23
|
end
|
24
|
+
allow(payment.source).to receive(:stripe_payment_method).and_return(stripe_payment_method)
|
24
25
|
allow(Stripe::PaymentIntent).to receive(:confirm).with(stripe_payment_intent.id).and_return(stripe_payment_intent)
|
25
26
|
|
26
27
|
result = gateway.authorize(123_45, payment.source, currency: 'USD', originator: order.payments.first)
|
27
28
|
|
28
|
-
expect(Stripe::PaymentIntent).to have_received(:update).with(
|
29
|
-
stripe_payment_intent.id,
|
30
|
-
{ payment_method: stripe_payment_method.id }
|
31
|
-
)
|
32
|
-
|
33
29
|
expect(Stripe::PaymentIntent).to have_received(:create).with(
|
34
30
|
amount: 123_45,
|
35
31
|
currency: 'USD',
|
36
32
|
capture_method: 'manual',
|
37
33
|
confirm: false,
|
34
|
+
payment_method: stripe_payment_method.id,
|
35
|
+
payment_method_types: [stripe_payment_method.type],
|
38
36
|
metadata: { solidus_order_number: order.number },
|
39
37
|
customer: "cus_123",
|
40
38
|
setup_future_usage: nil
|
@@ -45,20 +43,21 @@ RSpec.describe SolidusStripe::Gateway do
|
|
45
43
|
end
|
46
44
|
|
47
45
|
it 'generates error response on failure' do
|
48
|
-
stripe_payment_method = Stripe::PaymentMethod.construct_from(id: "pm_123")
|
46
|
+
stripe_payment_method = Stripe::PaymentMethod.construct_from(id: "pm_123", type: 'card')
|
49
47
|
stripe_payment_intent = Stripe::PaymentIntent.construct_from(id: "pi_123")
|
50
48
|
|
51
|
-
payment_method = build(:
|
49
|
+
payment_method = build(:solidus_stripe_payment_method)
|
52
50
|
gateway = payment_method.gateway
|
53
|
-
order = create(:
|
51
|
+
order = create(:solidus_stripe_order,
|
54
52
|
amount: 123.45,
|
55
53
|
payment_method: payment_method,
|
56
54
|
stripe_payment_method_id: stripe_payment_method.id)
|
57
55
|
payment = order.payments.last
|
58
56
|
|
59
|
-
[:create, :
|
57
|
+
[:create, :retrieve].each do |method|
|
60
58
|
allow(Stripe::PaymentIntent).to receive(method).and_return(stripe_payment_intent)
|
61
59
|
end
|
60
|
+
allow(payment.source).to receive(:stripe_payment_method).and_return(stripe_payment_method)
|
62
61
|
allow(Stripe::PaymentIntent).to receive(:confirm).with(
|
63
62
|
stripe_payment_intent.id
|
64
63
|
).and_raise(Stripe::StripeError.new("auth error"))
|
@@ -71,9 +70,9 @@ RSpec.describe SolidusStripe::Gateway do
|
|
71
70
|
end
|
72
71
|
|
73
72
|
it "raises if the given amount doesn't match the order total" do
|
74
|
-
payment_method = build(:
|
73
|
+
payment_method = build(:solidus_stripe_payment_method)
|
75
74
|
gateway = payment_method.gateway
|
76
|
-
order = create(:
|
75
|
+
order = create(:solidus_stripe_order, amount: 123.45, payment_method: payment_method)
|
77
76
|
|
78
77
|
expect { gateway.authorize(10, :source, originator: order.payments.first ) }.to raise_error(
|
79
78
|
/custom amount is not supported/
|
@@ -85,21 +84,21 @@ RSpec.describe SolidusStripe::Gateway do
|
|
85
84
|
it 'captures a pre-authorized Stripe payment' do
|
86
85
|
stripe_payment_intent = Stripe::PaymentIntent.construct_from(id: "pi_123")
|
87
86
|
|
88
|
-
gateway = build(:
|
87
|
+
gateway = build(:solidus_stripe_payment_method).gateway
|
89
88
|
payment = build(:payment, response_code: "pi_123", amount: 123.45)
|
90
89
|
|
91
90
|
allow(Stripe::PaymentIntent).to receive(:capture).and_return(stripe_payment_intent)
|
92
91
|
|
93
92
|
result = gateway.capture(123_45, "pi_123", originator: payment)
|
94
93
|
|
95
|
-
expect(Stripe::PaymentIntent).to have_received(:capture).with('pi_123')
|
94
|
+
expect(Stripe::PaymentIntent).to have_received(:capture).with('pi_123', { amount: 12_345 })
|
96
95
|
expect(result.params).to eq("data" => '{"id":"pi_123"}')
|
97
96
|
end
|
98
97
|
|
99
98
|
it "raises if the given amount doesn't match the order total" do
|
100
|
-
payment_method = build(:
|
99
|
+
payment_method = build(:solidus_stripe_payment_method)
|
101
100
|
gateway = payment_method.gateway
|
102
|
-
order = create(:
|
101
|
+
order = create(:solidus_stripe_order, amount: 123.45, payment_method: payment_method)
|
103
102
|
|
104
103
|
expect { gateway.capture(10, :payment_intent_id, originator: order.payments.first ) }.to raise_error(
|
105
104
|
/custom amount is not supported/
|
@@ -107,20 +106,20 @@ RSpec.describe SolidusStripe::Gateway do
|
|
107
106
|
end
|
108
107
|
|
109
108
|
it "raises if no payment_intent_id is given" do
|
110
|
-
payment_method = build(:
|
109
|
+
payment_method = build(:solidus_stripe_payment_method)
|
111
110
|
gateway = payment_method.gateway
|
112
|
-
order = create(:
|
111
|
+
order = create(:solidus_stripe_order, amount: 123.45, payment_method: payment_method)
|
113
112
|
|
114
113
|
expect { gateway.capture(123_45, nil, originator: order.payments.first ) }.to raise_error(
|
115
114
|
ArgumentError,
|
116
|
-
/missing
|
115
|
+
/missing stripe_payment_intent_id/
|
117
116
|
)
|
118
117
|
end
|
119
118
|
|
120
|
-
it "raises if
|
121
|
-
payment_method = build(:
|
119
|
+
it "raises if stripe_payment_intent_id is not valid" do
|
120
|
+
payment_method = build(:solidus_stripe_payment_method)
|
122
121
|
gateway = payment_method.gateway
|
123
|
-
order = create(:
|
122
|
+
order = create(:solidus_stripe_order, amount: 123.45, payment_method: payment_method)
|
124
123
|
|
125
124
|
expect { gateway.capture(123_45, "invalid", originator: order.payments.first ) }.to raise_error(
|
126
125
|
ArgumentError,
|
@@ -131,7 +130,7 @@ RSpec.describe SolidusStripe::Gateway do
|
|
131
130
|
|
132
131
|
describe '#void' do
|
133
132
|
it 'voids a payment that hasn not been captured yet' do
|
134
|
-
gateway = build(:
|
133
|
+
gateway = build(:solidus_stripe_payment_method).gateway
|
135
134
|
stripe_payment_intent = Stripe::PaymentIntent.construct_from(id: "pi_123")
|
136
135
|
allow(Stripe::PaymentIntent).to receive(:cancel).and_return(stripe_payment_intent)
|
137
136
|
|
@@ -141,18 +140,18 @@ RSpec.describe SolidusStripe::Gateway do
|
|
141
140
|
expect(result.params).to eq("data" => '{"id":"pi_123"}')
|
142
141
|
end
|
143
142
|
|
144
|
-
it "raises if no
|
145
|
-
payment_method = build(:
|
143
|
+
it "raises if no stripe_payment_intent_id is given" do
|
144
|
+
payment_method = build(:solidus_stripe_payment_method)
|
146
145
|
gateway = payment_method.gateway
|
147
146
|
|
148
147
|
expect { gateway.void(nil) }.to raise_error(
|
149
148
|
ArgumentError,
|
150
|
-
/missing
|
149
|
+
/missing stripe_payment_intent_id/
|
151
150
|
)
|
152
151
|
end
|
153
152
|
|
154
|
-
it "raises if
|
155
|
-
payment_method = build(:
|
153
|
+
it "raises if stripe_payment_intent_id is not valid" do
|
154
|
+
payment_method = build(:solidus_stripe_payment_method)
|
156
155
|
gateway = payment_method.gateway
|
157
156
|
|
158
157
|
expect { gateway.void("invalid") }.to raise_error(
|
@@ -164,36 +163,34 @@ RSpec.describe SolidusStripe::Gateway do
|
|
164
163
|
|
165
164
|
describe '#purchase' do
|
166
165
|
it 'authorizes and captures in a single operation' do
|
167
|
-
stripe_payment_method = Stripe::PaymentMethod.construct_from(id: "pm_123")
|
166
|
+
stripe_payment_method = Stripe::PaymentMethod.construct_from(id: "pm_123", type: 'card')
|
168
167
|
stripe_customer = Stripe::Customer.construct_from(id: 'cus_123')
|
169
168
|
stripe_payment_intent = Stripe::PaymentIntent.construct_from(id: "pi_123")
|
170
169
|
|
171
|
-
payment_method = build(:
|
170
|
+
payment_method = build(:solidus_stripe_payment_method)
|
172
171
|
gateway = payment_method.gateway
|
173
|
-
order = create(:
|
172
|
+
order = create(:solidus_stripe_order,
|
174
173
|
amount: 123.45,
|
175
174
|
payment_method: payment_method,
|
176
175
|
stripe_payment_method_id: stripe_payment_method.id)
|
177
176
|
payment = order.payments.last
|
178
177
|
|
179
178
|
allow(Stripe::Customer).to receive(:create).and_return(stripe_customer)
|
180
|
-
[:create, :
|
179
|
+
[:create, :retrieve].each do |method|
|
181
180
|
allow(Stripe::PaymentIntent).to receive(method).and_return(stripe_payment_intent)
|
182
181
|
end
|
182
|
+
allow(payment.source).to receive(:stripe_payment_method).and_return(stripe_payment_method)
|
183
183
|
allow(Stripe::PaymentIntent).to receive(:confirm).with(stripe_payment_intent.id).and_return(stripe_payment_intent)
|
184
184
|
|
185
185
|
result = gateway.purchase(123_45, payment.source, currency: 'USD', originator: order.payments.first)
|
186
186
|
|
187
|
-
expect(Stripe::PaymentIntent).to have_received(:update).with(
|
188
|
-
stripe_payment_intent.id,
|
189
|
-
{ payment_method: stripe_payment_method.id }
|
190
|
-
)
|
191
|
-
|
192
187
|
expect(Stripe::PaymentIntent).to have_received(:create).with(
|
193
188
|
amount: 123_45,
|
194
189
|
currency: 'USD',
|
195
190
|
capture_method: 'automatic',
|
196
191
|
confirm: false,
|
192
|
+
payment_method: stripe_payment_method.id,
|
193
|
+
payment_method_types: [stripe_payment_method.type],
|
197
194
|
metadata: { solidus_order_number: order.number },
|
198
195
|
customer: "cus_123",
|
199
196
|
setup_future_usage: nil
|
@@ -204,20 +201,21 @@ RSpec.describe SolidusStripe::Gateway do
|
|
204
201
|
end
|
205
202
|
|
206
203
|
it 'generates error response on failure' do
|
207
|
-
stripe_payment_method = Stripe::PaymentMethod.construct_from(id: "pm_123")
|
204
|
+
stripe_payment_method = Stripe::PaymentMethod.construct_from(id: "pm_123", type: 'card')
|
208
205
|
stripe_payment_intent = Stripe::PaymentIntent.construct_from(id: "pi_123")
|
209
206
|
|
210
|
-
payment_method = build(:
|
207
|
+
payment_method = build(:solidus_stripe_payment_method)
|
211
208
|
gateway = payment_method.gateway
|
212
|
-
order = create(:
|
209
|
+
order = create(:solidus_stripe_order,
|
213
210
|
amount: 123.45,
|
214
211
|
payment_method: payment_method,
|
215
212
|
stripe_payment_method_id: stripe_payment_method.id)
|
216
213
|
payment = order.payments.last
|
217
214
|
|
218
|
-
[:create, :
|
215
|
+
[:create, :retrieve].each do |method|
|
219
216
|
allow(Stripe::PaymentIntent).to receive(method).and_return(stripe_payment_intent)
|
220
217
|
end
|
218
|
+
allow(payment.source).to receive(:stripe_payment_method).and_return(stripe_payment_method)
|
221
219
|
allow(Stripe::PaymentIntent).to receive(:confirm).with(
|
222
220
|
stripe_payment_intent.id
|
223
221
|
).and_raise(Stripe::StripeError.new("auth error"))
|
@@ -230,9 +228,9 @@ RSpec.describe SolidusStripe::Gateway do
|
|
230
228
|
end
|
231
229
|
|
232
230
|
it "raises if the given amount doesn't match the order total" do
|
233
|
-
payment_method = build(:
|
231
|
+
payment_method = build(:solidus_stripe_payment_method)
|
234
232
|
gateway = payment_method.gateway
|
235
|
-
order = create(:
|
233
|
+
order = create(:solidus_stripe_order, amount: 123.45, payment_method: payment_method)
|
236
234
|
|
237
235
|
expect { gateway.purchase(10, :source, originator: order.payments.first ) }.to raise_error(
|
238
236
|
/custom amount is not supported/
|
@@ -242,10 +240,10 @@ RSpec.describe SolidusStripe::Gateway do
|
|
242
240
|
|
243
241
|
describe '#credit' do
|
244
242
|
it 'refunds when provided an originator payment' do
|
245
|
-
gateway = build(:
|
243
|
+
gateway = build(:solidus_stripe_payment_method).gateway
|
246
244
|
payment = instance_double(Spree::Payment, response_code: 'pi_123', currency: "USD")
|
247
|
-
|
248
|
-
allow(Stripe::Refund).to receive(:create).and_return(
|
245
|
+
stripe_refund = Stripe::Refund.construct_from(id: "re_123")
|
246
|
+
allow(Stripe::Refund).to receive(:create).and_return(stripe_refund)
|
249
247
|
|
250
248
|
result = gateway.credit(123_45, 'pi_123', currency: 'USD', originator: instance_double(
|
251
249
|
Spree::Refund,
|
@@ -260,18 +258,18 @@ RSpec.describe SolidusStripe::Gateway do
|
|
260
258
|
expect(result.params).to eq("data" => '{"id":"re_123"}')
|
261
259
|
end
|
262
260
|
|
263
|
-
it "raises if no
|
264
|
-
payment_method = build(:
|
261
|
+
it "raises if no stripe_payment_intent_id is given" do
|
262
|
+
payment_method = build(:solidus_stripe_payment_method)
|
265
263
|
gateway = payment_method.gateway
|
266
264
|
|
267
265
|
expect { gateway.credit(:amount, nil) }.to raise_error(
|
268
266
|
ArgumentError,
|
269
|
-
/missing
|
267
|
+
/missing stripe_payment_intent_id/
|
270
268
|
)
|
271
269
|
end
|
272
270
|
|
273
|
-
it "raises if
|
274
|
-
payment_method = build(:
|
271
|
+
it "raises if stripe_payment_intent_id is not valid" do
|
272
|
+
payment_method = build(:solidus_stripe_payment_method)
|
275
273
|
gateway = payment_method.gateway
|
276
274
|
|
277
275
|
expect { gateway.credit(:amount, "invalid") }.to raise_error(
|
@@ -5,7 +5,7 @@ require 'solidus_stripe_spec_helper'
|
|
5
5
|
RSpec.describe SolidusStripe::PaymentIntent do
|
6
6
|
describe "#reload" do
|
7
7
|
it "reloads the stripe intent" do
|
8
|
-
intent = create(:
|
8
|
+
intent = create(:solidus_stripe_payment_intent)
|
9
9
|
allow(Stripe::PaymentIntent).to receive(:retrieve) do
|
10
10
|
Stripe::PaymentIntent.construct_from(id: intent.stripe_intent_id)
|
11
11
|
end
|
@@ -14,4 +14,65 @@ RSpec.describe SolidusStripe::PaymentIntent do
|
|
14
14
|
expect(intent.stripe_intent.object_id).not_to eq(intent.reload.stripe_intent.object_id)
|
15
15
|
end
|
16
16
|
end
|
17
|
+
|
18
|
+
describe '.usable?' do
|
19
|
+
context 'when the Stripe intent is usable' do
|
20
|
+
it 'returns true' do
|
21
|
+
payment_intent = create(:solidus_stripe_payment_intent, order: create(:order_with_line_items))
|
22
|
+
status = 'requires_payment_method'
|
23
|
+
stripe_intent = Stripe::PaymentIntent.construct_from(
|
24
|
+
id: payment_intent.stripe_intent_id,
|
25
|
+
amount: payment_intent.stripe_order_amount,
|
26
|
+
status: status
|
27
|
+
)
|
28
|
+
|
29
|
+
allow(payment_intent).to receive(:stripe_intent).and_return(stripe_intent)
|
30
|
+
|
31
|
+
expect(payment_intent).to be_usable
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context 'when the Stripe intent ID is nil' do
|
36
|
+
it 'returns false' do
|
37
|
+
payment_intent = create(:solidus_stripe_payment_intent,
|
38
|
+
order: create(:order_with_line_items),
|
39
|
+
stripe_intent_id: nil)
|
40
|
+
|
41
|
+
expect(payment_intent).not_to be_usable
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'when the Stripe intent status is not "requires_payment_method"' do
|
46
|
+
it 'returns false' do
|
47
|
+
payment_intent = create(:solidus_stripe_payment_intent, order: create(:order_with_line_items))
|
48
|
+
status = 'requires_action'
|
49
|
+
stripe_intent = Stripe::PaymentIntent.construct_from(
|
50
|
+
id: payment_intent.stripe_intent_id,
|
51
|
+
amount: payment_intent.stripe_order_amount,
|
52
|
+
status: status
|
53
|
+
)
|
54
|
+
|
55
|
+
allow(payment_intent).to receive(:stripe_intent).and_return(stripe_intent)
|
56
|
+
|
57
|
+
expect(payment_intent).not_to be_usable
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'when the Stripe intent amount is different from the order amount' do
|
62
|
+
it 'returns false' do
|
63
|
+
payment_intent = create(:solidus_stripe_payment_intent, order: create(:order_with_line_items))
|
64
|
+
status = 'requires_payment_method'
|
65
|
+
amount = payment_intent.stripe_order_amount + 1
|
66
|
+
stripe_intent = Stripe::PaymentIntent.construct_from(
|
67
|
+
id: payment_intent.stripe_intent_id,
|
68
|
+
amount: amount,
|
69
|
+
status: status
|
70
|
+
)
|
71
|
+
|
72
|
+
allow(payment_intent).to receive(:stripe_intent).and_return(stripe_intent)
|
73
|
+
|
74
|
+
expect(payment_intent).not_to be_usable
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
17
78
|
end
|
@@ -4,13 +4,13 @@ require 'solidus_stripe_spec_helper'
|
|
4
4
|
|
5
5
|
RSpec.describe SolidusStripe::PaymentMethod do
|
6
6
|
it 'has a working factory' do
|
7
|
-
expect(create(:
|
7
|
+
expect(create(:solidus_stripe_payment_method)).to be_valid
|
8
8
|
end
|
9
9
|
|
10
10
|
describe 'Callbacks' do
|
11
11
|
describe 'after_create' do
|
12
12
|
it 'creates a webhook endpoint' do
|
13
|
-
payment_method = create(:
|
13
|
+
payment_method = create(:solidus_stripe_payment_method)
|
14
14
|
|
15
15
|
expect(payment_method.slug_entry).to be_present
|
16
16
|
end
|
@@ -28,7 +28,7 @@ RSpec.describe SolidusStripe::PaymentMethod do
|
|
28
28
|
|
29
29
|
context 'when the order has a payment intent' do
|
30
30
|
it 'fetches the payment intent id' do
|
31
|
-
intent = create(:
|
31
|
+
intent = create(:solidus_stripe_payment_intent, stripe_intent_id: 'pi_123')
|
32
32
|
payment = build(:payment, response_code: nil, payment_method: intent.payment_method, order: intent.order)
|
33
33
|
|
34
34
|
expect(described_class.intent_id_for_payment(payment)).to eq("pi_123")
|
@@ -43,20 +43,20 @@ RSpec.describe SolidusStripe::PaymentMethod do
|
|
43
43
|
describe '#stripe_dashboard_url' do
|
44
44
|
context 'with a payment intent id' do
|
45
45
|
it 'generates a dashboard link' do
|
46
|
-
payment_method = build(:
|
46
|
+
payment_method = build(:solidus_stripe_payment_method, preferred_test_mode: false)
|
47
47
|
|
48
48
|
expect(payment_method.stripe_dashboard_url('pi_123')).to eq("https://dashboard.stripe.com/payments/pi_123")
|
49
49
|
end
|
50
50
|
|
51
51
|
it 'supports test mode' do
|
52
|
-
payment_method = build(:
|
52
|
+
payment_method = build(:solidus_stripe_payment_method, preferred_test_mode: true)
|
53
53
|
|
54
54
|
expect(payment_method.stripe_dashboard_url('pi_123')).to eq("https://dashboard.stripe.com/test/payments/pi_123")
|
55
55
|
end
|
56
56
|
end
|
57
57
|
|
58
58
|
it 'returns nil with anything else' do
|
59
|
-
payment_method = build(:
|
59
|
+
payment_method = build(:solidus_stripe_payment_method)
|
60
60
|
|
61
61
|
expect(payment_method.stripe_dashboard_url(Object.new)).to eq(nil)
|
62
62
|
expect(payment_method.stripe_dashboard_url('')).to eq(nil)
|
@@ -66,7 +66,7 @@ RSpec.describe SolidusStripe::PaymentMethod do
|
|
66
66
|
|
67
67
|
describe '.with_slug' do
|
68
68
|
it 'selects by slug' do
|
69
|
-
payment_method = create(:
|
69
|
+
payment_method = create(:solidus_stripe_payment_method)
|
70
70
|
|
71
71
|
expect(described_class.with_slug(payment_method.slug)).to eq([payment_method])
|
72
72
|
expect(described_class.with_slug('bad-slug')).to eq([])
|
@@ -75,14 +75,14 @@ RSpec.describe SolidusStripe::PaymentMethod do
|
|
75
75
|
|
76
76
|
describe '.previous_sources' do
|
77
77
|
it 'finds no sources associated with the order' do
|
78
|
-
payment_method = create(:
|
78
|
+
payment_method = create(:solidus_stripe_payment_method)
|
79
79
|
order = create(:order, user: nil)
|
80
80
|
|
81
81
|
expect(payment_method.previous_sources(order)).to be_empty
|
82
82
|
end
|
83
83
|
|
84
84
|
it 'finds no sources associated with the user' do
|
85
|
-
payment_method = create(:
|
85
|
+
payment_method = create(:solidus_stripe_payment_method)
|
86
86
|
user = create(:user)
|
87
87
|
order = create(:order, user: user)
|
88
88
|
|
@@ -90,7 +90,7 @@ RSpec.describe SolidusStripe::PaymentMethod do
|
|
90
90
|
end
|
91
91
|
|
92
92
|
it 'finds sources associated with the user' do
|
93
|
-
payment_source = create(:
|
93
|
+
payment_source = create(:solidus_stripe_payment_source)
|
94
94
|
payment_method = payment_source.payment_method
|
95
95
|
user = create(:user)
|
96
96
|
order = create(:order, user: user.reload)
|
@@ -103,7 +103,7 @@ RSpec.describe SolidusStripe::PaymentMethod do
|
|
103
103
|
|
104
104
|
describe '.assign_slug' do
|
105
105
|
it 'generates a "test" slug for the first payment method in test mode' do
|
106
|
-
payment_method = build(:
|
106
|
+
payment_method = build(:solidus_stripe_payment_method)
|
107
107
|
|
108
108
|
payment_method.save!
|
109
109
|
|
@@ -111,7 +111,7 @@ RSpec.describe SolidusStripe::PaymentMethod do
|
|
111
111
|
end
|
112
112
|
|
113
113
|
it 'generates a "live" slug for the first payment method in live mode' do
|
114
|
-
payment_method = build(:
|
114
|
+
payment_method = build(:solidus_stripe_payment_method, preferred_test_mode: false)
|
115
115
|
|
116
116
|
payment_method.save!
|
117
117
|
|
@@ -119,8 +119,8 @@ RSpec.describe SolidusStripe::PaymentMethod do
|
|
119
119
|
end
|
120
120
|
|
121
121
|
it 'generates a random hex string' do
|
122
|
-
_existing_payment_method = create(:
|
123
|
-
payment_method = create(:
|
122
|
+
_existing_payment_method = create(:solidus_stripe_payment_method)
|
123
|
+
payment_method = create(:solidus_stripe_payment_method)
|
124
124
|
|
125
125
|
expect(payment_method.slug).to match(/^[0-9a-f]{32}$/)
|
126
126
|
end
|
@@ -128,10 +128,10 @@ RSpec.describe SolidusStripe::PaymentMethod do
|
|
128
128
|
it 'generates a unique slug' do
|
129
129
|
slug = SecureRandom.hex(16)
|
130
130
|
|
131
|
-
create(:
|
131
|
+
create(:solidus_stripe_slug_entry, slug: slug)
|
132
132
|
allow(SecureRandom).to receive(:hex).and_return(slug).and_call_original
|
133
133
|
|
134
|
-
expect(create(:
|
134
|
+
expect(create(:solidus_stripe_payment_method).slug).not_to eq(slug)
|
135
135
|
end
|
136
136
|
end
|
137
137
|
end
|
@@ -4,20 +4,20 @@ require 'solidus_stripe_spec_helper'
|
|
4
4
|
|
5
5
|
RSpec.describe SolidusStripe::PaymentSource, type: :model do
|
6
6
|
it 'has a working factory' do
|
7
|
-
expect(create(:
|
7
|
+
expect(create(:solidus_stripe_payment_source)).to be_valid
|
8
8
|
end
|
9
9
|
|
10
10
|
describe '#stripe_payment_method' do
|
11
11
|
it 'retrieves the Stripe::PaymentMethod object if the stripe_payment_method id is present' do
|
12
12
|
stripe_payment_method = Stripe::PaymentMethod.construct_from(id: 'pm_123')
|
13
|
-
source = create(:
|
13
|
+
source = create(:solidus_stripe_payment_source, stripe_payment_method_id: 'pm_123')
|
14
14
|
allow(Stripe::PaymentMethod).to receive(:retrieve).with('pm_123').and_return(stripe_payment_method)
|
15
15
|
|
16
16
|
expect(source.stripe_payment_method).to eq(stripe_payment_method)
|
17
17
|
end
|
18
18
|
|
19
19
|
it 'returns nil if the stripe_payment_method id is missing' do
|
20
|
-
source = create(:
|
20
|
+
source = create(:solidus_stripe_payment_source, stripe_payment_method_id: nil)
|
21
21
|
|
22
22
|
expect(source.stripe_payment_method).to be_nil
|
23
23
|
end
|
@@ -4,7 +4,7 @@ RSpec.describe SolidusStripe::IntentsController, type: :request do
|
|
4
4
|
describe "GET /after_confirmation" do
|
5
5
|
context 'when not provided a payment intent' do
|
6
6
|
it 'responds with unprocessable entity' do
|
7
|
-
payment_method = create(:
|
7
|
+
payment_method = create(:solidus_stripe_payment_method)
|
8
8
|
order = create(:order_ready_to_complete)
|
9
9
|
sign_in order.user
|
10
10
|
|
@@ -16,7 +16,7 @@ RSpec.describe SolidusStripe::IntentsController, type: :request do
|
|
16
16
|
|
17
17
|
context 'when the order is not at "confirm"' do
|
18
18
|
it 'redirects to the current order step' do
|
19
|
-
payment_method = create(:
|
19
|
+
payment_method = create(:solidus_stripe_payment_method)
|
20
20
|
order = create(:order)
|
21
21
|
sign_in order.user
|
22
22
|
|
@@ -4,7 +4,7 @@ RSpec.describe SolidusStripe::WebhooksController, type: %i[request webhook_reque
|
|
4
4
|
describe "POST /create charge.refunded" do
|
5
5
|
it "synchronizes refunds" do
|
6
6
|
SolidusStripe::Seeds.refund_reasons
|
7
|
-
payment_method = create(:
|
7
|
+
payment_method = create(:solidus_stripe_payment_method)
|
8
8
|
stripe_payment_intent = Stripe::PaymentIntent.construct_from(id: "pi_123")
|
9
9
|
payment = create(:payment,
|
10
10
|
amount: 10,
|
@@ -3,7 +3,7 @@ require "solidus_stripe_spec_helper"
|
|
3
3
|
RSpec.describe SolidusStripe::WebhooksController, type: %i[request webhook_request] do
|
4
4
|
describe "POST /create payment_intent.canceled" do
|
5
5
|
it "transitions the associated payment to failed" do
|
6
|
-
payment_method = create(:
|
6
|
+
payment_method = create(:solidus_stripe_payment_method)
|
7
7
|
stripe_payment_intent = Stripe::PaymentIntent.construct_from(id: "pi_123", cancellation_reason: "duplicate")
|
8
8
|
payment = create(:payment,
|
9
9
|
payment_method: payment_method,
|
@@ -3,7 +3,7 @@ require "solidus_stripe_spec_helper"
|
|
3
3
|
RSpec.describe SolidusStripe::WebhooksController, type: %i[request webhook_request] do
|
4
4
|
describe "POST /create payment_intent.payment_failed" do
|
5
5
|
it "transitions the associated payment to failed" do
|
6
|
-
payment_method = create(:
|
6
|
+
payment_method = create(:solidus_stripe_payment_method)
|
7
7
|
stripe_payment_intent = Stripe::PaymentIntent.construct_from(id: "pi_123")
|
8
8
|
payment = create(:payment,
|
9
9
|
payment_method: payment_method,
|
@@ -3,7 +3,7 @@ require "solidus_stripe_spec_helper"
|
|
3
3
|
RSpec.describe SolidusStripe::WebhooksController, type: %i[request webhook_request] do
|
4
4
|
describe "POST /create payment_intent.succeeded" do
|
5
5
|
it "captures the associated payment" do
|
6
|
-
payment_method = create(:
|
6
|
+
payment_method = create(:solidus_stripe_payment_method)
|
7
7
|
stripe_payment_intent = Stripe::PaymentIntent.construct_from(
|
8
8
|
id: "pi_123",
|
9
9
|
amount: 1000,
|
@@ -2,13 +2,17 @@ require "solidus_stripe_spec_helper"
|
|
2
2
|
|
3
3
|
RSpec.describe SolidusStripe::WebhooksController, type: [:request, :webhook_request] do
|
4
4
|
describe "POST /create" do
|
5
|
-
let(:
|
6
|
-
let(:
|
5
|
+
let(:payment_method) { create(:solidus_stripe_payment_method) }
|
6
|
+
let(:stripe_payment_intent) {
|
7
|
+
payment_method.gateway.request {
|
8
|
+
Stripe::PaymentIntent.create(amount: 100, currency: 'usd')
|
9
|
+
}
|
10
|
+
}
|
7
11
|
let(:context) do
|
8
12
|
SolidusStripe::Webhook::EventWithContextFactory.from_object(
|
9
|
-
object:
|
13
|
+
object: stripe_payment_intent,
|
10
14
|
type: "payment_intent.created",
|
11
|
-
payment_method:
|
15
|
+
payment_method: payment_method
|
12
16
|
)
|
13
17
|
end
|
14
18
|
|
@@ -6,7 +6,7 @@ RSpec.describe SolidusStripe::Webhook::ChargeSubscriber do
|
|
6
6
|
describe "#sync_refunds" do
|
7
7
|
it "synchronizes refunds" do
|
8
8
|
SolidusStripe::Seeds.refund_reasons
|
9
|
-
payment_method = create(:
|
9
|
+
payment_method = create(:solidus_stripe_payment_method)
|
10
10
|
stripe_payment_intent = Stripe::PaymentIntent.construct_from(id: "pi_123")
|
11
11
|
payment = create(:payment,
|
12
12
|
amount: 10,
|