prismpay 0.0.0 → 0.0.1
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/prism_credit_response.rb +119 -111
- data/lib/prismpay.rb +298 -264
- data/lib/prismpay_am.rb +1 -1
- data/lib/webpay.rb +211 -0
- data/spec/prism_credit_response_spec.rb +1 -1
- data/spec/prismpay_spec.rb +32 -32
- data/spec/webpay_spec.rb +17 -0
- data/spec/webpay_spec.rb~ +10 -0
- metadata +28 -13
data/lib/prismpay_am.rb
CHANGED
data/lib/webpay.rb
ADDED
@@ -0,0 +1,211 @@
|
|
1
|
+
require 'openssl' # required for encryption
|
2
|
+
require 'erb' # required for url_escaping
|
3
|
+
require 'yaml' # yaml parsing
|
4
|
+
|
5
|
+
module PrismPay
|
6
|
+
|
7
|
+
class Form
|
8
|
+
attr_reader :action, :id, :postback
|
9
|
+
|
10
|
+
def initialize(hash)
|
11
|
+
# takes a hash of form {action => {formid => url}}
|
12
|
+
# this is not ideal could come up with a much cleaner way...
|
13
|
+
# brains resources going elsewhere for now though
|
14
|
+
|
15
|
+
@action = hash.keys.first
|
16
|
+
@id = hash[@action].keys.first
|
17
|
+
@postback = hash[@action][@id]
|
18
|
+
end
|
19
|
+
|
20
|
+
end # Form
|
21
|
+
|
22
|
+
class WebpayPostback
|
23
|
+
# parent class for postbacks comming from transactions processed
|
24
|
+
# through the prismpay webpay interface
|
25
|
+
end # WebpayPostback
|
26
|
+
|
27
|
+
class AddProfilePB < WebpayPostback
|
28
|
+
# specifics to addprofile postback
|
29
|
+
end # AddProfilePB
|
30
|
+
|
31
|
+
class CreditSalePB < WebpayPostback
|
32
|
+
# specific to creditsale postback
|
33
|
+
end # CreditSalePB
|
34
|
+
|
35
|
+
class Webpay
|
36
|
+
# class to provide an interface to the prismpay webpay interface
|
37
|
+
# Somewhat problematic in that it is closely linked to webforms
|
38
|
+
# right now mainly providing methods necessary to implement a form
|
39
|
+
|
40
|
+
|
41
|
+
# an incomplete action map.. these are going to be what we are
|
42
|
+
# initially using to map some symbols to their corresponding
|
43
|
+
# webpay cgi actions
|
44
|
+
CGI_ACTIONS = { :profile_add => 'profile_add',
|
45
|
+
:cc_sale => 'ns_quicksale_cc'}
|
46
|
+
|
47
|
+
POST_URL = "https://trans.merchantpartners.com/cgi-bin/WebPay.cgi"
|
48
|
+
|
49
|
+
attr_reader :session_id
|
50
|
+
|
51
|
+
def initialize(config_file = "")
|
52
|
+
# make sure the file exists... if not wreck
|
53
|
+
# instance variables: form/postback_list, session_id, acct_id,
|
54
|
+
# password, subid, encryption_key
|
55
|
+
|
56
|
+
myopts = YAML.load_file(config_file)
|
57
|
+
@login = myopts["login"]
|
58
|
+
@session_id = myopts["session_id"]
|
59
|
+
@key = hexstr_to_str(myopts["key"])
|
60
|
+
@password = myopts["password"] # assigns nil if not in config
|
61
|
+
@subid = myopts["subid"] # assigns nil if not in config
|
62
|
+
|
63
|
+
# example of form_ids hash
|
64
|
+
|
65
|
+
# this could use some rethinking Went this route because it was
|
66
|
+
# the cleanest looking yaml config file
|
67
|
+
|
68
|
+
# form_ids = { action => {form_id1 => postback_url},
|
69
|
+
# action => {form_id2 => postback_url}}
|
70
|
+
|
71
|
+
@form_ids = [] # list of Form objs
|
72
|
+
myopts["form_ids"].each {|action, hash|
|
73
|
+
# ugly way to do this... No time to worry about that now though
|
74
|
+
@form_ids << Form.new({action => hash} )
|
75
|
+
}
|
76
|
+
end
|
77
|
+
|
78
|
+
|
79
|
+
########################################
|
80
|
+
# TODO: mega repitition.. good place to apply DRY in refactoring
|
81
|
+
# and do some things ruby is awesome at using the action map
|
82
|
+
########################################
|
83
|
+
|
84
|
+
def profile_add_form_id
|
85
|
+
form = nil
|
86
|
+
@form_ids.each{|x|
|
87
|
+
form = x if x.action == 'profile_add'
|
88
|
+
}
|
89
|
+
build_encrypted_form_id form.id
|
90
|
+
end
|
91
|
+
|
92
|
+
def profile_add_postback
|
93
|
+
form = nil
|
94
|
+
@form_ids.each{|x|
|
95
|
+
form = x if x.action == 'profile_add'
|
96
|
+
}
|
97
|
+
encrypt_string(form.postback)
|
98
|
+
end
|
99
|
+
|
100
|
+
def cc_sale_postback
|
101
|
+
form = nil
|
102
|
+
@form_ids.each{|x|
|
103
|
+
form = x if x.action == 'cc_sale'
|
104
|
+
}
|
105
|
+
encrypt_string(form.postback)
|
106
|
+
end
|
107
|
+
|
108
|
+
def cc_sale_form_id(amount)
|
109
|
+
form = nil
|
110
|
+
@form_ids.each{|x|
|
111
|
+
form = x if x.action == 'cc_sale'
|
112
|
+
}
|
113
|
+
build_encrypted_form_id form.id, amount
|
114
|
+
end
|
115
|
+
|
116
|
+
########################################
|
117
|
+
# TODO end the of the last refactor note
|
118
|
+
########################################
|
119
|
+
|
120
|
+
|
121
|
+
def get_formid(hexstr)
|
122
|
+
# returns the formid string to be used when composing our formid
|
123
|
+
# strings. Receives a hexstring generated from their web based
|
124
|
+
# form creation cms
|
125
|
+
str = decrypt_string(hexstr)
|
126
|
+
str.split(":")[2]
|
127
|
+
end
|
128
|
+
|
129
|
+
|
130
|
+
# This is kinda silly fast fix for something
|
131
|
+
# problematic because we don't have the @key
|
132
|
+
|
133
|
+
# def self.decrypt_string(hexstr)
|
134
|
+
# # maybe pass the need to convert from the hexstr
|
135
|
+
# str = [hexstr].pack 'H*'
|
136
|
+
# retstr = ""
|
137
|
+
# cipher = OpenSSL::Cipher.new('des-ede3')
|
138
|
+
# cipher.decrypt
|
139
|
+
# cipher.key = @key
|
140
|
+
# retstr << cipher.update(str)
|
141
|
+
# retstr << cipher.final
|
142
|
+
# return retstr
|
143
|
+
# end
|
144
|
+
|
145
|
+
|
146
|
+
def decrypt_string(hexstr)
|
147
|
+
# maybe pass the need to convert from the hexstr
|
148
|
+
str = hexstr_to_str(hexstr)
|
149
|
+
retstr = ""
|
150
|
+
cipher = OpenSSL::Cipher.new('des-ede3')
|
151
|
+
cipher.decrypt
|
152
|
+
cipher.key = @key
|
153
|
+
retstr << cipher.update(str)
|
154
|
+
retstr << cipher.final
|
155
|
+
return retstr
|
156
|
+
end
|
157
|
+
|
158
|
+
def build_encrypted_form_id(formid, amount="")
|
159
|
+
# build the encrypted formid hexstr
|
160
|
+
# acctid:subid:formid:amount:
|
161
|
+
str = "#{@login}:#{@subid}:#{formid}:#{amount}:"
|
162
|
+
encrypt_string(str)
|
163
|
+
end
|
164
|
+
|
165
|
+
def build_customdata(options = {})
|
166
|
+
# build encrypted string for customdata field
|
167
|
+
# the values of this need to be url_encrypted
|
168
|
+
str = ""
|
169
|
+
unless options.empty?
|
170
|
+
# build the string
|
171
|
+
options.each{|key, val|
|
172
|
+
str << "&" unless str.empty?
|
173
|
+
str << "#{ERB::Util::url_encode(key)}="
|
174
|
+
str << "#{ERB::Util::url_encode(val)}"
|
175
|
+
}
|
176
|
+
str = url_encrypt_string(str)
|
177
|
+
end
|
178
|
+
return str
|
179
|
+
end
|
180
|
+
|
181
|
+
def url_encrypt_string(str)
|
182
|
+
str = ERB::Util::url_encode(str)
|
183
|
+
encrypt_string(str)
|
184
|
+
end
|
185
|
+
|
186
|
+
def encrypt_string(str)
|
187
|
+
# returns the hexstr for the url
|
188
|
+
# TODO: need to uri escape the string before encrypting
|
189
|
+
retstr = ""
|
190
|
+
cipher = OpenSSL::Cipher.new("des-ede3")
|
191
|
+
cipher.encrypt
|
192
|
+
cipher.key = @key
|
193
|
+
retstr << cipher.update(str)
|
194
|
+
retstr << cipher.final
|
195
|
+
retstr = str_to_hexstr(retstr)
|
196
|
+
return retstr
|
197
|
+
end
|
198
|
+
|
199
|
+
|
200
|
+
def str_to_hexstr(hexstr)
|
201
|
+
hexstr.unpack('H*').first
|
202
|
+
end
|
203
|
+
|
204
|
+
|
205
|
+
def hexstr_to_str(str)
|
206
|
+
[str].pack 'H*'
|
207
|
+
end
|
208
|
+
|
209
|
+
end # class Webpay
|
210
|
+
|
211
|
+
end #module PrismPay
|
data/spec/prismpay_spec.rb
CHANGED
@@ -62,10 +62,10 @@ end
|
|
62
62
|
# Start Tests
|
63
63
|
############################################################
|
64
64
|
|
65
|
-
describe PrismPay, "#cc_purchase" do
|
65
|
+
describe PrismPay::PrismPay, "#cc_purchase" do
|
66
66
|
it "returns successful sale for sane values" do
|
67
67
|
amount = "10.00"
|
68
|
-
cc = CreditCard.new({})
|
68
|
+
cc = PrismPay::CreditCard.new({})
|
69
69
|
cc.number = 5454545454545454
|
70
70
|
cc.month = 7
|
71
71
|
cc.year = 14
|
@@ -88,11 +88,11 @@ describe PrismPay, "#cc_purchase" do
|
|
88
88
|
:address => addr2
|
89
89
|
}
|
90
90
|
|
91
|
-
gateway = PrismPay.new(options)
|
91
|
+
gateway = PrismPay::PrismPay.new(options)
|
92
92
|
|
93
93
|
purchase_amount = "23.32"
|
94
94
|
|
95
|
-
response = gateway.cc_purchase(purchase_amount, cc, options)
|
95
|
+
response = gateway.cc_purchase(purchase_amount, cc, options).soap_response
|
96
96
|
|
97
97
|
save_void_trans(response.body[:multi_ref][:orderid],
|
98
98
|
response.body[:multi_ref][:historyid],
|
@@ -102,10 +102,10 @@ describe PrismPay, "#cc_purchase" do
|
|
102
102
|
end
|
103
103
|
end
|
104
104
|
|
105
|
-
describe PrismPay, "#cc_authorize" do
|
105
|
+
describe PrismPay::PrismPay, "#cc_authorize" do
|
106
106
|
it "returns successful auth for sane values and saves orderid" do
|
107
107
|
amount = "10.00"
|
108
|
-
cc = CreditCard.new({})
|
108
|
+
cc = PrismPay::CreditCard.new({})
|
109
109
|
cc.number = 5454545454545454
|
110
110
|
cc.month = 7
|
111
111
|
cc.year = 14
|
@@ -128,11 +128,11 @@ describe PrismPay, "#cc_authorize" do
|
|
128
128
|
:address => addr2
|
129
129
|
}
|
130
130
|
|
131
|
-
gateway = PrismPay.new(options)
|
131
|
+
gateway = PrismPay::PrismPay.new(options)
|
132
132
|
|
133
133
|
purchase_amount = "23.32"
|
134
134
|
|
135
|
-
response = gateway.cc_authorize(purchase_amount, cc, options)
|
135
|
+
response = gateway.cc_authorize(purchase_amount, cc, options).soap_response
|
136
136
|
|
137
137
|
save_auth_trans(response.body[:multi_ref][:orderid],
|
138
138
|
response.body[:multi_ref][:historyid],
|
@@ -143,7 +143,7 @@ describe PrismPay, "#cc_authorize" do
|
|
143
143
|
end
|
144
144
|
|
145
145
|
|
146
|
-
describe PrismPay, "#build_address" do
|
146
|
+
describe PrismPay::PrismPay, "#build_address" do
|
147
147
|
addr1 = {
|
148
148
|
:name => "testee mcgee",
|
149
149
|
:company => "widgets R us",
|
@@ -164,7 +164,7 @@ describe PrismPay, "#build_address" do
|
|
164
164
|
:country => "US"
|
165
165
|
}
|
166
166
|
|
167
|
-
gw = PrismPay.new(addr1)
|
167
|
+
gw = PrismPay::PrismPay.new(addr1)
|
168
168
|
|
169
169
|
it "should return string" do
|
170
170
|
gw.build_address(addr1).class.should eq(String)
|
@@ -182,9 +182,9 @@ describe PrismPay, "#build_address" do
|
|
182
182
|
|
183
183
|
end
|
184
184
|
|
185
|
-
describe PrismPay, "#build_cc_sale_auth" do
|
185
|
+
describe PrismPay::PrismPay, "#build_cc_sale_auth" do
|
186
186
|
amount = "10.00"
|
187
|
-
cc = CreditCard.new({})
|
187
|
+
cc = PrismPay::CreditCard.new({})
|
188
188
|
cc.number = 5454545454545454
|
189
189
|
cc.month = 7
|
190
190
|
cc.year = 14
|
@@ -209,18 +209,18 @@ describe PrismPay, "#build_cc_sale_auth" do
|
|
209
209
|
|
210
210
|
|
211
211
|
it "should return xml builder block for sale/auth" do
|
212
|
-
gw = PrismPay.new(options)
|
212
|
+
gw = PrismPay::PrismPay.new(options)
|
213
213
|
gw.build_cc_sale_auth(amount, cc, options).class.should eq(Proc)
|
214
214
|
end
|
215
215
|
|
216
216
|
it "should take 1 arg" do
|
217
|
-
gw = PrismPay.new(options)
|
217
|
+
gw = PrismPay::PrismPay.new(options)
|
218
218
|
myproc = gw.build_cc_sale_auth(amount, cc, options)
|
219
219
|
myproc.arity.should > 0
|
220
220
|
end
|
221
221
|
|
222
222
|
it "should create xml object when passed to builder" do
|
223
|
-
gw = PrismPay.new(options)
|
223
|
+
gw = PrismPay::PrismPay.new(options)
|
224
224
|
myproc = gw.build_cc_sale_auth(amount, cc, options)
|
225
225
|
str = builder_wrapper(&myproc)
|
226
226
|
str.should =~ /^<ccinfo[^&]*<\/ccinfo>$/ #match the object
|
@@ -228,29 +228,29 @@ describe PrismPay, "#build_cc_sale_auth" do
|
|
228
228
|
|
229
229
|
end
|
230
230
|
|
231
|
-
describe PrismPay, "build_cc_void" do
|
231
|
+
describe PrismPay::PrismPay, "build_cc_void" do
|
232
232
|
it "should return xml builder block for void" do
|
233
|
-
gw = PrismPay.new({})
|
233
|
+
gw = PrismPay::PrismPay.new({})
|
234
234
|
gw.build_cc_void("", {}).class.should eq(Proc)
|
235
235
|
end
|
236
236
|
|
237
237
|
end
|
238
238
|
|
239
|
-
describe PrismPay, "build_cc_capture" do
|
239
|
+
describe PrismPay::PrismPay, "build_cc_capture" do
|
240
240
|
it "should return xml builder block for capture" do
|
241
|
-
gw = PrismPay.new({})
|
241
|
+
gw = PrismPay::PrismPay.new({})
|
242
242
|
gw.build_cc_capture("", "", {}).class.should eq(Proc)
|
243
243
|
end
|
244
244
|
end
|
245
245
|
|
246
|
-
describe PrismPay, "build_credit" do
|
246
|
+
describe PrismPay::PrismPay, "build_credit" do
|
247
247
|
it "should return xml builder block for refund" do
|
248
|
-
gw = PrismPay.new({})
|
248
|
+
gw = PrismPay::PrismPay.new({})
|
249
249
|
gw.build_credit("", "", {}).class.should eq(Proc)
|
250
250
|
end
|
251
251
|
end
|
252
252
|
|
253
|
-
describe PrismPay, "cc_capture" do
|
253
|
+
describe PrismPay::PrismPay, "cc_capture" do
|
254
254
|
it "should capture an auth successfully with sane values" do
|
255
255
|
options = { }
|
256
256
|
values = get_last_trans("./data~")
|
@@ -259,9 +259,9 @@ describe PrismPay, "cc_capture" do
|
|
259
259
|
authcode = values[:historyid]
|
260
260
|
amount = values[:amount]
|
261
261
|
|
262
|
-
gw = PrismPay.new(options)
|
262
|
+
gw = PrismPay::PrismPay.new(options)
|
263
263
|
|
264
|
-
response = gw.cc_capture(amount, authcode, options)
|
264
|
+
response = gw.cc_capture(amount, authcode, options).soap_response
|
265
265
|
|
266
266
|
response.body[:multi_ref][:status].should =~ /Approved/
|
267
267
|
|
@@ -271,7 +271,7 @@ describe PrismPay, "cc_capture" do
|
|
271
271
|
end
|
272
272
|
end
|
273
273
|
|
274
|
-
describe PrismPay, "cc_void" do
|
274
|
+
describe PrismPay::PrismPay, "cc_void" do
|
275
275
|
it "should void a sale" do
|
276
276
|
options = { }
|
277
277
|
values = get_last_trans("./void~")
|
@@ -281,9 +281,9 @@ describe PrismPay, "cc_void" do
|
|
281
281
|
options[:amount] = values[:amount]
|
282
282
|
amount = options[:amount]
|
283
283
|
|
284
|
-
gw = PrismPay.new(options)
|
284
|
+
gw = PrismPay::PrismPay.new(options)
|
285
285
|
|
286
|
-
response = gw.cc_void(authcode, options)
|
286
|
+
response = gw.cc_void(authcode, options).soap_response
|
287
287
|
|
288
288
|
response.body[:multi_ref][:status].should =~ /Approved/
|
289
289
|
|
@@ -293,11 +293,11 @@ describe PrismPay, "cc_void" do
|
|
293
293
|
end
|
294
294
|
end
|
295
295
|
|
296
|
-
describe PrismPay, "credit" do
|
296
|
+
describe PrismPay::PrismPay, "credit" do
|
297
297
|
it "should refund a sale" do
|
298
298
|
|
299
299
|
amount = "10.00"
|
300
|
-
cc = CreditCard.new({})
|
300
|
+
cc = PrismPay::CreditCard.new({})
|
301
301
|
cc.number = 5454545454545454
|
302
302
|
cc.month = 7
|
303
303
|
cc.year = 14
|
@@ -320,9 +320,9 @@ describe PrismPay, "credit" do
|
|
320
320
|
:address => addr2
|
321
321
|
}
|
322
322
|
|
323
|
-
gateway = PrismPay.new(options)
|
323
|
+
gateway = PrismPay::PrismPay.new(options)
|
324
324
|
|
325
|
-
response = gateway.cc_purchase(amount, cc, options)
|
325
|
+
response = gateway.cc_purchase(amount, cc, options).soap_response
|
326
326
|
|
327
327
|
save_refund_trans(response.body[:multi_ref][:orderid],
|
328
328
|
response.body[:multi_ref][:historyid],
|
@@ -333,7 +333,7 @@ describe PrismPay, "credit" do
|
|
333
333
|
authcode = values[:historyid]
|
334
334
|
|
335
335
|
options[:orderid] = oid = values[:order_id]
|
336
|
-
response = gateway.credit(values[:amount], authcode, options)
|
336
|
+
response = gateway.credit(values[:amount], authcode, options).soap_response
|
337
337
|
|
338
338
|
response.body[:multi_ref][:status].should =~ /Approved/
|
339
339
|
|
data/spec/webpay_spec.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'prismpay'
|
2
|
+
require 'webpay'
|
3
|
+
|
4
|
+
describe PrismPay::Webpay, "This is the planned class we'll see what happens"
|
5
|
+
|
6
|
+
describe PrismPay::Webpay do
|
7
|
+
it "converts hexstr to their hexvals"
|
8
|
+
it "should test the initialize and config file loading"
|
9
|
+
it "should bad config happen wreck with proper errors"
|
10
|
+
it "needs to test the get_formid"
|
11
|
+
it "need to test the encrypt and decrypt methods"
|
12
|
+
it "need to test formid building"
|
13
|
+
it "need to test the customdata building"
|
14
|
+
it "need to test other junk I'm sure"
|
15
|
+
it "need to test the postback processing functions"
|
16
|
+
it "need a way to map the postback processing junk to action"
|
17
|
+
end
|