From 57f83d596a87858e7356cb04d1029013548f9d49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Armando=20Rodr=C3=ADguez?= <127134616+armando-rodriguez-cko@users.noreply.github.com> Date: Wed, 29 Jul 2026 17:21:20 +0200 Subject: [PATCH] feat(identities): add Address Document Verification (Adv) endpoints Implements the Adv* family from swagger 2026-07-16 (INT-1665): POST/GET /address-document-verifications, anonymize, attempts (create/list/get) and pdf-report. Reuses the identity-verification OAuth scope (no new scope). - AddressDocumentVerificationClient with 7 methods - AddressDocumentVerificationRequest + AddressDocumentVerificationAttemptRequest (modeled from swagger: applicant_id, user_journey_id, declared_data; document) - Registered in identities.rb and exposed on CheckoutApi - Client + integration specs --- lib/checkout_sdk/checkout_api.rb | 6 ++ ...s_document_verification_attempt_request.rb | 15 ++++ .../address_document_verification_client.rb | 79 ++++++++++++++++++ .../address_document_verification_request.rb | 21 +++++ lib/checkout_sdk/identities/identities.rb | 5 ++ ...dress_document_verification_client_spec.rb | 81 +++++++++++++++++++ ..._document_verification_integration_spec.rb | 62 ++++++++++++++ 7 files changed, 269 insertions(+) create mode 100644 lib/checkout_sdk/identities/address_document_verification/address_document_verification_attempt_request.rb create mode 100644 lib/checkout_sdk/identities/address_document_verification/address_document_verification_client.rb create mode 100644 lib/checkout_sdk/identities/address_document_verification/address_document_verification_request.rb create mode 100644 spec/checkout_sdk/identities/address_document_verification/address_document_verification_client_spec.rb create mode 100644 spec/checkout_sdk/identities/address_document_verification/address_document_verification_integration_spec.rb diff --git a/lib/checkout_sdk/checkout_api.rb b/lib/checkout_sdk/checkout_api.rb index 0381617..3857e40 100644 --- a/lib/checkout_sdk/checkout_api.rb +++ b/lib/checkout_sdk/checkout_api.rb @@ -67,6 +67,8 @@ module CheckoutSdk # @return [CheckoutSdk::Identities::AmlScreening::AmlScreeningClient] # @!attribute id_document_verification # @return [CheckoutSdk::Identities::IdDocumentVerification::IdDocumentVerificationClient] + # @!attribute address_document_verification + # @return [CheckoutSdk::Identities::AddressDocumentVerification::AddressDocumentVerificationClient] # @!attribute identity_verification # @return [CheckoutSdk::Identities::IdentityVerification::IdentityVerificationClient] # @!attribute face_authentication @@ -109,6 +111,7 @@ class CheckoutApi :applicants, :aml_screening, :id_document_verification, + :address_document_verification, :identity_verification, :face_authentication, :apple_pay, @@ -152,6 +155,9 @@ def initialize(configuration) @aml_screening = CheckoutSdk::Identities::AmlScreening::AmlScreeningClient.new(api_client, configuration) @id_document_verification = CheckoutSdk::Identities::IdDocumentVerification::IdDocumentVerificationClient.new(api_client, configuration) + @address_document_verification = + CheckoutSdk::Identities::AddressDocumentVerification::AddressDocumentVerificationClient.new(api_client, + configuration) @identity_verification = CheckoutSdk::Identities::IdentityVerification::IdentityVerificationClient.new(api_client, configuration) @face_authentication = diff --git a/lib/checkout_sdk/identities/address_document_verification/address_document_verification_attempt_request.rb b/lib/checkout_sdk/identities/address_document_verification/address_document_verification_attempt_request.rb new file mode 100644 index 0000000..5921525 --- /dev/null +++ b/lib/checkout_sdk/identities/address_document_verification/address_document_verification_attempt_request.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module CheckoutSdk + module Identities + module AddressDocumentVerification + # Request body for POST /address-document-verifications/{id}/attempts. + # + # @!attribute document + # @return [String] The address document image to upload. [Required] Format: binary + class AddressDocumentVerificationAttemptRequest + attr_accessor :document + end + end + end +end diff --git a/lib/checkout_sdk/identities/address_document_verification/address_document_verification_client.rb b/lib/checkout_sdk/identities/address_document_verification/address_document_verification_client.rb new file mode 100644 index 0000000..671c373 --- /dev/null +++ b/lib/checkout_sdk/identities/address_document_verification/address_document_verification_client.rb @@ -0,0 +1,79 @@ +# frozen_string_literal: true + +module CheckoutSdk + module Identities + module AddressDocumentVerification + # Client for the Identities — Address Document Verification (Adv) API. + class AddressDocumentVerificationClient < Client + ADDRESS_DOCUMENT_VERIFICATIONS = 'address-document-verifications' + ANONYMIZE = 'anonymize' + ATTEMPTS = 'attempts' + PDF_REPORT = 'pdf-report' + private_constant :ADDRESS_DOCUMENT_VERIFICATIONS, :ANONYMIZE, :ATTEMPTS, :PDF_REPORT + + # @param [ApiClient] api_client + # @param [CheckoutConfiguration] configuration + def initialize(api_client, configuration) + super(api_client, configuration, CheckoutSdk::AuthorizationType::SECRET_KEY_OR_OAUTH) + end + + # @param [Hash, AddressDocumentVerificationRequest] request + def create_address_document_verification(request) + api_client.invoke_post(ADDRESS_DOCUMENT_VERIFICATIONS, sdk_authorization, request) + end + + # @param [String] address_document_verification_id + def get_address_document_verification(address_document_verification_id) + api_client.invoke_get( + build_path(ADDRESS_DOCUMENT_VERIFICATIONS, address_document_verification_id), + sdk_authorization + ) + end + + # @param [String] address_document_verification_id + def anonymize_address_document_verification(address_document_verification_id) + api_client.invoke_post( + build_path(ADDRESS_DOCUMENT_VERIFICATIONS, address_document_verification_id, ANONYMIZE), + sdk_authorization + ) + end + + # Create a new attempt for an existing address document verification. + # @param [String] address_document_verification_id + # @param [Hash, AddressDocumentVerificationAttemptRequest] attempt_request + def create_address_document_verification_attempt(address_document_verification_id, attempt_request = nil) + api_client.invoke_post( + build_path(ADDRESS_DOCUMENT_VERIFICATIONS, address_document_verification_id, ATTEMPTS), + sdk_authorization, + attempt_request + ) + end + + # @param [String] address_document_verification_id + def get_address_document_verification_attempts(address_document_verification_id) + api_client.invoke_get( + build_path(ADDRESS_DOCUMENT_VERIFICATIONS, address_document_verification_id, ATTEMPTS), + sdk_authorization + ) + end + + # @param [String] address_document_verification_id + # @param [String] attempt_id + def get_address_document_verification_attempt(address_document_verification_id, attempt_id) + api_client.invoke_get( + build_path(ADDRESS_DOCUMENT_VERIFICATIONS, address_document_verification_id, ATTEMPTS, attempt_id), + sdk_authorization + ) + end + + # @param [String] address_document_verification_id + def get_address_document_verification_pdf_report(address_document_verification_id) + api_client.invoke_get( + build_path(ADDRESS_DOCUMENT_VERIFICATIONS, address_document_verification_id, PDF_REPORT), + sdk_authorization + ) + end + end + end + end +end diff --git a/lib/checkout_sdk/identities/address_document_verification/address_document_verification_request.rb b/lib/checkout_sdk/identities/address_document_verification/address_document_verification_request.rb new file mode 100644 index 0000000..67fb474 --- /dev/null +++ b/lib/checkout_sdk/identities/address_document_verification/address_document_verification_request.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +module CheckoutSdk + module Identities + module AddressDocumentVerification + # Request body for POST /address-document-verifications. + # + # @!attribute applicant_id + # @return [String] The applicant's unique identifier. [Required] Pattern: ^aplt_\w+$ + # @!attribute user_journey_id + # @return [String] Your configuration ID. [Required] Pattern: ^usj_[a-z2-7]{26}$ + # @!attribute declared_data + # @return [IdvDeclaredData, Hash] The personal details provided by the applicant. [Optional] + class AddressDocumentVerificationRequest + attr_accessor :applicant_id, + :user_journey_id, + :declared_data + end + end + end +end diff --git a/lib/checkout_sdk/identities/identities.rb b/lib/checkout_sdk/identities/identities.rb index f743f1a..d4250ae 100644 --- a/lib/checkout_sdk/identities/identities.rb +++ b/lib/checkout_sdk/identities/identities.rb @@ -14,6 +14,11 @@ require 'checkout_sdk/identities/id_document_verification/id_document_verification_request' require 'checkout_sdk/identities/id_document_verification/id_document_verification_client' +# Address Document Verification +require 'checkout_sdk/identities/address_document_verification/address_document_verification_request' +require 'checkout_sdk/identities/address_document_verification/address_document_verification_attempt_request' +require 'checkout_sdk/identities/address_document_verification/address_document_verification_client' + # Identity Verification require 'checkout_sdk/identities/identity_verification/idv_declared_data' require 'checkout_sdk/identities/identity_verification/idv_client_information' diff --git a/spec/checkout_sdk/identities/address_document_verification/address_document_verification_client_spec.rb b/spec/checkout_sdk/identities/address_document_verification/address_document_verification_client_spec.rb new file mode 100644 index 0000000..958fc72 --- /dev/null +++ b/spec/checkout_sdk/identities/address_document_verification/address_document_verification_client_spec.rb @@ -0,0 +1,81 @@ +# frozen_string_literal: true + +RSpec.describe CheckoutSdk::Identities::AddressDocumentVerification do + let(:credentials_mock) { double('credentials') } + let(:api_client_mock) { double('api_client') } + let(:configuration_mock) { double('configuration') } + let(:client) do + CheckoutSdk::Identities::AddressDocumentVerification::AddressDocumentVerificationClient.new(api_client_mock, + configuration_mock) + end + + before do + allow(configuration_mock).to receive(:credentials).and_return(credentials_mock) + allow(credentials_mock).to receive(:get_authorization).and_return('secret_key') + end + + describe '#create_address_document_verification' do + it 'POSTs typed DTO to address-document-verifications' do + request = CheckoutSdk::Identities::AddressDocumentVerification::AddressDocumentVerificationRequest.new + expect(api_client_mock).to receive(:invoke_post) + .with('address-document-verifications', 'secret_key', request).and_return('response') + expect(client.create_address_document_verification(request)).to eq('response') + end + + it 'also accepts a raw Hash' do + hash_request = { 'applicant_id' => 'aplt_x', 'user_journey_id' => 'usj_x' } + expect(api_client_mock).to receive(:invoke_post) + .with('address-document-verifications', 'secret_key', hash_request).and_return('response') + expect(client.create_address_document_verification(hash_request)).to eq('response') + end + end + + describe '#get_address_document_verification' do + it 'GETs address-document-verifications/{id}' do + expect(api_client_mock).to receive(:invoke_get) + .with('address-document-verifications/adv_x', 'secret_key').and_return('response') + expect(client.get_address_document_verification('adv_x')).to eq('response') + end + end + + describe '#anonymize_address_document_verification' do + it 'POSTs address-document-verifications/{id}/anonymize' do + expect(api_client_mock).to receive(:invoke_post) + .with('address-document-verifications/adv_x/anonymize', 'secret_key').and_return('response') + expect(client.anonymize_address_document_verification('adv_x')).to eq('response') + end + end + + describe '#create_address_document_verification_attempt' do + it 'POSTs typed DTO to address-document-verifications/{id}/attempts' do + request = CheckoutSdk::Identities::AddressDocumentVerification::AddressDocumentVerificationAttemptRequest.new + expect(api_client_mock).to receive(:invoke_post) + .with('address-document-verifications/adv_x/attempts', 'secret_key', request).and_return('response') + expect(client.create_address_document_verification_attempt('adv_x', request)).to eq('response') + end + end + + describe '#get_address_document_verification_attempts' do + it 'GETs address-document-verifications/{id}/attempts' do + expect(api_client_mock).to receive(:invoke_get) + .with('address-document-verifications/adv_x/attempts', 'secret_key').and_return('response') + expect(client.get_address_document_verification_attempts('adv_x')).to eq('response') + end + end + + describe '#get_address_document_verification_attempt' do + it 'GETs address-document-verifications/{id}/attempts/{attempt_id}' do + expect(api_client_mock).to receive(:invoke_get) + .with('address-document-verifications/adv_x/attempts/adva_1', 'secret_key').and_return('response') + expect(client.get_address_document_verification_attempt('adv_x', 'adva_1')).to eq('response') + end + end + + describe '#get_address_document_verification_pdf_report' do + it 'GETs address-document-verifications/{id}/pdf-report' do + expect(api_client_mock).to receive(:invoke_get) + .with('address-document-verifications/adv_x/pdf-report', 'secret_key').and_return('response') + expect(client.get_address_document_verification_pdf_report('adv_x')).to eq('response') + end + end +end diff --git a/spec/checkout_sdk/identities/address_document_verification/address_document_verification_integration_spec.rb b/spec/checkout_sdk/identities/address_document_verification/address_document_verification_integration_spec.rb new file mode 100644 index 0000000..179af40 --- /dev/null +++ b/spec/checkout_sdk/identities/address_document_verification/address_document_verification_integration_spec.rb @@ -0,0 +1,62 @@ +# frozen_string_literal: true + +RSpec.describe CheckoutSdk::Identities::AddressDocumentVerification do + skip 'Requires sandbox credentials with Address Document Verification entitlement' do + let(:client) { default_sdk.address_document_verification } + + describe '#create_address_document_verification' do + it 'creates an address document verification' do + request = CheckoutSdk::Identities::AddressDocumentVerification::AddressDocumentVerificationRequest.new + request.applicant_id = ENV.fetch('CHECKOUT_APPLICANT_ID', nil) + request.user_journey_id = ENV.fetch('CHECKOUT_USER_JOURNEY_ID', nil) + response = client.create_address_document_verification(request) + expect(response).not_to be_nil + end + end + + describe '#get_address_document_verification' do + it 'retrieves an address document verification' do + response = client.get_address_document_verification(ENV.fetch('CHECKOUT_ADV_ID', nil)) + expect(response).not_to be_nil + end + end + + describe '#anonymize_address_document_verification' do + it 'anonymizes the verification' do + response = client.anonymize_address_document_verification(ENV.fetch('CHECKOUT_ADV_ID', nil)) + expect(response).not_to be_nil + end + end + + describe '#create_address_document_verification_attempt' do + it 'creates an attempt' do + request = CheckoutSdk::Identities::AddressDocumentVerification::AddressDocumentVerificationAttemptRequest.new + request.document = ENV.fetch('CHECKOUT_ADV_DOCUMENT', nil) + response = client.create_address_document_verification_attempt(ENV.fetch('CHECKOUT_ADV_ID', nil), request) + expect(response).not_to be_nil + end + end + + describe '#get_address_document_verification_attempts' do + it 'lists the verification attempts' do + response = client.get_address_document_verification_attempts(ENV.fetch('CHECKOUT_ADV_ID', nil)) + expect(response).not_to be_nil + end + end + + describe '#get_address_document_verification_attempt' do + it 'retrieves a single attempt' do + response = client.get_address_document_verification_attempt(ENV.fetch('CHECKOUT_ADV_ID', nil), + ENV.fetch('CHECKOUT_ADV_ATTEMPT_ID', nil)) + expect(response).not_to be_nil + end + end + + describe '#get_address_document_verification_pdf_report' do + it 'retrieves the PDF report' do + response = client.get_address_document_verification_pdf_report(ENV.fetch('CHECKOUT_ADV_ID', nil)) + expect(response).not_to be_nil + end + end + end +end