Class: CreditCardPayment

Inherits:
Payment show all
Defined in:
app/models/payments/credit_card_payment.rb

Instance Attribute Summary collapse

Attributes inherited from Payment

#amount, #customer, #transaction_id, #user_agreement

Instance Method Summary collapse

Methods inherited from Payment

create, payment_method, #reduce_amount_by, #refundable?

Constructor Details

#initialize(params = {}) ⇒ CreditCardPayment

Returns a new instance of CreditCardPayment.



7
8
9
10
11
# File 'app/models/payments/credit_card_payment.rb', line 7

def initialize(params = {})
  self.credit_card    ||= ActiveMerchant::Billing::CreditCard.new
  self.customer       ||= Person.new
  build(params) unless params.blank?
end

Instance Attribute Details

#credit_cardObject

ActiveMerchant::Billing::CreditCard



5
6
7
# File 'app/models/payments/credit_card_payment.rb', line 5

def credit_card
  @credit_card
end

Instance Method Details

#authorize(options = {}) ⇒ Object



100
101
102
103
104
# File 'app/models/payments/credit_card_payment.rb', line 100

def authorize(options={})
  response = gateway.authorize(self.amount, credit_card, options)
  self.transaction_id = response.authorization
  response.authorization
end

#build(params) ⇒ Object

We may be able to get some milage out of a repo called active_attr: github.com/cgriego/active_attr



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'app/models/payments/credit_card_payment.rb', line 24

def build(params)
  [:amount, :user_agreement, :transaction_id].each do |field| 
    self.instance_variable_set("@#{field.to_s}", params[field])
  end
  
  unless params[:credit_card].nil?
    params[:credit_card].each do |key, value| 
      self.credit_card.send("#{key}=", value)
    end
  end
  
  unless params[:customer].nil?
    self.customer.first_name  = params[:customer][:first_name]
    self.customer.last_name   = params[:customer][:last_name]
    self.customer.email       = params[:customer][:email]
    
    self.customer.phones      << Phone.new(:number => params[:customer][:phone]) unless params[:customer][:phone].blank?
    
    self.customer.address = Address.new(:address1 => params[:customer][:address][:address1],
                                        :city     => params[:customer][:address][:city],
                                        :state    => params[:customer][:address][:state],
                                        :zip      => params[:customer][:address][:zip])
  end
end

#capture(authorization, options = {}) ⇒ Object Also known as: settle



106
107
108
# File 'app/models/payments/credit_card_payment.rb', line 106

def capture(authorization, options={})
  gateway.capture(self.amount, authorization, options)
end

#gatewayObject



49
50
51
52
53
54
55
# File 'app/models/payments/credit_card_payment.rb', line 49

def gateway
  @gateway ||= ActiveMerchant::Billing::BraintreeGateway.new(
      :merchant_id => Rails.configuration.braintree.merchant_id,
      :public_key  => Rails.configuration.braintree.public_key,
      :private_key => Rails.configuration.braintree.private_key
    )
end

#payment_phone_numberObject



17
18
19
# File 'app/models/payments/credit_card_payment.rb', line 17

def payment_phone_number
  self.customer.phones.first.try(:number)
end

#per_item_processing_chargeObject



13
14
15
# File 'app/models/payments/credit_card_payment.rb', line 13

def per_item_processing_charge
  lambda { |item| item.realized_price * 0.035 }
end

#purchase(options = {}) ⇒ Object

purchase submits for auth and passes a flag to merchant to settle immediately



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'app/models/payments/credit_card_payment.rb', line 81

def purchase(options={})
  response = gateway.purchase(self.amount, credit_card, options.except(:service_fee))
  record_gateway_transaction(options[:service_fee], self.amount, response)
  self.transaction_id = response.authorization
  self.errors.add(:base, BRAINTREE_REJECT_MESSAGE_MAPPING[response.message]) unless response.message.blank?
  response.success?
  
  rescue Errno::ECONNREFUSED => e
    ::Rails.logger.error "Connection to processor refused"
    self.errors.add(:base, "We had a problem processing the sale, please check all your information and try again.")
    false
  rescue Exception => e
    ::Rails.logger.error "Could not contact processor"
    ::Rails.logger.error e
    ::Rails.logger.error e.backtrace
    self.errors.add(:base, "We had a problem processing the sale, please check all your information and try again.")
    false
end

#record_gateway_transaction(service_fee, amount, response) ⇒ Object

This can’t be delayed_job’d because DJ can’t deserialize ARs that haven’t been persisted



114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'app/models/payments/credit_card_payment.rb', line 114

def record_gateway_transaction(service_fee, amount, response)
  begin 
    attrs = {}
    attrs[:transaction_id] = response.authorization
    attrs[:success]        = response.success?
    attrs[:service_fee]    = service_fee
    attrs[:amount]         = amount
    attrs[:message]        = response.message
    attrs[:response]       = response
    @gateway_transaction = GatewayTransaction.create(attrs)
  rescue Exception => e
    ::Exceptional.context(:gateway_transaction => @gateway_transaction)
    ::Exceptional.handle(e, "Failed to persist Gateway Transaction")
  end
end

#refund(refund_amount, transaction_id, options = {}) ⇒ Object

refund_amount: The total amount of money to be sent to the patron transaction_id: The transaction_id of the original transaction options:

:service_fee: The service fees being refunded.  This is for record keeping *only*  It WILL NOT be added to refund_amount


71
72
73
74
75
76
77
78
# File 'app/models/payments/credit_card_payment.rb', line 71

def refund(refund_amount, transaction_id, options = {})
  return true if (refund_amount <= 0)
  response = gateway.refund(refund_amount, transaction_id)
  record_gateway_transaction((options[:service_fee] * -1), (refund_amount * -1), response)
  self.transaction_id = response.authorization
  self.errors.add(:base, response.message) unless response.message.blank?
  response.success?
end

#requires_authorization?Boolean

Returns:

  • (Boolean)


57
58
59
# File 'app/models/payments/credit_card_payment.rb', line 57

def requires_authorization?
  amount > 0
end

#requires_settlement?Boolean

Returns:

  • (Boolean)


61
62
63
# File 'app/models/payments/credit_card_payment.rb', line 61

def requires_settlement?
  true
end