activemerchant 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. data/CHANGELOG +40 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README +93 -0
  4. data/lib/active_merchant.rb +59 -0
  5. data/lib/active_merchant/billing/base.rb +52 -0
  6. data/lib/active_merchant/billing/credit_card.rb +217 -0
  7. data/lib/active_merchant/billing/gateway.rb +100 -0
  8. data/lib/active_merchant/billing/gateways.rb +15 -0
  9. data/lib/active_merchant/billing/gateways/authorize_net.rb +236 -0
  10. data/lib/active_merchant/billing/gateways/bogus.rb +92 -0
  11. data/lib/active_merchant/billing/gateways/eway.rb +235 -0
  12. data/lib/active_merchant/billing/gateways/linkpoint.rb +445 -0
  13. data/lib/active_merchant/billing/gateways/moneris.rb +205 -0
  14. data/lib/active_merchant/billing/gateways/payflow.rb +84 -0
  15. data/lib/active_merchant/billing/gateways/payflow/f73e89fd.0 +17 -0
  16. data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +190 -0
  17. data/lib/active_merchant/billing/gateways/payflow/payflow_express_response.rb +30 -0
  18. data/lib/active_merchant/billing/gateways/payflow_express.rb +123 -0
  19. data/lib/active_merchant/billing/gateways/payflow_express_uk.rb +9 -0
  20. data/lib/active_merchant/billing/gateways/payflow_uk.rb +17 -0
  21. data/lib/active_merchant/billing/gateways/paypal.rb +90 -0
  22. data/lib/active_merchant/billing/gateways/paypal/api_cert_chain.crt +35 -0
  23. data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +208 -0
  24. data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +30 -0
  25. data/lib/active_merchant/billing/gateways/paypal_express.rb +115 -0
  26. data/lib/active_merchant/billing/gateways/psigate.rb +265 -0
  27. data/lib/active_merchant/billing/gateways/trust_commerce.rb +330 -0
  28. data/lib/active_merchant/billing/gateways/usa_epay.rb +189 -0
  29. data/lib/active_merchant/billing/integrations.rb +12 -0
  30. data/lib/active_merchant/billing/integrations/action_view_helper.rb +65 -0
  31. data/lib/active_merchant/billing/integrations/bogus.rb +17 -0
  32. data/lib/active_merchant/billing/integrations/bogus/helper.rb +17 -0
  33. data/lib/active_merchant/billing/integrations/bogus/notification.rb +11 -0
  34. data/lib/active_merchant/billing/integrations/chronopay.rb +17 -0
  35. data/lib/active_merchant/billing/integrations/chronopay/helper.rb +81 -0
  36. data/lib/active_merchant/billing/integrations/chronopay/notification.rb +156 -0
  37. data/lib/active_merchant/billing/integrations/gestpay.rb +21 -0
  38. data/lib/active_merchant/billing/integrations/gestpay/common.rb +42 -0
  39. data/lib/active_merchant/billing/integrations/gestpay/helper.rb +72 -0
  40. data/lib/active_merchant/billing/integrations/gestpay/notification.rb +83 -0
  41. data/lib/active_merchant/billing/integrations/helper.rb +79 -0
  42. data/lib/active_merchant/billing/integrations/nochex.rb +21 -0
  43. data/lib/active_merchant/billing/integrations/nochex/helper.rb +68 -0
  44. data/lib/active_merchant/billing/integrations/nochex/notification.rb +101 -0
  45. data/lib/active_merchant/billing/integrations/notification.rb +52 -0
  46. data/lib/active_merchant/billing/integrations/paypal.rb +35 -0
  47. data/lib/active_merchant/billing/integrations/paypal/helper.rb +103 -0
  48. data/lib/active_merchant/billing/integrations/paypal/notification.rb +187 -0
  49. data/lib/active_merchant/billing/response.rb +28 -0
  50. data/lib/active_merchant/lib/country.rb +297 -0
  51. data/lib/active_merchant/lib/posts_data.rb +21 -0
  52. data/lib/active_merchant/lib/requires_parameters.rb +17 -0
  53. data/lib/active_merchant/lib/validateable.rb +76 -0
  54. data/lib/tasks/cia.rb +90 -0
  55. metadata +129 -0
