Class: Creditcard
- Inherits:
-
ActiveRecord::Base
- Object
- ActiveRecord::Base
- Creditcard
- Defined in:
- app/models/creditcard.rb
Instance Attribute Summary collapse
-
#number ⇒ Object
Returns the value of attribute number.
-
#verification_value ⇒ Object
Returns the value of attribute verification_value.
Instance Method Summary collapse
- #actions ⇒ Object
- #authorize(amount, payment) ⇒ Object
-
#brand ⇒ Object
needed for some of the ActiveMerchant gateways (eg. SagePay).
-
#can_capture?(payment) ⇒ Boolean
Indicates whether its possible to capture the payment.
-
#can_credit?(payment) ⇒ Boolean
Indicates whether its possible to credit the payment.
-
#can_void?(payment) ⇒ Boolean
Indicates whether its possible to void the payment.
- #capture(payment) ⇒ Object
- #credit(payment) ⇒ Object
-
#display_number ⇒ Object
Show the card number, with all but last 4 numbers replace with “X”.
- #first_name? ⇒ Boolean
- #gateway_error(error) ⇒ Object
- #gateway_options(payment) ⇒ Object
-
#generate_address_hash(address) ⇒ Object
Generates an ActiveMerchant compatible address hash from one of Spree’s address objects.
- #has_payment_profile? ⇒ Boolean
- #last_name? ⇒ Boolean
-
#minimal_gateway_options(payment) ⇒ Object
Generates a minimal set of gateway options.
- #name ⇒ Object
- #name? ⇒ Boolean
- #payment_gateway ⇒ Object
- #process!(payment) ⇒ Object
- #purchase(amount, payment) ⇒ Object
- #record_log(payment, response) ⇒ Object
- #set_last_digits ⇒ Object
- #spree_cc_type ⇒ Object
- #verification_value? ⇒ Boolean
- #void(payment) ⇒ Object
Instance Attribute Details
#number ⇒ Object
Returns the value of attribute number.
6 7 8 |
# File 'app/models/creditcard.rb', line 6 def number @number end |
#verification_value ⇒ Object
Returns the value of attribute verification_value.
6 7 8 |
# File 'app/models/creditcard.rb', line 6 def verification_value @verification_value end |
Instance Method Details
#actions ⇒ Object
164 165 166 |
# File 'app/models/creditcard.rb', line 164 def actions %w{capture void credit} end |
#authorize(amount, payment) ⇒ Object
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'app/models/creditcard.rb', line 64 def (amount, payment) # ActiveMerchant is configured to use cents so we need to multiply order total by 100 response = payment_gateway.((amount * 100).round, self, (payment)) record_log payment, response if response.success? payment.response_code = response. payment.avs_response = response.avs_result['code'] payment.pend else payment.fail gateway_error(response) end rescue ActiveMerchant::ConnectionError => e gateway_error I18n.t(:unable_to_connect_to_gateway) end |
#brand ⇒ Object
needed for some of the ActiveMerchant gateways (eg. SagePay)
58 59 60 |
# File 'app/models/creditcard.rb', line 58 def brand cc_type end |
#can_capture?(payment) ⇒ Boolean
Indicates whether its possible to capture the payment
169 170 171 |
# File 'app/models/creditcard.rb', line 169 def can_capture?(payment) payment.state == "pending" end |
#can_credit?(payment) ⇒ Boolean
Indicates whether its possible to credit the payment. Most gateways require that the payment be settled first which generally happens within 12-24 hours of the transaction. For this reason, the default behavior of Spree is to disallow credit operations until the payment is at least 12 hours old.
185 186 187 188 189 190 |
# File 'app/models/creditcard.rb', line 185 def can_credit?(payment) return false unless (Time.now - 12.hours) > payment.created_at return false unless payment.state == "completed" return false unless payment.order.payment_state == "credit_owed" payment.credit_allowed > 0 end |
#can_void?(payment) ⇒ Boolean
Indicates whether its possible to void the payment. Most gateways require that the payment has not been settled yet when performing a void (which generally happens within 12-24 hours of the transaction.) For this reason, the default behavior of Spree is to only allow void operations within the first 12 hours of the payment creation time.
177 178 179 180 |
# File 'app/models/creditcard.rb', line 177 def can_void?(payment) return false unless (Time.now - 12.hours) < payment.created_at %w{completed pending}.include? payment.state end |
#capture(payment) ⇒ Object
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'app/models/creditcard.rb', line 98 def capture(payment) return unless payment.pending? if payment_gateway.payment_profiles_supported? # Gateways supporting payment profiles will need access to creditcard object because this stores the payment profile information # so supply the authorization itself as well as the creditcard, rather than just the authorization code response = payment_gateway.capture(payment, self, (payment)) else # Standard ActiveMerchant capture usage response = payment_gateway.capture((payment.amount * 100).round, payment.response_code, (payment)) end record_log payment, response if response.success? payment.response_code = response. payment.complete else payment.fail gateway_error(response) end rescue ActiveMerchant::ConnectionError => e gateway_error I18n.t(:unable_to_connect_to_gateway) end |
#credit(payment) ⇒ Object
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
# File 'app/models/creditcard.rb', line 136 def credit(payment) amount = payment.credit_allowed >= payment.order.outstanding_balance.abs ? payment.order.outstanding_balance.abs : payment.credit_allowed.abs if payment_gateway.payment_profiles_supported? response = payment_gateway.credit((amount * 100).round, self, payment.response_code, (payment)) else response = payment_gateway.credit((amount * 100).round, payment.response_code, (payment)) end record_log payment, response if response.success? Payment.create(:order => payment.order, :source => payment, :payment_method => payment.payment_method, :amount => amount.abs * -1, :response_code => response., :state => 'completed') else gateway_error(response) end rescue ActiveMerchant::ConnectionError => e gateway_error I18n.t(:unable_to_connect_to_gateway) end |
#display_number ⇒ Object
Show the card number, with all but last 4 numbers replace with “X”. (XXXX-XXXX-XXXX-4338)
49 50 51 |
# File 'app/models/creditcard.rb', line 49 def display_number "XXXX-XXXX-XXXX-#{last_digits}" end |
#first_name? ⇒ Boolean
32 33 34 |
# File 'app/models/creditcard.rb', line 32 def first_name? !self.first_name.blank? end |
#gateway_error(error) ⇒ Object
200 201 202 203 204 205 206 207 208 209 |
# File 'app/models/creditcard.rb', line 200 def gateway_error(error) if error.is_a? ActiveMerchant::Billing::Response text = error.params['message'] || error.params['response_reason_text'] || error. else text = error.to_s end logger.error(I18n.t('gateway_error')) logger.error(" #{error.to_yaml}") raise Spree::GatewayError.new(text) end |
#gateway_options(payment) ⇒ Object
211 212 213 214 215 |
# File 'app/models/creditcard.rb', line 211 def (payment) = {:billing_address => generate_address_hash(payment.order.bill_address), :shipping_address => generate_address_hash(payment.order.ship_address)} .merge (payment) end |
#generate_address_hash(address) ⇒ Object
Generates an ActiveMerchant compatible address hash from one of Spree’s address objects
218 219 220 221 222 |
# File 'app/models/creditcard.rb', line 218 def generate_address_hash(address) return {} if address.nil? {:name => address.full_name, :address1 => address.address1, :address2 => address.address2, :city => address.city, :state => address.state_text, :zip => address.zipcode, :country => address.country.iso, :phone => address.phone} end |
#has_payment_profile? ⇒ Boolean
192 193 194 |
# File 'app/models/creditcard.rb', line 192 def has_payment_profile? gateway_customer_profile_id.present? end |
#last_name? ⇒ Boolean
36 37 38 |
# File 'app/models/creditcard.rb', line 36 def last_name? !self.last_name.blank? end |
#minimal_gateway_options(payment) ⇒ Object
Generates a minimal set of gateway options. There appears to be some issues with passing in a billing address when authorizing/voiding a previously captured transaction. So omits these options in this case since they aren’t necessary.
227 228 229 230 231 232 233 234 235 |
# File 'app/models/creditcard.rb', line 227 def (payment) {:email => payment.order.email, :customer => payment.order.email, :ip => payment.order.ip_address, :order_id => payment.order.number, :shipping => payment.order.ship_total * 100, :tax => payment.order.tax_total * 100, :subtotal => payment.order.item_total * 100} end |
#name ⇒ Object
40 41 42 |
# File 'app/models/creditcard.rb', line 40 def name "#{self.first_name} #{self.last_name}" end |
#name? ⇒ Boolean
28 29 30 |
# File 'app/models/creditcard.rb', line 28 def name? first_name? && last_name? end |
#payment_gateway ⇒ Object
242 243 244 |
# File 'app/models/creditcard.rb', line 242 def payment_gateway @payment_gateway ||= Gateway.current end |
#process!(payment) ⇒ Object
12 13 14 15 16 17 18 19 20 |
# File 'app/models/creditcard.rb', line 12 def process!(payment) begin if Spree::Config[:auto_capture] purchase(payment.amount.to_f, payment) else (payment.amount.to_f, payment) end end end |
#purchase(amount, payment) ⇒ Object
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'app/models/creditcard.rb', line 81 def purchase(amount, payment) #combined Authorize and Capture that gets processed by the ActiveMerchant gateway as one single transaction. response = payment_gateway.purchase((amount * 100).round, self, (payment)) record_log payment, response if response.success? payment.response_code = response. payment.avs_response = response.avs_result['code'] payment.complete else payment.fail gateway_error(response) unless response.success? end rescue ActiveMerchant::ConnectionError => e gateway_error t(:unable_to_connect_to_gateway) end |
#record_log(payment, response) ⇒ Object
196 197 198 |
# File 'app/models/creditcard.rb', line 196 def record_log(payment, response) payment.log_entries.create(:details => response.to_yaml) end |
#set_last_digits ⇒ Object
22 23 24 25 26 |
# File 'app/models/creditcard.rb', line 22 def set_last_digits number.to_s.gsub!(/\s/,'') unless number.nil? verification_value.to_s.gsub!(/\s/,'') unless number.nil? self.last_digits ||= number.to_s.length <= 4 ? number : number.to_s.slice(-4..-1) end |
#spree_cc_type ⇒ Object
237 238 239 240 |
# File 'app/models/creditcard.rb', line 237 def spree_cc_type return "visa" if ENV['RAILS_ENV'] == "development" self.class.type?(number) end |
#verification_value? ⇒ Boolean
44 45 46 |
# File 'app/models/creditcard.rb', line 44 def verification_value? !verification_value.blank? end |
#void(payment) ⇒ Object
122 123 124 125 126 127 128 129 130 131 132 133 134 |
# File 'app/models/creditcard.rb', line 122 def void(payment) response = payment_gateway.void(payment.response_code, self, (payment)) record_log payment, response if response.success? payment.response_code = response. payment.void else gateway_error(response) end rescue ActiveMerchant::ConnectionError => e gateway_error I18n.t(:unable_to_connect_to_gateway) end |