Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
damianlegawiec committed Oct 28, 2021
1 parent 4a984e7 commit cde713b
Show file tree
Hide file tree
Showing 5 changed files with 197 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,7 @@ def update
end

def create_payment
result = create_payment_service.call(
order: spree_current_order,
params: params,
user: spree_current_user
)
result = create_payment_service.call(order: spree_current_order, params: params)

if result.success?
render_serialized_payload(201) { payment_serializer.new(result.value).serializable_hash }
Expand Down
40 changes: 20 additions & 20 deletions core/app/services/spree/payments/create.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,46 @@ module Payments
class Create
prepend Spree::ServiceModule::Base

def call(order:, params: {}, user: nil)
def call(order:, params: {})
ApplicationRecord.transaction do
run :prepare_payment_attributes
run :prepare_source_attributes
run :find_or_create_payment_source
run :save_payment
end
end

protected

def prepare_payment_attributes(order:, params:, user: nil)
def prepare_payment_attributes(order:, params:)
payment_attributes = {
amount: params[:amount] || order.total - order.payment_total,
payment_method: order.available_payment_methods.find { |pm| pm.id.to_s == params[:payment_method_id]&.to_s }
}

success(order: order, params: params, user: user, payment_attributes: payment_attributes)
success(order: order, params: params, payment_attributes: payment_attributes)
end

def prepare_source_attributes(order:, params:, payment_attributes:, user: nil)
def find_or_create_payment_source(order:, params:, payment_attributes:)
payment_method = payment_attributes[:payment_method]

if payment_method&.source_required?
if user.present? && params[:source_id].present?
payment_attributes[:source] = payment_method.payment_source_class.find_by(id: params[:source_id])
if order.user.present? && params[:source_id].present?
source = payment_method.payment_source_class.find_by(id: params[:source_id])

return failure(:source_not_found) if source.nil?
else
payment_attributes[:source_attributes] = params.permit(permitted_source_attributes).merge(user_id: user&.id)
result = Spree::Wallet::CreatePaymentSource.call(
payment_method: payment_method,
params: params.delete(:source_attributes),
user: order.user
)

return failure(result.error) if result.failure?

source = result.value
end

payment_attributes[:source] = source
end

success(order: order, payment_attributes: payment_attributes)
Expand All @@ -44,18 +56,6 @@ def save_payment(order:, payment_attributes:)
failure(payment)
end
end

def permitted_source_attributes
%i[
payment_method_id
gateway_payment_profile_id
gateway_customer_profile_id
last_digits
month
year
name
]
end
end
end
end
25 changes: 25 additions & 0 deletions core/app/services/spree/wallet/create_payment_source.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
module Spree
module Wallet
class CreatePaymentSource
prepend Spree::ServiceModule::Base

def call(payment_method:, params: {}, user: nil)
return failure(:missing_attributes) if params.nil?

source_attributes = {
user_id: user&.id,
gateway_payment_profile_id: params[:gateway_payment_profile_id],
gateway_customer_profile_id: params[:gateway_customer_profile_id],
last_digits: params[:last_digits],
month: params[:month],
year: params[:year],
name: params[:name]
}

source = payment_method.payment_source_class.new(source_attributes)

source.save ? success(source) : failure(source)
end
end
end
end
94 changes: 94 additions & 0 deletions core/spec/services/spree/payments/create_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
require 'spec_helper'

module Spree
describe Payments::Create do
subject { described_class }

let(:store) { create(:store) }
let(:order) { create(:order_with_totals, store: store, user: nil, email: 'john@snow.org') }

let(:execute) { subject.call(order: order, params: params) }
let(:value) { execute.value }

let(:params) do
{
payment_method_id: payment_method.id,
amount: order.total,
source_attributes: {
gateway_payment_profile_id: '12345',
cc_type: 'visa',
last_digits: '1111',
name: 'John',
month: '12',
year: '2021'
}
}
end

let!(:payment_method) { create(:credit_card_payment_method, stores: [store]) }
let(:payment_source) { payment_method.payment_source_class.last }
let(:payment) { order.payments.last }

context 'valid attributes' do
shared_context 'creates a payment' do
it 'creates new payment record' do
expect { execute }.to change(order.payments, :count).by(1)
expect(payment.payment_method).to eq(payment_method)
end
end

shared_context 'creates a payment source' do
it 'creates new payment source record' do
expect { execute }.to change(payment_method.payment_source_class, :count).by(1)
expect(payment.payment_source).to eq(payment_source)
end
end

context 'with new source attributes' do
include_context 'creates a payment'
include_context 'creates a payment source'

context 'with user' do
let(:user) { create(:user) }
let(:order) { create(:order_with_totals, store: store, user: user) }

include_context 'creates a payment'
include_context 'creates a payment source'

context 'assigns user' do
before { execute }

it { expect(payment_source.user).to eq(user) }
end
end
end

context 'with existing source' do
let(:payment_source) { create(:credit_card, payment_method: payment_method) }
let(:params) do
{
payment_method_id: payment_method.id,
amount: order.total,
source_id: payment_source.id
}
end

include_context 'creates a payment'

it { expect { execute }.not_to change(payment_method.payment_source_class, :count) }
end

context 'without source' do

end
end

context 'missing payment method' do

end

context 'invalid attributes' do

end
end
end
57 changes: 57 additions & 0 deletions core/spec/services/spree/wallet/create_payment_source_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
require 'spec_helper'

module Spree
describe Wallet::CreatePaymentSource do
subject { described_class }

let(:store) { create(:store) }

let(:execute) { subject.call(payment_method: payment_method, params: params) }
let(:value) { execute.value }

let(:params) do
{
gateway_payment_profile_id: '12345',
cc_type: 'visa',
last_digits: '1111',
name: 'John',
month: '12',
year: '2021'
}
end

let!(:payment_method) { create(:credit_card_payment_method, stores: [store]) }
let(:payment_source) { payment_method.payment_source_class.last }

context 'valid attributes' do
shared_context 'creates a payment source' do
before { execute }

it 'creates new payment source record' do
expect { change(payment_method.payment_source_class, :count).by(1) }
end

it 'returns newly created record in .value' do
expect(execute.value).to be_kind_of(payment_method.payment_source_class)
end
end

context 'with source attributes' do
include_context 'creates a payment source'

context 'with user' do
let(:user) { create(:user) }
let(:execute) { subject.call(payment_method: payment_method, params: params, user: user) }

include_context 'creates a payment source'

context 'assigns user' do
before { execute }

it { expect(payment_source.user).to eq(user) }
end
end
end
end
end
end

0 comments on commit cde713b

Please sign in to comment.