spree_stripe 6.0.0.rc1 → 6.0.0.rc3
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
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 48c59a96220b4a90a1209052911ff9b7ce172bcf50d8b08199fd4764a0eec087
|
|
4
|
+
data.tar.gz: 9a07b180e0163852c0377aa049cc07c655fcfd2338bb590c6383eddaca0f9375
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1398a615dcfe7675c9719426a150a3ac94857fc2858f8f99e746647ab1ad9005c39fa94cc78c9da3d20518303f236097003e31c972b34ecc41357c11d35301b5
|
|
7
|
+
data.tar.gz: 18da786a5861d4e2deaa846f2e1256d67201e3a8943ffbf048050fa901dac2d20851e2acf3140dc9efe7f0949e87aa83410a0e55bc13eeb0b978d1c2155acc79
|
|
@@ -48,9 +48,9 @@ module SpreeStripe
|
|
|
48
48
|
# paid, or an earlier one could not be canceled
|
|
49
49
|
def create_payment_session(order:, amount: nil, external_data: {})
|
|
50
50
|
total = amount.presence || order.total_minus_store_credits
|
|
51
|
-
|
|
51
|
+
stripe_amount = SpreeStripe::Units.to_stripe(total, order.currency)
|
|
52
52
|
|
|
53
|
-
raise Spree::Core::GatewayError, I18n.t('spree.stripe.payment_session_errors.zero_amount') if
|
|
53
|
+
raise Spree::Core::GatewayError, I18n.t('spree.stripe.payment_session_errors.zero_amount') if stripe_amount.zero?
|
|
54
54
|
|
|
55
55
|
stripe_payment_method_id = external_data[:stripe_payment_method_id] || external_data['stripe_payment_method_id']
|
|
56
56
|
|
|
@@ -59,7 +59,7 @@ module SpreeStripe
|
|
|
59
59
|
gateway_customer = fetch_or_create_customer(order: order)
|
|
60
60
|
|
|
61
61
|
response = create_payment_intent(
|
|
62
|
-
|
|
62
|
+
stripe_amount, order,
|
|
63
63
|
payment_method_id: stripe_payment_method_id,
|
|
64
64
|
customer_profile_id: gateway_customer&.profile_id
|
|
65
65
|
)
|
|
@@ -85,18 +85,18 @@ module SpreeStripe
|
|
|
85
85
|
|
|
86
86
|
def update_payment_session(payment_session:, amount: nil, external_data: {})
|
|
87
87
|
attrs = {}
|
|
88
|
-
|
|
88
|
+
stripe_amount = nil
|
|
89
89
|
|
|
90
90
|
if amount.present?
|
|
91
91
|
attrs[:amount] = amount
|
|
92
|
-
|
|
92
|
+
stripe_amount = SpreeStripe::Units.to_stripe(amount, payment_session.currency)
|
|
93
93
|
end
|
|
94
94
|
|
|
95
95
|
stripe_payment_method_id = external_data[:stripe_payment_method_id] || external_data['stripe_payment_method_id']
|
|
96
96
|
|
|
97
97
|
update_payment_intent(
|
|
98
98
|
payment_session.external_id,
|
|
99
|
-
|
|
99
|
+
stripe_amount || SpreeStripe::Units.to_stripe(payment_session.amount, payment_session.currency),
|
|
100
100
|
payment_session.owner,
|
|
101
101
|
stripe_payment_method_id
|
|
102
102
|
)
|
|
@@ -165,8 +165,8 @@ module SpreeStripe
|
|
|
165
165
|
send_request { |opts| Stripe::PaymentIntent.confirm(payment_intent_id, {}, opts) }
|
|
166
166
|
end
|
|
167
167
|
|
|
168
|
-
def capture_payment_intent(payment_intent_id,
|
|
169
|
-
send_request { |opts| Stripe::PaymentIntent.capture(payment_intent_id, { amount_to_capture:
|
|
168
|
+
def capture_payment_intent(payment_intent_id, stripe_amount)
|
|
169
|
+
send_request { |opts| Stripe::PaymentIntent.capture(payment_intent_id, { amount_to_capture: stripe_amount }, opts) }
|
|
170
170
|
end
|
|
171
171
|
|
|
172
172
|
def cancel_payment_intent(payment_intent_id)
|
|
@@ -273,9 +273,9 @@ module SpreeStripe
|
|
|
273
273
|
|
|
274
274
|
# @param order [Spree::Cart, Spree::Order]
|
|
275
275
|
# @return [Spree::PaymentResponse]
|
|
276
|
-
def create_payment_intent(
|
|
276
|
+
def create_payment_intent(stripe_amount, order, payment_method_id: nil, customer_profile_id: nil)
|
|
277
277
|
payload = {
|
|
278
|
-
amount:
|
|
278
|
+
amount: stripe_amount,
|
|
279
279
|
currency: order.currency,
|
|
280
280
|
customer: customer_profile_id,
|
|
281
281
|
payment_method: payment_method_id,
|
|
@@ -304,10 +304,10 @@ module SpreeStripe
|
|
|
304
304
|
end
|
|
305
305
|
|
|
306
306
|
# Only the fields that can legitimately change while a session is pending.
|
|
307
|
-
def update_payment_intent(payment_intent_id,
|
|
307
|
+
def update_payment_intent(payment_intent_id, stripe_amount, order, payment_method_id = nil)
|
|
308
308
|
protect_from_error do
|
|
309
309
|
payload = {
|
|
310
|
-
amount:
|
|
310
|
+
amount: stripe_amount,
|
|
311
311
|
currency: order.currency,
|
|
312
312
|
customer: fetch_or_create_customer(order: order)&.profile_id,
|
|
313
313
|
payment_method: payment_method_id,
|
|
@@ -3,6 +3,8 @@ module SpreeStripe
|
|
|
3
3
|
# created and confirmed through sessions; core's payment lifecycle then drives
|
|
4
4
|
# capture, refund and cancellation against the resulting intent.
|
|
5
5
|
class Gateway < ::Spree::Gateway
|
|
6
|
+
self.accepts_money_amounts = true
|
|
7
|
+
|
|
6
8
|
include SpreeStripe::Gateway::PaymentSessions
|
|
7
9
|
include SpreeStripe::Gateway::PaymentSetupSessions
|
|
8
10
|
include SpreeStripe::Gateway::Webhooks
|
|
@@ -86,26 +88,26 @@ module SpreeStripe
|
|
|
86
88
|
# is already confirmed client-side in the session flow, so this reads back the
|
|
87
89
|
# intent rather than initiating a charge.
|
|
88
90
|
#
|
|
89
|
-
# @param
|
|
91
|
+
# @param money [Spree::Money]
|
|
90
92
|
# @param payment_source [Spree::PaymentSource, Spree::CreditCard]
|
|
91
93
|
# @param gateway_options [Hash] Spree::Payment::GatewayOptions#to_hash
|
|
92
94
|
# @return [Spree::PaymentResponse]
|
|
93
|
-
def authorize(
|
|
94
|
-
handle_authorize_or_purchase(
|
|
95
|
+
def authorize(money, payment_source, gateway_options = {})
|
|
96
|
+
handle_authorize_or_purchase(money, payment_source, gateway_options)
|
|
95
97
|
end
|
|
96
98
|
|
|
97
99
|
# @see #authorize — capture vs authorize is decided by the intent's capture
|
|
98
100
|
# method, so both resolve the same way.
|
|
99
|
-
def purchase(
|
|
100
|
-
handle_authorize_or_purchase(
|
|
101
|
+
def purchase(money, payment_source, gateway_options = {})
|
|
102
|
+
handle_authorize_or_purchase(money, payment_source, gateway_options)
|
|
101
103
|
end
|
|
102
104
|
|
|
103
|
-
def capture(
|
|
105
|
+
def capture(money, payment_intent_id, _gateway_options = {})
|
|
104
106
|
protect_from_error do
|
|
105
107
|
stripe_payment_intent = retrieve_payment_intent(payment_intent_id)
|
|
106
108
|
|
|
107
109
|
response = if payment_intent_requires_capture?(stripe_payment_intent)
|
|
108
|
-
capture_payment_intent(payment_intent_id,
|
|
110
|
+
capture_payment_intent(payment_intent_id, SpreeStripe::Units.to_stripe(money, money.currency))
|
|
109
111
|
elsif stripe_payment_intent.status == 'succeeded'
|
|
110
112
|
stripe_payment_intent
|
|
111
113
|
else
|
|
@@ -116,10 +118,10 @@ module SpreeStripe
|
|
|
116
118
|
end
|
|
117
119
|
end
|
|
118
120
|
|
|
119
|
-
def credit(
|
|
121
|
+
def credit(money, _source, payment_intent_id, _gateway_options = {})
|
|
120
122
|
protect_from_error do
|
|
121
123
|
response = send_request do |opts|
|
|
122
|
-
Stripe::Refund.create({ amount:
|
|
124
|
+
Stripe::Refund.create({ amount: SpreeStripe::Units.to_stripe(money, money.currency), payment_intent: payment_intent_id }, opts)
|
|
123
125
|
end
|
|
124
126
|
|
|
125
127
|
success(response.id, response)
|
|
@@ -269,7 +271,7 @@ module SpreeStripe
|
|
|
269
271
|
|
|
270
272
|
private
|
|
271
273
|
|
|
272
|
-
def handle_authorize_or_purchase(
|
|
274
|
+
def handle_authorize_or_purchase(_money, _payment_source, gateway_options)
|
|
273
275
|
# Scoped through this gateway's own payments — a cart-owned payment
|
|
274
276
|
# (checkout is still in flight) has no order to join through, and the
|
|
275
277
|
# payment method already belongs to exactly one store. Found by the
|
|
@@ -258,7 +258,7 @@ module SpreeStripe
|
|
|
258
258
|
wanted = currency.to_s.downcase
|
|
259
259
|
minor = balance.available.select { |entry| entry.currency == wanted }.sum(&:amount)
|
|
260
260
|
|
|
261
|
-
|
|
261
|
+
SpreeStripe::Units.from_stripe(minor, currency)
|
|
262
262
|
rescue *AMBIGUOUS_ERRORS => e
|
|
263
263
|
# The sweep must not read silence as "nothing to send" and settle a
|
|
264
264
|
# smaller batch than the seller is owed, nor as "no limit" and ask for
|
|
@@ -290,8 +290,7 @@ module SpreeStripe
|
|
|
290
290
|
return {} if balance_transaction.blank? || balance_transaction.try(:currency).blank?
|
|
291
291
|
|
|
292
292
|
{
|
|
293
|
-
settled_amount:
|
|
294
|
-
balance_transaction.currency),
|
|
293
|
+
settled_amount: SpreeStripe::Units.from_stripe(balance_transaction.amount, balance_transaction.currency),
|
|
295
294
|
settled_currency: balance_transaction.currency.upcase
|
|
296
295
|
}
|
|
297
296
|
end
|
|
@@ -322,7 +321,7 @@ module SpreeStripe
|
|
|
322
321
|
end
|
|
323
322
|
|
|
324
323
|
def minor_units(record)
|
|
325
|
-
|
|
324
|
+
SpreeStripe::Units.to_stripe(record.amount.abs, record.currency, payout: true)
|
|
326
325
|
end
|
|
327
326
|
|
|
328
327
|
# Ties transfers paid from the platform balance to the checkout they
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
module SpreeStripe
|
|
2
|
+
# Stripe's integer amounts. Mostly the currency's ISO minor unit, with
|
|
3
|
+
# Stripe's own exceptions (https://docs.stripe.com/currencies): its
|
|
4
|
+
# zero-decimal currencies are sent in whole units, and ISK and UGX, zero-decimal
|
|
5
|
+
# since, are still sent as two-decimal values ending in 00. Stripe also takes
|
|
6
|
+
# three-decimal currencies only in steps of 0.010, and pays out HUF and TWD
|
|
7
|
+
# only in whole units; an amount it would refuse raises here, naming the rule,
|
|
8
|
+
# rather than being rounded to a sum other than the one Spree records.
|
|
9
|
+
module Units
|
|
10
|
+
module_function
|
|
11
|
+
|
|
12
|
+
ZERO_DECIMAL = %w[BIF CLP DJF GNF JPY KMF KRW MGA PYG RWF VND VUV XAF XOF XPF].freeze
|
|
13
|
+
WHOLE_IN_HUNDREDTHS = %w[ISK UGX].freeze
|
|
14
|
+
THREE_DECIMAL = %w[BHD JOD KWD OMR TND].freeze
|
|
15
|
+
WHOLE_PAYOUTS = %w[HUF TWD].freeze
|
|
16
|
+
|
|
17
|
+
class UnsupportedAmount < Spree::Core::GatewayError; end
|
|
18
|
+
|
|
19
|
+
# @param amount [BigDecimal, Spree::Money]
|
|
20
|
+
# @param currency [String]
|
|
21
|
+
# @param payout [Boolean] a payout or transfer rather than a charge
|
|
22
|
+
# @return [Integer]
|
|
23
|
+
# @raise [UnsupportedAmount] when Stripe would refuse the amount
|
|
24
|
+
def to_stripe(amount, currency, payout: false)
|
|
25
|
+
amount = amount.to_d if amount.respond_to?(:to_d)
|
|
26
|
+
code = currency.to_s.upcase
|
|
27
|
+
return Spree::Money::Rounding.quantize(amount, 0).to_i if ZERO_DECIMAL.include?(code)
|
|
28
|
+
return Spree::Money::Rounding.quantize(amount, 0).to_i * 100 if WHOLE_IN_HUNDREDTHS.include?(code)
|
|
29
|
+
|
|
30
|
+
units = Spree::Money::Rounding.to_minor_units(amount, code)
|
|
31
|
+
if THREE_DECIMAL.include?(code) && (units % 10).nonzero?
|
|
32
|
+
raise UnsupportedAmount, "Stripe takes #{code} only in steps of 0.010, got #{amount.to_s('F')}"
|
|
33
|
+
end
|
|
34
|
+
if payout && WHOLE_PAYOUTS.include?(code) && (units % 100).nonzero?
|
|
35
|
+
raise UnsupportedAmount, "Stripe pays out #{code} only in whole units, got #{amount.to_s('F')}"
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
units
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# @param units [Integer] as Stripe reports it
|
|
42
|
+
# @param currency [String]
|
|
43
|
+
# @return [BigDecimal]
|
|
44
|
+
def from_stripe(units, currency)
|
|
45
|
+
code = currency.to_s.upcase
|
|
46
|
+
return BigDecimal(units) if ZERO_DECIMAL.include?(code)
|
|
47
|
+
return BigDecimal(units) / 100 if WHOLE_IN_HUNDREDTHS.include?(code)
|
|
48
|
+
|
|
49
|
+
Spree::Money::Rounding.from_minor_units(units, code)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: spree_stripe
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 6.0.0.
|
|
4
|
+
version: 6.0.0.rc3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Vendo Connect Inc.
|
|
@@ -9,7 +9,7 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date: 2026-10-
|
|
12
|
+
date: 2026-10-13 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: spree_core
|
|
@@ -17,14 +17,14 @@ dependencies:
|
|
|
17
17
|
requirements:
|
|
18
18
|
- - '='
|
|
19
19
|
- !ruby/object:Gem::Version
|
|
20
|
-
version: 6.0.0.
|
|
20
|
+
version: 6.0.0.rc3
|
|
21
21
|
type: :runtime
|
|
22
22
|
prerelease: false
|
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
|
24
24
|
requirements:
|
|
25
25
|
- - '='
|
|
26
26
|
- !ruby/object:Gem::Version
|
|
27
|
-
version: 6.0.0.
|
|
27
|
+
version: 6.0.0.rc3
|
|
28
28
|
- !ruby/object:Gem::Dependency
|
|
29
29
|
name: stripe
|
|
30
30
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -89,6 +89,7 @@ files:
|
|
|
89
89
|
- app/models/spree_stripe/payment_sources/przelewy24.rb
|
|
90
90
|
- app/models/spree_stripe/payment_sources/sepa_debit.rb
|
|
91
91
|
- app/models/spree_stripe/payout_provider.rb
|
|
92
|
+
- app/models/spree_stripe/units.rb
|
|
92
93
|
- app/presenters/spree_stripe/customer_presenter.rb
|
|
93
94
|
- app/presenters/spree_stripe/statement_descriptor_suffix_presenter.rb
|
|
94
95
|
- app/services/spree_stripe/create_gateway_webhooks.rb
|
|
@@ -110,9 +111,9 @@ licenses:
|
|
|
110
111
|
- MIT
|
|
111
112
|
metadata:
|
|
112
113
|
bug_tracker_uri: https://github.com/spree/spree/issues
|
|
113
|
-
changelog_uri: https://github.com/spree/spree/releases/tag/v6.0.0.
|
|
114
|
+
changelog_uri: https://github.com/spree/spree/releases/tag/v6.0.0.rc3
|
|
114
115
|
documentation_uri: https://docs.spreecommerce.org/
|
|
115
|
-
source_code_uri: https://github.com/spree/spree/tree/v6.0.0.
|
|
116
|
+
source_code_uri: https://github.com/spree/spree/tree/v6.0.0.rc3
|
|
116
117
|
post_install_message:
|
|
117
118
|
rdoc_options: []
|
|
118
119
|
require_paths:
|