Module: Spree::Payment::Processing

Included in:
Spree::Payment
Defined in:
app/models/spree/payment/processing.rb

Instance Method Summary collapse

Instance Method Details

#authorize!Object


37
38
39
# File 'app/models/spree/payment/processing.rb', line 37

def authorize!
  handle_payment_preconditions { process_authorization }
end

#cancel!Object


87
88
89
# File 'app/models/spree/payment/processing.rb', line 87

def cancel!
  Spree::Config.payment_canceller.cancel(self)
end

#capture!(capture_amount = nil) ⇒ Object

Takes the amount in cents to capture. Can be used to capture partial amounts of a payment, and will create a new pending payment record for the remaining amount to capture later.


49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'app/models/spree/payment/processing.rb', line 49

def capture!(capture_amount = nil)
  return true if completed?
  return false unless amount.positive?

  capture_amount ||= money.money.cents
  started_processing!
  protect_from_connection_error do
    # Standard ActiveMerchant capture usage
    response = payment_method.capture(
      capture_amount,
      response_code,
      gateway_options
    )
    money = ::Money.new(capture_amount, currency)
    capture_events.create!(amount: money.to_d)
    update!(amount: captured_amount)
    handle_response(response, :complete, :failure)
  end
end

#gateway_optionsObject


91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'app/models/spree/payment/processing.rb', line 91

def gateway_options
  order.reload
  options = {
    email: order.email,
    customer: order.email,
    customer_id: order.user_id,
    ip: order.last_ip_address,
    # Need to pass in a unique identifier here to make some
    # payment gateways happy.
    #
    # For more information, please see Spree::Payment#set_unique_identifier
    order_id: gateway_order_id,
    # The originator is passed to options used by the payment method.
    # One example of a place that it is used is in:
    # app/models/spree/payment_method/store_credit.rb
    originator: self
  }

  options[:shipping] = order.ship_total * 100
  options[:tax] = order.additional_tax_total * 100
  options[:subtotal] = order.item_total * 100
  options[:discount] = order.promo_total * 100
  options[:currency] = currency

  bill_address = source.try(:address)
  bill_address ||= order.bill_address

  options[:billing_address] = bill_address.try!(:active_merchant_hash)
  options[:shipping_address] = order.ship_address.try!(:active_merchant_hash)

  options
end

#gateway_order_idObject

The unique identifier to be passed in to the payment gateway


125
126
127
# File 'app/models/spree/payment/processing.rb', line 125

def gateway_order_id
  "#{order.number}-#{number}"
end

#handle_void_response(response) ⇒ Object


129
130
131
132
133
134
135
136
137
138
# File 'app/models/spree/payment/processing.rb', line 129

def handle_void_response(response)
  record_response(response)

  if response.success?
    self.response_code = response.authorization
    void
  else
    gateway_error(response)
  end
end

#process!Object

“process!” means:

- Do nothing when:
  - There is no payment method
  - The payment method does not require a source
  - The payment is in the "processing" state
  - 'auto_capture?' is false and the payment is already authorized.
- Raise an exception when:
  - The source is missing or invalid
  - The payment is in a state that cannot transition to 'processing'
    (failed/void/invalid states). Note: 'completed' can transition to
    'processing' and thus calling #process! on a completed Payment
    will attempt to re-authorize/re-purchase the payment.
- Otherwise:
  - If 'auto_capture?' is true:
    - Call #purchase on the payment gateway. (i.e. authorize+capture)
      even if the payment is already completed.
  - Else:
    - Call #authorize on the payment gateway even if the payment is
      already completed.

25
26
27
28
29
30
31
32
33
34
35
# File 'app/models/spree/payment/processing.rb', line 25

def process!
  return if payment_method.nil?

  if payment_method.auto_capture?
    purchase!
  elsif pending?
    # do nothing. already authorized.
  else
    authorize!
  end
end

#purchase!Object

Captures the entire amount of a payment.


42
43
44
# File 'app/models/spree/payment/processing.rb', line 42

def purchase!
  handle_payment_preconditions { process_purchase }
end

#void_transaction!Object


69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'app/models/spree/payment/processing.rb', line 69

def void_transaction!
  return true if void?
  return false unless amount.positive?

  protect_from_connection_error do
    if payment_method.payment_profiles_supported?
      # Gateways supporting payment profiles will need access to credit card object because this stores the payment profile information
      # so supply the authorization itself as well as the credit card, rather than just the authorization code
      response = payment_method.void(response_code, source, gateway_options)
    else
      # Standard ActiveMerchant void usage
      response = payment_method.void(response_code, gateway_options)
    end

    handle_void_response(response)
  end
end