Skip to content

Commit

Permalink
allow stripe connect options when create intent
Browse files Browse the repository at this point in the history
  • Loading branch information
ccarruitero committed Feb 24, 2022
1 parent 694d7e5 commit 99a75af
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 7 deletions.
12 changes: 5 additions & 7 deletions app/controllers/solidus_stripe/intents_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,16 +50,14 @@ def generate_payment_response
end

def create_payment_intent
intent_options = SolidusStripe::PrepareOptionsForIntentService.call(
current_order,
stripe
)
stripe.create_intent(
(current_order.total * 100).to_i,
params[:stripe_payment_method_id],
description: "Solidus Order ID: #{current_order.number} (pending)",
currency: current_order.currency,
confirmation_method: 'automatic',
capture_method: 'manual',
confirm: true,
setup_future_usage: 'off_session',
metadata: { order_id: current_order.id }
intent_options
)
end
end
Expand Down
52 changes: 52 additions & 0 deletions app/models/solidus_stripe/prepare_options_for_intent_service.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# frozen_string_literal: true

module SolidusStripe
class PrepareOptionsForIntentService
attr_reader :order, :payment_method

def self.call(...)
new(...).call
end

def initialize(order, payment_method)
@order = order
@payment_method = payment_method
end

def call
options = {
description: "Solidus Order ID: #{order.number} (pending)",
currency: order.currency,
confirmation_method: 'automatic',
capture_method: 'manual',
confirm: true,
setup_future_usage: 'off_session',
metadata: { order_id: order.id },
}
options.merge!(connect_options) if payment_method.preferred_stripe_connect
options
end

private

def connect_options
return unless payment_method.preferred_stripe_connect

opts = {
application_fee_amount: SolidusStripe.configuration.application_fee
}

case payment_method.preferred_connected_mode
when 'direct_charge'
opts.merge!(stripe_account: connected_account)
when 'destination_charge'
opts.merge!(transfer_data: { destination: connected_account })
end
opts
end

def connected_account
payment_method.preferred_connected_account
end
end
end
3 changes: 3 additions & 0 deletions app/models/spree/payment_method/stripe_credit_card.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ class StripeCreditCard < Spree::PaymentMethod::CreditCard
preference :stripe_country, :string
preference :v3_elements, :boolean
preference :v3_intents, :boolean
preference :stripe_connect, :boolean
preference :connected_mode, :string, default: 'direct_charge'
preference :connected_account, :string

CARD_TYPE_MAPPING = {
'American Express' => 'american_express',
Expand Down
1 change: 1 addition & 0 deletions lib/solidus_stripe/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ class Configuration
# Define here the settings for this extensions, e.g.:
#
# attr_accessor :my_setting
attr_accessor :application_fee
end

class << self
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe SolidusStripe::PrepareOptionsForIntentService do
let(:order) { create(:order_with_line_items) }
let(:payment_method) {
Spree::PaymentMethod::StripeCreditCard.create(
name: 'Stripe',
preferred_secret_key: 'secret',
preferred_publishable_key: 'published',
preferred_stripe_connect: stripe_connect,
preferred_connected_account: 'connect_account',
preferred_connected_mode: connected_mode
)
}
let(:connected_mode) { 'direct_charge' }
let(:service) { described_class.new(order, payment_method) }
let(:intent_options) { service.call }

context 'without stripe connect' do
let(:stripe_connect) { false }

it 'dont has any connect attributes' do
expect(intent_options[:application_fee]).to be_nil
end
end

context 'with stripe connect' do
let(:stripe_connect) { true }

before do
SolidusStripe.configure do |app|
app.application_fee = 5
end
end

it 'has application_fee option' do
expect(intent_options[:application_fee_amount]).to eq(5)
end

it 'has stripe_account option' do
expect(intent_options[:stripe_account]).to eq('connect_account')
end

context 'with destination_charge mode' do
let(:connected_mode) { 'destination_charge' }

it 'has transfer_destionation option' do
expect(intent_options[:transfer_data][:destination]).to eq('connect_account')
end

it 'doesnt have stripe_account option' do
expect(intent_options[:stripe_account]).to be_nil
end
end
end
end

0 comments on commit 99a75af

Please sign in to comment.