Class: Creditcard
- Inherits:
-
ActiveRecord::Base
- Object
- ActiveRecord::Base
- Creditcard
- Defined in:
- app/models/creditcard.rb
Direct Known Subclasses
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
-
#check_environment(gateway) ⇒ Object
Saftey check to make sure we’re not accidentally performing operations on a live gateway.
- #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
- #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
174 175 176 |
# File 'app/models/creditcard.rb', line 174 def actions %w{capture void credit} end |
#authorize(amount, payment) ⇒ Object
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'app/models/creditcard.rb', line 62 def (amount, payment) # ActiveMerchant is configured to use cents so we need to multiply order total by 100 payment_gateway = payment.payment_method check_environment(payment_gateway) 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 gateway_error I18n.t(:unable_to_connect_to_gateway) end |
#brand ⇒ Object
needed for some of the ActiveMerchant gateways (eg. SagePay)
56 57 58 |
# File 'app/models/creditcard.rb', line 56 def brand cc_type end |
#can_capture?(payment) ⇒ Boolean
Indicates whether its possible to capture the payment
179 180 181 |
# File 'app/models/creditcard.rb', line 179 def can_capture?(payment) payment.state == "pending" end |
#can_credit?(payment) ⇒ Boolean
Indicates whether its possible to credit the payment. Note that most gateways require that the payment be settled first which generally happens within 12-24 hours of the transaction.
190 191 192 193 194 |
# File 'app/models/creditcard.rb', line 190 def can_credit?(payment) 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.
184 185 186 |
# File 'app/models/creditcard.rb', line 184 def can_void?(payment) payment.state == "void" ? false : true end |
#capture(payment) ⇒ Object
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'app/models/creditcard.rb', line 102 def capture(payment) return unless payment.pending? payment_gateway = payment.payment_method check_environment(payment_gateway) 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 gateway_error I18n.t(:unable_to_connect_to_gateway) end |
#check_environment(gateway) ⇒ Object
Saftey check to make sure we’re not accidentally performing operations on a live gateway. Ex. When testing in staging environment with a copy of production data.
248 249 250 251 252 |
# File 'app/models/creditcard.rb', line 248 def check_environment(gateway) return if gateway.environment == Rails.env = I18n.t(:gateway_config_unavailable) + " - #{Rails.env}" raise Spree::GatewayError.new() end |
#credit(payment) ⇒ Object
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 |
# File 'app/models/creditcard.rb', line 146 def credit(payment) payment_gateway = payment.payment_method check_environment(payment_gateway) 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 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)
47 48 49 |
# File 'app/models/creditcard.rb', line 47 def display_number "XXXX-XXXX-XXXX-#{last_digits}" end |
#first_name? ⇒ Boolean
30 31 32 |
# File 'app/models/creditcard.rb', line 30 def first_name? first_name.present? end |
#gateway_error(error) ⇒ Object
204 205 206 207 208 209 210 211 212 213 |
# File 'app/models/creditcard.rb', line 204 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
215 216 217 218 219 |
# File 'app/models/creditcard.rb', line 215 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
222 223 224 225 226 |
# File 'app/models/creditcard.rb', line 222 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
196 197 198 |
# File 'app/models/creditcard.rb', line 196 def has_payment_profile? gateway_customer_profile_id.present? end |
#last_name? ⇒ Boolean
34 35 36 |
# File 'app/models/creditcard.rb', line 34 def last_name? last_name.present? 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.
231 232 233 234 235 236 237 238 239 |
# File 'app/models/creditcard.rb', line 231 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
38 39 40 |
# File 'app/models/creditcard.rb', line 38 def name "#{first_name} #{last_name}" end |
#name? ⇒ Boolean
26 27 28 |
# File 'app/models/creditcard.rb', line 26 def name? first_name? && last_name? end |
#process!(payment) ⇒ Object
12 13 14 15 16 17 18 |
# File 'app/models/creditcard.rb', line 12 def process!(payment) if Spree::Config[:auto_capture] purchase(payment.amount.to_f, payment) else (payment.amount.to_f, payment) end end |
#purchase(amount, payment) ⇒ Object
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'app/models/creditcard.rb', line 82 def purchase(amount, payment) #combined Authorize and Capture that gets processed by the ActiveMerchant gateway as one single transaction. payment_gateway = payment.payment_method check_environment(payment_gateway) 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 gateway_error t(:unable_to_connect_to_gateway) end |
#record_log(payment, response) ⇒ Object
200 201 202 |
# File 'app/models/creditcard.rb', line 200 def record_log(payment, response) payment.log_entries.create(:details => response.to_yaml) end |
#set_last_digits ⇒ Object
20 21 22 23 24 |
# File 'app/models/creditcard.rb', line 20 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
241 242 243 244 |
# File 'app/models/creditcard.rb', line 241 def spree_cc_type return "visa" if ENV['RAILS_ENV'] == "development" self.class.type?(number) end |
#verification_value? ⇒ Boolean
42 43 44 |
# File 'app/models/creditcard.rb', line 42 def verification_value? verification_value.present? end |
#void(payment) ⇒ Object
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
# File 'app/models/creditcard.rb', line 129 def void(payment) payment_gateway = payment.payment_method check_environment(payment_gateway) response = payment_gateway.void(payment.response_code, (payment)) record_log payment, response if response.success? payment.response_code = response. payment.void else gateway_error(response) end rescue ActiveMerchant::ConnectionError gateway_error I18n.t(:unable_to_connect_to_gateway) end |