paysimple 1.0.0

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.
@@ -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