fixed capture and credit due to spree 1.1 changes cf payment processing
This commit is contained in:
parent
26da577090
commit
b11a9dd9f2
|
@ -16,4 +16,46 @@ class Spree::BillingIntegration::PaypalExpressBase < Spree::BillingIntegration
|
||||||
def payment_profiles_supported?
|
def payment_profiles_supported?
|
||||||
!!preferred_review
|
!!preferred_review
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def capture(payment_or_amount, account_or_response_code, gateway_options)
|
||||||
|
if payment_or_amount.is_a?(Spree::Payment)
|
||||||
|
authorization = find_authorization(payment_or_amount)
|
||||||
|
provider.capture(amount_in_cents(payment_or_amount.amount), authorization.params["transaction_id"], :currency => preferred_currency)
|
||||||
|
else
|
||||||
|
provider.capture(payment_or_amount, account_or_response_code, :currency => preferred_currency)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def credit(amount, account, response_code, gateway_options)
|
||||||
|
provider.credit(amount, response_code, :currency => preferred_currency)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
def find_authorization(payment)
|
||||||
|
logs = payment.log_entries.all(:order => 'created_at DESC')
|
||||||
|
logs.each do |log|
|
||||||
|
details = YAML.load(log.details) # return the transaction details
|
||||||
|
if (details.params['payment_status'] == 'Pending' && details.params['pending_reason'] == 'authorization')
|
||||||
|
return details
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def find_capture(payment)
|
||||||
|
#find the transaction associated with the original authorization/capture
|
||||||
|
logs = payment.log_entries.all(:order => 'created_at DESC')
|
||||||
|
logs.each do |log|
|
||||||
|
details = YAML.load(log.details) # return the transaction details
|
||||||
|
if details.params['payment_status'] == 'Completed'
|
||||||
|
return details
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def amount_in_cents(amount)
|
||||||
|
(100 * amount).to_i
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
|
@ -6,46 +6,15 @@ class Spree::PaypalAccount < ActiveRecord::Base
|
||||||
%w{capture credit}
|
%w{capture credit}
|
||||||
end
|
end
|
||||||
|
|
||||||
def capture(payment)
|
|
||||||
authorization = find_authorization(payment)
|
|
||||||
|
|
||||||
ppx_response = payment.payment_method.provider.capture(amount_in_cents(payment.amount), authorization.params["transaction_id"], :currency => payment.payment_method.preferred_currency)
|
|
||||||
if ppx_response.success?
|
|
||||||
record_log payment, ppx_response
|
|
||||||
payment.complete
|
|
||||||
else
|
|
||||||
gateway_error(ppx_response.message)
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
def can_capture?(payment)
|
def can_capture?(payment)
|
||||||
!echeck?(payment) && payment.state == "pending"
|
!echeck?(payment) && payment.state == "pending"
|
||||||
end
|
end
|
||||||
|
|
||||||
def credit(payment, amount=nil)
|
|
||||||
authorization = find_capture(payment)
|
|
||||||
|
|
||||||
amount = payment.credit_allowed >= payment.order.outstanding_balance.abs ? payment.order.outstanding_balance : payment.credit_allowed
|
|
||||||
amount=amount.abs if amount
|
|
||||||
|
|
||||||
ppx_response = payment.payment_method.provider.credit(amount.nil? ? amount_in_cents(amount) : amount_in_cents(amount), authorization.params['transaction_id'], :currency => payment.payment_method.preferred_currency)
|
|
||||||
|
|
||||||
if ppx_response.success?
|
|
||||||
record_log payment, ppx_response
|
|
||||||
payment.update_attribute(:amount, payment.amount - amount)
|
|
||||||
payment.complete
|
|
||||||
payment.order.update!
|
|
||||||
else
|
|
||||||
gateway_error(ppx_response.message)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def can_credit?(payment)
|
def can_credit?(payment)
|
||||||
return false unless payment.state == "completed"
|
return false unless payment.state == "completed"
|
||||||
return false unless payment.order.payment_state == "credit_owed"
|
return false unless payment.order.payment_state == "credit_owed"
|
||||||
payment.credit_allowed > 0
|
payment.credit_allowed > 0
|
||||||
!find_capture(payment).nil?
|
!payment.payment_method.find_capture(payment).nil?
|
||||||
end
|
end
|
||||||
|
|
||||||
# fix for Payment#payment_profiles_supported?
|
# fix for Payment#payment_profiles_supported?
|
||||||
|
@ -64,43 +33,4 @@ class Spree::PaypalAccount < ActiveRecord::Base
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
def record_log(payment, response)
|
|
||||||
payment.log_entries.create(:details => response.to_yaml)
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
def find_authorization(payment)
|
|
||||||
logs = payment.log_entries.all(:order => 'created_at DESC')
|
|
||||||
logs.each do |log|
|
|
||||||
details = YAML.load(log.details) # return the transaction details
|
|
||||||
if (details.params['payment_status'] == 'Pending' && details.params['pending_reason'] == 'authorization')
|
|
||||||
return details
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
|
|
||||||
def find_capture(payment)
|
|
||||||
#find the transaction associated with the original authorization/capture
|
|
||||||
logs = payment.log_entries.all(:order => 'created_at DESC')
|
|
||||||
logs.each do |log|
|
|
||||||
details = YAML.load(log.details) # return the transaction details
|
|
||||||
if details.params['payment_status'] == 'Completed'
|
|
||||||
return details
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
|
|
||||||
def gateway_error(text)
|
|
||||||
msg = "#{I18n.t('gateway_error')} ... #{text}"
|
|
||||||
logger.error(msg)
|
|
||||||
raise Spree::Core::GatewayError.new(msg)
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def amount_in_cents(amount)
|
|
||||||
(100 * amount).to_i
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,108 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe Spree::BillingIntegration::PaypalExpressBase do
|
||||||
|
let(:order) do
|
||||||
|
order = Spree::Order.new(:bill_address => Spree::Address.new,
|
||||||
|
:ship_address => Spree::Address.new)
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:gateway) do
|
||||||
|
gateway = Spree::BillingIntegration::PaypalExpressBase.new({:environment => 'test', :active => true, :preferred_currency => "EUR"}, :without_protection => true)
|
||||||
|
gateway.stub :source_required => true
|
||||||
|
gateway.stub :provider => mock('paypal provider')
|
||||||
|
gateway.stub :find_authorization => mock('authorization', :params => authorization_params)
|
||||||
|
gateway
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:authorization_params) { {'transaction_id' => '123'} }
|
||||||
|
let(:provider) { gateway.provider }
|
||||||
|
|
||||||
|
let(:account) do
|
||||||
|
mock_model(Spree::PaypalAccount)
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:payment) do
|
||||||
|
payment = Spree::Payment.new
|
||||||
|
payment.source = account
|
||||||
|
payment.order = order
|
||||||
|
payment.payment_method = gateway
|
||||||
|
payment.amount = 10.0
|
||||||
|
payment
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:amount_in_cents) { payment.amount.to_f * 100 }
|
||||||
|
|
||||||
|
let!(:success_response) do
|
||||||
|
mock('success_response', :success? => true,
|
||||||
|
:authorization => '123',
|
||||||
|
:avs_result => { 'code' => 'avs-code' })
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:failed_response) { mock('gateway_response', :success? => false) }
|
||||||
|
|
||||||
|
before(:each) do
|
||||||
|
# So it doesn't create log entries every time a processing method is called
|
||||||
|
payment.log_entries.stub(:create)
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#capture" do
|
||||||
|
before { payment.state = 'pending' }
|
||||||
|
|
||||||
|
context "when payment_profiles_supported = true" do
|
||||||
|
before { gateway.stub :payment_profiles_supported? => true }
|
||||||
|
|
||||||
|
context "if sucessful" do
|
||||||
|
before do
|
||||||
|
provider.should_receive(:capture).with(amount_in_cents, '123', :currency => 'EUR').and_return(success_response)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should store the response_code" do
|
||||||
|
payment.capture!
|
||||||
|
payment.response_code.should == '123'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "if unsucessful" do
|
||||||
|
before do
|
||||||
|
gateway.should_receive(:capture).with(payment, account, anything).and_return(failed_response)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should not make payment complete" do
|
||||||
|
lambda { payment.capture! }.should raise_error(Spree::Core::GatewayError)
|
||||||
|
payment.state.should == "failed"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "when payment_profiles_supported = false" do
|
||||||
|
before do
|
||||||
|
payment.stub :response_code => '123'
|
||||||
|
gateway.stub :payment_profiles_supported? => false
|
||||||
|
end
|
||||||
|
|
||||||
|
context "if sucessful" do
|
||||||
|
before do
|
||||||
|
provider.should_receive(:capture).with(amount_in_cents, '123', anything).and_return(success_response)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should store the response_code" do
|
||||||
|
payment.capture!
|
||||||
|
payment.response_code.should == '123'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "if unsucessful" do
|
||||||
|
before do
|
||||||
|
provider.should_receive(:capture).with(amount_in_cents, '123', anything).and_return(failed_response)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should not make payment complete" do
|
||||||
|
lambda { payment.capture! }.should raise_error(Spree::Core::GatewayError)
|
||||||
|
payment.state.should == "failed"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
Loading…
Reference in New Issue