Skip to content

Commit

Permalink
Initial extraction
Browse files Browse the repository at this point in the history
Re-organized code & flattened out namespace.
  • Loading branch information
ntalbott committed Jun 3, 2014
0 parents commit abd025e
Show file tree
Hide file tree
Showing 249 changed files with 21,693 additions and 0 deletions.
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.yardoc
pkg
*.gem

# ignore Gemfile.lock because we support multiple versions of Rails and
# don't want to ship locked version requirements
Gemfile.lock
Gemfile*.lock
17 changes: 17 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
rvm:
- 2.1.0
- 2.0.0
- 1.9.3

gemfile:
- Gemfile
- Gemfile_rails40
- Gemfile_rails31
- Gemfile_rails30

script: "bundle exec rake test:units"

notifications:
email:
- payments-dev@shopify.com
- nathaniel@talbott.ws
1 change: 1 addition & 0 deletions .yardopts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- README.md
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Offsite Payments CHANGELOG

* Extracted from ActiveMerchant [ntalbott]
8 changes: 8 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
source 'https://rubygems.org'
gemspec

gem 'builder', '~> 3.0'
gem 'activesupport', '~> 3.2'
gem 'rails', '~> 3.2'

eval File.read(File.expand_path("../Gemfile_common", __FILE__))
12 changes: 12 additions & 0 deletions Gemfile_common
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
group :test do
gem 'json-jruby', :platforms => :jruby
gem 'jruby-openssl', :platforms => :jruby
end

group :remote_test do
gem 'mechanize'
gem 'launchy'
gem 'mongrel', '1.2.0.pre2', :platforms => :ruby
end

