From 8630ecc471206df06c0e39a5c123b4d50fdf8007 Mon Sep 17 00:00:00 2001 From: Lucas Gomes Date: Mon, 19 Jun 2023 23:05:32 -0300 Subject: [PATCH 1/2] Add register_payment method --- README.md | 78 ++++++++++++++++++ lib/incognia_api.rb | 1 + lib/incognia_api/api.rb | 13 +++ .../resources/payment_assessment.rb | 5 ++ spec/fixtures/payment-unknown.json | 36 +++++++++ spec/helpers/api_spec_helpers.rb | 13 +++ spec/incognia_spec.rb | 80 ++++++++++++++++++- 7 files changed, 225 insertions(+), 1 deletion(-) create mode 100644 lib/incognia_api/resources/payment_assessment.rb create mode 100644 spec/fixtures/payment-unknown.json diff --git a/README.md b/README.md index 91b4034..69fe87b 100644 --- a/README.md +++ b/README.md @@ -125,6 +125,84 @@ assessment = api.register_login( # => # ``` +### Registering Payment + +This method registers a new payment for the given installation and account, returning a `hash`, +containing the risk assessment and supporting evidence. + +```ruby +assessment = api.register_payment( + installation_id: 'installation-id', + account_id: 'account-id' +) + +# => # +``` + +It also supports optional parameters, for example: + +```ruby +addresses = [ + { + 'type': 'shipping', + 'structured_address': { + 'locale': 'pt-BR', + 'country_name': 'Brasil', + 'country_code': 'BR', + 'state': 'SP', + 'city': 'São Paulo', + 'borough': '', + 'neighborhood': 'Bela Vista', + 'street': 'Av. Paulista', + 'number': '1578', + 'complements': 'Andar 2', + 'postal_code': '01310-200' + }, + 'address_coordinates': { + 'lat': -23.561414, + 'lng': -46.6558819 + } + } +] + +payment_value = { + 'amount': 5.0, + 'currency': 'BRL' +} + +payment_methods = [ + { + 'type': 'credit_card', + 'credit_card_info': { + 'bin': '123456', + 'last_four_digits': '1234', + 'expiry_year': '2027', + 'expiry_month': '10' + } + }, + { + 'type': 'debit_card', + 'debit_card_info': { + 'bin': '123456', + 'last_four_digits': '1234', + 'expiry_year': '2027', + 'expiry_month': '10' + } + } +] + +assessment = api.register_payment( + installation_id: 'installation-id', + account_id: 'account-id', + external_id: 'external-id', + addresses: addresses, + payment_value: payment_value, + payment_methods: payment_methods +) + +# => # +``` + ### Registering a Feedback This method registers a feedback event for the given identifiers (optional arguments), returning true when success. diff --git a/lib/incognia_api.rb b/lib/incognia_api.rb index fb267b4..0ffe03c 100644 --- a/lib/incognia_api.rb +++ b/lib/incognia_api.rb @@ -9,6 +9,7 @@ require_relative "incognia_api/resources/api_resource" require_relative "incognia_api/resources/signup_assessment" require_relative "incognia_api/resources/login_assessment" +require_relative "incognia_api/resources/payment_assessment" require_relative "incognia_api/resources/credentials" require_relative "incognia_api/constants/feedback_event" diff --git a/lib/incognia_api/api.rb b/lib/incognia_api/api.rb index 2e6b200..5317e8d 100644 --- a/lib/incognia_api/api.rb +++ b/lib/incognia_api/api.rb @@ -69,5 +69,18 @@ def register_feedback(event: , timestamp: nil, **ids) response.success? end + + def register_payment(installation_id:, account_id:, **opts) + params = { installation_id: installation_id, account_id: account_id, type: :payment } + params.merge!(opts) + + response = connection.request( + :post, + 'v2/authentication/transactions', + params + ) + + PaymentAssessment.from_hash(response.body) if response.success? + end end end diff --git a/lib/incognia_api/resources/payment_assessment.rb b/lib/incognia_api/resources/payment_assessment.rb new file mode 100644 index 0000000..e74b21f --- /dev/null +++ b/lib/incognia_api/resources/payment_assessment.rb @@ -0,0 +1,5 @@ +require_relative "api_resource" + +module Incognia + class PaymentAssessment < APIResource; end +end diff --git a/spec/fixtures/payment-unknown.json b/spec/fixtures/payment-unknown.json new file mode 100644 index 0000000..a04d7c3 --- /dev/null +++ b/spec/fixtures/payment-unknown.json @@ -0,0 +1,36 @@ +{ + "id": "f3bf8d46-1abcd-2abcd-3abcd-51f95b05f6fb", + "risk_assessment": "unknown", + "reasons": [], + "evidence": { + "device_model": "iPhone9,3", + "known_account": false, + "location_services": { + "location_permission_enabled": true, + "location_sensors_enabled": true + }, + "device_integrity": { + "probable_root": false, + "emulator": false, + "gps_spoofing": false, + "from_official_store": true, + "app_tampering": false, + "installation_source": "not_available" + }, + "device_fraud_reputation": "unknown", + "device_behavior_reputation": "unknown", + "accessed_accounts": 2, + "app_reinstallations": 0, + "active_installations": 2, + "first_device_login": true, + "app_tampering": { + "result": "not_available", + "app_debugging": "not_available", + "code_injection": "not_available", + "signature_mismatch": "not_available", + "package_mismatch": "not_available" + } + }, + "installation_id": "installation_id", + "device_id": "device_id" +} diff --git a/spec/helpers/api_spec_helpers.rb b/spec/helpers/api_spec_helpers.rb index 682483e..f02a175 100644 --- a/spec/helpers/api_spec_helpers.rb +++ b/spec/helpers/api_spec_helpers.rb @@ -9,6 +9,9 @@ def self.included(rspec) rspec.let(:unknown_login_fixture) do File.new("spec/fixtures/login-unknown.json").read end + rspec.let(:unknown_payment_fixture) do + File.new("spec/fixtures/payment-unknown.json").read + end rspec.let(:missing_required_params_fixture) do File.new("spec/fixtures/missing-required-params.json").read end @@ -84,6 +87,16 @@ def stub_login_request headers: { 'Content-Type' => 'application/json' }) end + def stub_payment_request + stub_request( + :post, "https://api.incognia.com/api/v2/authentication/transactions" + ).with(body: hash_including(type: 'payment')). + to_return( + status: 200, + body: unknown_payment_fixture, + headers: { 'Content-Type' => 'application/json' }) + end + def stub_register_feedback_request stub_request(:post, "https://api.incognia.com/api/v2/feedbacks"). to_return( diff --git a/spec/incognia_spec.rb b/spec/incognia_spec.rb index 1669ff7..548c8f5 100644 --- a/spec/incognia_spec.rb +++ b/spec/incognia_spec.rb @@ -274,6 +274,85 @@ module Incognia end + describe "#register_payment" do + let(:installation_id) { SecureRandom.uuid } + let(:account_id) { SecureRandom.uuid } + + it "when successful returns the resource" do + stub_token_request + stub_payment_request + + payment = api.register_payment( + installation_id: installation_id, + account_id: account_id + ) + + expected = JSON.parse(unknown_payment_fixture, symbolize_names: true) + expect(payment.id).to eql expected[:id] + expect(payment.risk_assessment).to eql expected[:risk_assessment] + expect_evidences_to_match(payment, expected) + end + + context "HTTP request" do + it "hits the endpoint with installation_id and account_id" do + stub_token_request + + stub = stub_payment_request.with( + body: { + type: 'payment', + installation_id: installation_id, account_id: account_id + }, + headers: { + 'Content-Type' => 'application/json', 'Authorization' => /Bearer.*/ + } + ) + + payment = api.register_payment( + installation_id: installation_id, + account_id: account_id + ) + + expect(stub).to have_been_made.once + end + + context 'when receiving any other optional arguments' do + shared_examples_for 'receiving optional args' do |optional_arguments| + it "hits the endpoint also with #{optional_arguments}" do + stub_token_request + + stub = stub_payment_request.with( + body: { + type: 'payment', + installation_id: installation_id, + account_id: account_id + }.merge(opts), + headers: { + 'Content-Type' => 'application/json', 'Authorization' => /Bearer.*/ + } + ) + + payment = api.register_payment( + installation_id: installation_id, + account_id: account_id, + **opts + ) + + expect(stub).to have_been_made.once + end + end + + it_behaves_like 'receiving optional args', 'external_id', 'payment request', 'aaa' do + let(:opts) { { external_id: 'external-id' } } + end + it_behaves_like 'receiving optional args', 'payment_value' do + let(:opts) { { payment_value: { 'amount': 5.0, 'currency': 'BRL' } } } + end + it_behaves_like 'receiving optional args', 'external_id and payment_value' do + let(:opts) { { external_id: 'external-id', payment_value: 12.5 } } + end + end + end + end describe "#register_feedback" do let(:event) { Incognia::Constants::FeedbackEvent.constants.sample.to_s } @@ -389,5 +468,4 @@ def expect_evidences_to_match(model, expected) to eql expected[:evidence][:location_services][:location_sensors_enabled] end end - end From 147b52a46405c8baaf5ef769b936557eb64603d7 Mon Sep 17 00:00:00 2001 From: Ottony Costa Date: Thu, 13 Jul 2023 21:16:11 -0300 Subject: [PATCH 2/2] Bumps version 0.5.1 --- CHANGELOG.md | 4 ++++ Gemfile.lock | 4 ++-- lib/incognia_api/version.rb | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 66b9699..1fc364e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ ## [Unreleased] +## [0.5.1] - 2023-07-13 + +- Allow registering payments + ## [0.5.0] - 2023-04-20 - Specify dependencies version diff --git a/Gemfile.lock b/Gemfile.lock index 28c559f..082a995 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - incognia_api (0.5.0) + incognia_api (0.5.1) faraday (~> 1.10) faraday_middleware (~> 1.2) @@ -81,4 +81,4 @@ DEPENDENCIES webmock BUNDLED WITH - 2.3.7 + 2.4.13 diff --git a/lib/incognia_api/version.rb b/lib/incognia_api/version.rb index a33743d..c1945c3 100644 --- a/lib/incognia_api/version.rb +++ b/lib/incognia_api/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module Incognia - VERSION = "0.5.0" + VERSION = "0.5.1" end