paysimple 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ == 1.0.0 / 2007-06-29
2
+
3
+ * 1 major enhancement
4
+ * Birthday!
5
+
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2007 [Jonathan Younger]
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 PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL 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.
@@ -0,0 +1,10 @@
1
+ History.txt
2
+ MIT-LICENSE
3
+ Manifest.txt
4
+ README.txt
5
+ Rakefile
6
+ init.rb
7
+ lib/paysimple.rb
8
+ lib/usaepay.wsdl
9
+ test/paysimple_test.rb
10
+ uninstall.rb
@@ -0,0 +1,152 @@
1
+ [PaySimple](http://www.paysimple.com) is a payment gateway providing credit card
2
+ processing, check processing and recurring / subscription billing services.
3
+
4
+ == DESCRIPTION:
5
+
6
+ This library provides a simple interface to find, create, edit, delete, and query subscriptions
7
+ using the PaySimple SOAP API. [PaySimple API](https://www.usaepay.com/developer/docs/beta5)
8
+
9
+
10
+ == Installation:
11
+
12
+ The simple way:
13
+ $ sudo gem install paysimple
14
+
15
+ Directly from repository:
16
+ $ svn co svn://svn.roundhaus.com/daikini/plugins/paysimple
17
+
18
+ == Requirements:
19
+
20
+ * soap4r 1.5.6 or higher
21
+
22
+ == Configuration:
23
+
24
+ When you signup for a PaySimple account you can setup a source key and optionally a pin and client ip address.
25
+ These are your credentials when using the PaySimple API.
26
+
27
+ PaySimple.key = "123456"
28
+ PaySimple.pin = "topsecret"
29
+ PaySimple.client_ip = "192.168.0.1"
30
+
31
+
32
+ == Usage:
33
+
34
+ require 'paysimple'
35
+
36
+ # Bill Jennifer $12.00 monthly
37
+ begin
38
+ customer_number = PaySimple::Subscription.create(
39
+ :CustomerID => 12345,
40
+ :BillingAddress => {
41
+ :FirstName => "Jennifer",
42
+ :LastName => "Smith"
43
+ },
44
+ :CreditCardData => {
45
+ :CardNumber => '4444555566667779',
46
+ :CardExpiration => '0908'
47
+ },
48
+ :Schedule => :monthly,
49
+ :Next => "2008-09-05",
50
+ :Amount => 12.00
51
+ )
52
+
53
+ puts "Subscription created with Customer Number: #{customer_number}"
54
+ rescue Exception => e
55
+ puts "An error occurred: #{e.message}"
56
+ end
57
+
58
+
59
+ # Update subscription to use new credit card
60
+ begin
61
+ customer_number = 12345
62
+ response = PaySimple::Subscription.update(
63
+ customer_number,
64
+ :CreditCardData => {
65
+ :CardNumber => '4444555566667779',
66
+ :CardExpiration => '0908'
67
+ }
68
+ )
69
+
70
+ puts "Subscription updated"
71
+ rescue Exception => e
72
+ puts "An error occurred: #{e.message}"
73
+ end
74
+
75
+
76
+ # Delete subscription
77
+ begin
78
+ customer_number = 12345
79
+ response = PaySimple::Subscription.delete(customer_number)
80
+
81
+ puts "Subscription removed from active use."
82
+ rescue Exception => e
83
+ puts "An error occurred: #{e.message}"
84
+ end
85
+
86
+
87
+ # Find an existing subscription
88
+ begin
89
+ customer_number = 12345
90
+ customer = PaySimple::Subscription.find(customer_number)
91
+
92
+ puts "Found subscription for #{ [customer["BillingAddress"]["FirstName"], customer["BillingAddress"]["LastName"]].join(" ")}"
93
+ rescue Exception => e
94
+ puts "An error occurred: #{e.message}"
95
+ end
96
+
97
+
98
+ # Process one-time sale against existing subscription
99
+ begin
100
+ customer_number = 12345
101
+ response = PaySimple::Subscription.charge(customer_number, :Amount => 34.56)
102
+
103
+ if response['Response'] == "Approved"
104
+ puts "One-time charge successful."
105
+ else
106
+ puts "An error occurred: #{response['Error']}"
107
+ end
108
+ rescue Exception => e
109
+ puts "An error occurred: #{e.message}"
110
+ end
111
+
112
+
113
+ # Search for transactions
114
+ begin
115
+ response = PaySimple::Subscription.query(
116
+ [
117
+ { :Field => 'amount', :Type => 'gt', :Value => '5.0' }
118
+ ]
119
+ )
120
+
121
+ response.transactions.each do |transaction|
122
+ puts "CustomerID = #{transaction['CustomerID']}, Amount = #{transaction['Details']['Amount']}"
123
+ end
124
+ rescue Exception => e
125
+ puts "An error occurred: #{e.message}"
126
+ end
127
+
128
+
129
+ == LICENSE:
130
+
131
+ paysimple is licensed under the MIT License.
132
+
133
+ Copyright (c) 2007 [Jonathan Younger], released under the MIT license
134
+
135
+ Permission is hereby granted, free of charge, to any person obtaining a copy
136
+ of this software and associated documentation files (the "Software"), to deal
137
+ in the Software without restriction, including without limitation the rights
138
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
139
+ copies of the Software, and to permit persons to whom the Software is
140
+ furnished to do so, subject to the following conditions:
141
+
142
+ The above copyright notice and this permission notice shall be included in
143
+ all copies or substantial portions of the Software.
144
+
145
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
146
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
147
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
148
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
149
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
150
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
151
+ THE SOFTWARE.
152
+
@@ -0,0 +1,37 @@
1
+ require 'rubygems'
2
+ require 'hoe'
3
+ require 'rake'
4
+ require 'rake/testtask'
5
+ require 'rake/rdoctask'
6
+ require './lib/paysimple.rb'
7
+
8
+ Hoe.new('paysimple', PaySimple::VERSION) do |p|
9
+ p.rubyforge_name = 'paysimple'
10
+ p.author = ["Jonathan Younger"]
11
+ p.email = ["jonathan@daikini.com"]
12
+ p.summary = "Ruby library for the PaySimple payment gateway."
13
+ p.description = p.paragraphs_of('README.txt', 2..5).join("\n\n")
14
+ p.url = "http://paysimple.rubyforge.org/"
15
+ p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
16
+ p.remote_rdoc_dir = "" # Release to root
17
+ p.extra_deps << ["soap4r", ">= 1.5.6"]
18
+ end
19
+
20
+ desc 'Default: run unit tests.'
21
+ task :default => :test
22
+
23
+ desc 'Test the paysimple plugin.'
24
+ Rake::TestTask.new(:test) do |t|
25
+ t.libs << 'lib'
26
+ t.pattern = 'test/**/*_test.rb'
27
+ t.verbose = true
28
+ end
29
+
30
+ desc 'Generate documentation for the paysimple plugin.'
31
+ Rake::RDocTask.new(:rdoc) do |rdoc|
32
+ rdoc.rdoc_dir = 'rdoc'
33
+ rdoc.title = 'PaySimple'
34
+ rdoc.options << '--line-numbers' << '--inline-source'
35
+ rdoc.rdoc_files.include('README')
36
+ rdoc.rdoc_files.include('lib/**/*.rb')
37
+ end
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'paysimple'
@@ -0,0 +1,256 @@
1
+ require 'rubygems'
2
+ gem 'soap4r', '>= 1.5.6' # 1.5.6 or higher
3
+ require 'soap/wsdlDriver'
4
+ require 'digest/sha1'
5
+
6
+ # [PaySimple](http://www.paysimple.com) is a payment gateway providing credit card
7
+ # processing, check processing and recurring / subscription billing services.
8
+ #
9
+ # This library provides a simple interface to find, create, edit, delete, and query subscriptions
10
+ # using the PaySimple SOAP API. [PaySimple API](https://www.usaepay.com/developer/docs/beta5)
11
+ #
12
+ # == Installation
13
+ #
14
+ # The simple way:
15
+ # $ sudo gem install paysimple
16
+ #
17
+ # Directly from repository:
18
+ # $ ./script/plugin install svn://svn.roundhaus.com/daikini/plugins/paysimple
19
+ #
20
+ # Directly from repository using piston:
21
+ # $ piston import svn://svn.roundhaus.com/daikini/plugins/paysimple vendor/plugins/paysimple
22
+ #
23
+ # == Configuration
24
+ #
25
+ # When you signup for a PaySimple account you can setup a source key and optionally a pin and client ip address.
26
+ # These are your credentials when using the PaySimple API.
27
+ #
28
+ # PaySimple.key = "123456"
29
+ # PaySimple.pin = "topsecret"
30
+ # PaySimple.client_ip = "192.168.0.1"
31
+ #
32
+ class PaySimple
33
+ VERSION = "1.0.0"
34
+ WSDL_URL = File.dirname(__FILE__) + '/usaepay.wsdl'
35
+
36
+ class << self
37
+ attr_accessor :key, :pin, :client_ip
38
+ end
39
+ self.key = "TestMerchant"
40
+
41
+ class Subscription
42
+ class << self
43
+ # # Bill Jennifer $12.00 monthly
44
+ # begin
45
+ # customer_number = PaySimple::Subscription.create(
46
+ # :CustomerID => 12345,
47
+ # :BillingAddress => {
48
+ # :FirstName => "Jennifer",
49
+ # :LastName => "Smith"
50
+ # },
51
+ # :CreditCardData => {
52
+ # :CardNumber => '4444555566667779',
53
+ # :CardExpiration => '0908'
54
+ # },
55
+ # :Schedule => :monthly,
56
+ # :Next => "2008-09-05",
57
+ # :Amount => 12.00
58
+ # )
59
+ #
60
+ # puts "Subscription created with Customer Number: #{customer_number}"
61
+ # rescue Exception => e
62
+ # puts "An error occurred: #{e.message}"
63
+ # end
64
+ def create(options)
65
+ PaySimple.send_request(:addCustomer, { :NumLeft => 0, :Enabled => true }.merge(options))
66
+ end
67
+
68
+ # # Update subscription to use new credit card
69
+ # begin
70
+ # customer_number = 12345
71
+ # response = PaySimple::Subscription.update(
72
+ # customer_number,
73
+ # :CreditCardData => {
74
+ # :CardNumber => '4444555566667779',
75
+ # :CardExpiration => '0908'
76
+ # }
77
+ # )
78
+ #
79
+ # puts "Subscription updated"
80
+ # rescue Exception => e
81
+ # puts "An error occurred: #{e.message}"
82
+ # end
83
+ def update(customer_number, options)
84
+ customer = find(customer_number)
85
+ options = PaySimple.symbolize_hash(options)
86
+
87
+ # Add the existing customer properties to the options hash unless they already exist
88
+ [
89
+ :CustomerID,
90
+ :SendReceipt,
91
+ :ReceiptNote,
92
+ :Notes,
93
+ :User,
94
+ :Source,
95
+ :Schedule,
96
+ :Next,
97
+ :NumLeft,
98
+ :Amount,
99
+ :Enabled,
100
+ :CustomData,
101
+ :Description,
102
+ :OrderID
103
+ ].each do |property|
104
+ options[property] = customer[property.to_s] unless options.has_key?(property)
105
+ end
106
+
107
+ # Add the existing customer address properties to the options hash unless they already exist
108
+ options[:BillingAddress] ||= {}
109
+ [
110
+ :FirstName,
111
+ :LastName,
112
+ :Company,
113
+ :Street,
114
+ :Street2,
115
+ :City,
116
+ :State,
117
+ :Zip,
118
+ :Country,
119
+ :Phone,
120
+ :Fax,
121
+ :Email
122
+ ].each do |property|
123
+ options[:BillingAddress][property] = customer["BillingAddress"][property.to_s] unless options[:BillingAddress].has_key?(property)
124
+ end
125
+
126
+ # Add the existing customer credit card properties to the options hash unless they already exist
127
+ options[:CreditCardData] ||= {}
128
+ [
129
+ :CardNumber,
130
+ :CardExpiration,
131
+ :CardCode,
132
+ :AvsStreet,
133
+ :AvsZip,
134
+ :CardPresent,
135
+ :MagStripe,
136
+ :TermType,
137
+ :MagSupport,
138
+ :XID,
139
+ :CAVV,
140
+ :ECI,
141
+ :InternalCardAuth,
142
+ :Pares
143
+ ].each do |property|
144
+ options[:CreditCardData][property] = customer["CreditCardData"][property.to_s] unless options[:CreditCardData].has_key?(property)
145
+ end
146
+
147
+ # Add the existing customer check properties to the options hash unless they already exist
148
+ options[:CheckData] ||= {}
149
+ [
150
+ :CheckNumber,
151
+ :Routing,
152
+ :Account,
153
+ :SSN,
154
+ :DriversLicense,
155
+ :DriversLicenseState
156
+ ].each do |property|
157
+ options[:CheckData][property] = customer["CheckData"][property.to_s] unless options[:CheckData].has_key?(property)
158
+ end
159
+
160
+ PaySimple.send_request(:updateCustomer, customer_number, options)
161
+ end
162
+
163
+ # # Delete subscription
164
+ # begin
165
+ # customer_number = 12345
166
+ # response = PaySimple::Subscription.delete(customer_number)
167
+ #
168
+ # puts "Subscription removed from active use."
169
+ # rescue Exception => e
170
+ # puts "An error occurred: #{e.message}"
171
+ # end
172
+ def delete(customer_number)
173
+ PaySimple.send_request(:deleteCustomer, customer_number)
174
+ end
175
+
176
+ # # Find an existing subscription
177
+ # begin
178
+ # customer_number = 12345
179
+ # customer = PaySimple::Subscription.find(customer_number)
180
+ #
181
+ # puts "Found subscription for #{ [customer["BillingAddress"]["FirstName"], customer["BillingAddress"]["LastName"]].join(" ")}"
182
+ # rescue Exception => e
183
+ # puts "An error occurred: #{e.message}"
184
+ # end
185
+ def find(customer_number)
186
+ PaySimple.send_request(:getCustomer, customer_number)
187
+ end
188
+
189
+ # # Process one-time sale against existing subscription
190
+ # begin
191
+ # customer_number = 12345
192
+ # response = PaySimple::Subscription.charge(customer_number, :Amount => 34.56)
193
+ #
194
+ # if response['Response'] == "Approved"
195
+ # puts "One-time charge successful."
196
+ # else
197
+ # puts "An error occurred: #{response['Error']}"
198
+ # end
199
+ # rescue Exception => e
200
+ # puts "An error occurred: #{e.message}"
201
+ # end
202
+ def charge(customer_number, options, auth_only = false)
203
+ PaySimple.send_request(:runCustomerSale, customer_number, options, auth_only)
204
+ end
205
+
206
+ # # Search for transactions
207
+ # begin
208
+ # response = PaySimple::Subscription.query(
209
+ # [
210
+ # { :Field => 'amount', :Type => 'gt', :Value => '5.0' }
211
+ # ]
212
+ # )
213
+ #
214
+ # response.transactions.each do |transaction|
215
+ # puts "CustomerID = #{transaction['CustomerID']}, Amount = #{transaction['Details']['Amount']}"
216
+ # end
217
+ # rescue Exception => e
218
+ # puts "An error occurred: #{e.message}"
219
+ # end
220
+ def query(options)
221
+ match_all = options.delete(:match_all)
222
+ start = options.delete(:start) || 0
223
+ limit = options.delete(:limit) || 100
224
+ PaySimple.send_request(:searchTransactions, options, match_all, start, limit)
225
+ end
226
+ end
227
+ end
228
+
229
+ private
230
+ class << self
231
+ def symbolize_hash(hash)
232
+ hash.inject({}) { |h,(k,v)| h[k.to_sym] = v; h }
233
+ end
234
+
235
+ def token
236
+ seed = "#{Time.now.to_i}#{rand(999999)}"
237
+ hash = Digest::SHA1.hexdigest([key, seed, pin].join)
238
+ {
239
+ 'SourceKey' => key,
240
+ 'PinHash' => {
241
+ 'Type' => "sha1",
242
+ 'Seed' => seed,
243
+ 'HashValue' => hash
244
+ },
245
+ 'ClientIP' => client_ip
246
+ }
247
+ end
248
+
249
+ def send_request(request, *args)
250
+ @driver ||= SOAP::WSDLDriverFactory.new(WSDL_URL).create_rpc_driver
251
+ @driver.options["protocol.http.ssl_config.verify_mode"] = nil
252
+ @driver.send(request, token, *args)
253
+ end
254
+ end
255
+
256
+ end