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/prismpay_am.rb CHANGED
@@ -17,7 +17,7 @@ module ActiveMerchant
17
17
  def initialize(options = { })
18
18
  requires!(options, :login)
19
19
  @options = options
20
- @gateway = PrismPay.new(options)
20
+ @gateway = PrismPay::PrismPay.new(options)
21
21
  super
22
22
  end
23
23
 
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
@@ -1,4 +1,4 @@
1
1
  require "prismpay"
2
2
 
3
- describe PrismCreditResponse, "" do
3
+ describe PrismPay::PrismCreditResponse, "" do
4
4
  end
@@ -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
 
@@ -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