Add a :captured_at column on payments to store when they are captured

Fixes #8611.
This commit is contained in:
Cillian O'Ruanaidh
2021-12-17 12:18:53 +00:00
parent fd94f26765
commit 84eaafb822
13 changed files with 61 additions and 31 deletions

View File

@@ -89,6 +89,8 @@ module Spree
event :complete_authorization do
transition from: [:requires_authorization], to: :completed
end
after_transition to: :completed, do: :set_captured_at
end
def money
@@ -219,6 +221,10 @@ module Spree
OrderManagement::Order::Updater.new(order).after_payment_update(self)
end
def set_captured_at
update_column(:captured_at, Time.zone.now)
end
# Necessary because some payment gateways will refuse payments with
# duplicate IDs. We *were* using the Order number, but that's set once and
# is unchanging. What we need is a unique identifier on a per-payment basis,

View File

@@ -0,0 +1,5 @@
class AddCapturedAtToSpreePayments < ActiveRecord::Migration[6.1]
def change
add_column :spree_payments, :captured_at, :datetime
end
end

View File

@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 2021_10_29_174211) do
ActiveRecord::Schema.define(version: 2021_12_17_094141) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -597,6 +597,7 @@ ActiveRecord::Schema.define(version: 2021_10_29_174211) do
t.string "identifier", limit: 255
t.string "cvv_response_code", limit: 255
t.text "cvv_response_message"
t.datetime "captured_at"
t.index ["order_id"], name: "index_spree_payments_on_order_id"
end

View File

@@ -162,7 +162,7 @@ module OrderManagement
context "when the order has a payment that requires authorization and a completed payment" do
let!(:payment) { create(:payment, order: order, state: "requires_authorization") }
let!(:completed_payment) { create(:payment, order: order, state: "completed") }
let!(:completed_payment) { create(:payment, :completed, order: order) }
it "returns paid" do
updater.update_payment_state

View File

@@ -91,7 +91,7 @@ describe LineItemsController, type: :controller do
context "after a payment is captured" do
let(:payment) {
create(:check_payment, amount: order.total, order: order, state: 'completed')
create(:check_payment, :completed, amount: order.total, order: order)
}
before { payment.capture! }

View File

@@ -26,8 +26,8 @@ describe Spree::Admin::PaymentsController, type: :controller do
context "that was processed by stripe" do
let!(:payment_method) { create(:stripe_connect_payment_method, distributors: [shop]) }
let!(:payment) do
create(:payment, order: order, state: 'completed', payment_method: payment_method,
response_code: 'ch_1a2b3c', amount: order.total)
create(:payment, :completed, order: order, payment_method: payment_method,
response_code: 'ch_1a2b3c', amount: order.total)
end
before do
@@ -85,8 +85,8 @@ describe Spree::Admin::PaymentsController, type: :controller do
context "that was processed by stripe" do
let!(:payment_method) { create(:stripe_connect_payment_method, distributors: [shop]) }
let!(:payment) do
create(:payment, order: order, state: 'completed', payment_method: payment_method,
response_code: 'ch_1a2b3c', amount: order.total + 5)
create(:payment, :completed, order: order, payment_method: payment_method,
response_code: 'ch_1a2b3c', amount: order.total + 5)
end
before do
@@ -146,8 +146,8 @@ describe Spree::Admin::PaymentsController, type: :controller do
context "that was processed by stripe" do
let!(:payment_method) { create(:stripe_sca_payment_method, distributors: [shop]) }
let!(:payment) do
create(:payment, order: order, state: 'completed', payment_method: payment_method,
response_code: 'pi_123', amount: order.total)
create(:payment, :completed, order: order, payment_method: payment_method,
response_code: 'pi_123', amount: order.total)
end
let(:stripe_account) { create(:stripe_account, enterprise: shop) }
@@ -256,8 +256,8 @@ describe Spree::Admin::PaymentsController, type: :controller do
context "that was processed by stripe" do
let!(:payment_method) { create(:stripe_sca_payment_method, distributors: [shop]) }
let!(:payment) do
create(:payment, order: order, state: 'completed', payment_method: payment_method,
response_code: 'pi_123', amount: order.total + 5)
create(:payment, :completed, order: order, payment_method: payment_method,
response_code: 'pi_123', amount: order.total + 5)
end
before do

View File

@@ -48,7 +48,8 @@ FactoryBot.define do
payment_state { 'paid' }
shipment_state { 'ready' }
after(:create) do |order|
create(:payment, amount: order.total, order: order, state: 'completed')
create(:payment, :completed, amount: order.total, order: order)
order.shipments.each do |shipment|
shipment.inventory_units.each { |u| u.update_column('state', 'on_hand') }
shipment.update_column('state', 'ready')
@@ -174,8 +175,8 @@ FactoryBot.define do
end
after(:create) do |order, evaluator|
create(:payment, amount: order.total + evaluator.credit_amount, order: order,
state: "completed")
create(:payment, :completed, amount: order.total + evaluator.credit_amount, order: order)
order.reload
end
end

