From c2096b7c2a797521e18476979cf6fa348b0bd483 Mon Sep 17 00:00:00 2001 From: Aleksey Kashapov Date: Wed, 28 Jan 2026 14:20:12 +0300 Subject: [PATCH] BG-700: Adds wallet/source realm validation for deposit creation --- apps/ff_server/src/ff_deposit_handler.erl | 5 +++++ apps/ff_transfer/src/ff_deposit.erl | 14 ++++++++++++- apps/ff_transfer/test/ff_deposit_SUITE.erl | 23 ++++++++++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/apps/ff_server/src/ff_deposit_handler.erl b/apps/ff_server/src/ff_deposit_handler.erl index af411595..1bd2da7e 100644 --- a/apps/ff_server/src/ff_deposit_handler.erl +++ b/apps/ff_server/src/ff_deposit_handler.erl @@ -58,6 +58,11 @@ handle_function_('Create', {MarshaledParams, MarshaledContext}, Opts) -> {error, {bad_deposit_amount, Amount}} -> woody_error:raise(business, #fistful_InvalidOperationAmount{ amount = ff_codec:marshal(cash, Amount) + }); + {error, {realms_mismatch, {WalletRealm, DestinationRealm}}} -> + woody_error:raise(business, #fistful_RealmsMismatch{ + wallet_realm = WalletRealm, + destination_realm = DestinationRealm }) end; handle_function_('Get', {ID, EventRange}, _Opts) -> diff --git a/apps/ff_transfer/src/ff_deposit.erl b/apps/ff_transfer/src/ff_deposit.erl index 9ed4eaae..6aa2d2a8 100644 --- a/apps/ff_transfer/src/ff_deposit.erl +++ b/apps/ff_transfer/src/ff_deposit.erl @@ -77,7 +77,8 @@ | {wallet, notfound} | {party, notfound} | ff_party:validate_deposit_creation_error() - | {inconsistent_currency, {Deposit :: currency_id(), Source :: currency_id(), Wallet :: currency_id()}}. + | {inconsistent_currency, {Deposit :: currency_id(), Source :: currency_id(), Wallet :: currency_id()}} + | {realms_mismatch, {ff_payment_institution:realm(), ff_payment_institution:realm()}}. -export_type([deposit/0]). -export_type([deposit_state/0]). @@ -483,6 +484,7 @@ p_transfer_status(Deposit) -> validate_deposit_creation(Terms, Params, Source, Wallet, DomainRevision) -> #{body := Body} = Params, do(fun() -> + valid = unwrap(validate_deposit_realms(Source, Wallet, DomainRevision)), valid = unwrap(ff_party:validate_deposit_creation(Terms, Body)), valid = unwrap(validate_deposit_currency(Body, Source, Wallet, DomainRevision)) end). @@ -503,6 +505,16 @@ validate_deposit_currency(Body, Source, Wallet, DomainRevision) -> {error, {inconsistent_currency, {DepositCurencyID, SourceCurrencyID, WalletCurrencyID}}} end. +-spec validate_deposit_realms(source(), wallet(), domain_revision()) -> + {ok, valid} | {error, {realms_mismatch, {ff_payment_institution:realm(), ff_payment_institution:realm()}}}. +validate_deposit_realms(Source, #domain_WalletConfig{payment_institution = PaymentInstitutionRef}, DomainRevision) -> + {ok, WalletRealm} = ff_payment_institution:get_realm(PaymentInstitutionRef, DomainRevision), + SourceRealm = ff_source:realm(Source), + case WalletRealm =:= SourceRealm of + true -> {ok, valid}; + false -> {error, {realms_mismatch, {WalletRealm, SourceRealm}}} + end. + %% Limit helpers -spec limit_checks(deposit_state()) -> [limit_check_details()]. diff --git a/apps/ff_transfer/test/ff_deposit_SUITE.erl b/apps/ff_transfer/test/ff_deposit_SUITE.erl index 656dc149..2f2e66d9 100644 --- a/apps/ff_transfer/test/ff_deposit_SUITE.erl +++ b/apps/ff_transfer/test/ff_deposit_SUITE.erl @@ -20,6 +20,7 @@ -export([limit_check_fail_test/1]). -export([create_bad_amount_test/1]). -export([create_negative_amount_test/1]). +-export([create_realms_validation_error_test/1]). -export([create_currency_validation_error_test/1]). -export([create_source_notfound_test/1]). -export([create_wallet_notfound_test/1]). @@ -48,6 +49,7 @@ groups() -> limit_check_fail_test, create_bad_amount_test, create_negative_amount_test, + create_realms_validation_error_test, create_currency_validation_error_test, create_source_notfound_test, create_wallet_notfound_test, @@ -164,6 +166,27 @@ create_negative_amount_test(C) -> succeeded = await_final_deposit_status(DepositID), ok = ct_objects:await_wallet_balance({0, <<"RUB">>}, WalletID). +-spec create_realms_validation_error_test(config()) -> test_return(). +create_realms_validation_error_test(_C) -> + #{currency := Currency} = Ctx = ct_objects:build_default_ctx(), + #{ + wallet_id := WalletID, + party_id := PartyID + } = ct_objects:prepare_standard_environment(Ctx), + SourceID = ct_objects:create_source(PartyID, Currency, test), + DepositID = genlib:unique(), + DepositParams = #{ + id => DepositID, + body => {5000, <<"RUB">>}, + source_id => SourceID, + wallet_id => WalletID, + party_id => PartyID, + external_id => genlib:unique() + }, + ?assertMatch( + {error, {realms_mismatch, {live, test}}}, ff_deposit_machine:create(DepositParams, ff_entity_context:new()) + ). + -spec create_currency_validation_error_test(config()) -> test_return(). create_currency_validation_error_test(C) -> #{