Skip to content

Commit

Permalink
Adding human-readable messages to bank reports (#29)
Browse files Browse the repository at this point in the history
* Adding human-readable messages to bank reports

Resolves ENG-65

* linting
  • Loading branch information
cassiascheffer authored Jan 27, 2020
1 parent b547141 commit 65bc625
Show file tree
Hide file tree
Showing 5 changed files with 254 additions and 20 deletions.
81 changes: 81 additions & 0 deletions lib/bambora/bank/batch_report_messages.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# frozen_string_literal: true

module Bambora
module Bank
module BatchReportMessages
##
# Adds message text to the response as per the Bambora Docs:
# https://help.na.bambora.com/hc/en-us/articles/115010510248-Batch-reporting
MESSAGES = {
'1' => 'Invalid bank number',
'2' => 'Invalid branch number',
'3' => 'Invalid account number',
'4' => 'Invalid transaction amount',
'5' => 'Reference number too long',
'6' => 'Invalid due date',
'7' => 'Due date out of valid date range',
'8' => 'Customer name truncated to 32 characters',
'9' => 'Customer name missing',
'10' => 'Duplicate transaction matching bank account',
'11' => 'Zero, negative or non-numeric amount',
'12' => 'Invalid bank and/or branch number',
'13' => 'Payee/drawee name cannot be spaces',
'14' => 'Invalid payment code',
'15' => 'Invalid transaction type',
'16' => 'Account Closed',
'17' => 'NSF – Debit declined due to insufficient funds.',
'18' => 'Transaction rejected by Bank',
'19' => 'Invalid bank, branch, or account number',
'20' => 'Refused by payor',
'21' => 'Funds not cleared',
'22' => 'Account Frozen',
'23' => 'Payment Stopped',
'24' => 'Transaction Cancelled',
'25' => 'Cannot Trace',
'26' => 'Incorrect Payor/Payee Name',
'27' => 'Payor/Payee Deceased',
'28' => 'Invalid transit routing number',
'29' => 'Invalid Account Type',
'30' => 'Transaction type not permitted',
'31' => 'No Checking Privileges',
'33' => 'Edit Reject',
'35' => 'Reserved Return Code',
'36' => 'Payment Recalled',
'38' => 'Not in accordance with agreement – Personal',
'39' => 'Agreement revoked – Personal',
'40' => 'No pre-notification – Personal',
'41' => 'Not in accordance with agreement – Business',
'42' => 'Agreement revoked – Business',
'43' => 'No pre-notification – Business',
'44' => 'Customer Initiated Return Credit Only',
'45' => 'Currency/Account Mismatch',
'46' => 'No Debit Allowed',
'47' => 'Interbank – Returned Item',
'48' => 'Routing as entered, account modified',
'49' => 'Routing as entered, repair of account unknown',
'50' => 'Routing as entered, account unknown',
'51' => 'Routing number modified, account as entered',
'52' => 'Routing number modified, account modified',
'53' => 'Routing number modified, repair of account unknown',
'54' => 'Routing number modified, account unknown',
'55' => 'ACH Unavailable for account',
'56' => 'Customer code invalid/missing payment info',
'58' => 'Profile status is closed or disabled',
'59' => 'Invalid SEC code',
'60' => 'Invalid Account Identifier',
'61' => 'Invalid Account Identifier',
'62' => 'Reference Number is Missing',
'63' => 'Invalid Customer Country Code',
'64' => 'Invalid Bank Country Code',
'65' => 'Invalid Bank Name',
'66' => 'Bank Name is Missing',
'67' => 'Addendum not allowed, too long, or has invalid characters',
'68' => 'Invalid Bank Descriptor',
'69' => 'Invalid Customer Name',
'70' => 'Transaction rejected - contact support',
'71' => 'Refund Request by End Customer',
'72' => 'Blocked due to a Notice of Change',
}.freeze
end
end
end
13 changes: 12 additions & 1 deletion lib/bambora/bank/batch_report_resource.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ module Bank
#
# @see https://dev.na.bambora.com/docs/guides/batch_payment/report/
class BatchReportResource
include Bambora::Bank::BatchReportMessages

DEFAULT_REQUEST_PARAMS = {
rpt_format: 'JSON',
rpt_version: '2.0',
Expand Down Expand Up @@ -51,11 +53,20 @@ def initialize(client:, api_key:)
#
# @params profile_data [Hash] with values as noted in the example.
def show(report_data)
client.post(path: sub_path, body: batch_report_body(report_data))
add_messages_to_response(
client.post(path: sub_path, body: batch_report_body(report_data)),
)
end

private

def add_messages_to_response(response)
response.dig(:response, :record).map! do |record|
record.merge!(messages: record[:messageId].split(',').map { |id| MESSAGES[id] })
end
response
end

def batch_report_body(request_data)
DEFAULT_REQUEST_PARAMS.merge(request_data).merge(
merchant_id: client.merchant_id,
Expand Down
1 change: 1 addition & 0 deletions lib/bambora/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
require 'bambora/v1/payment_resource'
require 'bambora/v1/profile_resource'
require 'bambora/bank/payment_profile_resource'
require 'bambora/bank/batch_report_messages'
require 'bambora/bank/batch_report_resource'

module Bambora
Expand Down
2 changes: 1 addition & 1 deletion lib/bambora/factories/response_adapter_factory.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ def for(response)
when 'application/json'
Bambora::JSONResponse.new(response)
when 'text/html'
# Currently, the only endpoint that responds wit text/html is /scripts/payment_profiles.asp
# Currently, the only endpoint that responds with text/html is /scripts/payment_profiles.asp
Bambora::Bank::Adapters::PaymentProfileResponse.new(response)
else raise Bambora::Client::Error, "Unknown Content Type: #{content_type}. Response Body: #{response.body}"
end
Expand Down
177 changes: 159 additions & 18 deletions spec/bambora/bank/batch_report_resource_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,75 @@ module Bank
let(:headers) { { 'Authorization' => 'Passcode MTpmYWtla2V5', 'Sub-Merchant-ID' => sub_merchant_id } }
let(:response_body) do
{
code: 1,
message: 'Hup...want...buy.',
customer_code: 'aaa111',
validation: {
id: '',
approved: 1,
message_id: 1,
message: '',
auth_code: '',
trans_date: '',
order_number: '',
type: '',
amount: 0,
cvd_id: 123,
response: {
version: '1.0',
code: 1,
message: 'Report generated',
records: {
total: 3,
},
record: [
{
rowId: 1,
merchantId: 300_202_779,
batchId: 10_000_000,
transId: 1,
itemNumber: 1,
payeeName: 'General Motors',
reference: '1000070001',
operationType: 'C',
amount: 10_000,
stateId: 2,
stateName: 'Scheduled',
statusId: 1,
statusName: 'Validated/Approved',
bankDescriptor: '',
messageId: '',
customerCode: '',
settlementDate: '2017-08-09',
returnedDate: '',
returnType: '',
eftId: 0,
},
],
},
}
end

let(:expected_response) do
{
response: {
version: '1.0',
code: 1,
message: 'Report generated',
records: {
total: 3,
},
record: [
{
rowId: 1,
merchantId: 300_202_779,
batchId: 10_000_000,
transId: 1,
itemNumber: 1,
payeeName: 'General Motors',
reference: '1000070001',
operationType: 'C',
amount: 10_000,
stateId: 2,
stateName: 'Scheduled',
statusId: 1,
statusName: 'Validated/Approved',
bankDescriptor: '',
messageId: '',
messages: [],
customerCode: '',
settlementDate: '2017-08-09',
returnedDate: '',
returnType: '',
eftId: 0,
},
],
},
}
end
Expand All @@ -37,7 +92,7 @@ module Bank
'Bambora::Rest::XMLClient',
merchant_id: merchant_id,
sub_merchant_id: sub_merchant_id,
post: true,
post: response_body,
)
end

Expand Down Expand Up @@ -77,10 +132,96 @@ module Bank
}
end

before { reports.show(request_data) }
context 'with no messageId' do
it 'sends `post` to the client with the correct data' do
reports.show(request_data)
expect(client).to have_received(:post).with(posted_data)
end

it 'returns the expected response' do
expect(reports.show(request_data)).to eq expected_response
end
end

context 'with messageIds' do
let(:response_body) do
{
response: {
version: '1.0',
code: 1,
message: 'Report generated',
records: {
total: 3,
},
record: [
{
rowId: 1,
merchantId: 300_202_779,
batchId: 10_000_000,
transId: 1,
itemNumber: 1,
payeeName: 'General Motors',
reference: '1000070001',
operationType: 'C',
amount: 10_000,
stateId: 2,
stateName: 'Scheduled',
statusId: 1,
statusName: 'Validated/Approved',
bankDescriptor: '',
messageId: '1,2',
customerCode: '',
settlementDate: '2017-08-09',
returnedDate: '',
returnType: '',
eftId: 0,
},
],
},
}
end

let(:expected_response) do
{
response: {
version: '1.0',
code: 1,
message: 'Report generated',
records: {
total: 3,
},
record: [
{
rowId: 1,
merchantId: 300_202_779,
batchId: 10_000_000,
transId: 1,
itemNumber: 1,
payeeName: 'General Motors',
reference: '1000070001',
operationType: 'C',
amount: 10_000,
stateId: 2,
stateName: 'Scheduled',
statusId: 1,
statusName: 'Validated/Approved',
bankDescriptor: '',
messageId: '1,2',
messages: ['Invalid bank number', 'Invalid branch number'],
customerCode: '',
settlementDate: '2017-08-09',
returnedDate: '',
returnType: '',
eftId: 0,
},
],
},
}
end

it 'sends `post` to the client with the correct data' do
expect(client).to have_received(:post).with(posted_data)
it 'returns the expected response' do
expect(reports.show(request_data)).to eq expected_response
end
end
end
end
Expand Down

0 comments on commit 65bc625

Please sign in to comment.