@@ -1357,11 +1357,43 @@ def _send_with_possible_retry(self, dialog, command_seg, resume_func):
13571357 return resume_func (command_seg , response )
13581358
13591359 def _send_pay_with_possible_retry (self , dialog , command_seg , resume_func ):
1360+ """This adds VoP under the assumption that TAN will be sent,
1361+ There is no VoP flow without sending any authentication that I could distinguish.
1362+
1363+ There are really 2 VoP flows: with a full match and otherwise. All of them return the HIVPP response in NeedTANResponse.
1364+
1365+ On a full match, it's only needed to copy the vop_id alongside the TAN response.
1366+
1367+ In all other cases, the application should ask the user for confirmation based on HIVPP data in resp.vop_result.
1368+
1369+ The kind of response is in resp.vop_result.single_vop_result.result:
1370+ - 'RCVC' - full match
1371+ - 'RVMC' - partial match, extra info in single_vop_result.close_match_name and .other_identification.
1372+ - 'RVNM' - no match, no extra info seen
1373+ - 'RVNA' - check not available, reason in single_vop_result.na_reason
1374+ - 'PDNG' - pending, seems related to something not implemented right now.
1375+
1376+ Simple untested example.
1377+
1378+ ```
1379+ def process_tan(client, challenge, prompt):
1380+ if challenge.vop_result and not challenge.vop_result.vop_single_result.result == 'RCVC':
1381+ input("WARNING!!! Recipient name don't match:", challenge.vop_result.single_vop_result.close_match_name)
1382+ print("A TAN is required:", challenge.challenge)
1383+ hitan6 = challenge.tan_request
1384+ ... get TAN from user
1385+ return client.send_tan(challenge, tan)
1386+ ```
1387+
1388+ This gives the user a chance to slam ctrl+C before adding TAN.
1389+
1390+ Internally, the library always sends a positive confirmation of transaction because the user only really acknowledges it by sending the TAN.
1391+ Even if the legal liability moves on receiving the accepting message, there's no liability to be had before TAN goes through. Amirite?
1392+ """
13601393 vop_seg = []
13611394 vop_standard = self ._find_vop_format_for_segment (command_seg )
13621395 if vop_standard :
13631396 from .segments .auth import HKVPP1
1364- print (self .vpps )
13651397 vop_seg = [HKVPP1 (supported_reports = PSRD1 (psrd = [vop_standard ]))]
13661398 with dialog :
13671399 if self ._need_twostep_tan_for_segment (command_seg ):
@@ -1377,7 +1409,6 @@ def _send_pay_with_possible_retry(self, dialog, command_seg, resume_func):
13771409 vop_result = hivpp .vop_single_result
13781410 print (hivpp )
13791411 if vop_result .result == 'RVNA' :
1380- # TODO: let the user decide if they want to proceed by displaying a warning with TAN
13811412 print (vop_result .na_reason )
13821413 vop_seg = [HKVPA1 (vop_id = hivpp .vop_id )]
13831414 segments = vop_seg + [command_seg , tan_seg ]
@@ -1386,12 +1417,10 @@ def _send_pay_with_possible_retry(self, dialog, command_seg, resume_func):
13861417 vop_seg = [HKVPA1 (vop_id = hivpp .vop_id )]
13871418 segments = vop_seg + [command_seg , tan_seg ]
13881419 response = dialog .send (* segments )
1389- print ("WARNING! Recipient name does not match." )
13901420 elif vop_result .result == 'RVMC' :
13911421 vop_seg = [HKVPA1 (vop_id = hivpp .vop_id )]
13921422 segments = vop_seg + [command_seg , tan_seg ]
13931423 response = dialog .send (* segments )
1394- print ("WARNING! Recipient name differs:" , vop_result .close_match_name )
13951424 print (vop_result .result )
13961425 for resp in response .responses (tan_seg ):
13971426 if resp .code in ('0030' , '3955' ):
0 commit comments