From 439871aea4b4d076ca8f7f8a29f087fd85396bca Mon Sep 17 00:00:00 2001 From: Eddy Jaga Date: Fri, 7 Nov 2025 23:03:58 +1100 Subject: [PATCH 1/2] fix virtual account response --- Gemfile.lock | 2 +- docs/bank_accounts.md | 24 ++-- examples/bank_accounts.md | 6 +- lib/zai_payment/response.rb | 2 +- lib/zai_payment/version.rb | 2 +- .../resources/bank_account_spec.rb | 12 +- .../resources/virtual_account_spec.rb | 133 ++++++++---------- 7 files changed, 91 insertions(+), 90 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 596ea16..0cff616 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - zai_payment (2.8.0) + zai_payment (2.8.1) base64 (~> 0.3.0) faraday (~> 2.0) openssl (~> 3.3) diff --git a/docs/bank_accounts.md b/docs/bank_accounts.md index f355f72..ce44f29 100644 --- a/docs/bank_accounts.md +++ b/docs/bank_accounts.md @@ -117,7 +117,7 @@ Validate a US bank routing number before creating an account. This can be used t response = bank_accounts.validate_routing_number('122235821') if response.success? - routing_info = response.data + routing_info = response.data['routing_number'] puts "Routing Number: #{routing_info['routing_number']}" puts "Bank Name: #{routing_info['customer_name']}" puts "City: #{routing_info['city']}" @@ -133,16 +133,18 @@ end ```ruby { - "routing_number" => "122235821", - "customer_name" => "US BANK NA", - "address" => "EP-MN-WN1A", - "city" => "ST. PAUL", - "state_code" => "MN", - "zip" => "55107", - "zip_extension" => "1419", - "phone_area_code" => "800", - "phone_prefix" => "937", - "phone_suffix" => "631" + "routing_number" => { + "routing_number" => "122235821", + "customer_name" => "US BANK NA", + "address" => "EP-MN-WN1A", + "city" => "ST. PAUL", + "state_code" => "MN", + "zip" => "55107", + "zip_extension" => "1419", + "phone_area_code" => "800", + "phone_prefix" => "937", + "phone_suffix" => "631" + } } ``` diff --git a/examples/bank_accounts.md b/examples/bank_accounts.md index 1a4b230..e46a8e8 100644 --- a/examples/bank_accounts.md +++ b/examples/bank_accounts.md @@ -164,7 +164,7 @@ bank_accounts = ZaiPayment::Resources::BankAccount.new response = bank_accounts.validate_routing_number('122235821') if response.success? - routing_info = response.data + routing_info = response.data['routing_number'] puts "Routing Number Validation Results:" puts " Routing Number: #{routing_info['routing_number']}" @@ -197,7 +197,7 @@ begin validation_response = bank_accounts.validate_routing_number(routing_number) if validation_response.success? - bank_info = validation_response.data + bank_info = validation_response.data['routing_number'] # Show user the bank information for confirmation puts "You are creating an account with:" @@ -246,7 +246,7 @@ class BankAccountsController < ApplicationController response = bank_accounts.validate_routing_number(routing_number) if response.success? - bank_info = response.data + bank_info = response.data['routing_number'] # Return bank info to display in the form render json: { diff --git a/lib/zai_payment/response.rb b/lib/zai_payment/response.rb index a2fd19f..32469d9 100644 --- a/lib/zai_payment/response.rb +++ b/lib/zai_payment/response.rb @@ -8,7 +8,7 @@ class Response RESPONSE_DATA_KEYS = %w[ webhooks users items fees transactions batch_transactions batches bpay_accounts bank_accounts card_accounts - wallet_accounts virtual_accounts routing_number disbursements pay_ids + wallet_accounts virtual_accounts disbursements pay_ids ].freeze def initialize(faraday_response) diff --git a/lib/zai_payment/version.rb b/lib/zai_payment/version.rb index cfcea74..8f51740 100644 --- a/lib/zai_payment/version.rb +++ b/lib/zai_payment/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module ZaiPayment - VERSION = '2.8.0' + VERSION = '2.8.1' end diff --git a/spec/zai_payment/resources/bank_account_spec.rb b/spec/zai_payment/resources/bank_account_spec.rb index 1170fce..d1ce68b 100644 --- a/spec/zai_payment/resources/bank_account_spec.rb +++ b/spec/zai_payment/resources/bank_account_spec.rb @@ -217,8 +217,16 @@ it 'returns routing number details' do response = bank_account_resource.validate_routing_number('122235821') - expect(response.data['routing_number']).to eq('122235821') - expect(response.data['customer_name']).to eq('US BANK NA') + expect(response.data).to be_a(Hash) + expect(response.data['routing_number']['routing_number']).to eq('122235821') + end + + it 'returns city, state, and zip' do + response = bank_account_resource.validate_routing_number('122235821') + + expect(response.data['routing_number']['customer_name']).to eq('US BANK NA') + expect(response.data['routing_number']['city']).to eq('ST. PAUL') + expect(response.data['routing_number']['state_code']).to eq('MN') end end diff --git a/spec/zai_payment/resources/virtual_account_spec.rb b/spec/zai_payment/resources/virtual_account_spec.rb index 93cf31e..b7e031c 100644 --- a/spec/zai_payment/resources/virtual_account_spec.rb +++ b/spec/zai_payment/resources/virtual_account_spec.rb @@ -207,22 +207,20 @@ describe '#show' do let(:virtual_account_data) do { - 'virtual_accounts' => { - 'id' => '46deb476-c1a6-41eb-8eb7-26a695bbe5bc', - 'routing_number' => '123456', - 'account_number' => '100000017', - 'currency' => 'AUD', - 'user_external_id' => '46deb476-c1a6-41eb-8eb7-26a695bbe5bc', - 'wallet_account_id' => '46deb476-c1a6-41eb-8eb7-26a695bbe5bc', - 'status' => 'active', - 'created_at' => '2020-04-27T20:28:22.378Z', - 'updated_at' => '2020-04-27T20:28:22.378Z', - 'account_type' => 'NIND', - 'full_legal_account_name' => 'Prop Tech Marketplace', - 'account_name' => 'Real Estate Agency X', - 'aka_names' => ['Realestate Agency X', 'Realestate Agency X of PropTech Marketplace'], - 'merchant_id' => '46deb476c1a641eb8eb726a695bbe5bc' - } + 'id' => '46deb476-c1a6-41eb-8eb7-26a695bbe5bc', + 'routing_number' => '123456', + 'account_number' => '100000017', + 'currency' => 'AUD', + 'user_external_id' => '46deb476-c1a6-41eb-8eb7-26a695bbe5bc', + 'wallet_account_id' => '46deb476-c1a6-41eb-8eb7-26a695bbe5bc', + 'status' => 'active', + 'created_at' => '2020-04-27T20:28:22.378Z', + 'updated_at' => '2020-04-27T20:28:22.378Z', + 'account_type' => 'NIND', + 'full_legal_account_name' => 'Prop Tech Marketplace', + 'account_name' => 'Real Estate Agency X', + 'aka_names' => ['Realestate Agency X', 'Realestate Agency X of PropTech Marketplace'], + 'merchant_id' => '46deb476c1a641eb8eb726a695bbe5bc' } end @@ -337,22 +335,20 @@ describe '#update_aka_names' do let(:updated_virtual_account_data) do { - 'virtual_accounts' => { - 'id' => '46deb476-c1a6-41eb-8eb7-26a695bbe5bc', - 'routing_number' => '123456', - 'account_number' => '100000017', - 'currency' => 'AUD', - 'user_external_id' => '46deb476-c1a6-41eb-8eb7-26a695bbe5bc', - 'wallet_account_id' => '46deb476-c1a6-41eb-8eb7-26a695bbe5bc', - 'status' => 'active', - 'created_at' => '2020-04-27T20:28:22.378Z', - 'updated_at' => '2020-04-27T20:28:22.378Z', - 'account_type' => 'NIND', - 'full_legal_account_name' => 'Prop Tech Marketplace', - 'account_name' => 'Real Estate Agency X', - 'aka_names' => ['Updated Name 1', 'Updated Name 2'], - 'merchant_id' => '46deb476c1a641eb8eb726a695bbe5bc' - } + 'id' => '46deb476-c1a6-41eb-8eb7-26a695bbe5bc', + 'routing_number' => '123456', + 'account_number' => '100000017', + 'currency' => 'AUD', + 'user_external_id' => '46deb476-c1a6-41eb-8eb7-26a695bbe5bc', + 'wallet_account_id' => '46deb476-c1a6-41eb-8eb7-26a695bbe5bc', + 'status' => 'active', + 'created_at' => '2020-04-27T20:28:22.378Z', + 'updated_at' => '2020-04-27T20:28:22.378Z', + 'account_type' => 'NIND', + 'full_legal_account_name' => 'Prop Tech Marketplace', + 'account_name' => 'Real Estate Agency X', + 'aka_names' => ['Updated Name 1', 'Updated Name 2'], + 'merchant_id' => '46deb476c1a641eb8eb726a695bbe5bc' } end @@ -388,7 +384,7 @@ before do stubs.patch('/virtual_accounts/46deb476-c1a6-41eb-8eb7-26a695bbe5bc/aka_names') do [200, { 'Content-Type' => 'application/json' }, - { 'virtual_accounts' => updated_virtual_account_data['virtual_accounts'].merge('aka_names' => []) }] + updated_virtual_account_data.merge('aka_names' => [])] end end @@ -407,8 +403,8 @@ context 'with single aka_name' do before do stubs.patch('/virtual_accounts/46deb476-c1a6-41eb-8eb7-26a695bbe5bc/aka_names') do - updated_data = updated_virtual_account_data['virtual_accounts'].merge('aka_names' => ['Single Name']) - [200, { 'Content-Type' => 'application/json' }, { 'virtual_accounts' => updated_data }] + updated_data = updated_virtual_account_data.merge('aka_names' => ['Single Name']) + [200, { 'Content-Type' => 'application/json' }, updated_data] end end @@ -426,8 +422,7 @@ before do stubs.patch('/virtual_accounts/46deb476-c1a6-41eb-8eb7-26a695bbe5bc/aka_names') do [200, { 'Content-Type' => 'application/json' }, - { 'virtual_accounts' => updated_virtual_account_data['virtual_accounts'] - .merge('aka_names' => ['Name 1', 'Name 2', 'Name 3']) }] + updated_virtual_account_data.merge('aka_names' => ['Name 1', 'Name 2', 'Name 3'])] end end @@ -531,22 +526,20 @@ describe '#update_account_name' do let(:updated_account_data) do { - 'virtual_accounts' => { - 'id' => '46deb476-c1a6-41eb-8eb7-26a695bbe5bc', - 'routing_number' => '123456', - 'account_number' => '100000017', - 'currency' => 'AUD', - 'user_external_id' => '46deb476-c1a6-41eb-8eb7-26a695bbe5bc', - 'wallet_account_id' => '46deb476-c1a6-41eb-8eb7-26a695bbe5bc', - 'status' => 'active', - 'created_at' => '2020-04-27T20:28:22.378Z', - 'updated_at' => '2020-04-27T20:28:22.378Z', - 'account_type' => 'NIND', - 'full_legal_account_name' => 'Prop Tech Marketplace', - 'account_name' => 'Updated Account Name', - 'aka_names' => ['Realestate Agency X'], - 'merchant_id' => '46deb476c1a641eb8eb726a695bbe5bc' - } + 'id' => '46deb476-c1a6-41eb-8eb7-26a695bbe5bc', + 'routing_number' => '123456', + 'account_number' => '100000017', + 'currency' => 'AUD', + 'user_external_id' => '46deb476-c1a6-41eb-8eb7-26a695bbe5bc', + 'wallet_account_id' => '46deb476-c1a6-41eb-8eb7-26a695bbe5bc', + 'status' => 'active', + 'created_at' => '2020-04-27T20:28:22.378Z', + 'updated_at' => '2020-04-27T20:28:22.378Z', + 'account_type' => 'NIND', + 'full_legal_account_name' => 'Prop Tech Marketplace', + 'account_name' => 'Updated Account Name', + 'aka_names' => ['Realestate Agency X'], + 'merchant_id' => '46deb476c1a641eb8eb726a695bbe5bc' } end @@ -582,8 +575,8 @@ before do stubs.patch('/virtual_accounts/46deb476-c1a6-41eb-8eb7-26a695bbe5bc/account_name') do long_name = 'A' * 140 - updated_data = updated_account_data['virtual_accounts'].merge('account_name' => long_name) - [202, { 'Content-Type' => 'application/json' }, { 'virtual_accounts' => updated_data }] + updated_data = updated_account_data.merge('account_name' => long_name) + [202, { 'Content-Type' => 'application/json' }, updated_data] end end @@ -850,22 +843,20 @@ describe '#create' do let(:virtual_account_data) do { - 'virtual_accounts' => { - 'id' => 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee', - 'routing_number' => '123456', - 'account_number' => '100000017', - 'currency' => 'AUD', - 'wallet_account_id' => 'ae07556e-22ef-11eb-adc1-0242ac120002', - 'user_external_id' => 'ca12346e-22ef-11eb-adc1-0242ac120002', - 'status' => 'pending_activation', - 'created_at' => '2020-04-27T20:28:22.378Z', - 'updated_at' => '2020-04-27T20:28:22.378Z', - 'account_type' => 'NIND', - 'full_legal_account_name' => 'Prop Tech Marketplace', - 'account_name' => 'Real Estate Agency X', - 'aka_names' => ['Realestate agency X'], - 'merchant_id' => '46deb476c1a641eb8eb726a695bbe5bc' - } + 'id' => 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee', + 'routing_number' => '123456', + 'account_number' => '100000017', + 'currency' => 'AUD', + 'wallet_account_id' => 'ae07556e-22ef-11eb-adc1-0242ac120002', + 'user_external_id' => 'ca12346e-22ef-11eb-adc1-0242ac120002', + 'status' => 'pending_activation', + 'created_at' => '2020-04-27T20:28:22.378Z', + 'updated_at' => '2020-04-27T20:28:22.378Z', + 'account_type' => 'NIND', + 'full_legal_account_name' => 'Prop Tech Marketplace', + 'account_name' => 'Real Estate Agency X', + 'aka_names' => ['Realestate agency X'], + 'merchant_id' => '46deb476c1a641eb8eb726a695bbe5bc' } end From 9a02d2453d4cd386f67863185dae5fbbcfdf91ed Mon Sep 17 00:00:00 2001 From: Eddy Jaga Date: Fri, 7 Nov 2025 23:05:37 +1100 Subject: [PATCH 2/2] update changelog --- changelog.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/changelog.md b/changelog.md index 9486230..a2934a2 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,24 @@ ## [Released] +## [2.8.1] - 2025-11-07 + +### Fixed +- **Response Data Extraction Bug**: Fixed `.data` method returning only `routing_number` value instead of full object 🐛 + - Removed `routing_number` from `RESPONSE_DATA_KEYS` constant - it's a field within responses, not a collection wrapper key + - The `.data` method was incorrectly treating `routing_number` as a top-level data key + - This caused `response.data` to return just `"803320"` (the routing number) instead of the complete virtual account object + - Now properly returns the full response object when no wrapper key is found + - Affected resources: Virtual Accounts (and potentially other resources with `routing_number` field) + - Updated test mocks to match actual API response format (flat objects for single resources) + +### Changed +- **Virtual Account Test Fixtures**: Updated response structure to match actual Zai API format + - Single resource responses (show, create, update) now return flat objects without wrapper keys + - Collection responses (list) continue to use `virtual_accounts` wrapper key + - All 87 virtual account tests passing with corrected response structure + +**Full Changelog**: https://github.com/Sentia/zai-payment/compare/v2.8.0...v2.8.1 + ## [2.8.0] - 2025-11-07 ### Added