mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-02-27 01:43:22 +00:00
Payments can be refunded
This commit is contained in:
@@ -11,5 +11,42 @@ module Spree
|
||||
actions
|
||||
end
|
||||
alias_method_chain :actions, :pin_payment_adaptations
|
||||
|
||||
|
||||
def refund!(refund_amount=nil)
|
||||
protect_from_connection_error do
|
||||
check_environment
|
||||
|
||||
refund_amount = calculate_refund_amount(refund_amount)
|
||||
|
||||
if payment_method.payment_profiles_supported?
|
||||
response = payment_method.refund((refund_amount * 100).round, source, response_code, gateway_options)
|
||||
else
|
||||
response = payment_method.refund((refund_amount * 100).round, response_code, gateway_options)
|
||||
end
|
||||
|
||||
record_response(response)
|
||||
|
||||
if response.success?
|
||||
self.class.create({ :order => order,
|
||||
:source => self,
|
||||
:payment_method => payment_method,
|
||||
:amount => refund_amount.abs * -1,
|
||||
:response_code => response.authorization,
|
||||
:state => 'completed' }, :without_protection => true)
|
||||
else
|
||||
gateway_error(response)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
private
|
||||
|
||||
def calculate_refund_amount(refund_amount=nil)
|
||||
refund_amount ||= credit_allowed >= order.outstanding_balance.abs ? order.outstanding_balance.abs : credit_allowed.abs
|
||||
refund_amount.to_f
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
@@ -44,5 +44,85 @@ module Spree
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "refunding" do
|
||||
let(:payment) { create(:payment) }
|
||||
let(:success) { double(:success? => true, authorization: 'abc123') }
|
||||
let(:failure) { double(:success? => false) }
|
||||
|
||||
it "always checks the environment" do
|
||||
payment.payment_method.stub(:refund) { success }
|
||||
payment.should_receive(:check_environment)
|
||||
payment.refund!
|
||||
end
|
||||
|
||||
describe "calculating refund amount" do
|
||||
it "returns the parameter amount when given" do
|
||||
payment.send(:calculate_refund_amount, 123).should === 123.0
|
||||
end
|
||||
|
||||
it "refunds up to the value of the payment when the outstanding balance is larger" do
|
||||
payment.stub(:credit_allowed) { 123 }
|
||||
payment.stub(:order) { double(:order, outstanding_balance: 1000) }
|
||||
payment.send(:calculate_refund_amount).should == 123
|
||||
end
|
||||
|
||||
it "refunds up to the outstanding balance of the order when the payment is larger" do
|
||||
payment.stub(:credit_allowed) { 1000 }
|
||||
payment.stub(:order) { double(:order, outstanding_balance: 123) }
|
||||
payment.send(:calculate_refund_amount).should == 123
|
||||
end
|
||||
end
|
||||
|
||||
describe "performing refunds" do
|
||||
before do
|
||||
payment.stub(:calculate_refund_amount) { 123 }
|
||||
payment.payment_method.should_receive(:refund).and_return(success)
|
||||
end
|
||||
|
||||
it "performs the refund without payment profiles" do
|
||||
payment.payment_method.stub(:payment_profiles_supported?) { false }
|
||||
payment.refund!
|
||||
end
|
||||
|
||||
it "performs the refund with payment profiles" do
|
||||
payment.payment_method.stub(:payment_profiles_supported?) { true }
|
||||
payment.refund!
|
||||
end
|
||||
end
|
||||
|
||||
it "records the response" do
|
||||
payment.stub(:calculate_refund_amount) { 123 }
|
||||
payment.payment_method.stub(:refund).and_return(success)
|
||||
payment.should_receive(:record_response).with(success)
|
||||
payment.refund!
|
||||
end
|
||||
|
||||
it "records a payment on success" do
|
||||
payment.stub(:calculate_refund_amount) { 123 }
|
||||
payment.payment_method.stub(:refund).and_return(success)
|
||||
payment.stub(:record_response)
|
||||
|
||||
expect do
|
||||
payment.refund!
|
||||
end.to change(Payment, :count).by(1)
|
||||
|
||||
p = Payment.last
|
||||
p.order.should == payment.order
|
||||
p.source.should == payment
|
||||
p.payment_method.should == payment.payment_method
|
||||
p.amount.should == -123
|
||||
p.response_code.should == success.authorization
|
||||
p.state.should == 'completed'
|
||||
end
|
||||
|
||||
it "logs the error on failure" do
|
||||
payment.stub(:calculate_refund_amount) { 123 }
|
||||
payment.payment_method.stub(:refund).and_return(failure)
|
||||
payment.stub(:record_response)
|
||||
payment.should_receive(:gateway_error).with(failure)
|
||||
payment.refund!
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user