def parse_notification_xml(xml: str) -> Union[AliasRegistration, Payment]:
body = fromstring(xml).find('<STR_LIT:body>')<EOL>transaction = body.find('<STR_LIT>')<EOL>_user_parameters = transaction.find('<STR_LIT>')<EOL>def get_named_parameter(name):<EOL><INDENT>return _user_parameters.find("<STR_LIT>" + name + "<STR_LIT>")<EOL><DEDENT>def success():<EOL><INDENT>return transaction.get('<STR_LIT:status>') == '<STR_LIT:success>'<EOL><DEDENT>def parse_success():<EOL><INDENT>computed_signature = sign_web(body.get('<STR_LIT>'), transaction.find('<STR_LIT>').text,<EOL>transaction.find('<STR_LIT>').text,<EOL>transaction.find('<STR_LIT>').text)<EOL>sign2 = get_named_parameter('<STR_LIT>').text<EOL>if computed_signature != sign2:<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>success = transaction.find('<STR_LIT:success>')<EOL>d = dict(<EOL>response_code=success.find('<STR_LIT>').text,<EOL>response_message=success.find('<STR_LIT>').text,<EOL>authorization_code=success.find('<STR_LIT>').text,<EOL>acquirer_authorization_code=success.find('<STR_LIT>').text,<EOL>)<EOL>return {k: v for k, v in d.items() if v is not None}<EOL><DEDENT>def parse_error():<EOL><INDENT>error = transaction.find('<STR_LIT:error>')<EOL>d = dict(<EOL>error_code=error.find('<STR_LIT>').text,<EOL>error_message=error.find('<STR_LIT>').text,<EOL>error_detail=error.find('<STR_LIT>').text)<EOL>acquirer_error_code = get_named_parameter('<STR_LIT>')<EOL>if acquirer_error_code is not None:<EOL><INDENT>d['<STR_LIT>'] = acquirer_error_code.text<EOL><DEDENT>return {k: v for k, v in d.items() if v is not None}<EOL><DEDENT>def parse_common_attributes():<EOL><INDENT>d = dict(<EOL>transaction_id=transaction.find('<STR_LIT>').text,<EOL>merchant_id=body.get('<STR_LIT>'),<EOL>client_ref=transaction.get('<STR_LIT>'),<EOL>amount=parse_money(transaction))<EOL>payment_method = transaction.find('<STR_LIT>')<EOL>if payment_method is not None:<EOL><INDENT>d['<STR_LIT>'] = payment_method.text<EOL><DEDENT>request_type = transaction.find('<STR_LIT>')<EOL>if request_type is not None:<EOL><INDENT>d['<STR_LIT>'] = request_type.text<EOL><DEDENT>credit_card_country = get_named_parameter('<STR_LIT>')<EOL>if credit_card_country is not None:<EOL><INDENT>d['<STR_LIT>'] = credit_card_country.text<EOL><DEDENT>expiry_month = get_named_parameter('<STR_LIT>')<EOL>if expiry_month is not None:<EOL><INDENT>d['<STR_LIT>'] = int(expiry_month.text)<EOL><DEDENT>expiry_year = get_named_parameter('<STR_LIT>')<EOL>if expiry_year is not None:<EOL><INDENT>d['<STR_LIT>'] = int(expiry_year.text)<EOL><DEDENT>return d<EOL><DEDENT>use_alias_parameter = get_named_parameter('<STR_LIT>')<EOL>if use_alias_parameter is not None and use_alias_parameter.text == '<STR_LIT:true>':<EOL><INDENT>d = dict(parse_common_attributes())<EOL>masked_card_number = get_named_parameter('<STR_LIT>')<EOL>if masked_card_number is not None:<EOL><INDENT>d['<STR_LIT>'] = masked_card_number.text<EOL><DEDENT>card_alias = get_named_parameter('<STR_LIT>')<EOL>if card_alias is not None:<EOL><INDENT>d['<STR_LIT>'] = card_alias.text<EOL><DEDENT>if success():<EOL><INDENT>d['<STR_LIT:success>'] = True<EOL>d.update(parse_success())<EOL><DEDENT>else:<EOL><INDENT>d['<STR_LIT:success>'] = False<EOL>d.update(parse_error())<EOL><DEDENT>return AliasRegistration(**d)<EOL><DEDENT>else:<EOL><INDENT>if success():<EOL><INDENT>d = dict(success=True)<EOL>cardno = get_named_parameter('<STR_LIT>')<EOL>if cardno is not None:<EOL><INDENT>d['<STR_LIT>'] = cardno.text<EOL><DEDENT>d.update(parse_common_attributes())<EOL>d.update(parse_success())<EOL>return Payment(**d)<EOL><DEDENT>else:<EOL><INDENT>d = dict(success=False)<EOL>d.update(parse_common_attributes())<EOL>d.update(parse_error())<EOL>return Payment(**d)<EOL><DEDENT><DEDENT>
Both alias registration and payments are received here.
We can differentiate them by looking at the use-alias user-parameter (and verifying the amount is o).