diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f0a849..9eb4930 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ ## [Unreleased] +## [3.1.0] - 2025-10-01 + +- Adds support for passing optional debtor_account and creditor_account parameters for registering payments + ## [3.0.0] - 2025-09-22 - Update `faraday` dependency to version 2.13.4 - Remove `faraday_middleware` dependency diff --git a/Gemfile.lock b/Gemfile.lock index 23effcb..0c0d251 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - incognia_api (3.0.0) + incognia_api (3.1.0) faraday (~> 2.13) GEM diff --git a/lib/incognia_api.rb b/lib/incognia_api.rb index bb57e6f..2361627 100644 --- a/lib/incognia_api.rb +++ b/lib/incognia_api.rb @@ -8,6 +8,8 @@ require_relative "incognia_api/api" require_relative "incognia_api/location" require_relative "incognia_api/person_id" +require_relative "incognia_api/pix_key" +require_relative "incognia_api/bank_account" require_relative "incognia_api/resources/api_resource" require_relative "incognia_api/resources/signup_assessment" diff --git a/lib/incognia_api/api.rb b/lib/incognia_api/api.rb index 89f0ead..0a16bcf 100644 --- a/lib/incognia_api/api.rb +++ b/lib/incognia_api/api.rb @@ -59,7 +59,7 @@ def register_feedback(event:, occurred_at: nil, expires_at: nil, person_id: nil, response.success? end - def register_payment(account_id:, request_token: nil, location: nil, person_id: nil, **opts) + def register_payment(account_id:, request_token: nil, location: nil, person_id: nil, debtor_account: nil, creditor_account: nil, **opts) params = { type: :payment, account_id: account_id, @@ -67,6 +67,8 @@ def register_payment(account_id:, request_token: nil, location: nil, person_id: }.compact params.merge!(location: location.to_hash) if location params.merge!(person_id: person_id.to_hash) if person_id + params.merge!(debtor_account: debtor_account.to_hash) if debtor_account + params.merge!(creditor_account: creditor_account.to_hash) if creditor_account params.merge!(opts) response = connection.request( diff --git a/lib/incognia_api/bank_account.rb b/lib/incognia_api/bank_account.rb new file mode 100644 index 0000000..180ba30 --- /dev/null +++ b/lib/incognia_api/bank_account.rb @@ -0,0 +1,54 @@ +require_relative "pix_key" +require_relative "person_id" + +module Incognia + class BankAccount + attr_reader :account_type, :account_purpose, :holder_type, :holder_tax_id, + :country, :ispb_code, :branch_code, :account_number, + :account_check_digit, :pix_keys + + def initialize( + holder_type:, holder_tax_id:, branch_code:, account_number:, account_type: nil, + account_purpose: nil, + country: nil, + ispb_code: nil, + account_check_digit: nil, + pix_keys: nil + ) + @account_type = account_type + @account_purpose = account_purpose + @holder_type = holder_type + @holder_tax_id = holder_tax_id + @country = country + @ispb_code = ispb_code + @branch_code = branch_code + @account_number = account_number + @account_check_digit = account_check_digit + @pix_keys = pix_keys + end + + def to_hash + h = { + account_type: account_type, + account_purpose: account_purpose, + holder_type: holder_type, + country: country, + ispb_code: ispb_code, + branch_code: branch_code, + account_number: account_number, + account_check_digit: account_check_digit + }.compact + + if holder_tax_id + h[:holder_tax_id] = + holder_tax_id.respond_to?(:to_hash) ? holder_tax_id.to_hash : holder_tax_id + end + + if pix_keys && !pix_keys.empty? + h[:pix_keys] = pix_keys.map { |k| k.respond_to?(:to_hash) ? k.to_hash : k } + end + + h + end + end +end diff --git a/lib/incognia_api/pix_key.rb b/lib/incognia_api/pix_key.rb new file mode 100644 index 0000000..a1cd460 --- /dev/null +++ b/lib/incognia_api/pix_key.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +module Incognia + class PixKey + attr_reader :type, :value + + def initialize(type:, value:) + @type = type + @value = value + end + + def to_hash + {type: type, value: value} + end + end +end diff --git a/lib/incognia_api/version.rb b/lib/incognia_api/version.rb index 9c182c7..cebd329 100644 --- a/lib/incognia_api/version.rb +++ b/lib/incognia_api/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module Incognia - VERSION = "3.0.0" + VERSION = "3.1.0" end diff --git a/spec/bank_account_spec.rb b/spec/bank_account_spec.rb new file mode 100644 index 0000000..a15c073 --- /dev/null +++ b/spec/bank_account_spec.rb @@ -0,0 +1,133 @@ +require "spec_helper" + +module Incognia + RSpec.describe BankAccount do + let(:account_type) { "savings" } + let(:account_purpose) { "rural" } + let(:holder_type) { "business" } + let(:holder_tax_id) { Incognia::PersonId.new(type: "cpf", value: "12345678901") } + let(:country) { "BR" } + let(:ispb_code) { "18236120" } + let(:branch_code) { "0001" } + let(:account_number) { "123456" } + let(:account_check_digit) { "0" } + let(:pix_keys) do + [ + Incognia::PixKey.new(type: "cpf", value: "12345678901"), + Incognia::PixKey.new(type: "email", value: "human@being.com") + ] + end + let(:required_attrs) do + { + holder_type: holder_type, + holder_tax_id: holder_tax_id, + branch_code: branch_code, + account_number: account_number + } + end + + subject(:bank_account) do + described_class.new( + account_type: account_type, + account_purpose: account_purpose, + holder_type: holder_type, + holder_tax_id: holder_tax_id, + country: country, + ispb_code: ispb_code, + branch_code: branch_code, + account_number: account_number, + account_check_digit: account_check_digit, + pix_keys: pix_keys + ) + end + + it "raises error when no required kwargs are provided" do + expect { described_class.new }.to raise_error(ArgumentError) + end + + it "requires holder_type" do + expect { described_class.new(**required_attrs.except(:holder_type)) }.to raise_error(ArgumentError) + end + + it "requires holder_tax_id" do + expect { described_class.new(**required_attrs.except(:holder_tax_id)) }.to raise_error(ArgumentError) + end + + it "requires branch_code" do + expect { described_class.new(**required_attrs.except(:branch_code)) }.to raise_error(ArgumentError) + end + + it "requires account_number" do + expect { described_class.new(**required_attrs.except(:account_number)) }.to raise_error(ArgumentError) + end + + it "does not raise error when all required kwargs are provided" do + expect { described_class.new(**required_attrs) }.not_to raise_error + end + + describe "#to_hash" do + context "with only required fields" do + subject(:only_required) { described_class.new(**required_attrs) } + + it "returns required fields (optional fields omitted)" do + h = only_required.to_hash + expect(h).to include( + holder_type: holder_type, + holder_tax_id: holder_tax_id.to_hash, + branch_code: branch_code, + account_number: account_number + ) + expect(h).not_to include(:account_type, :account_purpose, :country, :ispb_code, :account_check_digit, :pix_keys) + end + end + + context "when informing optional fields" do + it "returns the API format with all fields" do + expect(bank_account.to_hash).to eql( + account_type: account_type, + account_purpose: account_purpose, + holder_type: holder_type, + holder_tax_id: holder_tax_id.to_hash, + country: country, + ispb_code: ispb_code, + branch_code: branch_code, + account_number: account_number, + account_check_digit: account_check_digit, + pix_keys: pix_keys.map(&:to_hash) + ) + end + end + + context "when holder_tax_id is not a PersonId nor a Hash" do + it "keeps the value unchanged" do + raw_id = "12345678901" + account = described_class.new(**required_attrs.merge(holder_tax_id: raw_id)) + expect(account.to_hash[:holder_tax_id]).to eq(raw_id) + end + end + + context "when pix_keys do not contain PixKey nor Hash items" do + it "keeps the items unchanged" do + raw_keys = ["a", :b, 123] + account = described_class.new(**required_attrs.merge(pix_keys: raw_keys)) + expect(account.to_hash[:pix_keys]).to eq(raw_keys) + end + end + end + + describe "readers" do + it "exposes attribute readers" do + expect(bank_account.account_type).to eq(account_type) + expect(bank_account.account_purpose).to eq(account_purpose) + expect(bank_account.holder_type).to eq(holder_type) + expect(bank_account.holder_tax_id).to eq(holder_tax_id) + expect(bank_account.country).to eq(country) + expect(bank_account.ispb_code).to eq(ispb_code) + expect(bank_account.branch_code).to eq(branch_code) + expect(bank_account.account_number).to eq(account_number) + expect(bank_account.account_check_digit).to eq(account_check_digit) + expect(bank_account.pix_keys).to eql(pix_keys) + end + end + end +end diff --git a/spec/incognia_spec.rb b/spec/incognia_spec.rb index 6b1da4e..b5b0929 100644 --- a/spec/incognia_spec.rb +++ b/spec/incognia_spec.rb @@ -400,6 +400,54 @@ module Incognia expect(stub).to have_been_made.once end + it "hits the endpoint with debtor_account and creditor_account" do + debtor_account = BankAccount.new( + holder_type: "business", + holder_tax_id: PersonId.new(type: "cpf", value: "12345678901"), + branch_code: "0001", + account_number: "123456" + ) + + creditor_account = BankAccount.new( + account_type: "savings", + account_purpose: "rural", + holder_type: "business", + holder_tax_id: PersonId.new(type: "cpf", value: "00000000011"), + country: "BR", + ispb_code: "18236120", + branch_code: "0002", + account_number: "654321", + account_check_digit: "0", + pix_keys: [ + PixKey.new(type: "cpf", value: "00000000011"), + PixKey.new(type: "email", value: "human@being.com") + ] + ) + + stub = stub_payment_request.with( + body: { + type: "payment", + request_token: request_token, + account_id: account_id, + debtor_account: debtor_account.to_hash, + creditor_account: creditor_account.to_hash + }, + headers: { + "Content-Type" => "application/json", + "Authorization" => /Bearer.*/ + } + ) + + described_class.register_payment( + request_token: request_token, + account_id: account_id, + debtor_account: debtor_account, + creditor_account: creditor_account + ) + + expect(stub).to have_been_made.once + end + shared_examples_for 'receiving one of the required tokens with account_id' do |token_name| let(:token_value) { SecureRandom.uuid } diff --git a/spec/person_id_spec.rb b/spec/person_id_spec.rb index 660f2cc..215ceeb 100644 --- a/spec/person_id_spec.rb +++ b/spec/person_id_spec.rb @@ -1,4 +1,3 @@ -# spec/incognia/person_id_spec.rb require "spec_helper" module Incognia