Skip to content
This repository has been archived by the owner on Sep 10, 2019. It is now read-only.

Commit

Permalink
extracted gateways out of Spree
Browse files Browse the repository at this point in the history
  • Loading branch information
cmar committed Dec 19, 2011
0 parents commit c20c3f6
Show file tree
Hide file tree
Showing 29 changed files with 1,036 additions and 0 deletions.
10 changes: 10 additions & 0 deletions .gitignore
@@ -0,0 +1,10 @@
\#*
*~
.#*
.DS_Store
.idea
.project
tmp
nbproject
*.swp
spec/dummy
1 change: 1 addition & 0 deletions .rspec
@@ -0,0 +1 @@
--colour
13 changes: 13 additions & 0 deletions Gemfile
@@ -0,0 +1,13 @@
source 'http://rubygems.org'

group :test do
gem 'ffaker'
end

if RUBY_VERSION < "1.9"
gem "ruby-debug"
else
gem "ruby-debug19"
end

gemspec
26 changes: 26 additions & 0 deletions LICENSE
@@ -0,0 +1,26 @@
Copyright (c) 2011 Spree Commerce
All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name Spree nor the names of its contributors may be used to
endorse or promote products derived from this software without specific
prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 changes: 29 additions & 0 deletions README.md
@@ -0,0 +1,29 @@
SpreeGateway
============

Community supported Spree Payment Method Gateways.

These can be used with Spree 1.0.x

http://guides.spreecommerce.com/payment_gateways.html

Installation
=======

In your gemfile:

gem 'spree'
gem 'spree_gateway' # make sure to include after spree

bundle install

Testing
-------

Be sure to bundle your dependencies and then create a dummy test app for the specs to run against.

$ bundle
$ bundle exec rake test app
$ bundle exec rspec spec

Copyright (c) 2011 Spree Commerce, released under the New BSD License
29 changes: 29 additions & 0 deletions Rakefile
@@ -0,0 +1,29 @@
require 'rake'
require 'rake/testtask'
require 'rake/packagetask'
require 'rubygems/package_task'
require 'rspec/core/rake_task'
require 'spree/core/testing_support/common_rake'

RSpec::Core::RakeTask.new

task :default => [:spec]

spec = eval(File.read('spree_gateway.gemspec'))

Gem::PackageTask.new(spec) do |p|
p.gem_spec = spec
end

desc "Release to gemcutter"
task :release => :package do
require 'rake/gemcutter'
Rake::Gemcutter::Tasks.new(spec).define
Rake::Task['gem:push'].invoke
end

desc "Generates a dummy app for testing"
task :test_app do
ENV['LIB_NAME'] = 'spree_gateway'
Rake::Task['common:test_app'].invoke
end
9 changes: 9 additions & 0 deletions Versionfile
@@ -0,0 +1,9 @@
# This file is used to designate compatibilty with different versions of Spree
# Please see http://spreecommerce.com/documentation/extensions.html#versionfile for details

# Examples
#
# "0.70.x" => { :branch => "master"}
# "0.60.x" => { :branch => "0-60-stable" }
# "0.40.x" => { :tag => "v1.0.0", :version => "1.0.0" }

21 changes: 21 additions & 0 deletions app/models/spree/gateway/authorize_net.rb
@@ -0,0 +1,21 @@
module Spree
class Gateway::AuthorizeNet < Gateway
preference :login, :string
preference :password, :string

def provider_class
ActiveMerchant::Billing::AuthorizeNetGateway
end

def options
# add :test key in the options hash, as that is what the ActiveMerchant::Billing::AuthorizeNetGateway expects
if self.preferred_test_mode
self.class.preference :test, :boolean, :default => true
else
self.class.remove_preference :test
end

super
end
end
end
131 changes: 131 additions & 0 deletions app/models/spree/gateway/authorize_net_cim.rb
@@ -0,0 +1,131 @@
module Spree
class Gateway::AuthorizeNetCim < Gateway
preference :login, :string
preference :password, :string
preference :test_mode, :boolean, :default => false
preference :validate_on_profile_create, :boolean, :default => false

ActiveMerchant::Billing::Response.class_eval do
attr_writer :authorization
end

def provider_class
self.class
end

