Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

allow stripe connect options when create intent #121

Open
wants to merge 1 commit into
base: v4
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 extension, 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