gem 'money', '5.0.0', :platforms => [:ruby_18]
20 changes: 20 additions & 0 deletions MIT-LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
Copyright (c) 2005-2014 Tobias Luetke

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
70 changes: 70 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Offsite Payments
[![Build Status](https://travis-ci.org/Shopify/offsite_payments.png?branch=master)](https://travis-ci.org/Shopify/offsite_payments)
[![Code Climate](https://codeclimate.com/github/Shopify/offsite_payments.png)](https://codeclimate.com/github/Shopify/offsite_payments)

Offsite Payments is an extraction from the ecommerce system [Shopify](http://www.shopify.com). Shopify's requirements for a simple and unified API to handle dozens of different offsite payment pages (often called hosted payment pages) with very different exposed APIs was the chief principle in designing the library.

It was developed for usage in Ruby on Rails web applications and integrates seamlessly
as a Rails plugin. It should also work as a stand alone Ruby library, but much of the benefit is in the ActionView helpers which are Rails-specific.

Offsite Payments has been in production use (originally as part of the [ActiveMerchant](https://github.com/Shopify/active_merchant) project) since June 2006. It is maintained by the [Shopify](http://www.shopify.com) team, with much help from an ever-growing set of contributors.

## Installation

### From Git

You can check out the latest source from git:

git clone https://github.com/Shopify/offsite_payments.git

### From RubyGems

Installation from RubyGems:

gem install offsite_payments

Or, if you're using Bundler, just add the following to your Gemfile:

gem 'offsite_payments'

[API documentation](http://rubydoc.info/github/Shopify/offsite_payments/master/file/README.md).

## Supported Integrations

* [2 Checkout](http://www.2checkout.com)
* [A1Agregator](http://a1agregator.ru/) - RU
* [Authorize.Net SIM](http://developer.authorize.net/api/sim/) - US
* [Banca Sella GestPay](https://www.gestpay.it/)
* [Chronopay](http://www.chronopay.com)
* [DirecPay](http://www.timesofmoney.com/direcpay/jsp/home.jsp)
* [Direct-eBanking / sofortueberweisung.de by Payment-Networks AG](https://www.payment-network.com/deb_com_en/merchantarea/home) - DE, AT, CH, BE, UK, NL
* [Dotpay](http://dotpay.pl)
* [Doku](http://doku.com)
* [Dwolla](https://www.dwolla.com/default.aspx)
* [ePay](http://www.epay.dk/epay-payment-solutions/)
* [First Data](https://firstdata.zendesk.com/entries/407522-first-data-global-gateway-e4sm-payment-pages-integration-manual)
* [HiTRUST](http://www.hitrust.com.hk/)
* [Moneybookers](http://www.moneybookers.com)
* [Nochex](http://www.nochex.com)
* [PagSeguro](http://www.pagseguro.com.br/) - BR
* [Paxum](https://www.paxum.com/)
* [PayPal Website Payments Standard](https://www.paypal.com/cgi-bin/webscr?cmd#_wp-standard-overview-outside)
* [Paysbuy](https://www.paysbuy.com/) - TH
* [Platron](https://www.platron.ru/) - RU
* [RBK Money](https://rbkmoney.ru/) - RU
* [Robokassa](http://robokassa.ru/) - RU
* [SagePay Form](http://www.sagepay.com/products_services/sage_pay_go/integration/form)
* [Suomen Maksuturva](https://www.maksuturva.fi/services/vendor_services/integration_guidelines.html)
* [Valitor](http://www.valitor.is/) - IS
* [Verkkomaksut](http://www.verkkomaksut.fi) - FI
* [WebMoney](http://www.webmoney.ru) - RU
* [WebPay](http://webpay.by/)
* [WorldPay](http://www.worldpay.com)

## Contributing

The source code is hosted at [GitHub](http://github.com/Shopify/offsite_payments), and can be fetched using:

git clone https://github.com/Shopify/offsite_payments.git

Please don't touch the CHANGELOG in your pull requests, we'll add the appropriate CHANGELOG entries at release time.
50 changes: 50 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
$:.unshift File.expand_path('../lib', __FILE__)
require 'offsite_payments/version'

begin
require 'bundler'
Bundler.setup
rescue LoadError => e
puts "Error loading bundler (#{e.message}): \"gem install bundler\" for bundler support."
require 'rubygems'
end

require 'rake'
require 'rake/testtask'

task :gem => :build
task :build do
raise "Please set a private key to sign the gem" unless ENV['GEM_PRIVATE_KEY']
system "gem build activemerchant.gemspec"
end

task :install => :build do
system "gem install activemerchant-#{ActiveMerchant::VERSION}.gem"
end

task :release => :build do
system "git tag -a v#{ActiveMerchant::VERSION} -m 'Tagging #{ActiveMerchant::VERSION}'"
system "git push --tags"
system "gem push activemerchant-#{ActiveMerchant::VERSION}.gem"
system "rm activemerchant-#{ActiveMerchant::VERSION}.gem"
end

desc "Run the unit test suite"
task :default => 'test:units'
task :test => 'test:units'

namespace :test do
Rake::TestTask.new(:units) do |t|
t.pattern = 'test/unit/**/*_test.rb'
t.ruby_opts << '-rubygems'
t.libs << 'test'
t.verbose = true
end

Rake::TestTask.new(:remote) do |t|
t.pattern = 'test/remote/**/*_test.rb'
t.ruby_opts << '-rubygems'
t.libs << 'test'
t.verbose = true
end
end
48 changes: 48 additions & 0 deletions generators/integration_generator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
require "thor/group"

class IntegrationGenerator < Thor::Group
include Thor::Actions

argument :name
class_option :destroy, :type => :boolean, :desc => "Destroys rather than generates the gateway"

source_root File.expand_path("..", __FILE__)

def initialize(*args)
super
rescue Thor::InvocationError
at_exit{print self.class.help(shell)}
raise
end

def generate
template "templates/integration.rb", "#{lib}.rb"
template "templates/integration_test.rb", "#{test_dir}/#{identifier}_test.rb"
end

protected

def template(source, dest)
if options[:destroy]
remove_file dest
else
super
end
end

def identifier
@identifier ||= class_name.gsub(%r{([A-Z])}){|m| "_#{$1.downcase}"}.sub(%r{^_}, "")
end

def class_name
@class_name ||= name.gsub(%r{(^[a-z])|_([a-zA-Z])}){|m| ($1||$2).upcase}
end

def lib
"lib/offsite_payments/integrations/#{identifier}"
end

def test_dir
"test/unit/integrations"
end
end
135 changes: 135 additions & 0 deletions generators/templates/integration.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
require File.dirname(__FILE__) + '/<%= identifier %>/helper.rb'
require File.dirname(__FILE__) + '/<%= identifier %>/notification.rb'

module OffsitePayments #:nodoc:
module Integrations #:nodoc:
module <%= class_name %>
mattr_accessor :service_url
self.service_url = 'https://www.example.com'
def self.notification(post)
Notification.new(post)
end
class Helper < OffsitePayments::Helper
# Replace with the real mapping
mapping :account, ''
mapping :amount, ''
mapping :order, ''
mapping :customer, :first_name => '',
:last_name => '',
:email => '',
:phone => ''

mapping :billing_address, :city => '',
:address1 => '',
:address2 => '',
:state => '',
:zip => '',
:country => ''

mapping :notify_url, ''
mapping :return_url, ''
mapping :cancel_return_url, ''
mapping :description, ''
mapping :tax, ''
mapping :shipping, ''
end

class Notification < OffsitePayments::Notification
def complete?
params['']
end

def item_id
params['']
end

def transaction_id
params['']
end

# When was this payment received by the client.
def received_at
params['']
end

def payer_email
params['']
end

def receiver_email
params['']
end

def security_key
params['']
end

# the money amount we received in X.2 decimal.
def gross
params['']
end

# Was this a test transaction?
def test?
params[''] == 'test'
end

def status
params['']
end

# Acknowledge the transaction to <%= class_name %>. This method has to be called after a new
# apc arrives. <%= class_name %> will verify that all the information we received are correct and will return a
# ok or a fail.
#
# Example:
#
# def ipn
# notify = <%= class_name %>Notification.new(request.raw_post)
#
# if notify.acknowledge
# ... process order ... if notify.complete?
# else
# ... log possible hacking attempt ...
# end
def acknowledge(authcode = nil)
payload = raw

uri = URI.parse(<%= class_name %>.notification_confirmation_url)
request = Net::HTTP::Post.new(uri.path)
request['Content-Length'] = "#{payload.size}"
request['User-Agent'] = "Active Merchant -- http://activemerchant.org/"
request['Content-Type'] = "application/x-www-form-urlencoded"
http = Net::HTTP.new(uri.host, uri.port)
http.verify_mode = OpenSSL::SSL::VERIFY_NONE unless @ssl_strict
http.use_ssl = true
response = http.request(request, payload)
# Replace with the appropriate codes
raise StandardError.new("Faulty <%= class_name %> result: #{response.body}") unless ["AUTHORISED", "DECLINED"].include?(response.body)
response.body == "AUTHORISED"
end

private

# Take the posted data and move the relevant data into a hash
def parse(post)
@raw = post.to_s
for line in @raw.split('&')
key, value = *line.scan( %r{^([A-Za-z0-9_.-]+)\=(.*)$} ).flatten
params[key] = CGI.unescape(value.to_s) if key.present?
end
end
end
end
end
end
Loading

0 comments on commit abd025e

Please sign in to comment.