Skip to content

Commit

Permalink
Add StripeCreditCard#try_void
Browse files Browse the repository at this point in the history
This method is now the preferred way in Solidus for canceling a payment
and supersedes the old #cancel method.

If a payment for a Payment Intent was captured, it cannot be cancelled
anymore, but needs to be refunded.
For this refund we're using the default order cancel reason named after
`Spree::Payment::Cancellation::DEFAULT_REASON`.
  • Loading branch information
spaghetticode committed May 18, 2020
1 parent 09a2633 commit b0b1a8d
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 1 deletion.
15 changes: 15 additions & 0 deletions app/models/spree/payment_method/stripe_credit_card.rb
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,21 @@ def void(response_code, _creditcard, _transaction_options)
gateway.void(response_code, {})
end

def payment_intents_refund_reason
Spree::RefundReason.where(name: Spree::Payment::Cancellation::DEFAULT_REASON).first_or_create
end

def try_void(payment)
if v3_intents? && payment.completed?
payment.refunds.create!(
amount: payment.credit_allowed,
reason: payment_intents_refund_reason
).response
else
payment.void_transaction!
end
end

def cancel(response_code)
gateway.void(response_code, {})
end
Expand Down
45 changes: 44 additions & 1 deletion spec/models/spree/payment_method/stripe_credit_card_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@
let(:payment) {
double('Spree::Payment',
source: source,
order: order
order: order,
amount: order.total
)
}

Expand Down Expand Up @@ -241,4 +242,46 @@
expect(gateway).to receive(:capture).with(9855, '12345', anything).and_return(success_response)
end
end

describe '#try_void' do
let(:payment) { create :payment, amount: order.total }

shared_examples 'voids the payment transaction' do
it 'voids the payment transaction' do
expect(payment).to receive(:void_transaction!)

subject.try_void(payment)
end
end

context 'when using Payment Intents' do
before { subject.preferred_v3_intents = true }

context 'when the payment is completed' do
before do
allow(payment).to receive(:completed?) { true }
end

it 'creates a refund' do
expect { subject.try_void(payment) }.to change { Spree::Refund.count }.by(1)
end
end

context 'when the payment is not completed' do
it_behaves_like 'voids the payment transaction'
end
end

context 'when not using Payment Intents' do
before { subject.preferred_v3_intents = false }

context 'when the payment is completed' do
it_behaves_like 'voids the payment transaction'
end

context 'when the payment is not completed' do
it_behaves_like 'voids the payment transaction'
end
end
end
end

0 comments on commit b0b1a8d

Please sign in to comment.