payment 0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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: []
|