From c496d0f14d77a769aa37e70c2b4963b891a7d3d4 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Thu, 10 May 2018 17:49:13 +1000 Subject: [PATCH] Allow credit owed on payments made via stripe to be refunded via the admin section --- app/assets/stylesheets/admin/icons.css.scss | 1 + app/models/spree/gateway/stripe_connect.rb | 5 ++ .../spree/admin/payments_controller_spec.rb | 54 +++++++++++++++++++ 3 files changed, 60 insertions(+) diff --git a/app/assets/stylesheets/admin/icons.css.scss b/app/assets/stylesheets/admin/icons.css.scss index e7737ce8e9..9bd900d083 100644 --- a/app/assets/stylesheets/admin/icons.css.scss +++ b/app/assets/stylesheets/admin/icons.css.scss @@ -1,3 +1,4 @@ @import 'plugins/font-awesome'; .icon-refund:before { @extend .icon-ok:before } +.icon-credit:before { @extend .icon-ok:before } diff --git a/app/models/spree/gateway/stripe_connect.rb b/app/models/spree/gateway/stripe_connect.rb index 6efd2f79ef..e9e70671b2 100644 --- a/app/models/spree/gateway/stripe_connect.rb +++ b/app/models/spree/gateway/stripe_connect.rb @@ -43,6 +43,11 @@ module Spree provider.void(response_code, gateway_options) end + def credit(money, _creditcard, response_code, gateway_options) + gateway_options[:stripe_account] = stripe_account_id + provider.refund(money, response_code, gateway_options) + end + def create_profile(payment) return unless payment.source.gateway_customer_profile_id.nil? diff --git a/spec/controllers/spree/admin/payments_controller_spec.rb b/spec/controllers/spree/admin/payments_controller_spec.rb index 50edfc468a..7bf9e6e522 100644 --- a/spec/controllers/spree/admin/payments_controller_spec.rb +++ b/spec/controllers/spree/admin/payments_controller_spec.rb @@ -66,5 +66,59 @@ describe Spree::Admin::PaymentsController, type: :controller do end end end + + context "requesting a partial credit on a payment" do + let(:params) { { id: payment.id, order_id: order.number, e: :credit } } + + # Required for the respond override in the controller decorator to work + before { @request.env['HTTP_REFERER'] = spree.admin_order_payments_url(payment) } + + context "that was processed by stripe" do + let!(:payment_method) { create(:stripe_payment_method, distributors: [shop], preferred_enterprise_id: shop.id) } + let!(:payment) { create(:payment, order: order, state: 'completed', payment_method: payment_method, response_code: 'ch_1a2b3c', amount: order.total + 5) } + + + before do + allow(Stripe).to receive(:api_key) { "sk_test_12345" } + end + + context "where the request succeeds" do + before do + stub_request(:post, "https://sk_test_12345:@api.stripe.com/v1/charges/ch_1a2b3c/refunds"). + to_return(:status => 200, :body => JSON.generate(id: 're_123', object: 'refund', status: 'succeeded') ) + end + + it "partially refunds the payment" do + order.reload + expect(order.payment_total).to eq order.total + 5 + expect(order.outstanding_balance).to eq(-5) + spree_put :fire, params + expect(payment.reload.state).to eq 'completed' + order.reload + expect(order.payment_total).to eq order.total + expect(order.outstanding_balance).to eq 0 + end + end + + context "where the request fails" do + before do + stub_request(:post, "https://sk_test_12345:@api.stripe.com/v1/charges/ch_1a2b3c/refunds"). + to_return(:status => 200, :body => JSON.generate(error: { message: "Bup-bow!"}) ) + end + + it "does not void the payment" do + order.reload + expect(order.payment_total).to eq order.total + 5 + expect(order.outstanding_balance).to eq(-5) + spree_put :fire, params + expect(payment.reload.state).to eq 'completed' + order.reload + expect(order.payment_total).to eq order.total + 5 + expect(order.outstanding_balance).to eq -5 + expect(flash[:error]).to eq "Bup-bow!" + end + end + end + end end end