prismpay 0.0.8 → 0.0.9

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