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



35
36
37
# File 'app/models/spree/payment/processing.rb', line 35

def authorize!
  handle_payment_preconditions { process_authorization }
end

#cancel!Object



81
82
83
84
# File 'app/models/spree/payment/processing.rb', line 81

def cancel!
  response = payment_method.cancel(response_code)
  handle_void_response(response)
end

#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.



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

def capture!(amount = nil)
  return true if completed?
  amount ||= money.money.cents
  started_processing!
  protect_from_connection_error do
    # Standard ActiveMerchant capture usage
    response = payment_method.capture(
      amount,
      response_code,
      gateway_options
    )
    money = ::Money.new(amount, currency)
    capture_events.create!(amount: money.to_f)
    update_attributes!(amount: captured_amount)
    handle_response(response, :complete, :failure)
  end
end

#gateway_optionsObject



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'app/models/spree/payment/processing.rb', line 86

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 }

  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

#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.


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

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.



40
41
42
# File 'app/models/spree/payment/processing.rb', line 40

def purchase!
  handle_payment_preconditions { process_purchase }
end

#void_transaction!Object



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'app/models/spree/payment/processing.rb', line 65

def void_transaction!
  return true if void?
  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