Class: Spree::Gateway

Inherits:
PaymentMethod show all
Defined in:
app/models/spree/gateway.rb

Direct Known Subclasses

Bogus, CustomPaymentSourceMethod

Defined Under Namespace

Classes: Bogus, CustomPaymentSourceMethod

Constant Summary collapse

FROM_DOLLAR_TO_CENT_RATE =
100.0

Constants included from DisplayOn

DisplayOn::DISPLAY

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from PaymentMethod

#auto_capture?, #available_for_order?, #available_for_store?, #cancel, #complete_payment_session, #complete_payment_setup_session, #confirmation_required?, #create_payment_session, #create_payment_setup_session, #default_name, find_with_destroyed, #parse_webhook_event, #payment_icon_name, #payment_session_class, #payment_setup_session_class, #provider_class, providers, #public_preferences, #session_required?, #setup_session_supported?, #show_in_admin?, #source_required?, #store_credit?, #update_payment_session, #webhook_url

Methods included from Metadata

#metadata, #metadata=, #public_metadata=

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args) ⇒ Object



55
56
57
58
59
60
61
# File 'app/models/spree/gateway.rb', line 55

def method_missing(method, *args)
  if @provider.nil? || !@provider.respond_to?(method)
    super
  else
    provider.send(method, *args)
  end
end

Class Method Details

.api_typeObject

Payment provider gems conventionally ship a top-level ‘Gateway` class — `SpreeStripe::Gateway`, `SpreeAdyen::Gateway`, `SpreePaypalCheckout::Gateway`. The default demodulized `api_type` collapses every provider to `“gateway”`, which collides in the registry and produces duplicate keys in admin UIs. For gateway subclasses, use the outer module instead (with a leading `Spree` namespace stripped), matching the labelling convention in `PreferenceSchema#subclass_label`:

SpreeStripe::Gateway           "stripe"
SpreeAdyen::Gateway            "adyen"
SpreePaypalCheckout::Gateway   "paypal_checkout"
MyShop::Gateway                "my_shop"

Subclasses nested under a Gateway module (e.g. ‘Spree::Gateway::Bogus`) demodulize to their own leaf and bypass this fallback.



26
27
28
29
30
31
32
# File 'app/models/spree/gateway.rb', line 26

def self.api_type
  leaf = super
  return leaf unless leaf == 'gateway'

  outer = to_s.deconstantize.delete_prefix('Spree::').delete_prefix('Spree').presence
  outer ? outer.underscore : leaf
end

Instance Method Details

#disable_customer_profile(source) ⇒ Object



82
83
84
85
86
87
88
# File 'app/models/spree/gateway.rb', line 82

def disable_customer_profile(source)
  if source.is_a? CreditCard
    source.update_column :gateway_customer_profile_id, nil
  else
    raise 'You must implement disable_customer_profile method for this gateway.'
  end
end

#exchange_multiplierObject



71
72
73
# File 'app/models/spree/gateway.rb', line 71

def exchange_multiplier
  FROM_DOLLAR_TO_CENT_RATE
end

#gateway_dashboard_payment_url(_payment) ⇒ Object

Override in the gateway to provide a payment url eg. for Stripe, this would be the payment intent url dashboard.stripe.com/payments/#Spree::Gateway.paymentpayment.transaction_id



41
42
43
# File 'app/models/spree/gateway.rb', line 41

def gateway_dashboard_payment_url(_payment)
  nil
end

#method_typeObject



67
68
69
# File 'app/models/spree/gateway.rb', line 67

def method_type
  'gateway'
end

#optionsObject



51
52
53
# File 'app/models/spree/gateway.rb', line 51

def options
  preferences.each_with_object({}) { |(key, value), memo| memo[key.to_sym] = value; }
end

#payment_profiles_supported?Boolean

Returns:



63
64
65
# File 'app/models/spree/gateway.rb', line 63

def payment_profiles_supported?
  false
end

#payment_source_classObject



34
35
36
# File 'app/models/spree/gateway.rb', line 34

def payment_source_class
  CreditCard
end

#providerObject



45
46
47
48
49
# File 'app/models/spree/gateway.rb', line 45

def provider
  gateway_options = options
  gateway_options.delete :login if gateway_options.key?(:login) && gateway_options[:login].nil?
  @provider ||= provider_class.new(gateway_options)
end

#reusable_sources(order) ⇒ Object



95
96
97
98
99
100
101
102
103
104
105
# File 'app/models/spree/gateway.rb', line 95

def reusable_sources(order)
  if order.completed?
    sources_by_order order
  else
    if order.user_id
      credit_cards.where(user_id: order.user_id).capturable
    else
      []
    end
  end
end

#sources_by_order(order) ⇒ Object



90
91
92
93
# File 'app/models/spree/gateway.rb', line 90

def sources_by_order(order)
  source_ids = order.payments.where(source_type: payment_source_class.to_s, payment_method_id: id).pluck(:source_id).uniq
  payment_source_class.where(id: source_ids).capturable
end

#supports?(source) ⇒ Boolean

Returns:



75
76
77
78
79
80
# File 'app/models/spree/gateway.rb', line 75

def supports?(source)
  return true unless provider_class.respond_to? :supports?
  return false unless source.brand

  provider_class.supports?(source.brand)
end