Skip to content

Commit 7f78aff

Browse files
authored
EMP-327: Allows chargeback activity for finalized payment status; adds testcase (#156)
* EMP-327: Allows chargeback activity for finilized payment status; adds testcase * Adds payment status reversal for canceling accepted chargeback * Removes obsolete comment
1 parent 6440a47 commit 7f78aff

File tree

3 files changed

+72
-9
lines changed

3 files changed

+72
-9
lines changed

apps/hellgate/include/hg_invoice_payment.hrl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
-record(st, {
55
activity :: hg_invoice_payment:activity(),
6+
status_log = [] :: [dmsl_domain_thrift:'InvoicePaymentStatus'()],
67
payment :: undefined | hg_invoice_payment:payment(),
78
risk_score :: undefined | hg_inspector:risk_score(),
89
routes = [] :: [hg_route:payment_route()],

apps/hellgate/src/hg_invoice_payment.erl

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2218,8 +2218,18 @@ process_chargeback(Type = finalising_accounter, ID, Action0, St) ->
22182218
process_chargeback(Type, ID, Action0, St) ->
22192219
ChargebackState = get_chargeback_state(ID, St),
22202220
ChargebackOpts = get_chargeback_opts(St),
2221-
{Changes, Action1} = hg_invoice_payment_chargeback:process_timeout(Type, ChargebackState, Action0, ChargebackOpts),
2222-
{done, {[?chargeback_ev(ID, C) || C <- Changes], Action1}}.
2221+
{Changes0, Action1} = hg_invoice_payment_chargeback:process_timeout(Type, ChargebackState, Action0, ChargebackOpts),
2222+
Changes1 = [?chargeback_ev(ID, C) || C <- Changes0],
2223+
case Type of
2224+
%% NOTE In case if payment is already charged back and we want
2225+
%% to reopen and change it, this will ensure machine to
2226+
%% continue processing activities following cashflow update
2227+
%% event.
2228+
updating_cash_flow ->
2229+
{next, {Changes1, Action1}};
2230+
_ ->
2231+
{done, {Changes1, Action1}}
2232+
end.
22232233

22242234
maybe_set_charged_back_status(?chargeback_status_accepted(), ChargebackBody, St) ->
22252235
InterimPaymentAmount = get_remaining_payment_balance(St),
@@ -2229,6 +2239,15 @@ maybe_set_charged_back_status(?chargeback_status_accepted(), ChargebackBody, St)
22292239
?cash(Amount, _) when Amount > 0 ->
22302240
[]
22312241
end;
2242+
maybe_set_charged_back_status(
2243+
?chargeback_status_cancelled(),
2244+
_ChargebackBody,
2245+
#st{
2246+
payment = #domain_InvoicePayment{status = ?charged_back()},
2247+
status_log = [_ActualStatus, PrevStatus | _]
2248+
}
2249+
) ->
2250+
[?payment_status_changed(PrevStatus)];
22322251
maybe_set_charged_back_status(_ChargebackStatus, _ChargebackBody, _St) ->
22332252
[].
22342253

@@ -3262,22 +3281,22 @@ merge_change(Change = ?payment_status_changed({failed, _} = Status), #st{payment
32623281
St,
32633282
Opts
32643283
),
3265-
St#st{
3284+
(record_status_change(Change, St))#st{
32663285
payment = Payment#domain_InvoicePayment{status = Status},
32673286
activity = idle,
32683287
failure = undefined,
32693288
timings = accrue_status_timing(failed, Opts, St)
32703289
};
32713290
merge_change(Change = ?payment_status_changed({cancelled, _} = Status), #st{payment = Payment} = St, Opts) ->
32723291
_ = validate_transition({payment, finalizing_accounter}, Change, St, Opts),
3273-
St#st{
3292+
(record_status_change(Change, St))#st{
32743293
payment = Payment#domain_InvoicePayment{status = Status},
32753294
activity = idle,
32763295
timings = accrue_status_timing(cancelled, Opts, St)
32773296
};
32783297
merge_change(Change = ?payment_status_changed({captured, Captured} = Status), #st{payment = Payment} = St, Opts) ->
3279-
_ = validate_transition({payment, finalizing_accounter}, Change, St, Opts),
3280-
St#st{
3298+
_ = validate_transition([idle, {payment, finalizing_accounter}], Change, St, Opts),
3299+
(record_status_change(Change, St))#st{
32813300
payment = Payment#domain_InvoicePayment{
32823301
status = Status,
32833302
cost = get_captured_cost(Captured, Payment)
@@ -3288,19 +3307,19 @@ merge_change(Change = ?payment_status_changed({captured, Captured} = Status), #s
32883307
};
32893308
merge_change(Change = ?payment_status_changed({processed, _} = Status), #st{payment = Payment} = St, Opts) ->
32903309
_ = validate_transition({payment, processing_accounter}, Change, St, Opts),
3291-
St#st{
3310+
(record_status_change(Change, St))#st{
32923311
payment = Payment#domain_InvoicePayment{status = Status},
32933312
activity = {payment, flow_waiting},
32943313
timings = accrue_status_timing(processed, Opts, St)
32953314
};
32963315
merge_change(Change = ?payment_status_changed({refunded, _} = Status), #st{payment = Payment} = St, Opts) ->
32973316
_ = validate_transition(idle, Change, St, Opts),
3298-
St#st{
3317+
(record_status_change(Change, St))#st{
32993318
payment = Payment#domain_InvoicePayment{status = Status}
33003319
};
33013320
merge_change(Change = ?payment_status_changed({charged_back, _} = Status), #st{payment = Payment} = St, Opts) ->
33023321
_ = validate_transition(idle, Change, St, Opts),
3303-
St#st{
3322+
(record_status_change(Change, St))#st{
33043323
payment = Payment#domain_InvoicePayment{status = Status}
33053324
};
33063325
merge_change(Change = ?chargeback_ev(ID, Event), St, Opts) ->
@@ -3467,6 +3486,9 @@ merge_change(Change = ?session_ev(Target, Event), St = #st{activity = Activity},
34673486
St2
34683487
end.
34693488

3489+
record_status_change(?payment_status_changed(Status), St) ->
3490+
St#st{status_log = [Status | St#st.status_log]}.
3491+
34703492
latest_adjustment_id(#st{adjustments = []}) ->
34713493
undefined;
34723494
latest_adjustment_id(#st{adjustments = Adjustments}) ->

apps/hellgate/test/hg_invoice_tests_SUITE.erl

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@
128128
-export([accept_payment_chargeback_twice/1]).
129129
-export([accept_payment_chargeback_new_body/1]).
130130
-export([accept_payment_chargeback_new_levy/1]).
131+
-export([reopen_accepted_payment_chargeback_and_cancel_ok/1]).
131132
-export([reopen_payment_chargeback_inconsistent/1]).
132133
-export([reopen_payment_chargeback_exceeded/1]).
133134
-export([reopen_payment_chargeback_cancel/1]).
@@ -388,6 +389,7 @@ groups() ->
388389
accept_payment_chargeback_twice,
389390
accept_payment_chargeback_new_body,
390391
accept_payment_chargeback_new_levy,
392+
reopen_accepted_payment_chargeback_and_cancel_ok,
391393
reopen_payment_chargeback_inconsistent,
392394
reopen_payment_chargeback_exceeded,
393395
reopen_payment_chargeback_cancel,
@@ -4062,6 +4064,44 @@ accept_payment_chargeback_new_levy(C) ->
40624064
?assertEqual(Paid - Cost - NewLevyAmount, maps:get(min_available_amount, Settlement1)),
40634065
?assertEqual(Paid - Cost - NewLevyAmount, maps:get(max_available_amount, Settlement1)).
40644066

4067+
-spec reopen_accepted_payment_chargeback_and_cancel_ok(config()) -> _ | no_return().
4068+
reopen_accepted_payment_chargeback_and_cancel_ok(C) ->
4069+
Client = cfg(client, C),
4070+
Cost = 42000,
4071+
LevyAmount = 5000,
4072+
Levy = ?cash(LevyAmount, <<"RUB">>),
4073+
CBParams = make_chargeback_params(Levy),
4074+
{IID, PID, _SID, CB} = start_chargeback(C, Cost, CBParams, make_payment_params(?pmt_sys(<<"visa-ref">>))),
4075+
CBID = CB#domain_InvoicePaymentChargeback.id,
4076+
[
4077+
?payment_ev(PID, ?chargeback_ev(CBID, ?chargeback_created(CB))),
4078+
?payment_ev(PID, ?chargeback_ev(CBID, ?chargeback_cash_flow_changed(CBCF)))
4079+
] = next_changes(IID, 2, Client),
4080+
AcceptParams = make_chargeback_accept_params(),
4081+
ok = hg_client_invoicing:accept_chargeback(IID, PID, CBID, AcceptParams, Client),
4082+
[
4083+
?payment_ev(PID, ?chargeback_ev(CBID, ?chargeback_target_status_changed(?chargeback_status_accepted()))),
4084+
?payment_ev(PID, ?chargeback_ev(CBID, ?chargeback_status_changed(?chargeback_status_accepted()))),
4085+
?payment_ev(PID, ?payment_status_changed(?charged_back()))
4086+
] = next_changes(IID, 3, Client),
4087+
ReopenParams = make_chargeback_reopen_params(Levy),
4088+
ok = hg_client_invoicing:reopen_chargeback(IID, PID, CBID, ReopenParams, Client),
4089+
[
4090+
?payment_ev(PID, ?chargeback_ev(CBID, ?chargeback_stage_changed(?chargeback_stage_pre_arbitration()))),
4091+
?payment_ev(PID, ?chargeback_ev(CBID, ?chargeback_target_status_changed(?chargeback_status_pending()))),
4092+
?payment_ev(PID, ?chargeback_ev(CBID, ?chargeback_cash_flow_changed(CBCF))),
4093+
?payment_ev(PID, ?chargeback_ev(CBID, ?chargeback_status_changed(?chargeback_status_pending())))
4094+
] = next_changes(IID, 4, Client),
4095+
CancelParams = make_chargeback_cancel_params(),
4096+
ok = hg_client_invoicing:cancel_chargeback(IID, PID, CBID, CancelParams, Client),
4097+
[
4098+
?payment_ev(PID, ?chargeback_ev(CBID, ?chargeback_target_status_changed(?chargeback_status_cancelled()))),
4099+
?payment_ev(PID, ?chargeback_ev(CBID, ?chargeback_cash_flow_changed([]))),
4100+
?payment_ev(PID, ?chargeback_ev(CBID, ?chargeback_status_changed(?chargeback_status_cancelled()))),
4101+
?payment_ev(PID, ?payment_status_changed(?captured()))
4102+
] = next_changes(IID, 4, Client),
4103+
ok.
4104+
40654105
-spec reopen_payment_chargeback_inconsistent(config()) -> _ | no_return().
40664106
reopen_payment_chargeback_inconsistent(C) ->
40674107
Client = cfg(client, C),

0 commit comments

Comments
 (0)