ach_client 1.1.0 → 2.0.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +28 -0
- data/README.md +10 -0
- data/lib/ach_client/objects/return_code.rb +4 -1
- data/lib/ach_client/providers/soap/i_check_gateway/ach_transaction.rb +26 -1
- data/lib/ach_client/providers/soap/i_check_gateway/instant_rejection_error.rb +33 -0
- data/lib/ach_client/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bdcfddb63a2f873af45df29f8fcf6765ec99aff800eb04e8ec2b7500f0827e3c
|
4
|
+
data.tar.gz: 3bfa32675ec76f4e31b830b3616cc913b13f865c2c789394d49cc07758e93b89
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 25670e16c050eb8248d80f22ffeea4a649cef6f624828118e32c866b7b7e0b0e19f0735150b7b636e5cb88dafc7d57fe7a2ac3225b8c507100b42a3a9fba668e
|
7
|
+
data.tar.gz: ed197b466da4182a732f463b7c51f4a0bd24fdfbfa58755bd058d2f830790719e5f6d6c600abf480e045430e186c962f331ee0a7e17534546d93f7ed44cc8819
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
### 2.0.0
|
2
|
+
|
3
|
+
* Add new AchClient::ICheckGateway::InstantRejectionError to handle API errors raised by ICheckGateway in situations
|
4
|
+
where other providers would accept the transaction and issue a return when polling in the future. This is a breaking
|
5
|
+
change as previous versions would raise a RuntimeError with the message 'ICheckGateway ACH Transaction Failure' and
|
6
|
+
including the API response.
|
7
|
+
|
8
|
+
* Include "internal corrections" (return codes starting with 'XZ') in the AchClient::ReturnCode#correction? predicate
|
9
|
+
|
10
|
+
### 1.1.0
|
11
|
+
|
12
|
+
* Add AchClient::Fake provider to facilitate testing
|
13
|
+
|
14
|
+
### 1.0.3
|
15
|
+
|
16
|
+
* Add presumed description for X09 return code
|
17
|
+
|
18
|
+
### 1.0.2
|
19
|
+
|
20
|
+
* Add previously undocumented X01 internal return code
|
21
|
+
|
22
|
+
### 1.0.1
|
23
|
+
|
24
|
+
* Remove newline characters from fields before generating NACHA files
|
25
|
+
|
26
|
+
### 1.0.0
|
27
|
+
|
28
|
+
* Prior to 1.0.0, ach_client did not have a stable API.
|
data/README.md
CHANGED
@@ -115,6 +115,16 @@ returned by the `#send` method. So you should:
|
|
115
115
|
|
116
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
117
|
|
118
|
+
### ICheckGateway instant rejection caveat
|
119
|
+
|
120
|
+
ICheckGateway sometimes returns an API error when a valid ACH transaction is sent in a handful of
|
121
|
+
rejection scenarios. This is unusual because most providers will accept the transaction, return an
|
122
|
+
`external_ach_id`, and then supply the rejection info when you poll for responses (see section on response polling
|
123
|
+
below) at a later date. This idiosyncrasy is handled by raising an exception `InstantRejectionError` which contains
|
124
|
+
information about the premature ACH return. In this case, no `external_ach_id` is returned by the `#send` method
|
125
|
+
because ICheck does not return one, nor do they maintain a record of the transaction in their system. See the
|
126
|
+
`InstantRejectionError` class for more details.
|
127
|
+
|
118
128
|
## Batched ACH transactions
|
119
129
|
|
120
130
|
A group of ACH transactions can also be sent in a single batched transaction to
|
@@ -9,6 +9,9 @@ module AchClient
|
|
9
9
|
# The first character in an internal return code
|
10
10
|
INTERNAL_START_CHARACTER = 'X'
|
11
11
|
|
12
|
+
# Returns that are both internal and corrections start with this string
|
13
|
+
INTERNAL_CORRECTION_STRING = 'XZ'
|
14
|
+
|
12
15
|
attr_accessor :code,
|
13
16
|
:description,
|
14
17
|
:reason
|
@@ -25,7 +28,7 @@ module AchClient
|
|
25
28
|
|
26
29
|
# @return Whether or not this return is a correction/notice of change
|
27
30
|
def correction?
|
28
|
-
@code.start_with?(CORRECTION_START_CHARACTER)
|
31
|
+
@code.start_with?(CORRECTION_START_CHARACTER) || @code.start_with?(INTERNAL_CORRECTION_STRING)
|
29
32
|
end
|
30
33
|
|
31
34
|
# @return Whether or not the return is internal
|
@@ -3,11 +3,23 @@ module AchClient
|
|
3
3
|
# ICheckGateway implementation for AchTransaction
|
4
4
|
class AchTransaction < Abstract::AchTransaction
|
5
5
|
|
6
|
+
# When ICheck API gives us an error response containing a correction, the response field looks like this:
|
7
|
+
# DECLINED - Notice of Change (XXX - Change Data: YYYYYY)
|
8
|
+
# Where X is a three character string representing the return code (example: C01)
|
9
|
+
# Where Y is any number of digits representing the updated information for the correction - the
|
10
|
+
# ACH attribute that should be updated (example: 123456789)
|
11
|
+
# The (\w{3}) capture group matches the return code, while the (\d+) capture group matches the correction data
|
12
|
+
# for later use.
|
13
|
+
NOC_RESPONSE_MATCHER = /DECLINED - Notice of Change \((\w{3}) - Change Data: (\d+)\)/
|
14
|
+
|
6
15
|
# Sends this transaction to ICheckGateway
|
7
16
|
# If successful, returns a string from the response that seems to be
|
8
17
|
# a unique identifier for the transaction from ICheckGateway
|
9
18
|
# Raises an exception with as much info as possible if something goes
|
10
|
-
# wrong
|
19
|
+
# wrong.
|
20
|
+
# ICheck sometimes returns an API error for certain rejection scenarios. In this case we raise a
|
21
|
+
# InstantRejectionError which can be caught to handle any business logic appropriate for this edge case.
|
22
|
+
# The exception contains a method ach_response that returns the information about the return.
|
11
23
|
# @return [String] a string returned by ICheckGateway - external_ach_id
|
12
24
|
def do_send
|
13
25
|
# The response comes back as a | separated list of field values with
|
@@ -21,6 +33,19 @@ module AchClient
|
|
21
33
|
if response[0] == 'APPROVED'
|
22
34
|
# Return the confirmation number
|
23
35
|
response[7]
|
36
|
+
elsif response[0].include?('DECLINED - Notice of Change')
|
37
|
+
return_code, addendum = NOC_RESPONSE_MATCHER.match(response[0]).captures
|
38
|
+
# The API error message incorrectly uses the normal correction return codes when the internal correction
|
39
|
+
# return codes should be used instead (since the transaction is never forwarded through to the NACHA system)
|
40
|
+
# Correcting this involves replacing `C0` with `XZ` (ie C01 becomes XZ1)
|
41
|
+
corrected_return_code = "XZ#{return_code.last}"
|
42
|
+
raise ICheckGateway::InstantRejectionError.new(
|
43
|
+
nacha_return_code: corrected_return_code,
|
44
|
+
addendum: addendum,
|
45
|
+
transaction: self
|
46
|
+
), response[0]
|
47
|
+
elsif response[0].include?('DECLINED - Invalid Routing Number')
|
48
|
+
raise ICheckGateway::InstantRejectionError.new(nacha_return_code: 'X13', transaction: self), response[0]
|
24
49
|
else
|
25
50
|
# Don't have a reliable way of getting the error message, so we will
|
26
51
|
# just raise the whole response.
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module AchClient
|
2
|
+
class ICheckGateway
|
3
|
+
# ICheckGateway sometimes returns an API error when a valid ACH transaction is sent in a handful of
|
4
|
+
# rejection scenarios. This is unusual because most providers will accept the transaction, return an
|
5
|
+
# external_ach_id, and then supply the rejection info when you poll for responses at a later date.
|
6
|
+
# So far we have observed this happening in the following scenarios:
|
7
|
+
# - When an invalid routing number is supplied (X13 - Invalid ACH Routing Number - Entry contains a Receiving DFI
|
8
|
+
# Identification or Gateway Identification that is not a valid ACH routing number.)
|
9
|
+
# - When there is a Notice of Change for the account number (C01 - ACH Change Code. Incorrect Account Number)
|
10
|
+
# - When there is a Notice of Change for the routing number (C02 - ACH Change Code. Incorrect Transit Route)
|
11
|
+
# This exception can be caught to handle the API error in the appropriate manner.
|
12
|
+
# The NACHA return code inferred from the error message is retrievable from the exception instance as well as any
|
13
|
+
# addendum information provided by the API error (ie the correct new account/routing number)
|
14
|
+
class InstantRejectionError < RuntimeError
|
15
|
+
attr_reader :ach_response
|
16
|
+
|
17
|
+
def initialize(message = nil, nacha_return_code:, addendum: nil, transaction:)
|
18
|
+
super(message)
|
19
|
+
return_code = ReturnCodes.find_by(code: nacha_return_code)
|
20
|
+
response_args = {
|
21
|
+
amount: transaction.amount,
|
22
|
+
date: transaction.effective_entry_date,
|
23
|
+
return_code: return_code,
|
24
|
+
}
|
25
|
+
@ach_response = if return_code.correction?
|
26
|
+
CorrectedAchResponse.new(**response_args, corrections: addendum)
|
27
|
+
else
|
28
|
+
ReturnedAchResponse.new(**response_args)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/lib/ach_client/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ach_client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Zach Cotter
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-05-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ach
|
@@ -262,6 +262,7 @@ files:
|
|
262
262
|
- ".tool-versions"
|
263
263
|
- ".tool-versions-e"
|
264
264
|
- ".travis.yml"
|
265
|
+
- CHANGELOG.md
|
265
266
|
- Gemfile
|
266
267
|
- README.md
|
267
268
|
- Rakefile
|
@@ -321,6 +322,7 @@ files:
|
|
321
322
|
- lib/ach_client/providers/soap/i_check_gateway/ach_transaction.rb
|
322
323
|
- lib/ach_client/providers/soap/i_check_gateway/company_info.rb
|
323
324
|
- lib/ach_client/providers/soap/i_check_gateway/i_check_gateway.rb
|
325
|
+
- lib/ach_client/providers/soap/i_check_gateway/instant_rejection_error.rb
|
324
326
|
- lib/ach_client/providers/soap/i_check_gateway/response_record_processor.rb
|
325
327
|
- lib/ach_client/providers/soap/i_check_gateway/transaction_type_transformer.rb
|
326
328
|
- lib/ach_client/providers/soap/soap_provider.rb
|