prismpay 0.0.8 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,624 +1,11 @@
1
1
  require 'savon'
2
2
  require 'activemerchant'
3
- require 'prism_credit_response'
4
- require 'webpay'
5
3
  require 'builder'
6
-
7
- module PrismPay
8
-
9
- class PrismPay
10
- # this class will manage the connection to the gateway and handle
11
- # transactions
12
-
13
- # WSDL = "https://trans.myprismpay.com/MPWeb/services/TransactionService?wsdl"
14
- WSDL = File.expand_path("../TransactionService.xml", __FILE__)
15
-
16
- ACH_CHECK_ACCT_TYPE = {"checking" => 1, "savings" => 2}
17
- ACH_SEC_CODES = %w(POP, ARC, TEL, PPD, ICL, RCK, BOC, CCDN)
18
-
19
- attr_accessor :acctid, :password
20
- attr_reader :client
21
-
22
- def initialize(options = {})
23
- merchant_info = options
24
- merchant_info.merge!({:login => 'TEST0'}) unless merchant_info[:login]
25
-
26
- if merchant_info.respond_to?("has_key?")
27
- @acctid = merchant_info[:login] if merchant_info.has_key?(:login)
28
- @password = merchant_info[:password] if merchant_info.has_key?(:password)
29
- end
30
-
31
- @client = Savon::Client.new(WSDL) # initialize savon client
32
-
33
- end
34
-
35
-
36
- ############################################################
37
- # CreditCard SOAP methods:
38
- # ###########################################################
39
- # TODO: the profile methods should be refactored to be either for
40
- # credit cards or for ACH transactions
41
- ############################################################
42
-
43
- def profile_sale(amount, profile_id, last_four, options = {})
44
- # response = @client.request :process_profile_sale do
45
- response = @client.request 'processProfileSale' do
46
- http.auth.ssl.verify_mode = :none
47
- soap.body &build_profile_sale(amount, profile_id, last_four, options)
48
- end
49
- PrismCreditResponse.new(response)
50
- end
51
-
52
-
53
- def profile_retrieve(options = {})
54
- # process a profile retrieve request
55
- # response = @client.request :process_profile_retrieve do
56
- response = @client.request 'processProfileRetrieve' do
57
- http.auth.ssl.verify_mode = :none
58
- soap.body &build_profile_retrieve(options)
59
- end
60
- end
61
-
62
-
63
- def cc_purchase(amount, creditcard, options ={})
64
- # process a credit card sale and right now return the savon response
65
- # The savon response needs to be mapped back into the proper response
66
- # fields
67
-
68
- # need to merge the gateway instance options with the options
69
-
70
- # response = @client.request :process_cc_sale do
71
- response = @client.request 'processCCSale' do
72
- http.auth.ssl.verify_mode = :none
73
- soap.body &build_cc_sale_auth(amount, creditcard, options)
74
- end
75
-
76
- PrismCreditResponse.new(response)
77
-
78
- end
79
-
80
-
81
- def cc_authorize(amount, creditcard, options = {})
82
- # reserve funds for future captures
83
- # response = @client.request :process_cc_auth do
84
- response = @client.request 'processCCAuth' do
85
- http.auth.ssl.verify_mode = :none
86
- soap.body &build_cc_sale_auth(amount, creditcard, options)
87
- end
88
-
89
- PrismCreditResponse.new(response)
90
- end
91
-
92
-
93
- def cc_capture(amount, authorization, pp_txn_id, options = {})
94
- # Captures reservered funds from previous auths
95
- # need to put some validation into these methods before
96
- # making the call to the build methods
97
-
98
- # response = @client.request :process_cc_post do
99
- response = @client.request 'processCCPost' do
100
- http.auth.ssl.verify_mode = :none
101
- soap.body &build_cc_capture(amount, authorization, pp_txn_id, options)
102
- end
103
-
104
- PrismCreditResponse.new(response)
105
- end
106
-
107
-
108
- def cc_void(amount, identification, pp_txn_id, options = {})
109
- # voids previous transactions
110
- # response = @client.request :process_cc_void do
111
- response = @client.request 'processCCVoid' do
112
- http.auth.ssl.verify_mode = :none
113
- soap.body &build_cc_void(amount, identification, pp_txn_id, options)
114
- end
115
-
116
- PrismCreditResponse.new(response)
117
- end
118
-
119
-
120
- def credit(amount, identification, pp_txn_id, options = {})
121
- # applies credit back against previous transaction
122
- # response = @client.request :process_credit do
123
- response = @client.request 'processCredit' do
124
- http.auth.ssl.verify_mode = :none
125
- soap.body &build_credit(amount, identification, pp_txn_id, options)
126
- end
127
-
128
- PrismCreditResponse.new(response)
129
- end
130
-
131
- ############################################################
132
- # ACH Methods
133
- ############################################################
134
- # These should be for normal ACH transactions ie: transactions
135
- # coming from a client into a prismpay vendor.
136
- ############################################################
137
-
138
- # def ach_sale(amount, bank_account, options ={})
139
- # response = @client.request :process_ach_sale do
140
- # http.auth.ssl.verify_mode = :none
141
- # soap.body &build_ach_sale()
142
- # end
143
-
144
- # PrismCreditResponse.new(response)
145
- # end
146
-
147
- # def ach_credit(amount, auth, pp_txn_id, options = {})
148
- # response = @client.request :process_ach_credit do
149
- # http.auth.ssl.verify_mode = :none
150
- # soap.body &build_ach_credit()
151
- # end
152
-
153
- # PrismCreditResponse.new(response)
154
- # end
155
-
156
-
157
- ############################################################
158
- # ACH Ext Check Sale
159
- ############################################################
160
- # These will be used for checks coming in which will have
161
- # disbursments to a third party as well
162
- ############################################################
163
-
164
- def ext_ach_sale(amount, bank_account, options = {})
165
- # response = @client.request :process_ext_ach_sale do
166
- response = @client.request 'processExtACHSale' do
167
- http.auth.ssl.verify_mode = :none
168
- soap.body &build_ext_ach_sale_disburse(amount, bank_account, options)
169
- end
170
-
171
- PrismCreditResponse.new(response)
172
- end
173
-
174
- ############################################################
175
- # ext_ach_void doesn't work in generic testing accounts
176
- ############################################################
177
- def ext_ach_void(identification, pp_txn_id, options = {})
178
- # response = @client.request :process_ext_ach_void do
179
- response = @client.request 'processExtACHVoid' do
180
- http.auth.ssl.verify_mode = :none
181
- soap.body &build_ext_ach_refund_void(nil, identification,
182
- pp_txn_id, options)
183
- end
184
-
185
- PrismCreditResponse.new(response)
186
- end
187
-
188
- def ext_ach_refund(amount, identification, pp_txn_id, options = {})
189
- # response = @client.request :process_ext_ach_credit do
190
- response = @client.request 'processExtACHCredit' do
191
- http.auth.ssl.verify_mode = :none
192
- soap.body &build_ext_ach_refund_void(amount, identification,
193
- pp_txn_id, options)
194
- end
195
-
196
- PrismCreditResponse.new(response)
197
- end
198
-
199
- def ext_ach_consumer_disbursement(amount, bank_account, options = {})
200
- # response = @client.request :process_ext_ach_consumer_disbursement do
201
- response = @client.request 'processExtACHConsumerDisbursement' do
202
- http.auth.ssl.verify_mode = :none
203
- soap.body &build_ext_ach_sale_disburse(amount, bank_account, options)
204
- end
205
-
206
- PrismCreditResponse.new(response)
207
- end
208
-
209
-
210
-
211
- # helper methods
212
- private
213
-
214
- def build_address(addr, type= "bill")
215
- # receives a hash that contains the keys for active_merchant
216
- # address and type which should be 'bill' or 'ship'
217
- # returns a str to be eval and included in xml builder block
218
-
219
- if type != "bill" && type != "ship"
220
- type = "bill"
221
- end
222
-
223
- retstr =
224
- "xml.#{type}address('xsi:type' => 'urn:address'){
225
- xml.addr1 '#{addr[:address1]}'
226
- xml.addr2 '#{addr[:address2]}'
227
- xml.city '#{addr[:city]}'
228
- xml.state '#{addr[:state]}'
229
- xml.zip '#{addr[:zip]}'
230
- xml.country '#{addr[:country]}'
231
- }"
232
- end
233
-
234
- def build_profile_retrieve(options = {})
235
- xml_block = Proc.new { |xml|
236
- xml.miscprocess("xsi:type" => "urn:ProfileRetrieve"){
237
- xml.acctid @acctid
238
- xml.merchantpin @password if @password
239
- xml.subid options[:subid] if options[:subid]
240
- xml.last4digits options[:last_four]
241
- xml.userprofileid options[:profileid]
242
- xml.merchantpin options[:merchantpin] if options[:merchantpin]
243
- xml.ipaddress
244
- }
245
- }
246
-
247
- return xml_block
248
- end
249
-
250
- def build_credit(amount, id, pp_txn_id, options)
251
- xml_block = Proc.new { |xml|
252
- xml.miscprocess("xsi:type" => "urn:VoidCreditPost"){
253
- xml.acctid @acctid
254
- xml.merchantpin @password if @password
255
- xml.amount amount
256
- xml.orderid pp_txn_id
257
- xml.historyid id
258
- xml.ipaddress
259
- }
260
- }
261
-
262
- return xml_block
263
- end
264
-
265
- def build_cc_void(amount, auth, pp_txn_id, options)
266
- # needs to have orderid and amount in options
267
- xml_block = Proc.new {|xml|
268
- xml.miscprocess("xsi:type" => "urn:VoidCreditPost"){
269
- xml.acctid @acctid
270
- xml.merchantpin @password if @password
271
- xml.amount amount
272
- xml.orderid pp_txn_id
273
- # xml.customizedfields{
274
- # xml.custom1
275
- # xml.custom2
276
- # xml.custom3
277
- # xml.custom4
278
- # xml.custom5
279
- # xml.custom6
280
- # }
281
- xml.historyid auth
282
- xml.ipaddress
283
- }
284
- }
285
-
286
- return xml_block
287
- end
288
-
289
- def build_cc_capture(amount, auth, pp_txn_id, options)
290
- # as of now auth is historyid and we need :orderid set in options
291
- xml_block = Proc.new {|xml|
292
- xml.miscprocess("xsi:type" => "urn:VoidCreditPost"){
293
- xml.acctid @acctid
294
- xml.merchantpin @password if @password
295
- xml.amount amount
296
- xml.orderid pp_txn_id
297
- xml.historyid auth
298
- xml.merchantordernumber auth
299
- xml.merchantpin auth
300
- xml.ipaddress
301
- }
302
- }
303
- return xml_block
304
- end
305
-
306
- def build_cc_sale_auth(amount, credit_card, options)
307
- # return a proc object to be used as a block for builder
308
- # passed to response.body {|xml| my xml block}
309
-
310
- missing_fields_for_options = {
311
- :acctid => '',
312
- :merchantpin => '',
313
- :subid => ''
314
- }
315
-
316
- # to map the active_merchant option keys to prismpay
317
- active_merchant_credit_card = {
318
- :first_name => '',
319
- :last_name => '',
320
- :month => '',
321
- :number => '',
322
- :type => '',
323
- :verification_value => '',
324
- :year => ''
325
- }
326
-
327
- active_merchant_option_map = {
328
- :order_id => :merchantordernumber,
329
- :ip => :ipaddress,
330
- :customer => '', # customer info
331
- :invoice => '', # invoice
332
- :merchant => '', # name of merchant offering the product
333
- :description => '', # A description of the transaction
334
- :email => :email, # The email address of the customer
335
- :currency => :currencycode,
336
- :address => '', # if this is set it is both billing and shipping
337
- :billing_address => {
338
- :name => '',
339
- :company => '',
340
- :address1 => '',
341
- :address2 => '',
342
- :city => '',
343
- :state => '',
344
- :country => '',
345
- :zip => '',
346
- :phone => ''
347
- },
348
- :shipping_address => {
349
- :name => '',
350
- :company => '',
351
- :address1 => '',
352
- :address2 => '',
353
- :city => '',
354
- :state => '',
355
- :country => '',
356
- :zip => '',
357
- :phone => ''
358
- }
359
- }
360
-
361
- if options.has_key?(:address)
362
- bill_address = ship_address = options[:address]
363
- else
364
- # assigns nil to variables if keys aren't present
365
- bill_address = options[:billing_address]
366
- ship_address = options[:shipping_address]
367
- end
368
-
369
- xml_block = Proc.new{ |xml|
370
- xml.ccinfo("xsi:type" => "urn:CreditCardInfo") {
371
- xml.acctid @acctid
372
- xml.merchantpin @password if @password
373
- # xml.merchantpin options[:password] if options.has_key?(:password)
374
- # xml.subid "xsi:nil" => "true"
375
- xml.ccname "#{credit_card.first_name} #{credit_card.last_name}"
376
- # xml.swipedata "xsi:nil" => "true"
377
- # xml.cardpresent "xsi;nil" => "true"
378
- # xml.cardreaderpresent "xsi:nil" => "true"
379
- # xml.voiceauth "xsi:nil" => "true"
380
- # xml.track1 "xsi:nil" => "true"
381
- # xml.track2 "xsi:nil" => "true"
382
- xml.ccnum credit_card.number
383
- xml.cctype credit_card.type
384
- xml.expmon credit_card.month
385
- xml.expyear credit_card.year
386
- xml.cvv2 credit_card.verification_value
387
- xml.amount amount
388
- xml.merchantordernumber options[:order_id] if options.has_key?(:order_id) # or invoice?
389
- # xml.companyname # says its our companyname
390
- eval(build_address(bill_address)) if bill_address
391
- eval(build_address(ship_address, "ship")) if ship_address
392
- xml.email options[:email] if options.has_key?(:email)
393
- # xml.dlnum
394
- # xml.ssnum
395
- xml.phone bill_address[:phone] if bill_address
396
- # xml.dobday
397
- # xml.dobmonth
398
- # xml.dobyear
399
- # xml.memo
400
- # xml.customizedemail("xsi:type" => "urn:customEmail"){ #method
401
- # xml.emailto "vpat@comcast.net"
402
- # xml.emailfrom "null@atsbank.com"
403
- # xml.emailsubject "Transaction Service Test"
404
- # xml.emailtext "This is just a test"
405
- # }
406
- # xml.recurring("xsi:type" => "urn:Recur") { #nees method
407
- # xml.create 0
408
- # xml.billingcycle 0
409
- # xml.billingmax 0
410
- # xml.start 0
411
- # xml.amount 0
412
- # }
413
- xml.ipaddress options[:ip] # req field ... nil if !(exists?)
414
- # xml.accttype ---> #have no clue
415
- # xml.merchantpin ----> #believe this is password
416
- # xml.currencycode
417
- # xml.industrycode ----> # no clue
418
- # xml.dynamicdescriptor ---> carries onto receipt for VITAL auths
419
- # xml.profileactiontype # no clue
420
- # xml.manualrecurring #number 1 if manual recurring
421
- }
422
- }
423
-
424
- return xml_block
425
- end
426
-
427
-
428
- def build_profile_sale(amount, profile_id, last_four, options)
429
- # as of now auth is historyid and we need :orderid set in options
430
-
431
- xml_block = Proc.new {|xml|
432
- xml.miscprocess("xsi:type" => "urn:MPTransProcess"){
433
- xml.acctid @acctid
434
- xml.merchantpin @password if @password
435
- xml.last4digits last_four
436
- xml.userprofileid profile_id
437
- xml.amount amount
438
- xml.ipaddress
439
- }
440
- }
441
- return xml_block
442
- end
443
-
444
-
445
- def build_ext_ach_sale_disburse(amount, bank_account, options)
446
- # should probably pass in the companyname under options
447
- acct_type = "#{bank_account.account_holder_type} " +
448
- "#{bank_account.account_type}"
449
-
450
- xml_block = Proc.new { |xml|
451
- xml.ckinfo("xsi:type" => "urn:ACHInfo"){
452
- xml.acctid @acctid
453
- xml.merchantpin(@password) if @password
454
- xml.ckname bank_account.name
455
- xml.firstname bank_account.first_name
456
- xml.lastname bank_account.last_name
457
- xml.ckaba bank_account.routing_number
458
- xml.ckacct bank_account.account_number
459
- xml.ckno(bank_account.cknumber) if bank_account.number
460
- xml.amount amount
461
- if bank_account.account_holder_type =~ /business/i
462
- xml.cktype('CCD')
463
- else
464
- xml.cktype('PPD')
465
- end
466
- xml.ckaccttypedesc acct_type
467
- xml.companyname options[:companyname]
468
- xml.ipaddress
469
- }
470
- }
471
-
472
- return xml_block
473
- end
474
-
475
- def build_ext_ach_refund_void(amount, auth, pp_txn_id, options)
476
- # should probably pass in the companyname under options
477
-
478
- xml_block = Proc.new { |xml|
479
- xml.ckinfo("xsi:type" => "urn:ACHInfo"){
480
- xml.acctid @acctid
481
- xml.merchantpin(@password) if @password
482
- xml.orderid pp_txn_id
483
- xml.historyid auth
484
- xml.amount amount if amount
485
- xml.ipaddress
486
- }
487
- }
488
-
489
- return xml_block
490
- end
491
-
492
-
493
-
494
- end # class PrismPay
495
-
496
-
497
- class BankAccount
498
- # mimic ActiveMerchant check object for compatibility, tesing, and
499
- # stand alone purposes
500
-
501
- attr_accessor :first_name, :last_name, :account_number, :routing_number,
502
- :account_holder_type, :account_type, :cknumber
503
-
504
- def number=(n)
505
- @cknumber = n
506
- end
507
-
508
- def number
509
- @cknumber
510
- end
511
-
512
- def [](method)
513
- eval ("self.#{method}")
514
- end
515
-
516
- def []=(method, rval)
517
- eval ("self.#{method} = rval")
518
- end
519
-
520
- def name
521
- [@first_name, @last_name].join(' ')
522
- end
523
-
524
- def name=(n)
525
- names = n.split(' ')
526
- @first_name = names[0]
527
- @last_name = names[1]
528
- end
529
-
530
- def initialize(checkinfo = {})
531
- if checkinfo.respond_to?("has_key?")
532
- @account_number = checkinfo[:account_number] if checkinfo.has_key?(:account_number)
533
- @name = checkinfo[:name] if checkinfo.has_key?(:name)
534
- @routing_number = checkinfo[:routing_number] if checkinfo.has_key?(:routing_number)
535
- @cknumber = checkinfo[:number] if checkinfo.has_key?(:number)
536
- @account_type = checkinfo[:account_type] if checkinfo.has_key?(:account_type)
537
- @account_holder_type = checkinfo[:account_holder_type] if checkinfo.has_key?(:account_holder_type)
538
- end
539
- end
540
-
541
- end # BankAccount
542
-
543
- class CreditCard
544
- # credit card information... mimic ActiveMerchant
545
- attr_accessor :number, :month, :year, :first_name,
546
- :verification_value, :type, :last_name
547
-
548
- def [](method)
549
- eval ("self.#{method}")
550
- end
551
-
552
- def name
553
- join(@first_name, @last_name)
554
- end
555
-
556
- def name=(n)
557
- names = n.split(' ')
558
- @first_name = names[0]
559
- @last_name = names[1]
560
- end
561
-
562
- def []=(method, rval)
563
- eval ("self.#{method} = rval")
564
- end
565
-
566
- def initialize(ccinfo = {})
567
- if ccinfo.respond_to?("has_key?")
568
- @number = ccinfo[:number] if ccinfo.has_key?(:number)
569
- @month = ccinfo[:month] if ccinfo.has_key?(:month)
570
- @year = ccinfo[:year] if ccinfo.has_key?(:year)
571
- @name = ccinfo[:name] if ccinfo.has_key?(:name)
572
- @verification_value = ccinfo[:verification_value] if ccinfo.has_key?(:verification_value)
573
- @type = ccinfo[:type] if ccinfo.has_key?(:type)
574
- end
575
- end
576
- end # CreditCard
577
-
578
- end #module PrismPay
579
-
580
-
581
- # #####################
582
- # # Demo driver
583
- # #####################
584
-
585
- # cc = CreditCard.new({})
586
- # cc.number = 5454545454545454
587
- # cc.month = 7
588
- # cc.year = 14
589
- # cc.name = "JohnDoe Soap"
590
- # cc.verification_value = 123
591
- # cc.type = "Visa"
592
-
593
- # addr2 = {
594
- # :name => "Fathead Don",
595
- # :address1 => "1501 S Delany Ave",
596
- # :city => "Orlando",
597
- # :state => "FL",
598
- # :zip => "32806",
599
- # :country => "US"
600
- # }
601
-
602
- # options = {
603
- # :login => "TEST0",
604
- # :order_id => Time.now.strftime("%y%m%d%H%M%S"),
605
- # :address => addr2
606
- # }
607
-
608
- # gateway = PrismPay.new(options)
609
-
610
- # purchase_amount = "23.32"
611
-
612
- # response = gateway.cc_purchase(purchase_amount, cc, options)
613
-
614
- # ########################################
615
- # # NOTE
616
- # ########################################
617
- # # as of now the cc_purchase and cc_auth method will return the soap
618
- # # response object from the client that objects meaningful values are
619
- # # accessible from response.body[:multi_ref].keys()
620
-
621
- # response = gateway.credit_sale(purchase_amount, credit_card)
622
-
623
- # puts "The unparsed authcode is #{response.body[:multi_ref][:authcode]}"
624
-
4
+ require 'openssl'
5
+ require 'erb' # required for url_escaping
6
+ require 'yaml' # yaml parsing
7
+ require 'prismpay/prismpay'
8
+ require 'prismpay/prism_credit_response'
9
+ require 'prismpay/prismpay_am'
10
+ require 'prismpay/prismpay_reports'
11
+ require 'prismpay/webpay'