dcas-ruby 0.1.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.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,22 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
22
+ spec/fixtures/clients.yml
data/API.rdoc ADDED
@@ -0,0 +1,44 @@
1
+ = Functions of DCAS:
2
+
3
+ * Generate a file
4
+ * Upload a file
5
+ * Check for response files
6
+ * Receive response files
7
+ * Parse response files
8
+
9
+ === First you must set up the login info and a cache location
10
+ angola = DCAS::Client.new(:username => 'angola', :password => '4ng014', :cache_location => './EFT')
11
+
12
+ === Create a Payment Batch
13
+ ach_payments = angola.new_batch(batch_id)
14
+ cc_payments = angola.new_batch(batch_id)
15
+
16
+ === Populate it with payments
17
+ ach_payments << DCAS::AchPayment.new(client_id, client_name, amount, account_type, routing_number, account_number, check_number)
18
+ cc_payments << DCAS::CreditCardPayment.new(client_id, client_name, amount, card_type, credit_card_number, expiration)
19
+
20
+ === You can generate a payments file from a collection of DCAS::Payment objects
21
+ File.open(filename, 'w') {|f| f << cc_payments.to_csv }
22
+ File.open(ach_filename, 'w') {|f| f << ach_payments.to_csv }
23
+
24
+ === Upload a generated file to the payments folder of a DCAS bucket
25
+ angola.submit_payments_file!(filename)
26
+
27
+ === Simpler method, just submit batches in one go
28
+ angola.submit_batches!
29
+
30
+ === Check for response file availability and return the available filenames
31
+ response_filenames = angola.available_response_files
32
+ response_filename = response_filenames.first
33
+
34
+ === Download all response files
35
+ angola.download_response_files!
36
+ response_file_content = File.read(angola.cache_location + '/' + response_filename)
37
+
38
+ === Return an array of DCAS::Response objects parsed from the response file/content
39
+ responses = DCAS.parse_response_file(response_filename)
40
+ responses = DCAS.parse_response_file(response_file_content)
41
+
42
+ === Run the block for each DCAS::Response in the response file/content
43
+ angola.each_response_in(response_filename) { |response| ... }
44
+ angola.each_response_in(response_file_content) { |response| ... }
data/HISTORY.rdoc ADDED
@@ -0,0 +1,3 @@
1
+ = v0.1.0 2010/01/15
2
+
3
+ * Initial package. FTPS operations work properly and creates payment files.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 BehindLogic
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.
data/README.rdoc ADDED
@@ -0,0 +1,18 @@
1
+ = dcas-ruby
2
+
3
+ Ruby codebase for creating payment batch files for DCAS, uploading them, and receiving response files from DCAS.
4
+ For the Ruby API, see API.
5
+
6
+ == Note on Patches/Pull Requests
7
+
8
+ * Fork the project.
9
+ * Make your feature addition or bug fix.
10
+ * Add tests for it. This is important so I don't break it in a
11
+ future version unintentionally.
12
+ * Commit, do not mess with rakefile, version, or history.
13
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
14
+ * Send me a pull request. Bonus points for topic branches.
15
+
16
+ == Copyright
17
+
18
+ Copyright (c) 2010 BehindLogic. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,46 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "dcas-ruby"
8
+ gem.summary = %Q{Ruby codebase for managing payments with DCAS.}
9
+ gem.description = %Q{Ruby codebase for creating payment batch files for DCAS, uploading them, and receiving response files from DCAS.}
10
+ gem.email = "gems@behindlogic.com"
11
+ gem.homepage = "http://github.com/dcparker/dcas-ruby"
12
+ gem.authors = ["BehindLogic"]
13
+ gem.add_development_dependency "rspec", ">= 1.2.9"
14
+ gem.add_dependency "fastercsv"
15
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
16
+ end
17
+ Jeweler::GemcutterTasks.new
18
+ rescue LoadError
19
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
20
+ end
21
+
22
+ require 'spec/rake/spectask'
23
+ Spec::Rake::SpecTask.new(:spec) do |spec|
24
+ spec.libs << 'lib' << 'spec'
25
+ spec.spec_files = FileList['spec/**/*_spec.rb']
26
+ end
27
+
28
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
29
+ spec.libs << 'lib' << 'spec'
30
+ spec.pattern = 'spec/**/*_spec.rb'
31
+ spec.rcov = true
32
+ end
33
+
34
+ task :spec => :check_dependencies
35
+
36
+ task :default => :spec
37
+
38
+ require 'rake/rdoctask'
39
+ Rake::RDocTask.new do |rdoc|
40
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
41
+
42
+ rdoc.rdoc_dir = 'rdoc'
43
+ rdoc.title = "dcas-ruby #{version}"
44
+ rdoc.rdoc_files.include('README*')
45
+ rdoc.rdoc_files.include('lib/**/*.rb')
46
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
data/dcas-ruby.gemspec ADDED
@@ -0,0 +1,87 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{dcas-ruby}
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["BehindLogic"]
12
+ s.date = %q{2010-01-15}
13
+ s.description = %q{Ruby codebase for creating payment batch files for DCAS, uploading them, and receiving response files from DCAS.}
14
+ s.email = %q{gems@behindlogic.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".gitignore",
22
+ "API.rdoc",
23
+ "HISTORY.rdoc",
24
+ "LICENSE",
25
+ "README.rdoc",
26
+ "Rakefile",
27
+ "VERSION",
28
+ "dcas-ruby.gemspec",
29
+ "lib/dcas.rb",
30
+ "lib/dcas/ach_response.rb",
31
+ "lib/dcas/ach_return.rb",
32
+ "lib/dcas/payment.rb",
33
+ "lib/dcas/response.rb",
34
+ "lib/net/ftps_implicit.rb",
35
+ "spec/dcas/response_spec.rb",
36
+ "spec/dcas_spec.rb",
37
+ "spec/fixtures/ach_first_response.csv.sample",
38
+ "spec/fixtures/ach_payments.csv",
39
+ "spec/fixtures/ach_payments.yml",
40
+ "spec/fixtures/ach_second_response.csv.sample",
41
+ "spec/fixtures/cc_response.csv.sample",
42
+ "spec/fixtures/clients.yml.sample",
43
+ "spec/fixtures/credit_card_payments.csv",
44
+ "spec/fixtures/credit_card_payments.yml",
45
+ "spec/fixtures/test_upload0.txt",
46
+ "spec/fixtures/test_upload1.txt",
47
+ "spec/fixtures/test_upload2.txt",
48
+ "spec/fixtures/test_upload3.txt",
49
+ "spec/fixtures/test_upload4.txt",
50
+ "spec/fixtures/test_upload5.txt",
51
+ "spec/fixtures/test_upload6.txt",
52
+ "spec/fixtures/test_upload7.txt",
53
+ "spec/fixtures/test_upload8.txt",
54
+ "spec/fixtures/test_upload9.txt",
55
+ "spec/ftps_implicit_spec.rb",
56
+ "spec/spec.opts",
57
+ "spec/spec_helper.rb"
58
+ ]
59
+ s.homepage = %q{http://github.com/dcparker/dcas-ruby}
60
+ s.rdoc_options = ["--charset=UTF-8"]
61
+ s.require_paths = ["lib"]
62
+ s.rubygems_version = %q{1.3.5}
63
+ s.summary = %q{Ruby codebase for managing payments with DCAS.}
64
+ s.test_files = [
65
+ "spec/dcas/response_spec.rb",
66
+ "spec/dcas_spec.rb",
67
+ "spec/ftps_implicit_spec.rb",
68
+ "spec/spec_helper.rb"
69
+ ]
70
+
71
+ if s.respond_to? :specification_version then
72
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
73
+ s.specification_version = 3
74
+
75
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
76
+ s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
77
+ s.add_runtime_dependency(%q<fastercsv>, [">= 0"])
78
+ else
79
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
80
+ s.add_dependency(%q<fastercsv>, [">= 0"])
81
+ end
82
+ else
83
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
84
+ s.add_dependency(%q<fastercsv>, [">= 0"])
85
+ end
86
+ end
87
+
@@ -0,0 +1,83 @@
1
+ module DCAS
2
+ class AchResponse < Response
3
+ DESCRIPTIONS = {
4
+ '00' => 'Processing',
5
+ '02' => 'Account Closed',
6
+ '03' => 'Account Closed',
7
+ '04' => 'Stop Payment',
8
+ '05' => 'Stop Payment',
9
+ '10' => 'No Debits Allowed',
10
+ '11' => 'No Checks Allowed',
11
+ '12' => 'Account Closed',
12
+ '14' => 'Account Closed',
13
+ '20' => 'Insufficient Funds',
14
+ '21' => 'Insufficient Funds',
15
+ '22' => 'Insufficient Funds',
16
+ '30' => 'Insufficient Funds',
17
+ '31' => 'Insufficient Funds',
18
+ '32' => 'Insufficient Funds',
19
+ '33' => 'Insufficient Funds',
20
+ '37' => 'Account Restricted',
21
+ '80' => 'Non-DDA Participant Credit Card',
22
+ '81' => 'Non-DDA Participant Line of Credit',
23
+ '82' => 'Non-DDA Participant Home Equity',
24
+ '83' => 'Non-DDA Non-Participant Credit Card / LOC',
25
+ '84' => 'Non-DDA Participant Broker Check',
26
+ '85' => 'Non-DDA Non-Participant Broker Check',
27
+ '96' => 'Non-Participant',
28
+ '97' => 'Non-Participant',
29
+ '98' => 'Non-DDA',
30
+ '99' => 'Account Not Located',
31
+ '128' => 'WARNING: Authentication Required',
32
+ '256' => 'WARNING: Account Validation Declined',
33
+ '257' => 'WARNING: Insufficient Funds',
34
+ '258' => 'WARNING: Account - Invalid Card',
35
+ '259' => 'WARNING: Account - Expired Card',
36
+ '260' => 'WARNING: Referral',
37
+ '261' => 'WARNING: Authentication Failed',
38
+ '262' => 'WARNING: Authentication Server Not Available',
39
+ '1026' => 'WARNING: Account Validation Error',
40
+ '1027' => 'WARNING: Account Validation Failure',
41
+ '1028' => 'WARNING: Account Duplicate',
42
+ '1029' => 'WARNING: Account - Invalid Merchant',
43
+ '1034' => 'WARNING: Account - Invalid Transaction',
44
+ '9001' => 'WARNING; Bank ABA not Verified',
45
+ '9033' => 'WARNING: Insufficient Funds',
46
+ '9097' => 'WARNING: ABA Not Valid',
47
+ '9098' => 'WARNING: Batch not closed',
48
+ '9099' => 'WARNING: No Batch on file',
49
+ '9999' => 'Unspecified Error'
50
+ }
51
+
52
+ def initialize(batch_id,attrs={})
53
+ new_attrs = {}
54
+ nattrs = attrs.dup
55
+ if nattrs.is_a?(Hash) # Is xml-hash
56
+ nattrs.stringify_keys!
57
+ # status, order_number, transacted_at, transaction_id, description
58
+ new_attrs = nattrs
59
+ elsif nattrs.respond_to?('[]') # Is csv row
60
+ # GotoBilling: MerchantID,FirstName,LastName,CustomerID,Amount,SentDate,SettleDate,TransactionID,TransactionType,Status,Description
61
+ # DCAS: RT,BankABA,AccountNumber,CheckNumber,Amount,ReturnCode,Description,CustTraceCode
62
+ # ret could be 0 (denied), 1 (approved), 2 (call for authorization), or 99 (error)
63
+ new_attrs = {
64
+ :status => nattrs[3][0..0] == 'A' ? 'A' : 'D',
65
+ :description => DESCRIPTIONS[nattrs[3].match(/(\d+)/)[1]] + " / " + nattrs[3].split(/-/)[1], # "Processing" if everything's good
66
+ :ach_submitted => true,
67
+ :client_id => nattrs[4][4..-1],
68
+ :account_number => nattrs[2]
69
+ }
70
+ end
71
+ self.attributes = new_attrs
72
+ self.batch_id = batch_id
73
+ end
74
+
75
+ def record_to_transaction!
76
+ return unless transaction.status != status && transaction.description != description
77
+ transaction.status = status
78
+ transaction.description = description
79
+ transaction.ach_submitted = true if ach_submitted
80
+ transaction.save
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,133 @@
1
+ module DCAS
2
+ class AchReturn < Response
3
+ DESCRIPTIONS = {
4
+ 'C01' => 'Incorrect DFI account number',
5
+ 'C02' => 'Incorrect T/R number',
6
+ 'C03' => 'Incorrect T/R number and incorrect DFI account number',
7
+ 'C04' => 'Incorrect indvidual name/receiving company name',
8
+ 'C05' => 'Incorrect transaction codes',
9
+ 'C06' => 'Incorrect DFI account number and incorrect transaction code',
10
+ 'C07' => 'Incorrect T/R number, incorrect DFI number and incorrect transaction code',
11
+ 'C08' => 'Reserved',
12
+ 'C09' => 'Incorrect individual identification number',
13
+ 'C10' => 'Incorrect company name',
14
+ 'C11' => 'Incorrect',
15
+ 'C12' => 'Incorrect company name and company identification',
16
+ 'C13' => 'Addenda format error',
17
+ 'C61' => 'Misrouted notification change',
18
+ 'C62' => 'Incorrect trace number',
19
+ 'C63' => 'Incorrect company identification number',
20
+ 'C64' => 'Incorrect individual identification number/identification number',
21
+ 'C65' => 'Incorrectly formatted corrected data',
22
+ 'C66' => 'Incorrect discretionary data',
23
+ 'C67' => 'Routing number not from original entry detail record',
24
+ 'C68' => 'DFI account number not from original entry detail record',
25
+ 'C69' => 'Incorrect transaction code',
26
+ 'R01' => 'Insufficient funds',
27
+ 'R02' => 'Account closed',
28
+ 'R03' => 'No account/Unable to locate account',
29
+ 'R04' => 'Invalid account number',
30
+ 'R05' => 'Reserved',
31
+ 'R06' => 'Returned per Originating DFIs request',
32
+ 'R07' => 'Authorization revoked by customer',
33
+ 'R08' => 'Payment stopped',
34
+ 'R09' => 'Uncollected Funds',
35
+ 'R10' => 'Customer advises not authorized',
36
+ 'R11' => 'Check truncation entry return',
37
+ 'R12' => 'Branch sold to another DFI',
38
+ 'R13' => 'Receiving DFI not qualified to participate',
39
+ 'R14' => 'Account-holder deceased',
40
+ 'R15' => 'Beneficiary deceased',
41
+ 'R16' => 'Account frozen',
42
+ 'R17' => 'File record edit criteria',
43
+ 'R18' => 'Improper effective entry date',
44
+ 'R19' => 'Amount field error',
45
+ 'R20' => 'Non-transaction account',
46
+ 'R21' => 'Invalid company identification',
47
+ 'R22' => 'Invalid individual ID number',
48
+ 'R23' => 'Credit entry refused by receiver',
49
+ 'R24' => 'Duplicate entry',
50
+ 'R25' => 'Addenda error',
51
+ 'R26' => 'Mandatory field error',
52
+ 'R27' => 'Trace number error',
53
+ 'R28' => 'Transit/Routing check digit error',
54
+ 'R29' => 'Corporate customer advises not authorized',
55
+ 'R30' => 'Receiving DFI not participant in check truncation program',
56
+ 'R31' => 'Permissible return entry',
57
+ 'R32' => 'RDFI - non-settlement',
58
+ 'R33' => 'Return for XCK',
59
+ 'R34' => 'Limited participation DFI',
60
+ '900' => 'Edit Reject',
61
+ '901' => 'Non-Sufficient Funds',
62
+ '902' => 'Cannot Trace',
63
+ '903' => 'Payment Stopped/Recalled',
64
+ '904' => 'Post/Stale Dated',
65
+ '905' => 'Account Closed',
66
+ '906' => 'Account Transferred',
67
+ '907' => 'No Checquing Privileges',
68
+ '908' => 'Funds Not Cleared',
69
+ '910' => 'Payer/Payee Deceased',
70
+ '911' => 'Account Frozen',
71
+ '912' => 'Invalid/Incorrect Account Number',
72
+ '914' => 'Incorrect Payer/Payee Name',
73
+ '915' => 'Refused By Payer/Payee',
74
+ '990' => 'Institution In Default',
75
+ '998' => 'No Agreement For Returns'
76
+ }
77
+
78
+ ACH_RET_CODES = {
79
+ 'A' => 'G',
80
+ 'C' => 'I',
81
+ 'R' => 'D',
82
+ '9' => 'D'
83
+ }
84
+ def initialize(batch_id,attrs={})
85
+ new_attrs = {}
86
+ nattrs = attrs.dup
87
+ if nattrs.is_a?(Hash) # Is xml-hash
88
+ nattrs.stringify_keys!
89
+ # status, order_number, transacted_at, transaction_id, description
90
+ new_attrs = nattrs
91
+ elsif nattrs.respond_to?('[]') # Is csv row
92
+ # GotoBilling: MerchantID,FirstName,LastName,CustomerID,Amount,SentDate,SettleDate,TransactionID,TransactionType,Status,Description
93
+ # DCAS: RT,BankABA,AccountNumber,CheckNumber,Amount,ReturnCode,Description,CustTraceCode
94
+ # ret could be 0 (denied), 1 (approved), 2 (call for authorization), or 99 (error)
95
+ status = ACH_RET_CODES[nattrs[5][0..0]]
96
+ new_attrs = {
97
+ :account_number => nattrs[2],
98
+ :check_number => nattrs[3],
99
+ :client_id => nattrs[7] ? nattrs[7][4..-1] : nil
100
+ }
101
+ if status == 'I'
102
+ new_attrs[:information] = "#{DESCRIPTIONS[nattrs[5]]} (#{nattrs[6]})"
103
+ else
104
+ new_attrs[:status] = status
105
+ new_attrs[:description] = "#{DESCRIPTIONS[nattrs[5]]} (#{nattrs[6]})"
106
+ end
107
+ end
108
+ self.attributes = new_attrs
109
+ self.batch_id = batch_id
110
+ end
111
+
112
+ def transaction
113
+ @transaction ||= GotoTransaction.find_by_batch_id_and_client_id(self.batch_id, self.client_id)
114
+ @transaction ||= GotoTransaction.find_by_batch_id_and_bank_account_number_and_check_number(self.batch_id, self.account_number, self.check_number)
115
+ @transaction
116
+ end
117
+
118
+ def record_to_transaction!
119
+ return unless transaction.status != status && transaction.description != description
120
+
121
+ transaction.transaction_id = 0 if transaction.transaction_id.to_i != 0 && transaction.status == 'G' && status == 'D' # Was accepted, now declined.
122
+
123
+ if status == 'I'
124
+ transaction.information = information
125
+ else
126
+ transaction.description = description
127
+ end
128
+ transaction.status = status
129
+ transaction.ach_submitted = ach_submitted if ach_submitted
130
+ transaction.save
131
+ end
132
+ end
133
+ end
@@ -0,0 +1,147 @@
1
+ require 'fastercsv'
2
+
3
+ module DCAS
4
+ class PaymentBatch
5
+ def initialize(client, batch_id)
6
+ @client = client
7
+ @batch_id = batch_id
8
+ end
9
+
10
+ attr_reader :batch_id
11
+
12
+ def payments
13
+ @payments ||= []
14
+ end
15
+
16
+ def <<(payment)
17
+ raise ArgumentError, "payment should be instance of Payment" unless payment.is_a?(Payment)
18
+ type = payments.first.class
19
+ raise ArgumentError, "payment added to a #{type} batch should be a #{type} but was #{payment.class.name}!" if !payments.empty? && !payment.is_a?(type)
20
+ payment.batch = self
21
+ payments << payment
22
+ end
23
+
24
+ def type
25
+ payments.first.class.name.gsub(/.*::/,'').downcase
26
+ end
27
+
28
+ # Generates a payment batch file and returns its contents.
29
+ def to_csv
30
+ FasterCSV.generate do |csv|
31
+ csv << [ 'HD', @client.company_alias, @client.company_username, @client.company_password, 'Check' ]
32
+ payments.each do |payment|
33
+ csv << payment.to_csv_data if payment.batch == self # Safety net in case the same payment was applied to more than one batch. It will only go through in the last batch it was added to.
34
+ end
35
+ end
36
+ end
37
+ end
38
+
39
+ class Payment
40
+ attr_accessor :batch
41
+
42
+ def initialize(client_id, client_name, amount, *args)
43
+ @client_id = client_id
44
+ @client_name = client_name
45
+ @amount = amount
46
+ @txn_type = 'Debit'
47
+ return args
48
+ end
49
+ end
50
+
51
+ class AchPayment < Payment
52
+ # Arguments: client_id, client_name, amount, account_type, routing_number, account_number, check_number
53
+ def initialize(*args)
54
+ @account_type, @routing_number, @account_number, @check_number = *super
55
+ end
56
+
57
+ def to_csv_data(options={})
58
+ # Example from DCAS:
59
+ # HD,CompanyName,UserName,Password,Check
60
+ # CA,111000753,1031103,42676345,50.99,,Darwin Rogers,1409 N AVE,,,75090,,,,,2919,,,,,Checking,,,,,,200
61
+ # CC,VISA,4118000000981234,04/2009,19.99,N,,162078,JACLYN ,545 Sheridan Ave,,,07203,,,,9872,,,2,3,1
62
+ [ # This is for bank account transactions
63
+ 'CA',
64
+ @routing_number,
65
+ @account_number,
66
+ @check_number, # check number field can be used to prevent duplicates
67
+ @amount,
68
+ nil, # invoice number
69
+ @client_name,
70
+ nil, # address - API says required, but it's really not.
71
+ nil, # city
72
+ nil, # state
73
+ nil, # zip
74
+ nil, # phone number
75
+ nil, # driver license number
76
+ nil, # driver license state
77
+ nil, # third party check? 1=yes, 0=no
78
+ "#{@batch.batch_id}#{@client_id}", # CustTraceCode
79
+ nil, # image name
80
+ nil, # back image name
81
+ @txn_type, # Credit/Debit (default Debit)
82
+ nil, # Internal Account Number: date (in 4 digits: YYMM) + client id
83
+ @account_type,
84
+ #, nil, # ECC - Default Entry Class Code (??)
85
+ # nil, nil, nil, nil, # Deposit info
86
+ # nil, # CPA Code
87
+ # nil, nil, # scanned MICR info
88
+ # nil, nil # endorsement and image
89
+ ]
90
+ end
91
+ end
92
+
93
+ class AchRefund < AchPayment
94
+ # Arguments: client_id, client_name, amount, account_type, routing_number, account_number, check_number
95
+ def initialize(*args)
96
+ super
97
+ @txn_type = 'Credit'
98
+ end
99
+ end
100
+
101
+ class CreditCardPayment < Payment
102
+ # Arguments: client_id, client_name, amount, card_type, credit_card_number, expiration
103
+ def initialize(*args)
104
+ @card_type, @credit_card_number, @expiration = *super
105
+ end
106
+
107
+ def to_csv_data(options={})
108
+ # DCAS Example:
109
+ # HD,CompanyName,UserName,Password,CHECK
110
+ # CA,111000753,1031103,42676345,50.99,,Darwin Rogers,1409 N AVE,,,75090,,,,,2919,,,,,Checking,,,,,,200
111
+ # CC,VISA,4118000000981234,04/2009,19.99,N,,162078,JACLYN ,545 Sheridan Ave,,,07203,,,,9872,,,2,3,1
112
+ [ # This is for credit card transactions
113
+ 'CC',
114
+ @card_type, # Card Type
115
+ @credit_card_number, # Account Number
116
+ @expiration, # Expiration date (MM/YYYY)
117
+ @amount, # Amount (00.00)
118
+ 'N', # Card Present
119
+ nil, # Card verification (if present)
120
+ nil, # invoice number
121
+ @client_name, # name # Larry Cummings @ DCAS Support: (972) 239-2327, ext 153 #OR# (972) 392-4654
122
+ nil, # address
123
+ nil, # city
124
+ nil, # state
125
+ nil, # zip
126
+ nil, # phone number
127
+ nil, # driver license number
128
+ nil, # driver license state
129
+ "#{@batch.batch_id}#{@client_id}", # CustTraceCode
130
+ @txn_type, # Credit/Debit (default Debit)
131
+ nil,
132
+ 2,
133
+ 3,
134
+ 1,
135
+ nil
136
+ ]
137
+ end
138
+ end
139
+
140
+ class CreditCardRefund < Payment
141
+ # Arguments: client_id, client_name, amount, card_type, credit_card_number, expiration
142
+ def initialize(*args)
143
+ super
144
+ @txn_type = 'Credit'
145
+ end
146
+ end
147
+ end