View File

@@ -19,6 +19,11 @@ FactoryBot.define do
payment_method { FactoryBot.create(:payment_method, distributors: [distributor]) }
end
trait :completed do
state { 'completed' }
captured_at { Time.zone.now }
end
factory :check_payment, class: Spree::Payment do
amount { 45.75 }
payment_method

View File

@@ -41,7 +41,7 @@ describe '
context "with one payment" do
let!(:payment1) do
create(:payment, order: order, state: 'completed', payment_method: payment_method1)
create(:payment, :completed, order: order, payment_method: payment_method1)
end
before do
order.save!
@@ -58,8 +58,9 @@ describe '
context "with two payments, and one that failed" do
before do
order.update payments: []
order.payments << create(:payment, order: order, state: 'completed',
payment_method: payment_method1, created_at: 1.day.ago)
order.payments << create(:payment, :completed, order: order,
payment_method: payment_method1,
created_at: 1.day.ago)
order.payments << create(:payment, order: order, state: 'failed',
payment_method: payment_method2, created_at: 2.days.ago)
order.save!
@@ -76,10 +77,12 @@ describe '
context "with two completed payments" do
before do
order.update payments: []
order.payments << create(:payment, order: order, state: 'completed',
payment_method: payment_method1, created_at: 2.days.ago)
order.payments << create(:payment, order: order, state: 'completed',
payment_method: payment_method2, created_at: 1.day.ago)
order.payments << create(:payment, :completed, order: order,
payment_method: payment_method1,
created_at: 2.days.ago)
order.payments << create(:payment, :completed, order: order,
payment_method: payment_method2,
created_at: 1.day.ago)
order.save!
end

View File

@@ -286,7 +286,7 @@ describe Spree::Payment do
# Regression test for #2119
context "when payment is completed" do
it "should do nothing" do
payment = build_stubbed(:payment, state: 'completed')
payment = build_stubbed(:payment, :completed)
expect(payment).to_not receive(:complete)
expect(payment.payment_method).to_not receive(:capture)
expect(payment.log_entries).to_not receive(:create)
@@ -569,7 +569,7 @@ describe Spree::Payment do
context "#save" do
context "completed payments" do
it "updates order payment total" do
payment = create(:payment, amount: 100, order: order, state: "completed")
payment = create(:payment, :completed, amount: 100, order: order)
expect(order.payment_total).to eq payment.amount
end
end
@@ -583,7 +583,7 @@ describe Spree::Payment do
end
context 'when the payment was completed but now void' do
let(:payment) { create(:payment, amount: 100, order: order, state: 'completed') }
let(:payment) { create(:payment, :completed, amount: 100, order: order) }
it 'updates order payment total' do
payment.void
@@ -672,7 +672,7 @@ describe Spree::Payment do
end
context 'when the payment was completed but now void' do
let(:payment) { create(:payment, amount: 100, order: order, state: 'completed') }
let(:payment) { create(:payment, :completed, amount: 100, order: order) }
it 'updates order payment total' do
payment.void
@@ -1009,4 +1009,13 @@ describe Spree::Payment do
expect(payment.cvv_response_message).to eq(nil)
end
end
describe "#complete" do
let(:payment) { build(:payment, state: "processing") }
it "sets :captured_at to the current time" do
payment.complete
expect(payment.captured_at).to be_present
end
end
end

View File

@@ -12,7 +12,7 @@ describe Api::OrderSerializer do
describe '#serializable_hash' do
let!(:completed_payment) do
create(:payment, order: order, state: 'completed', amount: order.total - 1)
create(:payment, :completed, order: order, amount: order.total - 1)
end
let!(:payment) { create(:payment, order: order, state: 'checkout', amount: 123.45) }

View File

@@ -8,7 +8,7 @@ describe OrderPaymentFinder do
context "when order has several non pending payments" do
let!(:failed_payment) { create(:payment, order: order, state: 'failed') }
let!(:complete_payment) { create(:payment, order: order, state: 'completed') }
let!(:complete_payment) { create(:payment, :completed, order: order) }
it "#last_payment returns the last payment" do
expect(finder.last_payment).to eq complete_payment

View File

@@ -119,8 +119,8 @@ describe 'Customers' do
create(:stripe_sca_payment_method, distributors: [managed_distributor1])
}
let!(:payment1) {
create(:payment, order: order1, state: 'completed', payment_method: payment_method,
response_code: 'pi_123', amount: 88.00)
create(:payment, :completed, order: order1, payment_method: payment_method,
response_code: 'pi_123', amount: 88.00)
}
before do
@@ -149,8 +149,8 @@ describe 'Customers' do
context "with an additional negative payment (or refund)" do
let!(:payment2) {
create(:payment, order: order1, state: 'completed', payment_method: payment_method,
response_code: 'pi_123', amount: -25.00)
create(:payment, :completed, order: order1, payment_method: payment_method,
response_code: 'pi_123', amount: -25.00)
}
before do