solidus_stripe 5.0.0.alpha.1 → 5.0.0.rc.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
data/lib/generators/solidus_stripe/install/templates/app/views/checkouts/payment/_stripe.html.erb
CHANGED
@@ -1,22 +1,57 @@
|
|
1
|
-
<%
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
1
|
+
<%
|
2
|
+
bill_address = current_order.bill_address
|
3
|
+
options = {
|
4
|
+
elementsInitialization: {
|
5
|
+
mode: 'payment',
|
6
|
+
amount: SolidusStripe::MoneyToStripeAmountConverter.to_stripe_amount(
|
7
|
+
current_order.display_order_total_after_store_credit.money.fractional,
|
8
|
+
current_order.currency,
|
9
|
+
),
|
10
|
+
currency: current_order.currency.downcase,
|
11
|
+
paymentMethodCreation: 'manual',
|
12
|
+
captureMethod: payment_method.auto_capture? ? 'automatic' : 'manual',
|
13
|
+
|
14
|
+
# If you want to allow the display/use of specific payment method types
|
15
|
+
# activated from the Stripe Dashboard, you can use this option.
|
16
|
+
#
|
17
|
+
# For a complete list of payment method types available on Stripe:
|
18
|
+
# https://stripe.com/docs/payments/payment-methods/overview
|
19
|
+
# https://stripe.com/docs/api/payment_methods/object#payment_method_object-type
|
20
|
+
#
|
21
|
+
# To activate/deactivate Stripe payment methods:
|
22
|
+
# https://dashboard.stripe.com/settings/payment_methods
|
23
|
+
# paymentMethodTypes: ['card', 'sepa_debit'],
|
24
|
+
|
25
|
+
# Fully customizable with appearance API.
|
26
|
+
# https://stripe.com/docs/elements/appearance-api
|
27
|
+
# appearance: {},
|
28
|
+
},
|
29
|
+
paymentElementCreation: {
|
30
|
+
layout: "tabs",
|
31
|
+
defaultValues: {
|
32
|
+
billingDetails: {
|
33
|
+
name: bill_address.name,
|
34
|
+
email: current_order.email,
|
35
|
+
phone: bill_address.phone,
|
36
|
+
address: {
|
37
|
+
line1: bill_address.address1,
|
38
|
+
line2: bill_address.address2,
|
39
|
+
city: bill_address.city,
|
40
|
+
state: bill_address.state.abbr,
|
41
|
+
country: bill_address.country.iso,
|
42
|
+
postal_code: bill_address.zipcode,
|
43
|
+
}
|
44
|
+
}
|
45
|
+
},
|
46
|
+
},
|
47
|
+
}
|
48
|
+
%>
|
14
49
|
|
15
50
|
<div
|
16
51
|
class="solidus-stripe-payment"
|
17
52
|
data-controller="solidus-stripe-payment"
|
18
53
|
data-solidus-stripe-payment-publishable-key-value="<%= payment_method.preferred_publishable_key %>"
|
19
|
-
data-solidus-stripe-payment-
|
54
|
+
data-solidus-stripe-payment-options-value="<%= options.to_json %>"
|
20
55
|
data-solidus-stripe-payment-radio-selector-value="#order_payments_attributes__payment_method_id_<%= payment_method.id %>"
|
21
56
|
data-solidus-stripe-payment-submit-selector-value="#checkout_form_payment [type='submit']"
|
22
57
|
data-action="submit@window->solidus-stripe-payment#handleSubmit"
|
data/lib/generators/solidus_stripe/install/templates/app/views/orders/payment_info/_stripe.html.erb
CHANGED
@@ -1,7 +1,19 @@
|
|
1
|
-
<%
|
1
|
+
<%
|
2
|
+
stripe_payment_method = payment.source.stripe_payment_method
|
3
|
+
|
4
|
+
# https://stripe.com/docs/api/payment_methods/object#payment_method_object-type
|
5
|
+
partial_base = "checkouts/existing_payment/stripe"
|
6
|
+
payment_type = stripe_payment_method.type
|
7
|
+
|
8
|
+
# Fallback on the default partial if a specialized partial is not available.
|
9
|
+
payment_type = 'default' if lookup_context.find_all("#{partial_base}/_#{payment_type}").none?
|
10
|
+
%>
|
11
|
+
|
2
12
|
<%= render(
|
3
|
-
"
|
4
|
-
stripe_payment_method: stripe_payment_method
|
13
|
+
"#{partial_base}/#{payment_type}",
|
14
|
+
stripe_payment_method: stripe_payment_method,
|
15
|
+
partial_base: partial_base,
|
16
|
+
payment_type: payment_type
|
5
17
|
) %>
|
6
18
|
|
7
19
|
<% if current_order&.confirm? %>
|
@@ -32,52 +32,54 @@ module SolidusStripe
|
|
32
32
|
class RefundsSynchronizer
|
33
33
|
include MoneyToStripeAmountConverter
|
34
34
|
|
35
|
-
# Metadata key used to mark refunds that shouldn't be synced back to Solidus.
|
36
|
-
# @return [Symbol]
|
37
35
|
SKIP_SYNC_METADATA_KEY = :solidus_skip_sync
|
36
|
+
private_constant :SKIP_SYNC_METADATA_KEY
|
38
37
|
|
39
|
-
# Metadata value used to mark refunds that shouldn't be synced back to Solidus.
|
40
|
-
# @return [String]
|
41
38
|
SKIP_SYNC_METADATA_VALUE = 'true'
|
39
|
+
private_constant :SKIP_SYNC_METADATA_VALUE
|
40
|
+
|
41
|
+
# Metadata used to mark Stripe refunds that shouldn't be synced back to Solidus.
|
42
|
+
# @return [Hash]
|
43
|
+
def self.skip_sync_metadata
|
44
|
+
{ SKIP_SYNC_METADATA_KEY => SKIP_SYNC_METADATA_VALUE }
|
45
|
+
end
|
42
46
|
|
43
47
|
# @param payment_method [SolidusStripe::PaymentMethod]
|
44
48
|
def initialize(payment_method)
|
45
49
|
@payment_method = payment_method
|
46
50
|
end
|
47
51
|
|
48
|
-
# @param
|
49
|
-
def call(
|
50
|
-
payment =
|
52
|
+
# @param stripe_payment_intent_id [String]
|
53
|
+
def call(stripe_payment_intent_id)
|
54
|
+
payment = @payment_method.payments.find_by!(response_code: stripe_payment_intent_id)
|
51
55
|
|
52
|
-
stripe_refunds(
|
53
|
-
.select
|
54
|
-
.map(
|
55
|
-
&method(:create_refund).curry[payment]
|
56
|
-
)
|
56
|
+
stripe_refunds(stripe_payment_intent_id)
|
57
|
+
.select { stripe_refund_needs_sync?(_1) }
|
58
|
+
.map { create_refund(payment, _1) }
|
57
59
|
end
|
58
60
|
|
59
61
|
private
|
60
62
|
|
61
|
-
def stripe_refunds(
|
63
|
+
def stripe_refunds(stripe_payment_intent_id)
|
62
64
|
@payment_method.gateway.request do
|
63
|
-
Stripe::Refund.list(payment_intent:
|
65
|
+
Stripe::Refund.list(payment_intent: stripe_payment_intent_id).data
|
64
66
|
end
|
65
67
|
end
|
66
68
|
|
67
|
-
def stripe_refund_needs_sync?(
|
68
|
-
originated_outside_solidus =
|
69
|
-
not_already_synced = Spree::Refund.find_by(transaction_id:
|
69
|
+
def stripe_refund_needs_sync?(stripe_refund)
|
70
|
+
originated_outside_solidus = stripe_refund.metadata[SKIP_SYNC_METADATA_KEY] != SKIP_SYNC_METADATA_VALUE
|
71
|
+
not_already_synced = Spree::Refund.find_by(transaction_id: stripe_refund.id).nil?
|
70
72
|
|
71
73
|
originated_outside_solidus && not_already_synced
|
72
74
|
end
|
73
75
|
|
74
|
-
def create_refund(payment,
|
76
|
+
def create_refund(payment, stripe_refund)
|
75
77
|
Spree::Refund.create!(
|
76
78
|
payment: payment,
|
77
|
-
amount: refund_decimal_amount(
|
78
|
-
transaction_id:
|
79
|
+
amount: refund_decimal_amount(stripe_refund),
|
80
|
+
transaction_id: stripe_refund.id,
|
79
81
|
reason: SolidusStripe::PaymentMethod.refund_reason
|
80
|
-
).tap(
|
82
|
+
).tap { log_refund(payment, _1) }
|
81
83
|
end
|
82
84
|
|
83
85
|
def log_refund(payment, refund)
|
@@ -88,9 +90,9 @@ module SolidusStripe
|
|
88
90
|
)
|
89
91
|
end
|
90
92
|
|
91
|
-
def refund_decimal_amount(
|
92
|
-
to_solidus_amount(
|
93
|
-
.then { |amount| solidus_subunit_to_decimal(amount,
|
93
|
+
def refund_decimal_amount(stripe_refund)
|
94
|
+
to_solidus_amount(stripe_refund.amount, stripe_refund.currency)
|
95
|
+
.then { |amount| solidus_subunit_to_decimal(amount, stripe_refund.currency) }
|
94
96
|
end
|
95
97
|
end
|
96
98
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
FactoryBot.define do
|
4
|
-
factory :
|
4
|
+
factory :solidus_stripe_payment_method, class: 'SolidusStripe::PaymentMethod' do
|
5
5
|
type { "SolidusStripe::PaymentMethod" }
|
6
6
|
name { "Stripe Payment Method" }
|
7
7
|
preferences {
|
@@ -16,13 +16,13 @@ FactoryBot.define do
|
|
16
16
|
}
|
17
17
|
end
|
18
18
|
|
19
|
-
factory :
|
20
|
-
association :payment_method, factory: :
|
19
|
+
factory :solidus_stripe_payment_source, class: 'SolidusStripe::PaymentSource' do
|
20
|
+
association :payment_method, factory: :solidus_stripe_payment_method
|
21
21
|
stripe_payment_method_id { "pm_#{SecureRandom.uuid.delete('-')}" }
|
22
22
|
end
|
23
23
|
|
24
|
-
factory :
|
25
|
-
association :payment_method, factory: :
|
24
|
+
factory :solidus_stripe_payment, parent: :payment do
|
25
|
+
association :payment_method, factory: :solidus_stripe_payment_method
|
26
26
|
amount { order.outstanding_balance }
|
27
27
|
response_code { "pi_#{SecureRandom.uuid.delete('-')}" }
|
28
28
|
state { 'checkout' }
|
@@ -33,7 +33,7 @@ FactoryBot.define do
|
|
33
33
|
|
34
34
|
source {
|
35
35
|
create(
|
36
|
-
:
|
36
|
+
:solidus_stripe_payment_source,
|
37
37
|
payment_method: payment_method,
|
38
38
|
stripe_payment_method_id: stripe_payment_method_id
|
39
39
|
)
|
@@ -44,7 +44,7 @@ FactoryBot.define do
|
|
44
44
|
|
45
45
|
after(:create) do |payment, _evaluator|
|
46
46
|
create(
|
47
|
-
:
|
47
|
+
:solidus_stripe_payment_log_entry,
|
48
48
|
:authorize,
|
49
49
|
source: payment
|
50
50
|
)
|
@@ -56,7 +56,7 @@ FactoryBot.define do
|
|
56
56
|
|
57
57
|
after(:create) do |payment, _evaluator|
|
58
58
|
create(
|
59
|
-
:
|
59
|
+
:solidus_stripe_payment_log_entry,
|
60
60
|
:autocapture,
|
61
61
|
source: payment
|
62
62
|
)
|
@@ -64,19 +64,19 @@ FactoryBot.define do
|
|
64
64
|
end
|
65
65
|
end
|
66
66
|
|
67
|
-
factory :
|
67
|
+
factory :solidus_stripe_payment_intent, class: 'SolidusStripe::PaymentIntent' do
|
68
68
|
association :order
|
69
|
-
association :payment_method, factory: :
|
69
|
+
association :payment_method, factory: :solidus_stripe_payment_method
|
70
70
|
stripe_intent_id { "pm_#{SecureRandom.uuid.delete('-')}" }
|
71
71
|
end
|
72
72
|
|
73
|
-
factory :
|
74
|
-
association :payment_method, factory: :
|
73
|
+
factory :solidus_stripe_slug_entry, class: 'SolidusStripe::SlugEntry' do
|
74
|
+
association :payment_method, factory: :solidus_stripe_payment_method
|
75
75
|
slug { SecureRandom.hex(16) }
|
76
76
|
end
|
77
77
|
|
78
|
-
factory :
|
79
|
-
association :payment_method, factory: :
|
78
|
+
factory :solidus_stripe_customer, class: 'SolidusStripe::Customer' do
|
79
|
+
association :payment_method, factory: :solidus_stripe_payment_method
|
80
80
|
association :source, factory: :user
|
81
81
|
stripe_id { "cus_#{SecureRandom.uuid.delete('-')}" }
|
82
82
|
|
@@ -85,7 +85,7 @@ FactoryBot.define do
|
|
85
85
|
end
|
86
86
|
end
|
87
87
|
|
88
|
-
factory :
|
88
|
+
factory :solidus_stripe_payment_log_entry, class: 'Spree::LogEntry' do
|
89
89
|
transient do
|
90
90
|
success { true }
|
91
91
|
message { nil }
|
@@ -134,10 +134,10 @@ FactoryBot.define do
|
|
134
134
|
}
|
135
135
|
end
|
136
136
|
|
137
|
-
factory :
|
137
|
+
factory :solidus_stripe_order, parent: :order do
|
138
138
|
transient do
|
139
139
|
amount { 10 }
|
140
|
-
payment_method { build(:
|
140
|
+
payment_method { build(:solidus_stripe_payment_method) }
|
141
141
|
stripe_payment_method_id { "pm_#{SecureRandom.uuid.delete('-')}" }
|
142
142
|
end
|
143
143
|
|
@@ -145,7 +145,7 @@ FactoryBot.define do
|
|
145
145
|
|
146
146
|
after(:create) do |order, evaluator|
|
147
147
|
build(
|
148
|
-
:
|
148
|
+
:solidus_stripe_payment,
|
149
149
|
amount: evaluator.amount,
|
150
150
|
order: order,
|
151
151
|
payment_method: evaluator.payment_method,
|
@@ -13,6 +13,7 @@ module SolidusStripe
|
|
13
13
|
PREFIX = "stripe."
|
14
14
|
private_constant :PREFIX
|
15
15
|
|
16
|
+
# /!\ This list must be kept in sync with the list of events in the README
|
16
17
|
CORE_EVENTS = Set[*%i[
|
17
18
|
payment_intent.succeeded
|
18
19
|
payment_intent.payment_failed
|
@@ -31,7 +32,7 @@ module SolidusStripe
|
|
31
32
|
payment_method.preferred_webhook_endpoint_signing_secret,
|
32
33
|
tolerance: tolerance
|
33
34
|
)
|
34
|
-
new(stripe_event: stripe_event,
|
35
|
+
new(stripe_event: stripe_event, payment_method: payment_method)
|
35
36
|
rescue ActiveRecord::RecordNotFound, Stripe::SignatureVerificationError, JSON::ParserError
|
36
37
|
nil
|
37
38
|
end
|
@@ -53,12 +54,12 @@ module SolidusStripe
|
|
53
54
|
attr_reader :omnes_event_name
|
54
55
|
|
55
56
|
# @attr_reader [SolidusStripe::PaymentMethod]
|
56
|
-
attr_reader :
|
57
|
+
attr_reader :payment_method
|
57
58
|
|
58
59
|
# @api private
|
59
|
-
def initialize(stripe_event:,
|
60
|
+
def initialize(stripe_event:, payment_method:)
|
60
61
|
@stripe_event = stripe_event
|
61
|
-
@
|
62
|
+
@payment_method = payment_method
|
62
63
|
@omnes_event_name = :"#{PREFIX}#{stripe_event.type}"
|
63
64
|
end
|
64
65
|
|
@@ -72,7 +73,7 @@ module SolidusStripe
|
|
72
73
|
def payload
|
73
74
|
{
|
74
75
|
"stripe_event" => @stripe_event.as_json,
|
75
|
-
"
|
76
|
+
"payment_method_id" => @payment_method.id
|
76
77
|
}
|
77
78
|
end
|
78
79
|
|
data/solidus_stripe.gemspec
CHANGED
@@ -29,7 +29,7 @@ Gem::Specification.new do |spec|
|
|
29
29
|
spec.executables = files.grep(%r{^exe/}) { |f| File.basename(f) }
|
30
30
|
spec.require_paths = ["lib"]
|
31
31
|
|
32
|
-
spec.add_dependency 'solidus_core', ['>= 3.2', '<
|
32
|
+
spec.add_dependency 'solidus_core', ['>= 3.2', '< 5']
|
33
33
|
spec.add_dependency 'solidus_support', '~> 0.8'
|
34
34
|
|
35
35
|
spec.add_dependency 'stripe', '~> 8.0'
|
@@ -5,8 +5,8 @@ require "solidus_stripe/refunds_synchronizer"
|
|
5
5
|
require "solidus_stripe/seeds"
|
6
6
|
|
7
7
|
RSpec.describe SolidusStripe::RefundsSynchronizer do
|
8
|
-
def
|
9
|
-
allow(Stripe::Refund).to receive(:list).with(payment_intent:
|
8
|
+
def mock_stripe_refund_list(stripe_payment_intent_id, refunds)
|
9
|
+
allow(Stripe::Refund).to receive(:list).with(payment_intent: stripe_payment_intent_id).and_return(
|
10
10
|
Stripe::ListObject.construct_from(
|
11
11
|
data: refunds
|
12
12
|
)
|
@@ -14,13 +14,13 @@ RSpec.describe SolidusStripe::RefundsSynchronizer do
|
|
14
14
|
end
|
15
15
|
|
16
16
|
describe "#call" do
|
17
|
-
let(:payment_method) { create(:
|
17
|
+
let(:payment_method) { create(:solidus_stripe_payment_method) }
|
18
18
|
|
19
19
|
it "creates missing refunds on Solidus" do
|
20
20
|
SolidusStripe::Seeds.refund_reasons
|
21
|
-
|
22
|
-
payment = create(:payment, response_code:
|
23
|
-
|
21
|
+
stripe_payment_intent_id = "pi_123"
|
22
|
+
payment = create(:payment, response_code: stripe_payment_intent_id, amount: 10, payment_method: payment_method)
|
23
|
+
mock_stripe_refund_list(stripe_payment_intent_id, [
|
24
24
|
{
|
25
25
|
id: "re_123",
|
26
26
|
amount: 1000,
|
@@ -29,16 +29,16 @@ RSpec.describe SolidusStripe::RefundsSynchronizer do
|
|
29
29
|
}
|
30
30
|
])
|
31
31
|
|
32
|
-
described_class.new(payment_method).call(
|
32
|
+
described_class.new(payment_method).call(stripe_payment_intent_id)
|
33
33
|
|
34
34
|
expect(payment.refunds.count).to eq(1)
|
35
35
|
end
|
36
36
|
|
37
37
|
it "uses the stripe refund id as created Solidus refund transaction_id field" do
|
38
38
|
SolidusStripe::Seeds.refund_reasons
|
39
|
-
|
40
|
-
payment = create(:payment, response_code:
|
41
|
-
|
39
|
+
stripe_payment_intent_id = "pi_123"
|
40
|
+
payment = create(:payment, response_code: stripe_payment_intent_id, amount: 10, payment_method: payment_method)
|
41
|
+
mock_stripe_refund_list(stripe_payment_intent_id, [
|
42
42
|
{
|
43
43
|
id: "re_123",
|
44
44
|
amount: 1000,
|
@@ -47,7 +47,7 @@ RSpec.describe SolidusStripe::RefundsSynchronizer do
|
|
47
47
|
}
|
48
48
|
])
|
49
49
|
|
50
|
-
described_class.new(payment_method).call(
|
50
|
+
described_class.new(payment_method).call(stripe_payment_intent_id)
|
51
51
|
|
52
52
|
refund = payment.refunds.first
|
53
53
|
expect(refund.transaction_id).to eq("re_123")
|
@@ -55,9 +55,9 @@ RSpec.describe SolidusStripe::RefundsSynchronizer do
|
|
55
55
|
|
56
56
|
it "uses the stripe amount as created Solidus refund amount" do
|
57
57
|
SolidusStripe::Seeds.refund_reasons
|
58
|
-
|
59
|
-
payment = create(:payment, response_code:
|
60
|
-
|
58
|
+
stripe_payment_intent_id = "pi_123"
|
59
|
+
payment = create(:payment, response_code: stripe_payment_intent_id, amount: 10, payment_method: payment_method)
|
60
|
+
mock_stripe_refund_list(stripe_payment_intent_id, [
|
61
61
|
{
|
62
62
|
id: "re_123",
|
63
63
|
amount: 1000,
|
@@ -66,7 +66,7 @@ RSpec.describe SolidusStripe::RefundsSynchronizer do
|
|
66
66
|
}
|
67
67
|
])
|
68
68
|
|
69
|
-
described_class.new(payment_method).call(
|
69
|
+
described_class.new(payment_method).call(stripe_payment_intent_id)
|
70
70
|
|
71
71
|
refund = payment.refunds.first
|
72
72
|
expect(refund.amount).to eq(10)
|
@@ -74,9 +74,9 @@ RSpec.describe SolidusStripe::RefundsSynchronizer do
|
|
74
74
|
|
75
75
|
it "uses the configured reason for created Solidus refunds" do
|
76
76
|
SolidusStripe::Seeds.refund_reasons
|
77
|
-
|
78
|
-
payment = create(:payment, response_code:
|
79
|
-
|
77
|
+
stripe_payment_intent_id = "pi_123"
|
78
|
+
payment = create(:payment, response_code: stripe_payment_intent_id, amount: 10, payment_method: payment_method)
|
79
|
+
mock_stripe_refund_list(stripe_payment_intent_id, [
|
80
80
|
{
|
81
81
|
id: "re_123",
|
82
82
|
amount: 1000,
|
@@ -85,16 +85,16 @@ RSpec.describe SolidusStripe::RefundsSynchronizer do
|
|
85
85
|
}
|
86
86
|
])
|
87
87
|
|
88
|
-
described_class.new(payment_method).call(
|
88
|
+
described_class.new(payment_method).call(stripe_payment_intent_id)
|
89
89
|
|
90
90
|
refund = payment.refunds.first
|
91
91
|
expect(refund.reason).to eq(SolidusStripe::PaymentMethod.refund_reason)
|
92
92
|
end
|
93
93
|
|
94
94
|
it "skips the creation of Solidus refunds with transaction_id matching some stripe refund id" do
|
95
|
-
|
96
|
-
payment = create(:payment, response_code:
|
97
|
-
|
95
|
+
stripe_payment_intent_id = "pi_123"
|
96
|
+
payment = create(:payment, response_code: stripe_payment_intent_id, amount: 10, payment_method: payment_method)
|
97
|
+
mock_stripe_refund_list(stripe_payment_intent_id, [
|
98
98
|
{
|
99
99
|
id: "re_123",
|
100
100
|
amount: 1000,
|
@@ -104,15 +104,15 @@ RSpec.describe SolidusStripe::RefundsSynchronizer do
|
|
104
104
|
])
|
105
105
|
create(:refund, amount: 10, payment: payment, transaction_id: "re_123")
|
106
106
|
|
107
|
-
described_class.new(payment_method).call(
|
107
|
+
described_class.new(payment_method).call(stripe_payment_intent_id)
|
108
108
|
|
109
109
|
expect(payment.refunds.count).to be(1)
|
110
110
|
end
|
111
111
|
|
112
112
|
it "skips the creation of Solidus refunds when specified in their metadata" do
|
113
|
-
|
114
|
-
payment = create(:payment, response_code:
|
115
|
-
|
113
|
+
stripe_payment_intent_id = "pi_123"
|
114
|
+
payment = create(:payment, response_code: stripe_payment_intent_id, amount: 10, payment_method: payment_method)
|
115
|
+
mock_stripe_refund_list(stripe_payment_intent_id, [
|
116
116
|
{
|
117
117
|
id: "re_123",
|
118
118
|
amount: 1000,
|
@@ -123,16 +123,16 @@ RSpec.describe SolidusStripe::RefundsSynchronizer do
|
|
123
123
|
}
|
124
124
|
])
|
125
125
|
|
126
|
-
described_class.new(payment_method).call(
|
126
|
+
described_class.new(payment_method).call(stripe_payment_intent_id)
|
127
127
|
|
128
128
|
expect(payment.refunds.count).to be(0)
|
129
129
|
end
|
130
130
|
|
131
131
|
it "creates multiple Solidus refunds if needed" do
|
132
132
|
SolidusStripe::Seeds.refund_reasons
|
133
|
-
|
134
|
-
payment = create(:payment, response_code:
|
135
|
-
|
133
|
+
stripe_payment_intent_id = "pi_123"
|
134
|
+
payment = create(:payment, response_code: stripe_payment_intent_id, amount: 10, payment_method: payment_method)
|
135
|
+
mock_stripe_refund_list(stripe_payment_intent_id, [
|
136
136
|
{
|
137
137
|
id: "re_123",
|
138
138
|
amount: 500,
|
@@ -147,16 +147,16 @@ RSpec.describe SolidusStripe::RefundsSynchronizer do
|
|
147
147
|
}
|
148
148
|
])
|
149
149
|
|
150
|
-
described_class.new(payment_method).call(
|
150
|
+
described_class.new(payment_method).call(stripe_payment_intent_id)
|
151
151
|
|
152
152
|
expect(payment.refunds.count).to be(2)
|
153
153
|
end
|
154
154
|
|
155
155
|
it "creates only the missing Solidus refunds when there're multiple Stripe refunds" do
|
156
156
|
SolidusStripe::Seeds.refund_reasons
|
157
|
-
|
158
|
-
payment = create(:payment, response_code:
|
159
|
-
|
157
|
+
stripe_payment_intent_id = "pi_123"
|
158
|
+
payment = create(:payment, response_code: stripe_payment_intent_id, amount: 10, payment_method: payment_method)
|
159
|
+
mock_stripe_refund_list(stripe_payment_intent_id, [
|
160
160
|
{
|
161
161
|
id: "re_123",
|
162
162
|
amount: 500,
|
@@ -172,16 +172,16 @@ RSpec.describe SolidusStripe::RefundsSynchronizer do
|
|
172
172
|
])
|
173
173
|
create(:refund, amount: 5, payment: payment, transaction_id: "re_123")
|
174
174
|
|
175
|
-
described_class.new(payment_method).call(
|
175
|
+
described_class.new(payment_method).call(stripe_payment_intent_id)
|
176
176
|
|
177
177
|
expect(payment.refunds.pluck(:transaction_id)).to contain_exactly("re_123", "re_456")
|
178
178
|
end
|
179
179
|
|
180
180
|
it "adds a log entry for created Solidus refund" do
|
181
181
|
SolidusStripe::Seeds.refund_reasons
|
182
|
-
|
183
|
-
payment = create(:payment, response_code:
|
184
|
-
|
182
|
+
stripe_payment_intent_id = "pi_123"
|
183
|
+
payment = create(:payment, response_code: stripe_payment_intent_id, amount: 10, payment_method: payment_method)
|
184
|
+
mock_stripe_refund_list(stripe_payment_intent_id, [
|
185
185
|
{
|
186
186
|
id: "re_123",
|
187
187
|
amount: 1000,
|
@@ -190,16 +190,16 @@ RSpec.describe SolidusStripe::RefundsSynchronizer do
|
|
190
190
|
}
|
191
191
|
])
|
192
192
|
|
193
|
-
described_class.new(payment_method).call(
|
193
|
+
described_class.new(payment_method).call(stripe_payment_intent_id)
|
194
194
|
|
195
195
|
expect(payment.log_entries.count).to eq(1)
|
196
196
|
end
|
197
197
|
|
198
198
|
it "sets created log entry as successful" do
|
199
199
|
SolidusStripe::Seeds.refund_reasons
|
200
|
-
|
201
|
-
payment = create(:payment, response_code:
|
202
|
-
|
200
|
+
stripe_payment_intent_id = "pi_123"
|
201
|
+
payment = create(:payment, response_code: stripe_payment_intent_id, amount: 10, payment_method: payment_method)
|
202
|
+
mock_stripe_refund_list(stripe_payment_intent_id, [
|
203
203
|
{
|
204
204
|
id: "re_123",
|
205
205
|
amount: 1000,
|
@@ -208,7 +208,7 @@ RSpec.describe SolidusStripe::RefundsSynchronizer do
|
|
208
208
|
}
|
209
209
|
])
|
210
210
|
|
211
|
-
described_class.new(payment_method).call(
|
211
|
+
described_class.new(payment_method).call(stripe_payment_intent_id)
|
212
212
|
|
213
213
|
expect(
|
214
214
|
payment.log_entries.first.parsed_details.success?
|
@@ -217,9 +217,9 @@ RSpec.describe SolidusStripe::RefundsSynchronizer do
|
|
217
217
|
|
218
218
|
it "uses a meaningful message with the refunded amount in created log entry" do
|
219
219
|
SolidusStripe::Seeds.refund_reasons
|
220
|
-
|
221
|
-
payment = create(:payment, response_code:
|
222
|
-
|
220
|
+
stripe_payment_intent_id = "pi_123"
|
221
|
+
payment = create(:payment, response_code: stripe_payment_intent_id, amount: 10, payment_method: payment_method)
|
222
|
+
mock_stripe_refund_list(stripe_payment_intent_id, [
|
223
223
|
{
|
224
224
|
id: "re_123",
|
225
225
|
amount: 500,
|
@@ -228,7 +228,7 @@ RSpec.describe SolidusStripe::RefundsSynchronizer do
|
|
228
228
|
}
|
229
229
|
])
|
230
230
|
|
231
|
-
described_class.new(payment_method).call(
|
231
|
+
described_class.new(payment_method).call(stripe_payment_intent_id)
|
232
232
|
|
233
233
|
expect(
|
234
234
|
payment.log_entries.first.parsed_details.message
|
@@ -27,7 +27,7 @@ RSpec.describe SolidusStripe::Webhook::Event do
|
|
27
27
|
let(:context) do
|
28
28
|
SolidusStripe::Webhook::EventWithContextFactory.from_data(
|
29
29
|
data: SolidusStripe::Webhook::DataFixtures.charge_succeeded,
|
30
|
-
payment_method: create(:
|
30
|
+
payment_method: create(:solidus_stripe_payment_method)
|
31
31
|
)
|
32
32
|
end
|
33
33
|
|
@@ -88,24 +88,24 @@ RSpec.describe SolidusStripe::Webhook::Event do
|
|
88
88
|
let(:context) do
|
89
89
|
SolidusStripe::Webhook::EventWithContextFactory.new(
|
90
90
|
data: SolidusStripe::Webhook::DataFixtures.charge_succeeded,
|
91
|
-
payment_method: create(:
|
91
|
+
payment_method: create(:solidus_stripe_payment_method)
|
92
92
|
)
|
93
93
|
end
|
94
94
|
|
95
95
|
it "sets the payment method" do
|
96
|
-
event = described_class.new(stripe_event: context.stripe_object,
|
96
|
+
event = described_class.new(stripe_event: context.stripe_object, payment_method: context.payment_method)
|
97
97
|
|
98
|
-
expect(event.
|
98
|
+
expect(event.payment_method).to be(context.payment_method)
|
99
99
|
end
|
100
100
|
|
101
101
|
it "sets the omnes_event_name from the event type field" do
|
102
|
-
event = described_class.new(stripe_event: context.stripe_object,
|
102
|
+
event = described_class.new(stripe_event: context.stripe_object, payment_method: context.payment_method)
|
103
103
|
|
104
104
|
expect(event.omnes_event_name).to be(:"stripe.charge.succeeded")
|
105
105
|
end
|
106
106
|
|
107
107
|
it "delegates all other methods to the stripe event" do
|
108
|
-
event = described_class.new(stripe_event: context.stripe_object,
|
108
|
+
event = described_class.new(stripe_event: context.stripe_object, payment_method: context.payment_method)
|
109
109
|
|
110
110
|
expect(event.type).to eq("charge.succeeded")
|
111
111
|
end
|
@@ -115,20 +115,20 @@ RSpec.describe SolidusStripe::Webhook::Event do
|
|
115
115
|
let(:context) do
|
116
116
|
SolidusStripe::Webhook::EventWithContextFactory.new(
|
117
117
|
data: SolidusStripe::Webhook::DataFixtures.charge_succeeded,
|
118
|
-
payment_method: create(:
|
118
|
+
payment_method: create(:solidus_stripe_payment_method)
|
119
119
|
)
|
120
120
|
end
|
121
121
|
|
122
122
|
it "includes stripe event Hash representation" do
|
123
|
-
event = described_class.new(stripe_event: context.stripe_object,
|
123
|
+
event = described_class.new(stripe_event: context.stripe_object, payment_method: context.payment_method)
|
124
124
|
|
125
125
|
expect(event.payload["stripe_event"]).to eq(context.stripe_object.as_json)
|
126
126
|
end
|
127
127
|
|
128
128
|
it "includes spree payment method id" do
|
129
|
-
event = described_class.new(stripe_event: context.stripe_object,
|
129
|
+
event = described_class.new(stripe_event: context.stripe_object, payment_method: context.payment_method)
|
130
130
|
|
131
|
-
expect(event.payload["
|
131
|
+
expect(event.payload["payment_method_id"]).to be(context.payment_method.id)
|
132
132
|
end
|
133
133
|
end
|
134
134
|
end
|