payment 0.9
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/payment.rb +81 -0
- data/lib/payment/authorize_net.rb +207 -0
- data/lib/payment/base.rb +38 -0
- metadata +40 -0
data/lib/payment.rb
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2005 Lucas Carlson
|
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
|
+
# == Welcome to Payment
|
25
|
+
#
|
26
|
+
# Payment is used to process credit cards and electronic cash through merchant accounts.
|
27
|
+
#
|
28
|
+
# To choose a gateway, require 'payment/gateway_name'. For example, if you want to use Authorize.net, do a require 'payment/authorize_net'. If you would like to use multiple gateways in the same code, simply do a require 'payment' and it will grab each gateway's code for you.
|
29
|
+
#
|
30
|
+
# Payment was inspired by and has borrowed much of its infrastructure from the Business::OnlinePayment Perl module (http://search.cpan.org/~jasonk/Business-OnlinePayment-2.01/OnlinePayment.pm).
|
31
|
+
#
|
32
|
+
# If you would like to loosely check the validity of a credit card without using a merchant account, look at the CreditCard module (http://rubyforge.org/projects/creditcard/).
|
33
|
+
#
|
34
|
+
# == Example
|
35
|
+
#
|
36
|
+
# require 'payment/authorize_net'
|
37
|
+
#
|
38
|
+
# transaction = Payment::AuthorizeNet.new (
|
39
|
+
# :login => 'username',
|
40
|
+
# :password => 'password',
|
41
|
+
# :amount => '49.95',
|
42
|
+
# :card_number => '1234123412341238',
|
43
|
+
# :expiration => '03/05',
|
44
|
+
# :first_name => 'John',
|
45
|
+
# :last_name => 'Doe'
|
46
|
+
# )
|
47
|
+
# transaction.submit
|
48
|
+
#
|
49
|
+
# if transaction.success?
|
50
|
+
# puts "Card processed successfully: #{transaction.authorization}";
|
51
|
+
# else
|
52
|
+
# puts "Card was rejected: #{transaction.error_message}";
|
53
|
+
# end
|
54
|
+
#
|
55
|
+
# == Currently Supported Gateways
|
56
|
+
#
|
57
|
+
# * Authorize.Net (authorize_net) - http://www.authorize.net/
|
58
|
+
#
|
59
|
+
# == Planned Support for the Following Gateways
|
60
|
+
#
|
61
|
+
# * Trust Commerce - http://www.trustcommerce.com/
|
62
|
+
# * Verisign Payflow Pro - http://www.verisign.com/
|
63
|
+
# * Moneris - http://www.moneris.com/
|
64
|
+
# * Cardstream - http://www.cardstream.com/
|
65
|
+
# * Beanstream - http://www.beanstream.com/
|
66
|
+
# * Vital - http://www.vitalps.com/
|
67
|
+
# * Merchant Commerce - http://www.innuity.com/
|
68
|
+
# * iAuthorizer - http://www.iauthorizer.com/
|
69
|
+
# * Electronic Clearing House, Inc. - http://www.echo-inc.com/
|
70
|
+
# * Bank of America eStores - http://www.bankofamerica.com/
|
71
|
+
# * Network1Financial - http://www.eftsecure.com/
|
72
|
+
# * eSec - http://www.esecpayments.com.au/
|
73
|
+
# * Ingenico OCV - http://www.ingenico.com.au/
|
74
|
+
# * St.George IPG - https://www.ipg.stgeorge.com.au/
|
75
|
+
# * Jettis - http://www.jettis.com/
|
76
|
+
# * PaymentsGateway.Net - http://www.paymentsgateway.net/
|
77
|
+
# * PayConnect - http://www.paymentone.com/
|
78
|
+
# * Secure Hosting UPG - http://www.securehosting.com/
|
79
|
+
|
80
|
+
require 'payment/base'
|
81
|
+
require 'payment/authorize_net'
|
@@ -0,0 +1,207 @@
|
|
1
|
+
# Author:: Lucas Carlson (mailto:lucas@rufy.com)
|
2
|
+
# Copyright:: Copyright (c) 2005 Lucas Carlson
|
3
|
+
# License:: Distributes under the same terms as Ruby
|
4
|
+
|
5
|
+
require 'payment/base'
|
6
|
+
require 'cgi'
|
7
|
+
require 'csv'
|
8
|
+
|
9
|
+
module Payment
|
10
|
+
|
11
|
+
class AuthorizeNet < Base
|
12
|
+
attr_reader :server_response, :avs_code, :order_number, :md5, :cvv2_response, :cavv_response
|
13
|
+
attr_accessor :first_name, :last_name, :transaction_key
|
14
|
+
|
15
|
+
# version of the gateway's API
|
16
|
+
API_VERSION = '3.1'
|
17
|
+
|
18
|
+
# map the instance variable names to the gateway's requested variable names
|
19
|
+
FIELDS = {
|
20
|
+
'type' => 'x_Method',
|
21
|
+
'login' => 'x_Login',
|
22
|
+
'password' => 'x_Password',
|
23
|
+
'transaction_key' => 'x_Tran_Key',
|
24
|
+
'type' => 'x_Type',
|
25
|
+
'description' => 'x_Description',
|
26
|
+
'amount' => 'x_Amount',
|
27
|
+
'currency_code' => 'x_Currency_Code',
|
28
|
+
'invoice_num' => 'x_Invoice_Num',
|
29
|
+
'trans_id' => 'x_Trans_ID',
|
30
|
+
'auth_code' => 'x_Auth_Code',
|
31
|
+
'cust_id' => 'x_Cust_ID',
|
32
|
+
'customer_ip' => 'x_Customer_IP',
|
33
|
+
'last_name' => 'x_Last_Name',
|
34
|
+
'first_name' => 'x_First_Name',
|
35
|
+
'company' => 'x_Company',
|
36
|
+
'address' => 'x_Address',
|
37
|
+
'city' => 'x_City',
|
38
|
+
'state' => 'x_State',
|
39
|
+
'zip' => 'x_Zip',
|
40
|
+
'country' => 'x_Country',
|
41
|
+
'ship_to_last_name' => 'x_Ship_To_Last_Name',
|
42
|
+
'ship_to_first_name' => 'x_Ship_To_First_Name',
|
43
|
+
'ship_to_address' => 'x_Ship_To_Address',
|
44
|
+
'ship_to_city' => 'x_Ship_To_City',
|
45
|
+
'ship_to_state' => 'x_Ship_To_State',
|
46
|
+
'ship_to_zip' => 'x_Ship_To_Zip',
|
47
|
+
'ship_to_country' => 'x_Ship_To_Country',
|
48
|
+
'phone' => 'x_Phone',
|
49
|
+
'fax' => 'x_Fax',
|
50
|
+
'email' => 'x_Email',
|
51
|
+
'card_number' => 'x_Card_Num',
|
52
|
+
'expiration' => 'x_Exp_Date',
|
53
|
+
'card_code' => 'x_Card_Code',
|
54
|
+
'echeck_type' => 'x_Echeck_Type',
|
55
|
+
'account_name' => 'x_Bank_Acct_Name',
|
56
|
+
'account_number' => 'x_Bank_Acct_Num',
|
57
|
+
'account_type' => 'x_Bank_Acct_Type',
|
58
|
+
'bank_name' => 'x_Bank_Name',
|
59
|
+
'bank_aba_code' => 'x_Bank_ABA_Code',
|
60
|
+
'customer_org' => 'x_Customer_Organization_Type',
|
61
|
+
'customer_ssn' => 'x_Customer_Tax_ID',
|
62
|
+
'drivers_license_num' => 'x_Drivers_License_Num',
|
63
|
+
'drivers_license_state' => 'x_Drivers_License_State',
|
64
|
+
'drivers_license_dob' => 'x_Drivers_License_DOB',
|
65
|
+
'recurring_billing' => 'x_Recurring_Billing',
|
66
|
+
'test_request' => 'x_Test_Request',
|
67
|
+
'adc_delim_data' => 'x_ADC_Delim_Data',
|
68
|
+
'adc_url' => 'x_ADC_URL',
|
69
|
+
'version' => 'x_Version',
|
70
|
+
}
|
71
|
+
|
72
|
+
# map the actions to the merchant's action names
|
73
|
+
ACTIONS = {
|
74
|
+
'normal authorization' => 'AUTH_CAPTURE',
|
75
|
+
'authorization only' => 'AUTH_ONLY',
|
76
|
+
'credit' => 'CREDIT',
|
77
|
+
'post authorization' => 'PRIOR_AUTH_CAPTURE',
|
78
|
+
'void' => 'VOID',
|
79
|
+
}
|
80
|
+
|
81
|
+
def initialize(options = {})
|
82
|
+
# set some sensible defaults
|
83
|
+
@url = 'https://secure.authorize.net/gateway/transact.dll'
|
84
|
+
@adc_delim_data = 'TRUE'
|
85
|
+
@adc_url = 'FALSE'
|
86
|
+
@version = API_VERSION
|
87
|
+
|
88
|
+
# include all provided data
|
89
|
+
super options
|
90
|
+
end
|
91
|
+
|
92
|
+
def submit
|
93
|
+
uri = URI.parse @url
|
94
|
+
http = Net::HTTP.new uri.host, uri.port
|
95
|
+
|
96
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE if @strict_ssl == false
|
97
|
+
http.use_ssl = true
|
98
|
+
|
99
|
+
begin
|
100
|
+
response = http.post uri.path, post_data
|
101
|
+
rescue
|
102
|
+
@is_success = false
|
103
|
+
@error_message = "Could not access #{@url}. Error code #{response.code}. #{response.message}"
|
104
|
+
return
|
105
|
+
end
|
106
|
+
|
107
|
+
col = nil
|
108
|
+
CSV::Reader.parse response.body do |row|
|
109
|
+
col ||= row
|
110
|
+
end
|
111
|
+
|
112
|
+
if col
|
113
|
+
@server_response = response.code
|
114
|
+
@result_code = col[0].data
|
115
|
+
@avs_code = col[5].data
|
116
|
+
@order_number = col[6].data
|
117
|
+
@md5 = col[37].data
|
118
|
+
@cvv2_response = col[38].data
|
119
|
+
@cavv_response = col[39].data
|
120
|
+
|
121
|
+
if @result_code == "1" # Approved/Pending/Test
|
122
|
+
@is_success = true
|
123
|
+
@authorization = col[4].data
|
124
|
+
else
|
125
|
+
@is_success = false
|
126
|
+
@error_code = col[2].data
|
127
|
+
@error_message = col[3].data
|
128
|
+
end
|
129
|
+
else
|
130
|
+
@is_success = false
|
131
|
+
@error_message = "Could not interpret the result. #{response.body}"
|
132
|
+
end
|
133
|
+
|
134
|
+
return @is_success
|
135
|
+
end
|
136
|
+
|
137
|
+
def post_data
|
138
|
+
prepare_data
|
139
|
+
|
140
|
+
post_array = Array.new
|
141
|
+
FIELDS.each do |loc_var, gate_var|
|
142
|
+
if @@required.include?(loc_var) && eval("@#{loc_var}").nil?
|
143
|
+
raise PaymentError, "The required variable '#{loc_var}' was left empty"
|
144
|
+
else
|
145
|
+
value = eval "CGI.escape(@#{loc_var}.to_s)"
|
146
|
+
post_array << "#{gate_var}=#{value}"
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
return post_array.join("&")
|
151
|
+
end
|
152
|
+
|
153
|
+
def prepare_data
|
154
|
+
# make sensible changes to data
|
155
|
+
@card_number = @card_number.to_s.gsub(/[^\d]/, "") unless @card_number.nil?
|
156
|
+
|
157
|
+
@test_request = @test_transaction == true ? "TRUE" : "FALSE"
|
158
|
+
|
159
|
+
if @recurring_billing.class != String
|
160
|
+
if @recurring_billing == true
|
161
|
+
@recurring_billing = "YES"
|
162
|
+
elsif @recurring_billing == false
|
163
|
+
@recurring_billing = "NO"
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
@expiration = @expiration.strftime "%m/%y" rescue nil # in case a date or time is passed
|
168
|
+
|
169
|
+
@type = (@type.nil? && @card_number) ? 'CC' : @type.upcase
|
170
|
+
|
171
|
+
# convert the action
|
172
|
+
if ACTIONS.include?(@action)
|
173
|
+
@action = ACTIONS[@action]
|
174
|
+
elsif ! ACTIONS.has_value?(@action)
|
175
|
+
raise PaymentError, "The action '#{@action}' is not valid"
|
176
|
+
end
|
177
|
+
|
178
|
+
# add some required fields specific to this payment gateway and the provided data
|
179
|
+
@@required.concat %w(type action login test_request adc_delim_data adc_url)
|
180
|
+
|
181
|
+
if @transaction_key.nil?
|
182
|
+
@@required.concat %w(password)
|
183
|
+
else
|
184
|
+
@@required.concat %w(transaction_key)
|
185
|
+
end
|
186
|
+
|
187
|
+
unless @type == 'VOID'
|
188
|
+
if @type == 'ECHECK'
|
189
|
+
@@required.concat %w(amount routing_code account_number account_type bank_name account_name account_type)
|
190
|
+
@@required.concat %w(customer_org customer_ssn) unless @customer_org.nil?
|
191
|
+
elsif @type == 'CC'
|
192
|
+
@@required.concat %w(amount)
|
193
|
+
if @action == 'PRIOR_AUTH_CAPTURE'
|
194
|
+
@@required.concat @order_number ? %w(order_number) : %w(card_number expiration)
|
195
|
+
else
|
196
|
+
@@required.concat %w(last_name first_name card_number expiration)
|
197
|
+
end
|
198
|
+
else
|
199
|
+
raise PaymentError, "Can't handle transaction type: #{@type}"
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
@@required.uniq!
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
end
|
data/lib/payment/base.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
# Author:: Lucas Carlson (mailto:lucas@rufy.com)
|
2
|
+
# Copyright:: Copyright (c) 2005 Lucas Carlson
|
3
|
+
# License:: Distributes under the same terms as Ruby
|
4
|
+
|
5
|
+
require 'net/http'
|
6
|
+
require 'net/https'
|
7
|
+
|
8
|
+
module Payment
|
9
|
+
|
10
|
+
class PaymentError < StandardError; end # :nodoc:
|
11
|
+
|
12
|
+
class Base
|
13
|
+
attr_reader :error_message, :authorization, :transaction_type, :result_code
|
14
|
+
attr_accessor :url
|
15
|
+
attr_accessor :require_avs, :test_transaction, :strict_ssl
|
16
|
+
attr_accessor :type, :login, :password, :action, :description, :amount, :invoice_number, :customer_id, :name, :address, :city, :state, :zip, :country, :phone, :fax, :email, :card_number, :expiration, :account_number, :routing_code, :bank_name
|
17
|
+
|
18
|
+
@@required = []
|
19
|
+
|
20
|
+
def initialize(options = {})
|
21
|
+
# set some sensible defaults
|
22
|
+
@strict_ssl = true
|
23
|
+
@action = 'credit'
|
24
|
+
|
25
|
+
# include all provided data
|
26
|
+
options.each { |method, value| eval "@#{method} = '#{value}'" if methods.include? "#{method}=" }
|
27
|
+
end
|
28
|
+
|
29
|
+
def submit
|
30
|
+
raise PaymentError, "No gateway specified"
|
31
|
+
end
|
32
|
+
|
33
|
+
def success?
|
34
|
+
@is_success ? true : false
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
metadata
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.8.3
|
3
|
+
specification_version: 1
|
4
|
+
name: payment
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: "0.9"
|
7
|
+
date: 2005-02-04
|
8
|
+
summary: Payment is used to process credit cards and electronic cash through merchant accounts.
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
email: lucas@rufy.com
|
12
|
+
homepage: http://payment.rubyforge.org
|
13
|
+
rubyforge_project: payment
|
14
|
+
description: "These functions tell you whether a credit card number is self-consistent using known algorithms for credit card numbers. All non-integer values are removed from the string before parsing so that you don't have to worry about the format of the string."
|
15
|
+
autorequire:
|
16
|
+
default_executable:
|
17
|
+
bindir: bin
|
18
|
+
has_rdoc: true
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
+
requirements:
|
21
|
+
-
|
22
|
+
- ">"
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: 0.0.0
|
25
|
+
version:
|
26
|
+
platform: ruby
|
27
|
+
authors:
|
28
|
+
- Lucas Carlson
|
29
|
+
files:
|
30
|
+
- lib/payment
|
31
|
+
- lib/payment.rb
|
32
|
+
- lib/payment/authorize_net.rb
|
33
|
+
- lib/payment/base.rb
|
34
|
+
test_files: []
|
35
|
+
rdoc_options: []
|
36
|
+
extra_rdoc_files: []
|
37
|
+
executables: []
|
38
|
+
extensions: []
|
39
|
+
requirements: []
|
40
|
+
dependencies: []
|