def options
# add :test key in the options hash, as that is what the ActiveMerchant::Billing::AuthorizeNetGateway expects
if self.preferred_test_mode
self.class.preference :test, :boolean, :default => true
else
self.class.remove_preference :test
end

super
end

def authorize(amount, creditcard, gateway_options)
create_transaction(amount, creditcard, :auth_only)
end

def purchase(amount, creditcard, gateway_options)
create_transaction(amount, creditcard, :auth_capture)
end

def capture(authorization, creditcard, gateway_options)
create_transaction((authorization.amount * 100).round, creditcard, :prior_auth_capture, :trans_id => authorization.response_code)
end

def credit(amount, creditcard, response_code, gateway_options)
create_transaction(amount, creditcard, :refund, :trans_id => response_code)
end

def void(response_code, creditcard, gateway_options)
create_transaction(nil, creditcard, :void, :trans_id => response_code)
end

def payment_profiles_supported?
true
end

# Create a new CIM customer profile ready to accept a payment
def create_profile(payment)
if payment.source.gateway_customer_profile_id.nil?
profile_hash = create_customer_profile(payment)
payment.source.update_attributes(:gateway_customer_profile_id => profile_hash[:customer_profile_id], :gateway_payment_profile_id => profile_hash[:customer_payment_profile_id])
end
end

# simpler form
def create_profile_from_card(card)
if card.gateway_customer_profile_id.nil?
profile_hash = create_customer_profile(card)
card.update_attributes(:gateway_customer_profile_id => profile_hash[:customer_profile_id], :gateway_payment_profile_id => profile_hash[:customer_payment_profile_id])
end
end

private
# Create a transaction on a creditcard
# Set up a CIM profile for the card if one doesn't exist
# Valid transaction_types are :auth_only, :capture_only and :auth_capture
def create_transaction(amount, creditcard, transaction_type, options = {})
#create_profile(creditcard, creditcard.gateway_options)
creditcard.save
if amount
amount = "%.2f" % (amount / 100.0) # This gateway requires formated decimal, not cents
end
transaction_options = {
:type => transaction_type,
:amount => amount,
:customer_profile_id => creditcard.gateway_customer_profile_id,
:customer_payment_profile_id => creditcard.gateway_payment_profile_id,
}.update(options)
t = cim_gateway.create_customer_profile_transaction(:transaction => transaction_options)
logger.debug("\nAuthorize Net CIM Transaction")
logger.debug(" transaction_options: #{transaction_options.inspect}")
logger.debug(" response: #{t.inspect}\n")
t
end

# Create a new CIM customer profile ready to accept a payment
def create_customer_profile(payment)
options = options_for_create_customer_profile(payment)
response = cim_gateway.create_customer_profile(options)
if response.success?
{ :customer_profile_id => response.params['customer_profile_id'],
:customer_payment_profile_id => response.params['customer_payment_profile_id_list'].values.first }
else
payment.gateway_error(response) if payment.respond_to? :gateway_error
payment.source.gateway_error(response)
end
end

def options_for_create_customer_profile(payment)
if payment.is_a? Creditcard
info = { :bill_to => generate_address_hash(payment.address), :payment => { :credit_card => payment } }
else
info = { :bill_to => generate_address_hash(payment.order.bill_address),
:payment => { :credit_card => payment.source } }
end
validation_mode = preferred_validate_on_profile_create ? preferred_server.to_sym : :none

{ :profile => { :merchant_customer_id => "#{Time.now.to_f}",
#:ship_to_list => generate_address_hash(creditcard.checkout.ship_address),
:payment_profiles => info },
:validation_mode => validation_mode }
end

# As in PaymentGateway but with separate name fields
def generate_address_hash(address)
return {} if address.nil?
{:first_name => address.firstname, :last_name => address.lastname, :address1 => address.address1, :address2 => address.address2, :city => address.city,
:state => address.state_text, :zip => address.zipcode, :country => address.country.iso, :phone => address.phone}
end

def cim_gateway
ActiveMerchant::Billing::Base.gateway_mode = preferred_server.to_sym
gateway_options = options
ActiveMerchant::Billing::AuthorizeNetCimGateway.new(gateway_options)
end
end
end

0 comments on commit c20c3f6

Please sign in to comment.