Class: SolidusStripe::RefundsSynchronizer

Inherits:
Object
  • Object
show all
Includes:
MoneyToStripeAmountConverter
Defined in:
lib/solidus_stripe/refunds_synchronizer.rb

Overview

Synchronizes refunds from Stripe to Solidus.

For our use case, Stripe has two ways to inform us about refunds initiated on their side:

  1. The charge.refunded webhook event, which is triggered when a refund is explicitly created.
  2. The payment_intent.succeeded webhook event, which is triggered when a payment intent is captured. If the payment intent is captured for less than the full amount, a refund is automatically created for the remaining amount.

In both cases, Stripe doesn't tell us which refund was recently created, so we need to fetch all the refunds for the payment intent and check if any of them is missing on Solidus. We're using the transaction_id field on Spree::Refund to match refunds against Stripe refunds ids. We could think about only syncing the single refund not present on Solidus, but we need to acknowledge concurrent partial refunds.

The Spree::RefundReason with SolidusStripe::Config.refund_reason_name as name is used as created refunds' reason.

Besides, we need to account for refunds created from Solidus admin panel, which calls the Stripe API. In this case, we need to avoid syncing the refund back to Solidus on the subsequent webhook, otherwise we would end up with duplicate records. We're marking those refunds with a metadata field on Stripe, so we can filter them out (see Gateway#credit).

Constant Summary

Constants included from MoneyToStripeAmountConverter

MoneyToStripeAmountConverter::DIVISIBLE_BY_100, MoneyToStripeAmountConverter::THREE_DECIMAL_CURRENCIES, MoneyToStripeAmountConverter::ZERO_DECIMAL_CURRENCIES

Class Method Summary collapse

Instance Method Summary collapse

Methods included from MoneyToStripeAmountConverter

#solidus_decimal_to_subunit, #solidus_subunit_to_decimal, #to_solidus_amount, #to_stripe_amount

Constructor Details

#initialize(payment_method) ⇒ RefundsSynchronizer

Returns a new instance of RefundsSynchronizer.

Parameters:



48
49
50
# File 'lib/solidus_stripe/refunds_synchronizer.rb', line 48

def initialize(payment_method)
  @payment_method = payment_method
end

Class Method Details

.skip_sync_metadataHash

Metadata used to mark Stripe refunds that shouldn't be synced back to Solidus.

Returns:

  • (Hash)


43
44
45
# File 'lib/solidus_stripe/refunds_synchronizer.rb', line 43

def self.
  { SKIP_SYNC_METADATA_KEY => SKIP_SYNC_METADATA_VALUE }
end

Instance Method Details

#call(stripe_payment_intent_id) ⇒ Object

Parameters:

  • stripe_payment_intent_id (String)


53
54
55
56
57
58
59
# File 'lib/solidus_stripe/refunds_synchronizer.rb', line 53

def call(stripe_payment_intent_id)
  payment = @payment_method.payments.find_by!(response_code: stripe_payment_intent_id)

  stripe_refunds(stripe_payment_intent_id)
    .select { stripe_refund_needs_sync?(_1) }
    .map { create_refund(payment, _1) }
end