ach_client 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. checksums.yaml +7 -0
  2. data/.codeclimate.yml +18 -0
  3. data/.gitignore +9 -0
  4. data/.rubocop.yml +1156 -0
  5. data/.ruby-version +1 -0
  6. data/.travis.yml +10 -0
  7. data/Gemfile +4 -0
  8. data/README.md +388 -0
  9. data/Rakefile +10 -0
  10. data/ach_client.gemspec +58 -0
  11. data/bin/console +93 -0
  12. data/bin/setup +8 -0
  13. data/config/return_codes.yml +761 -0
  14. data/lib/ach_client/abstract/abstract_method_error.rb +3 -0
  15. data/lib/ach_client/helpers/dollars_to_cents.rb +15 -0
  16. data/lib/ach_client/logging/log_provider_job.rb +36 -0
  17. data/lib/ach_client/logging/log_providers/log_provider.rb +22 -0
  18. data/lib/ach_client/logging/log_providers/null_log_provider.rb +14 -0
  19. data/lib/ach_client/logging/log_providers/stdout_log_provider.rb +14 -0
  20. data/lib/ach_client/logging/logging.rb +76 -0
  21. data/lib/ach_client/logging/savon_observer.rb +26 -0
  22. data/lib/ach_client/objects/account_types.rb +32 -0
  23. data/lib/ach_client/objects/responses/ach_response.rb +15 -0
  24. data/lib/ach_client/objects/responses/corrected_ach_response.rb +18 -0
  25. data/lib/ach_client/objects/responses/processing_ach_response.rb +6 -0
  26. data/lib/ach_client/objects/responses/returned_ach_response.rb +16 -0
  27. data/lib/ach_client/objects/responses/settled_ach_response.rb +5 -0
  28. data/lib/ach_client/objects/return_code.rb +20 -0
  29. data/lib/ach_client/objects/return_codes.rb +33 -0
  30. data/lib/ach_client/objects/transaction_types.rb +16 -0
  31. data/lib/ach_client/providers/abstract/ach_batch.rb +23 -0
  32. data/lib/ach_client/providers/abstract/ach_status_checker.rb +21 -0
  33. data/lib/ach_client/providers/abstract/ach_transaction.rb +70 -0
  34. data/lib/ach_client/providers/abstract/company_info.rb +28 -0
  35. data/lib/ach_client/providers/abstract/response_record_processor.rb +15 -0
  36. data/lib/ach_client/providers/abstract/transformer.rb +38 -0
  37. data/lib/ach_client/providers/sftp/account_type_transformer.rb +20 -0
  38. data/lib/ach_client/providers/sftp/ach_batch.rb +97 -0
  39. data/lib/ach_client/providers/sftp/ach_status_checker.rb +146 -0
  40. data/lib/ach_client/providers/sftp/ach_transaction.rb +62 -0
  41. data/lib/ach_client/providers/sftp/nacha_provider.rb +30 -0
  42. data/lib/ach_client/providers/sftp/sftp_provider.rb +124 -0
  43. data/lib/ach_client/providers/sftp/transaction_type_transformer.rb +19 -0
  44. data/lib/ach_client/providers/soap/ach_works/account_type_transformer.rb +17 -0
  45. data/lib/ach_client/providers/soap/ach_works/ach_batch.rb +89 -0
  46. data/lib/ach_client/providers/soap/ach_works/ach_status_checker.rb +86 -0
  47. data/lib/ach_client/providers/soap/ach_works/ach_transaction.rb +80 -0
  48. data/lib/ach_client/providers/soap/ach_works/ach_works.rb +57 -0
  49. data/lib/ach_client/providers/soap/ach_works/company_info.rb +87 -0
  50. data/lib/ach_client/providers/soap/ach_works/correction_details_processor.rb +92 -0
  51. data/lib/ach_client/providers/soap/ach_works/date_formatter.rb +33 -0
  52. data/lib/ach_client/providers/soap/ach_works/response_record_processor.rb +91 -0
  53. data/lib/ach_client/providers/soap/ach_works/transaction_type_transformer.rb +18 -0
  54. data/lib/ach_client/providers/soap/i_check_gateway/account_type_transformer.rb +20 -0
  55. data/lib/ach_client/providers/soap/i_check_gateway/ach_batch.rb +12 -0
  56. data/lib/ach_client/providers/soap/i_check_gateway/ach_status_checker.rb +35 -0
  57. data/lib/ach_client/providers/soap/i_check_gateway/ach_transaction.rb +53 -0
  58. data/lib/ach_client/providers/soap/i_check_gateway/company_info.rb +51 -0
  59. data/lib/ach_client/providers/soap/i_check_gateway/i_check_gateway.rb +39 -0
  60. data/lib/ach_client/providers/soap/i_check_gateway/response_record_processor.rb +59 -0
  61. data/lib/ach_client/providers/soap/i_check_gateway/transaction_type_transformer.rb +8 -0
  62. data/lib/ach_client/providers/soap/soap_provider.rb +47 -0
  63. data/lib/ach_client/version.rb +4 -0
  64. data/lib/ach_client.rb +38 -0
  65. metadata +346 -0
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.3.1
data/.travis.yml ADDED
@@ -0,0 +1,10 @@
1
+ language: ruby
2
+ script:
3
+ - bundle exec rake test
4
+ - bundle exec codeclimate-test-reporter
5
+ before_install:
6
+ - export TZ=US/Eastern
7
+ - export CODECLIMATE_REPO_TOKEN=1fc324a28beed303e632765cca14487904a23023d85b9127a288f04cc007d28d
8
+ - date
9
+ notifications:
10
+ email: false
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in ach_client.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,388 @@
1
+ [![Code Climate](https://codeclimate.com/github/ForwardFinancing/ach_client/badges/gpa.svg)](https://codeclimate.com/github/ForwardFinancing/ach_client)
2
+
3
+ [![Test Coverage](https://codeclimate.com/github/ForwardFinancing/ach_client/badges/coverage.svg)](https://codeclimate.com/github/ForwardFinancing/ach_client/coverage)
4
+
5
+ [![Issue Count](https://codeclimate.com/github/ForwardFinancing/ach_client/badges/issue_count.svg)](https://codeclimate.com/github/ForwardFinancing/ach_client)
6
+
7
+ [![Build Status](https://travis-ci.org/ForwardFinancing/ach_client.svg?branch=master)](https://travis-ci.org/ForwardFinancing/ach_client)
8
+
9
+ # AchClient
10
+
11
+ ## Overview
12
+
13
+ The AchClient gem provides a common interface for working with a variety of
14
+ ACH providers.
15
+
16
+ Supported features include:
17
+
18
+ - **Individual Transactions:** Sending a single ACH transaction for the provider to process
19
+ - **Batch Transactions:** Sending a batch of ACH transactions together to the provider to process
20
+ - **Response Polling:** Retrieving the results of sent ACH transactions from the provider, and processing that response into a standardized format
21
+
22
+ Some providers may not support all features
23
+
24
+
25
+ | Provider | Individual ACH | Batch ACH | Response Polling |
26
+ | ------------------ | ------------------- | ------------------- | ------------------- |
27
+ | AchWorks | :white_check_mark: | :white_check_mark: | :white_check_mark: |
28
+ | ICheckGateway | :white_check_mark: | :x: | :white_check_mark: |
29
+ | NACHA+SFTP Providers | :x: | :white_check_mark: | :white_check_mark: |
30
+
31
+ ### About NACHA+SFTP Providers
32
+
33
+ Many banks/financial institutions use a similar system for receiving ACH
34
+ transactions. For these providers, batches of ACH transactions can be
35
+ represented in the NACHA file format. The bank provides you with an SFTP server
36
+ where you can deposit these files. After the transactions are processed, the
37
+ provider will leave another NACHA file containing the results on the server in
38
+ an "Inbox" or "Outgoing" directory.
39
+
40
+ The two API providers tend to be more reliable and easier to work with, but it
41
+ is usually cheaper to interact directly with a financial institution.
42
+
43
+ ## Structure
44
+
45
+ Each provider has its own namespace. For all of the example code, you must replace `Provider` with a provider you want to use.
46
+
47
+ For example, `AchClient::Provider::AchBatch` might become `AchClient::AchWorks::AchBatch`
48
+
49
+ For NACHA+SFTP providers, referencing them by name will create the namespace.
50
+ For example, Silicon Valley Bank is a provider which adheres to the NACHA/SFTP
51
+ standard. There is no AchClient::SiliconValleyBank namespace in the codebase,
52
+ but if you reference that provider, it will be dynamically defined for you.
53
+
54
+ ## Individual ACH transactions
55
+
56
+ Create an instance of an AchTransaction following the code sample below:
57
+
58
+ - *The Merchant* is the person/company to whom you will be sending an ACH credit or debit.
59
+
60
+ - All account type classes are listed [here](https://forwardfinancing.github.io/ach_client/doc/AchClient/AccountTypes.html)
61
+
62
+ - All transaction type classes are listed [here](https://forwardfinancing.github.io/ach_client/doc/AchClient/TransactionTypes.html)
63
+
64
+ - Checkout the abstract `AchTransaction` class and the `AchTransaction` class for each provider for more info.
65
+
66
+ ```ruby
67
+ AchClient::Provider::AchTransaction.new(
68
+ # The merchant's account number
69
+ account_number: '115654668777',
70
+ # The merchant's account type (see account types note above)
71
+ account_type: AchClient::AccountTypes::BusinessChecking,
72
+ # The amount of the ACH transaction, should be positive
73
+ amount: BigDecimal.new('575.45'),
74
+ # The date on which you would like the transaction to take effect.
75
+ # Beware that some providers may use this field to charge you extra for
76
+ # same-day ACH ( a recent feature for ACH providers )
77
+ effective_entry_date: Date.today,
78
+ # Will show up on the merchant's bank statement
79
+ memo: '????',
80
+ # The name of the merchant
81
+ merchant_name: 'test merchant',
82
+ # Your name (or the name of your company)
83
+ originator_name: 'ff',
84
+ # The merchants routing number
85
+ routing_number: '083000108',
86
+ # The ACH "Standard Entry Class" code to use for the ACH (google it for more)
87
+ sec_code: 'CCD',
88
+ # Is the transaction a credit or debit against the merchant?
89
+ transaction_type: AchClient::TransactionTypes::Debit,
90
+ # See section below
91
+ external_ach_id: 'blah'
92
+ )
93
+ ```
94
+
95
+ You can send the transaction to the provider by invoking the `#send` instance method on your instance of an `AchTransaction`. If the ACH transaction was successfully sent to the provider, the `external_ach_id` for the transaction will be returned. If sending the transaction was unsuccessful, an exception will be thrown.
96
+
97
+ Successfully sending the transaction does not equate to the transaction actually being executed against the merchant's bank account. ACH transactions are inherently asynchronous because financial institutions can take days and in rare cases even months to process them.
98
+
99
+ ### External ACH ID
100
+
101
+ The `external_ach_id` value can be used to track what happens to your transaction after you send it. You can use it to match transactions that you sent against results later received by the response polling methods.
102
+
103
+ The `external_ach_id` should be unique per transaction.
104
+
105
+ Some providers do not allow you to supply your own tracking id. Other providers require you to provide your own unique tracking id.
106
+
107
+ The tracking id that the provider actually uses with your transaction will be
108
+ returned by the `#send` method. So you should:
109
+
110
+ 1) Create an instance of `AchTransaction` with a unique `external_ach_id` that you would *like* to use
111
+
112
+ 2) Call `#send` on your transaction
113
+
114
+ 3) Store the return value of `#send` somewhere - this is the `external_ach_id` that was actually used
115
+
116
+ 4) When you eventually poll the provider for the status of your transactions, you can use the `external_ach_id` you stored to reconcile the returned data against your records
117
+
118
+ ## Batched ACH transactions
119
+
120
+ A group of ACH transactions can also be sent in a single batched transaction to
121
+ providers who support this functionality.
122
+
123
+ Checkout the abstract `AchBatch` class and the `AchBatch` class for each provider for more info.
124
+
125
+ Create an instance of `AchBatch` for your provider. The constructor takes an array of `AchTransactions` (which are described above).
126
+
127
+ ```ruby
128
+ AchClient::Provider::AchBatch.new(
129
+ ach_transactions: []
130
+ )
131
+ ```
132
+
133
+ To send the batch to the provider, invoke the `#send_batch` method on your instance of `AchBatch`.
134
+
135
+ If sending the batch was successful, a list of `external_ach_id` will be returned. If it was unsuccessful, either because the whole batch or a single transaction was invalid, an exception will be raised, and none of the transactions will have been sent to the provider.
136
+
137
+ Successfully sending the transaction batch does not equate to the transactions actually being executed against the merchants' bank accounts. ACH transactions are inherently asynchronous because financial institutions can take days and in rare cases even months to process them.
138
+
139
+ SFTP+NACHA providers take an optional `batch_number` parameter which may be used in the filename for uploaded NACHA files.
140
+
141
+ ```ruby
142
+ AchClient::SomeBank::AchBatch.new(
143
+ ach_transactions: [],
144
+ batch_number: 5
145
+ )
146
+ ```
147
+
148
+ ## Response Polling - Checking Transaction Status
149
+
150
+ None of the providers support querying for transaction status by external_ach_id. Instead, we must query by date and
151
+
152
+ To check statuses:
153
+
154
+ ```ruby
155
+ # Check the most recent transactions
156
+ AchClient::Provider::AchStatusChecker.most_recent
157
+
158
+ # Check the transactions with a date range
159
+ AchClient::Provider::AchStatusChecker.in_range(
160
+ start_date: 1.week.ago,
161
+ end_date: Date.today
162
+ )
163
+ ```
164
+
165
+ Both of these methods return a `Hash` with the `external_ach_id` for ach_transaction as the keys and
166
+ instances of AchClient::AchResponse as values.
167
+
168
+ ### Responses
169
+
170
+ There are a number of response states that can result from checking on the
171
+ status of your ACH transactions. Each inherit from `AchClient::AchResponse`
172
+
173
+ - `SettledAchResponse`: The transaction went through. :tada:
174
+ - `ProcessingAchResponse`: The transaction hasn't gone through yet. Patience.
175
+ - `ReturnedAchResponse`: The transaction was returned cause something went
176
+ wrong. Check the return code on the response object for details
177
+ - `CorrectedAchResponse`: The transaction received a correction because some
178
+ information has changed. Check the return code on the response object for
179
+ details on what happened. Check the corrections hash on the response object for
180
+ the new attributes
181
+
182
+ ## Logging
183
+
184
+ For record keeping purposes, there is a log provider that allows you to hook
185
+ into all requests sent to a SOAP provider and send them to your logging service.
186
+
187
+ The default log provider is the NullLogProvider, which does not log requests.
188
+
189
+ ```ruby
190
+ # No logging
191
+ AchClient::Logging.log_provider = AchClient::Logging::NullLogProvider
192
+
193
+ # Log to stdout
194
+ AchClient::Logging.log_provider = AchClient::Logging::StdoutLogProvider
195
+
196
+ # Log to wherever you want by creating your own LogProvider class
197
+ # and overriding #send_logs
198
+ class MyCustomLogger < AchClient::Logging::LogProvider
199
+ # This method takes a log body and a log name
200
+ def self.send_logs(body:, name:)
201
+ # Do whatever you want, like send the log data to S3, or whatever
202
+ # logging service you choose
203
+ end
204
+ end
205
+ AchClient::Logging.log_provider = MyCustomLogger
206
+ ```
207
+
208
+ ### Log Filtering
209
+
210
+ Log filtering is available for logs with key/value pairs. To enable log filtering, provide a list of keys who's values you would like to be scrubbed. Those values will be replaced with *
211
+
212
+ ```ruby
213
+ AchClient::Logging.log_filters = [
214
+ 'AccountNumber',
215
+ 'RoutingNumber',
216
+ ...
217
+ ]
218
+ ```
219
+
220
+ ### Log Encryption
221
+
222
+ To enable encryption of logs, provide both a `password` and a `salt`
223
+
224
+ ```ruby
225
+ AchClient::Logging.password = 'password'
226
+ AchClient::Logging.salt = 'pepper'
227
+ ```
228
+
229
+ Logs will be encrypted after they are filtered, but before they are passed to the `LogProvider` implementation you chose.
230
+
231
+ AchClient doesn't support reading from your log store, you will need to decrypt logs yourself as needed. For convenience, a decryption function has been provided that decrypts a message using the above provided `password` and `salt`.
232
+
233
+ ```ruby
234
+ AchClient::Logging.decrypt_log('encrypted log gibberish.....')
235
+ ```
236
+
237
+ ## Provider Configuration Setup
238
+
239
+ Each provider has a set of configuration attributes that must be set.
240
+ Most of these values can be retrieved by contacting the provider directly.
241
+ You can set the configuration variables by assigning them directly to the class attributes on the provider module. For example, if the provider is AchWorks, and the configuration attribute is password:
242
+
243
+ ```ruby
244
+ AchClient::AchWorks.password = 'your password'
245
+ ```
246
+
247
+ You probably want to set these variables from environment variables instead of hardcoding them into your app.
248
+
249
+ Some test configuration values are provided for testing/development of this gem. You can find them in the `bin/console` file and in the test helper. Be aware that these credentials may be used to send data to some providers' test environments under a shared test account. Avoid using real customer data in test.
250
+
251
+ ### AchWorks
252
+
253
+ | Attribute | Description |
254
+ | -------------- | ---------------------------------------- |
255
+ | `company_key` | Company credential provided by AchWorks |
256
+ | `company` | Company credential provided by AchWorks |
257
+ | `loc_i_d` | Company credential provided by AchWorks |
258
+ | `s_s_s` | Company credential provided by AchWorks |
259
+ | `wsdl` | URL for the WSDL for AchWorks SOAP API |
260
+
261
+ ### ICheckGateway
262
+
263
+ | Attribute | Description |
264
+ | -------------- | ---------------------------------------- |
265
+ | `site_i_d` | Company credential provided by ICheckGateway |
266
+ | `site_key` | Company credential provided by ICheckGateway |
267
+ | `api_key` | Company credential provided by ICheckGateway |
268
+ | `live` | `true` if you want transactions to be actually processed, `false` otherwise. Note: `true` only works with your production credentials, and `false` only works with the shared test credentials |
269
+ | `wsdl` | URL for the WSDL for ICheckGateway SOAP API |
270
+
271
+ ### NACHA + SFTP Providers
272
+
273
+ Most US banks use the same system for sending and receiving ACH transactions.
274
+
275
+ For these providers, batches of ACH transactions are
276
+ represented in the NACHA file format. The bank provides you with an SFTP server
277
+ where you can deposit these files. After the transactions are processed, the
278
+ provider will leave another NACHA file containing the results on the server in
279
+ an "Inbox" or "Outgoing" directory.
280
+
281
+ So far this setup has been confirmed to work with the following providers:
282
+ - Bank Of America
283
+ - Silicon Valley Bank
284
+
285
+ You'll notice there aren't any provider namespaces in the codebase for these.
286
+ You can define your own namespace simply by referencing it.
287
+
288
+ For example, the first time you reference `AchClient::FakeBank`, all the following class attributes will be automatically defined for
289
+ `AchClient::FakeBank`, along with the following classes:
290
+ - `AchClient::FakeBank::AchTransaction`
291
+ - `AchClient::FakeBank::AchBatch`
292
+ - `AchClient::FakeBank::AchStatusChecker`
293
+
294
+ After setting the variables described in the below table, you can interact with
295
+ these new classes using the same interface described above for the API providers.
296
+
297
+ | Attribute | Description |
298
+ | -------------- | ---------------------------------------- |
299
+ | `immediate_destination` | ID for company that is receiving the NACHA file (the bank) |
300
+ | `immediate_destination_name` | Name of company that is receiving the NACHA file (the bank) |
301
+ | `immediate_origin` | ID for company that is sending the NACHA file (you) |
302
+ | `immediate_origin_name` | Name of company that is sending the NACHA file (you) |
303
+ | `company_identification` | ID of your company |
304
+ | `company_entry_description` | ID of company (provided by bank) |
305
+ | `originating_dfi_identification` | ID of bank (provided by bank) |
306
+ | `host` | URL of bank's SFTP server |
307
+ | `username` | Username to connect via SFTP to bank's server |
308
+ | `password` | Password to connect via SFTP to bank's server |
309
+ | `private_ssh_key` | Private SSH key that matches the public key you gave the bank to put on their SFTP server (if applicable) |
310
+ | `passphrase` | Passphrase for your private SSH key. If your passphrase was blank, leave this `nil` |
311
+ | `outgoing_path` | Path on the remote server where bank has asked you to dump your NACHAs |
312
+ | `incoming_path` | Path on the remote server where the bank leaves confirmation/return files |
313
+ | `file_naming_strategy` | Function to define filenames for the NACHA files |
314
+
315
+ #### File Naming Strategy
316
+
317
+ This attribute is a function to define filenames for the NACHA files. It is
318
+ called from the `send_batch` method of the `AchBatch` class in your SFTP+NACHA provider's namespace. It will be passed a `batch_number` parameter, which may be
319
+ `nil`.
320
+
321
+ As an example, SiliconValleyBank's naming convention is as follows:
322
+ - The first four characters are ACHP
323
+ - The next 6 characters are the date formatted MMDDYY
324
+ - The last 2 characters are a "sequence number" which shows the number of
325
+ batches that have sent in the current day.
326
+ The `file_naming_strategy` for this can be defined as follows:
327
+
328
+ ```ruby
329
+ AchClient::SiliconValleyBank.file_naming_strategy = lambda do |batch_number|
330
+ batch_number ||= 1
331
+ "ACHP#{Date.today.strftime('%m%d%y')}#{batch_number.to_s.rjust(2, '0')}"
332
+ end
333
+ ```
334
+
335
+ #### Assumptions about response files from NACHA/SFTP providers
336
+
337
+ NACHA response files containing transaction confirmations, returns, and
338
+ corrections are deposited by your bank in an 'Inbox' or 'Outgoing' folder on the
339
+ SFTP server they provide. The status check functionality for these providers
340
+ makes a few assumptions about this folder:
341
+
342
+ - All the files in it are inbound response files, which should be processed. If
343
+ this is not true for some bank, we will need to add a file naming strategy configuration attribute for inbound files.
344
+ - The SFTP user has write access to the inbound file directory. The
345
+ `most_recent` functionality leaves a file that records the last access
346
+ timestamp. If the SFTP user does not have write access, and your bank won't give
347
+ it to you, we'll have to find another way to implement that.
348
+
349
+ ## Installation
350
+
351
+ Add this line to your application's Gemfile:
352
+
353
+ ```ruby
354
+ gem 'ach_client'
355
+ ```
356
+
357
+ And then execute:
358
+
359
+ $ bundle install
360
+
361
+ Or install it yourself:
362
+
363
+ $ gem install ach_client
364
+
365
+ ## Development
366
+
367
+ After checking out the repo, run `bin/setup` to install dependencies.
368
+
369
+ Then, run `bundle exec rake test` to run the tests.
370
+
371
+ Execute `bin/console` to run this gem in terminal.
372
+
373
+ ### Documentation
374
+
375
+ View them at https://forwardfinancing.github.io/ach_client/doc/index.html
376
+
377
+ Uses yardocs. Run `yard doc && open docs/index.html` to generate and view docs.
378
+
379
+ To update the docs, checkout the `gh-pages` branch and rebase it against
380
+ master.
381
+ Then run `yard doc` and push your changes up.
382
+ The `gh-pages` has the doc directory included in source control. It should
383
+ never be merged.
384
+
385
+ ## Contributing
386
+
387
+ Bug reports and pull requests are welcome on GitHub at
388
+ https://github.com/ForwardFinancing/ach_client.
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rake/testtask'
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << 'test'
6
+ t.libs << 'lib'
7
+ t.test_files = FileList['test/**/*_test.rb']
8
+ end
9
+
10
+ task default: :test
@@ -0,0 +1,58 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'ach_client/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'ach_client'
8
+ spec.version = AchClient::VERSION
9
+ spec.authors = [
10
+ 'Zach Cotter'
11
+ ]
12
+ spec.email = [
13
+ 'zach@zachcotter.com'
14
+ ]
15
+ spec.licenses = ['MIT']
16
+
17
+ spec.summary = %q{ Adapter to interact with various ACH service providers }
18
+ spec.homepage = 'https://github.com/ForwardFinancing/ach_client'
19
+
20
+ spec.files = `git ls-files -z`.split(/\x0/)
21
+ .reject do |f|
22
+ f.match(%r{^(test|spec|features)/})
23
+ end
24
+ spec.bindir = 'exe'
25
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
26
+ spec.require_paths = [
27
+ 'lib',
28
+ 'config'
29
+ ]
30
+
31
+ # NACHA library
32
+ spec.add_dependency 'ach', '~> 0'
33
+
34
+ # Handy ruby behavior from rails
35
+ spec.add_dependency 'activesupport'
36
+
37
+ # SFTP client (for Bank providers)
38
+ spec.add_dependency 'net-sftp'
39
+
40
+ # SOAP client (for AchWorks and ICheckGateway clients)
41
+ spec.add_dependency 'savon', '~> 2'
42
+
43
+ # Asynchronocity w/out extra infrastucture dependency (database/redis)
44
+ spec.add_dependency 'sucker_punch', '~> 2'
45
+
46
+ spec.add_development_dependency 'bundler', '~> 1.12'
47
+ spec.add_development_dependency 'codeclimate-test-reporter'
48
+ spec.add_development_dependency 'minitest-reporters'
49
+ spec.add_development_dependency 'minitest', '~> 5'
50
+ spec.add_development_dependency 'mocha'
51
+ spec.add_development_dependency 'pry'
52
+ spec.add_development_dependency 'rake', '~> 10'
53
+ spec.add_development_dependency 'simplecov'
54
+ spec.add_development_dependency 'timecop'
55
+ spec.add_development_dependency 'vcr'
56
+ spec.add_development_dependency 'webmock'
57
+ spec.add_development_dependency 'yard'
58
+ end
data/bin/console ADDED
@@ -0,0 +1,93 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Prerequisites for working with this gem in console
4
+ require 'bundler/setup'
5
+ require 'ach_client'
6
+ require 'pry'
7
+
8
+ # Initialize constants to test values so we don't have to repeat this every
9
+ # time we run a console session
10
+ AchClient::AchWorks.company_key = 'SASD%!%$DGLJGWYRRDGDDUDFDESDHDD'
11
+ AchClient::AchWorks.company = 'MYCOMPANY'
12
+ AchClient::AchWorks.loc_i_d = '9505'
13
+ AchClient::AchWorks.s_s_s = 'TST'
14
+ AchClient::AchWorks.wsdl = 'http://tstsvr.achworks.com/dnet/achws.asmx?wsdl'
15
+
16
+ AchClient::ICheckGateway.site_i_d = 'SEDZ'
17
+ AchClient::ICheckGateway.site_key = '236652'
18
+ AchClient::ICheckGateway.api_key = 'a3GFMBGz6KhkTzg'
19
+ AchClient::ICheckGateway.live = false
20
+ AchClient::ICheckGateway.wsdl = 'https://icheckgateway.com/API/Service.asmx?WSDL'
21
+
22
+ AchClient::SiliconValleyBank.immediate_destination = '000000000'
23
+ AchClient::SiliconValleyBank.immediate_destination_name = 'Test Destination'
24
+ AchClient::SiliconValleyBank.immediate_origin = '000000000'
25
+ AchClient::SiliconValleyBank.immediate_origin_name = 'Test Origin'
26
+ AchClient::SiliconValleyBank.company_identification = '123456789'
27
+ AchClient::SiliconValleyBank.company_entry_description = 'idk brah'
28
+ AchClient::SiliconValleyBank.originating_dfi_identification = '00000000'
29
+ AchClient::SiliconValleyBank.host = 'localhost:3000'
30
+ AchClient::SiliconValleyBank.username = 'ebachman@piedpiper.org'
31
+ AchClient::SiliconValleyBank.password = 'AviatoRulez7'
32
+ AchClient::SiliconValleyBank.private_ssh_key = "-----BEGIN RSA PRIVATE KEY-----
33
+ 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
82
+ -----END RSA PRIVATE KEY-----
83
+ "
84
+ AchClient::SiliconValleyBank.outgoing_path = '/outbox'
85
+ AchClient::SiliconValleyBank.incoming_path = '/Inbox'
86
+ AchClient::SiliconValleyBank.file_naming_strategy = lambda do |batch_number|
87
+ batch_number ||= 1
88
+ "ACHP#{Date.today.strftime('%m%d%y')}#{batch_number.to_s.rjust(2, '0')}"
89
+ end
90
+
91
+
92
+ # Start a console session using pry
93
+ Pry.start
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here