@@ -0,0 +1,40 @@
1
+ # CHANGELOG
2
+ # ---
3
+ # * Add discover to list of supported card types for Authorize.net
4
+ #
5
+ # * Fix Psigate crediting [sean.alien8@gmail.com]
6
+ #
7
+ # * Fix dependency loading of tests
8
+ #
9
+ # * Add methods for storing credit cards to the Bogus gateway [Jim Kane]
10
+ #
11
+ # * Fix bugs in expiration dates. [Jim Kane]
12
+ #
13
+ # * Fixed bugs related to authorized.net [Rick Olson]
14
+ #
15
+ # * Linkpoint is now a full featured backend for active merchant [Ryan Heneise]
16
+ #
17
+ # * Added linkpoint support [Ryan Heneise]
18
+ #
19
+ # * Added trust commerce gateway [Hans Friedrich]
20
+ #
21
+ # * Removed shipping stuff until there is time to implement it properly
22
+ #
23
+ # * The library now rejects money amounts which are not either cents as integer or a Money object
24
+ #
25
+ # * Moneris now uses the same layout as the authorized.net plugin
26
+ #
27
+ # * Added authorized.net
28
+ #
29
+ # * Changed default to :test mode. Set to production with ActiveMerchant::Billing::Base.gateway_mode = :production
30
+ #
31
+ # * More refactoring
32
+ #
33
+ # * Refactored a bit so that there is space for billing and shipping area. None of the shipping aids are fleshed out yet. Needs more work.
34
+ #
35
+ # * Added Moneris support
36
+ #
37
+ # * Credit card in memory object resembling a AR object
38
+ #
39
+ # * Credit card validation methods as static methods of the credit card object
40
+ #
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2005 Tobias Luetke
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOa AND
17
+ NONINFRINGEMENT. IN NO EVENT SaALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,93 @@
1
+ = Active Merchant
2
+
3
+ This library is supposed to aid in creating e-commerce software in Ruby.
4
+ In the future we want to support all "good" payment gateways.
5
+
6
+ This library is the foundation of commerce for http://www.shopify.com.
7
+
8
+ Please visit the {ActiveMerchant homepage}[http://activemerchant.org] for more resources, tutorials and other information about this project.
9
+
10
+ == Supported Direct Payment Gateways
11
+
12
+ * Bogus -- your trusty test gateway which does nothing. Great for testing your app!
13
+
14
+ ==== Australia
15
+
16
+ * eWay[http://www.eway.com.au]
17
+
18
+ ==== Canada
19
+
20
+ * Moneris[http://www.moneris.com]
21
+ * Psigate[http://www.psigate.com]
22
+
23
+ ==== United Kingdom
24
+
25
+ * {PayPal Website Payments Pro UK}[https://www.paypal.com/uk/cgi-bin/webscr?cmd=_wp-pro-overview-outside]
26
+
27
+ ==== USA
28
+
29
+ * Authorize.net[http://www.authorize.net]
30
+ * LinkPoint[http://www.linkpoint.com]
31
+ * {PayPal Payflow Pro}[https://www.paypal.com/cgi-bin/webscr?cmd=_payflow-gateway-overview-outside]
32
+ * {PayPal Website Payments Pro US}[https://www.paypal.com/cgi-bin/webscr?cmd=_wp-pro-overview-outside]
33
+ * TrustCommerce[http://www.trustcommerce.com] - Requires the tclink ruby library from http://www.trustcommerce.com/tclink.html. Otherwise it will not be loaded.
34
+ * {USA ePay}[www.usaepay.com/]
35
+
36
+ == Supported Offsite Payment Gateways
37
+
38
+ * {PayPal Website Payments Standard}[https://www.paypal.com/cgi-bin/webscr?cmd=_wp-standard-overview-outside]
39
+ * Chronopay[http://www.chronopay.com]
40
+ * Nochex[http://www.nochex.com]
41
+ * {Banca Sella GestPay}[https://www.sella.it/banca/ecommerce/gestpay/gestpay.jsp]
42
+
43
+ == Download
44
+
45
+ Currently this library is available with svn from:
46
+
47
+ http://activemerchant.googlecode.com/svn/trunk/active_merchant
48
+
49
+ == Installation
50
+
51
+ === From Subversion
52
+
53
+ You can check out the latest source from svn:
54
+
55
+ > svn co http://activemerchant.googlecode.com/svn/trunk/active_merchant
56
+
57
+ === As a Rails plugin
58
+
59
+ ActiveMerchant includes an init.rb file. This means that Rails will automatically load ActiveMerchant on startup. Run the following command from the root directory of your Rails project to install ActiveMerchant as a Rails plugin:
60
+
61
+ > ./script/plugin install http://activemerchant.googlecode.com/svn/trunk/active_merchant
62
+
63
+ === From Ruby Gems
64
+
65
+ Installation from RubyGems
66
+
67
+ > gem install activemerchant -y
68
+
69
+ == Sample Usage
70
+
71
+ ten_dollars = Money.new(1000, 'USD')
72
+
73
+ credit_card = CreditCard.new(
74
+ :number => '4242424242424242',
75
+ :month => 8,
76
+ :year => 2006,
77
+ :name => 'Tobias Luetke',
78
+ :type => 'visa'
79
+ )
80
+
81
+ if creditcard.valid?
82
+ gateway = ActiveMerchant::Billing::AuthorizeNetGateway.new(
83
+ :login => 'LOGIN_ID',
84
+ :password => 'TRANSACTION_KEY'
85
+ )
86
+ response = gateway.purchase(ten_dollars, credit_card)
87
+
88
+ if response.success?
89
+ ...
90
+ else
91
+ raise StandardError.new( response.message )
92
+ end
93
+ end
@@ -0,0 +1,59 @@
1
+ #--
2
+ # Copyright (c) 2005 Tobias Luetke
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #++
23
+
24
+ $:.unshift(File.dirname(__FILE__))
25
+
26
+ # Include rails' active support for all the core extensions we love
27
+ begin
28
+ require 'active_support'
29
+ rescue LoadError
30
+ require 'rubygems'
31
+ require 'activesupport'
32
+ end
33
+
34
+ begin
35
+ require 'builder'
36
+ rescue LoadError
37
+ require 'rubygems'
38
+ require 'builder'
39
+ end
40
+
41
+ require 'cgi'
42
+
43
+ require 'active_merchant/lib/validateable'
44
+ require 'active_merchant/lib/posts_data'
45
+ require 'active_merchant/lib/requires_parameters'
46
+
47
+ # Require the country class
48
+ require 'active_merchant/lib/country'
49
+
50
+ # CreditCard Utility class.
51
+ require 'active_merchant/billing/credit_card'
52
+
53
+ require 'active_merchant/billing/base'
54
+
55
+ # Require the supported gateways
56
+ require 'active_merchant/billing/gateways'
57
+
58
+ # Require the supported integrations
59
+ require 'active_merchant/billing/integrations'
@@ -0,0 +1,52 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ module Base
4
+ # Set ActiveMerchant gateways in test mode.
5
+ #
6
+ # ActiveMerchant::Billing::Base.gateway_mode = :test
7
+ mattr_accessor :gateway_mode
8
+
9
+ # Set ActiveMerchant gateways in test mode.
10
+ #
11
+ # ActiveMerchant::Billing::Base.gateway_mode = :test
12
+ mattr_accessor :integration_mode
13
+
14
+ # Set both the mode of both the gateways and integrations
15
+ # at once
16
+ mattr_reader :mode
17
+
18
+ def self.mode=(mode)
19
+ @@mode = mode
20
+ self.gateway_mode = mode
21
+ self.integration_mode = mode
22
+ end
23
+
24
+ self.mode = :production
25
+
26
+ # Return the matching gateway for the provider
27
+ # * <tt>bogus</tt>: BogusGateway - Does nothing (for testing)
28
+ # * <tt>moneris</tt>: MonerisGateway
29
+ # * <tt>authorize_net</tt>: AuthorizeNetGateway
30
+ # * <tt>trust_commerce</tt>: TrustCommerceGateway
31
+ #
32
+ # ActiveMerchant::Billing::Base.gateway('moneris').new
33
+ def self.gateway(name)
34
+ ActiveMerchant::Billing.const_get("#{name.to_s.downcase}_gateway".camelize)
35
+ end
36
+
37
+
38
+ # Return the matching integration module
39
+ # You can then get the notification from the module
40
+ # * <tt>bogus</tt>: Bogus - Does nothing (for testing)
41
+ # * <tt>chronopay</tt>: Chronopay - Does nothing (for testing)
42
+ # * <tt>paypal</tt>: Chronopay - Does nothing (for testing)
43
+ #
44
+ # chronopay = ActiveMerchant::Billing::Base.integration('chronopay')
45
+ # notification = chronopay.notification(raw_post)
46
+ #
47
+ def self.integration(name)
48
+ ActiveMerchant::Billing::Integrations.const_get("#{name.to_s.downcase}".camelize)
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,217 @@
1
+ require 'time'
2
+ require 'delegate'
3
+ require 'date'
4
+
5
+ module ActiveMerchant #:nodoc:
6
+ module Billing #:nodoc:
7
+
8
+ # This credit card object can be used as a stand alone object. It acts just like a active record object
9
+ # but doesn't support the .save method as its not backed by a database.
10
+ class CreditCard
11
+ cattr_accessor :require_verification_value
12
+ self.require_verification_value = false
13
+
14
+ def self.requires_verification_value?
15
+ require_verification_value
16
+ end
17
+
18
+ include Validateable
19
+
20
+ class ExpiryMonth < DelegateClass(Fixnum)#:nodoc:
21
+ def to_s(format = :default) #:nodoc:
22
+ case format
23
+ when :default
24
+ __getobj__.to_s
25
+ when :two_digit
26
+ sprintf("%.2i", self)[-2..-1]
27
+ else
28
+ super
29
+ end
30
+ end
31
+
32
+ def valid? #:nodoc:
33
+ (1..12).include?(self)
34
+ end
35
+ end
36
+
37
+ class ExpiryYear < DelegateClass(Fixnum)#:nodoc:
38
+ def to_s(format = :default) #:nodoc:
39
+ case format
40
+ when :default
41
+ __getobj__.to_s
42
+ when :two_digit
43
+ sprintf("%.2i", self)[-2..-1]
44
+ when :four_digit
45
+ sprintf("%.4i", self)
46
+ else
47
+ super
48
+ end
49
+ end
50
+
51
+ def valid? #:nodoc:
52
+ (Time.now.year..Time.now.year + 20).include?(self)
53
+ end
54
+ end
55
+
56
+ class ExpiryDate #:nodoc:
57
+ attr_reader :month, :year
58
+ def initialize(month, year)
59
+ @month = ExpiryMonth.new(month)
60
+ @year = ExpiryYear.new(year)
61
+ end
62
+
63
+ def expired? #:nodoc:
64
+ Time.now > expiration rescue true
65
+ end
66
+
67
+ def expiration #:nodoc:
68
+ Time.parse("#{month}/#{month_days}/#{year} 23:59:59") rescue Time.at(0)
69
+ end
70
+
71
+ private
72
+ def month_days
73
+ mdays = [nil,31,28,31,30,31,30,31,31,30,31,30,31]
74
+ mdays[2] = 29 if Date.leap?(year)
75
+ mdays[month]
76
+ end
77
+ end
78
+
79
+ # required
80
+ attr_accessor :number, :month, :year, :type, :first_name, :last_name
81
+
82
+ # Optional verification_value (CVV, CVV2 etc)
83
+ #
84
+ # Gateways will try their best to run validation on the passed in value if it is supplied
85
+ #
86
+ attr_accessor :verification_value
87
+
88
+ def before_validate
89
+ self.type.downcase! if type.respond_to?(:downcase)
90
+ self.month = month.to_i
91
+ self.year = year.to_i
92
+ self.number.to_s.gsub!(/[^\d]/, "")
93
+ end
94
+
95
+ def validate
96
+ @errors.add "year", "expired" if expired?
97
+
98
+ @errors.add "first_name", "cannot be empty" if @first_name.blank?
99
+ @errors.add "last_name", "cannot be empty" if @last_name.blank?
100
+ @errors.add "month", "cannot be empty" unless month.valid?
101
+ @errors.add "year", "cannot be empty" unless year.valid?
102
+
103
+ # Bogus card is pretty much for testing purposes. Lets just skip these extra tests if its used
104
+
105
+ return if type == 'bogus'
106
+
107
+ @errors.add "number", "is not a valid credit card number" unless CreditCard.valid_number?(number)
108
+ @errors.add "type", "is invalid" unless CreditCard.card_companies.keys.include?(type)
109
+ @errors.add "type", "is not the correct card type" unless CreditCard.type?(number) == type
110
+
111
+ if CreditCard.requires_verification_value?
112
+ @errors.add "verification_value", "is required" unless verification_value?
113
+ end
114
+ end
115
+
116
+ def expired?
117
+ expiry_date.expired?
118
+ end
119
+
120
+ def name?
121
+ @first_name != nil and @last_name != nil
122
+ end
123
+
124
+ def first_name?
125
+ @first_name != nil
126
+ end
127
+
128
+ def last_name?
129
+ @last_name != nil
130
+ end
131
+
132
+ def name
133
+ "#{@first_name} #{@last_name}"
134
+ end
135
+
136
+ def verification_value?
137
+ !@verification_value.blank?
138
+ end
139
+
140
+ # Regular expressions for the known card companies
141
+ # == Known card types
142
+ # Card Type Prefix Length
143
+ # --------------------------------------------------------------------------
144
+ # master 51-55 16
145
+ # visa 4 13, 16
146
+ # american_express 34, 37 15
147
+ # diners_club 300-305, 36, 38 14
148
+ # discover 6011 16
149
+ # jcb 3 16
150
+ # jcb 2131, 1800 15
151
+ # switch various 16,18,19
152
+ # solo 63, 6767 16,18,19
153
+ def self.card_companies
154
+ {
155
+ 'visa' => /^4\d{12}(\d{3})?$/,
156
+ 'master' => /^5[1-5]\d{14}$/,
157
+ 'discover' => /^6011\d{12}$/,
158
+ 'american_express' => /^3[47]\d{13}$/,
159
+ 'diners_club' => /^3(0[0-5]|[68]\d)\d{11}$/,
160
+ 'jcb' => /^(3\d{4}|2131|1800)\d{11}$/,
161
+ 'switch' => [/^49(03(0[2-9]|3[5-9])|11(0[1-2]|7[4-9]|8[1-2])|36[0-9]{2})\d{10}(\d{2,3})?$/, /^564182\d{10}(\d{2,3})?$/, /^6(3(33[0-4][0-9])|759[0-9]{2})\d{10}(\d{2,3})?$/],
162
+ 'solo' => /^6(3(34[5-9][0-9])|767[0-9]{2})\d{10}(\d{2,3})?$/
163
+ }
164
+ end
165
+
166
+ # Returns a string containing the type of card from the list of known information below.
167
+ def self.type?(number)
168
+ return 'visa' if Base.gateway_mode == :test and ['1','2','3','success','failure','error'].include?(number.to_s)
169
+
170
+ card_companies.each do |company, patterns|
171
+ return company if [patterns].flatten.any? { |pattern| number =~ pattern }
172
+ end
173
+
174
+ return nil
175
+ end
176
+
177
+ # Returns true if it validates. Optionally, you can pass a card type as an argument and make sure it is of the correct type.
178
+ # == References
179
+ # - http://perl.about.com/compute/perl/library/nosearch/P073000.htm
180
+ # - http://www.beachnet.com/~hstiles/cardtype.html
181
+ def self.valid_number?(number)
182
+ return true if Base.gateway_mode == :test and ['1','2','3','success','failure','error'].include?(number.to_s)
183
+
184
+ return false unless number.to_s.length >= 13
185
+
186
+ sum = 0
187
+ for i in 0..number.length
188
+ weight = number[-1 * (i + 2), 1].to_i * (2 - (i % 2))
189
+ sum += (weight < 10) ? weight : weight - 9
190
+ end
191
+
192
+ (number[-1,1].to_i == (10 - sum % 10) % 10)
193
+ end
194
+
195
+ # Show the card number, with all but last 4 numbers replace with "X". (XXXX-XXXX-XXXX-4338)
196
+ def display_number
197
+ "XXXX-XXXX-XXXX-#{last_digits}"
198
+ end
199
+
200
+ def last_digits
201
+ number.nil? ? "" : number.last(4)
202
+ end
203
+
204
+ def month
205
+ expiry_date.month
206
+ end
207
+
208
+ def year
209
+ expiry_date.year
210
+ end
211
+
212
+ def expiry_date
213
+ ExpiryDate.new(@month, @year)
214
+ end
215
+ end
216
+ end
217
+ end