diff --git a/.gitignore b/.gitignore index 094d3e7..202c883 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ Gemfile.lock coverage .ruby-version pkg +.env diff --git a/Gemfile b/Gemfile index 4e30e9d..36e521c 100644 --- a/Gemfile +++ b/Gemfile @@ -3,8 +3,15 @@ source "https://rubygems.org" branch = ENV.fetch('SOLIDUS_BRANCH', 'master') gem "solidus", github: "solidusio/solidus", branch: branch +# ActiveMerchant v1.58 through v1.59 introduced a breaking change +# to the stripe gateway. +# +# This was resolved in v1.60, but we still need to skip 1.58 & 1.59. +gem "activemerchant", "~> 1.48", "!= 1.58.0", "!= 1.59.0", github: "dynamomtl/active_merchant_new", branch: 'feature/shopify/prototype-implementation' + group :development, :test do gem "pry-rails" + gem "dotenv-rails", require: 'dotenv/rails-now' end gem 'pg' diff --git a/app/models/spree/gateway/shopify_gateway.rb b/app/models/spree/gateway/shopify_gateway.rb new file mode 100644 index 0000000..934f090 --- /dev/null +++ b/app/models/spree/gateway/shopify_gateway.rb @@ -0,0 +1,46 @@ +module Spree + class Gateway::ShopifyGateway < Gateway + preference :api_key, :string + preference :password, :string + preference :shop_name, :string + + def provider_class + ActiveMerchant::Billing::ShopifyGateway + end + + def method_type + 'shopify' + end + + def credit(money, transaction_id, gateway_options) + refund = gateway_options[:originator] + options = { order_id: refund.pos_order_id, reason: refund.reason.name } + provider.refund(money, transaction_id, options) + end + + def void(transaction_id, gateway_options) + pos_order_id = gateway_options[:originator].pos_order_id + provider.void(transaction_id, order_id: pos_order_id) + end + + def cancel(_transaction_id) + raise NotImplementedError + end + + def purchase(_money, _creditcard, _gateway_options) + raise NotImplementedError + end + + def authorize(_money, _creditcard, _gateway_options) + raise NotImplementedError + end + + def capture(_money, _response_code, _gateway_options) + raise NotImplementedError + end + + def create_profile(_payment) + raise NotImplementedError + end + end +end diff --git a/lib/spree_gateway/engine.rb b/lib/spree_gateway/engine.rb index 6f00024..629e95d 100644 --- a/lib/spree_gateway/engine.rb +++ b/lib/spree_gateway/engine.rb @@ -28,6 +28,7 @@ class Engine < Rails::Engine app.config.spree.payment_methods << Spree::Gateway::Paymill app.config.spree.payment_methods << Spree::Gateway::PayflowPro app.config.spree.payment_methods << Spree::Gateway::SecurePayAU + app.config.spree.payment_methods << Spree::Gateway::ShopifyGateway app.config.spree.payment_methods << Spree::Gateway::Maxipago app.config.spree.payment_methods << Spree::Gateway::Migs app.config.spree.payment_methods << Spree::Gateway::SpreedlyCoreGateway diff --git a/solidus_gateway.gemspec b/solidus_gateway.gemspec index 0eb62f1..628cca3 100644 --- a/solidus_gateway.gemspec +++ b/solidus_gateway.gemspec @@ -11,7 +11,7 @@ Gem::Specification.new do |s| s.version = SolidusGateway::VERSION s.summary = "Additional Payment Gateways for Solidus" s.description = s.summary - s.required_ruby_version = ">= 2.1" + s.required_ruby_version = ">= 2.3" s.author = "Solidus Team" s.email = "contact@solidus.io" @@ -25,12 +25,6 @@ Gem::Specification.new do |s| s.add_dependency "solidus_core", "~> 1.1" - # ActiveMerchant v1.58 through v1.59 introduced a breaking change - # to the stripe gateway. - # - # This was resolved in v1.60, but we still need to skip 1.58 & 1.59. - s.add_dependency "activemerchant", "~> 1.48", "!= 1.58.0", "!= 1.59.0" - s.add_development_dependency "braintree", "~> 2.0" s.add_development_dependency "rspec-rails", "~> 3.2" s.add_development_dependency "simplecov" @@ -41,4 +35,7 @@ Gem::Specification.new do |s| s.add_development_dependency "capybara" s.add_development_dependency "poltergeist", "~> 1.9" s.add_development_dependency "database_cleaner", "1.2.0" + + s.add_development_dependency "shopify_api", "~> 4.0" + # s.add_development_dependency "dotenv-rails" end diff --git a/spec/models/gateway/shopify_gateway_spec.rb b/spec/models/gateway/shopify_gateway_spec.rb new file mode 100644 index 0000000..1f0fb10 --- /dev/null +++ b/spec/models/gateway/shopify_gateway_spec.rb @@ -0,0 +1,63 @@ +require 'spec_helper' + +describe Spree::Gateway::ShopifyGateway do + let(:transaction_id) { '0xDEADBEEF' } + let(:pos_order_id) { '0xBAADF00D' } + let(:refund) { double('refund', pos_order_id: pos_order_id) } + let(:refund_reason) { double('refund_reason', name: 'Product not working') } + let(:gateway_options) { { originator: refund } } + + let(:provider_class) { ActiveMerchant::Billing::ShopifyGateway } + let(:provider_instance) { double('provider', refund: true, void: true) } + + before do + subject.preferences = { api_key: ENV['SHOPIFY_API_KEY'], + password: ENV['SHOPIFY_PASSWORD'], + shop_name: ENV['SHOPIFY_SHOP_NAME'] } + allow(provider_class).to receive(:new).and_return(provider_instance) + end + + context '.void' do + it 'calls the provider void method once' do + expect(provider_instance).to receive(:void).once + void! + end + + private + + def void! + subject.void(transaction_id, gateway_options) + end + end + + context '.cancel' do + it 'throws an error because it\'s not implemented' do + expect { cancel! }.to raise_error(NotImplementedError) + end + + private + + def cancel! + subject.cancel(transaction_id) + end + end + + context '.credit' do + let(:amount_in_cents) { '100' } + + before do + allow(refund).to receive(:reason).and_return(refund_reason) + end + + it 'calls the provider refund method once' do + expect(provider_instance).to receive(:refund).once + refund! + end + + private + + def refund! + subject.credit(amount_in_cents, transaction_id, originator: refund) + end + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 72f8644..19d056c 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -17,6 +17,7 @@ require "database_cleaner" require "braintree" require "ffaker" +require "dotenv-rails" require "spree/testing_support/factories" require "spree/testing_support/order_walkthrough"