Skip to content

Conversation

@TNGkernelMaster
Copy link

@TNGkernelMaster TNGkernelMaster commented Oct 15, 2025

✨ feat(vies): expose VIES requestIdentifier (consultation number)

Why

Audits/ERPs often require storing the official VIES consultation number for each VAT check. The legacy checkVat API does not return it; requestIdentifier is provided by checkVatApprox (SOAP) and the REST API.

✅ What changed

  • New field: request_identifier in VatNumberCheckResult

  • New path: checkVatApprox flow that returns requestIdentifier when requester details are provided

  • Prefix-agnostic parsing: robust XML by localName (ignores nsX: prefixes)

  • Field mapping: traderNamebusiness_name, traderAddressbusiness_address

  • HTTPS endpoint: ensured SOAP URL uses HTTPS

  • Logging: log_lines include request/response and the parsed requestIdentifier

🔒 Backward compatibility

Call | Behavior | requestIdentifier -- | -- | -- check_vat_number(vat, country) | Uses checkVat SOAP Call | Not present (by design) check_vat_number_with_request_identifier(vat, country, requester_country_code, requester_vat_number) | Uses checkVatApprox SOAP Call | Present (if VIES returns it)

🧭 Usage

import pyvat

res = pyvat.check_vat_number_with_request_identifier(
vat_number="7770003038",
country_code=
"PL",
requester_country_code=
"DK", # your Member State
requester_vat_number=
"43083341" # number only, no country prefix
)

print(res.is_valid) # True/False
print(res.request_identifier) # e.g. "WAPIAAAAZnnAjXKl"
print(res.business_name) # from traderName
print(res.business_address) # from traderAddress

🧪 Tests

  • Canned checkVatApproxResponse XML verifies:

    • is_valid == True

    • business_country_code == "PL"

    • business_name / business_address parsed

    • request_identifier == "WAPIAAAAZnnAjXKl"

DEVELOPER COMMENTS

Check if a VAT number is valid using a registry that supports request identification.

This function validates the given VAT number, taking into account the requester's information (requester_country_code and requester_vat_number) as required by certain national authorities for proper auditing and evidence. When called, the function will attempt to verify the VAT number and will return a VatNumberCheckResult instance containing the result of the validation. The result object also contains a 'verificationIdentifier' (request_identifier), which serves as a unique proof of the verification that can be stored and presented to authorities should a selling company undergo an audit.

:param vat_number: VAT number to validate.
:param requester_country_code: Country code of the requesting party (e.g., your own company).
:param requester_vat_number: VAT number of the requesting party (e.g., your own company VAT number).
:param country_code:
    Optional country code. Should be supplied if known, as there is no
    guarantee that naively entered VAT numbers contain the correct alpha-2
    country code prefix for EU countries just as not all non-EU countries
    have a reliable country code prefix. Default ``None`` prompting
    detection.
:returns:
    a :class:`VatNumberCheckResult` instance containing the result for the
    full VAT number check. The result includes a 'verificationIdentifier' that can be retained
    for compliance and audit purposes with relevant authorities.

@TNGkernelMaster TNGkernelMaster changed the title added seller specific vat check with verification identifier Seller specific vat check with verification identifier in response Oct 15, 2025
@TNGkernelMaster
Copy link
Author

@nickbruun @kdeldycke @aladagemre @sniku may you kindly have a look at this PR?

@JanmanX
Copy link
Contributor

JanmanX commented Oct 17, 2025

Looks good to me.

@martinleblanc Can you have a look? :)

@TNGkernelMaster
Copy link
Author

Thanks for the re-direct @JanmanX and for your email!

@martinleblanc martinleblanc requested a review from Copilot October 21, 2025 07:09
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds support for retrieving VIES consultation numbers (requestIdentifier) when validating EU VAT numbers, enabling businesses to maintain audit trails required by tax authorities.

Key Changes:

  • Introduces check_vat_number_with_request_identifier() function that uses VIES checkVatApprox SOAP endpoint
  • Adds request_identifier field to VatNumberCheckResult for storing consultation numbers
  • Implements prefix-agnostic XML parsing to handle varying namespace prefixes in VIES responses

Reviewed Changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.

File Description
pyvat/init.py Adds new public API function for VAT validation with request identifier support
pyvat/result.py Extends result class with request_identifier field and updates documentation
pyvat/registries.py Implements checkVatApprox SOAP call with robust XML parsing and identifier extraction
pyvat/utils.py Adds utility function for prefix-agnostic XML element lookup

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

@martinleblanc
Copy link
Member

Logging sensitive data (privacy/GDPR)
You log the full SOAP payload and full XML response into result.log_lines. Those include VAT numbers, addresses, and the request identifier meant as audit evidence.

Recommendation:
• Do not log the requester VAT or full response.
• Log only essential fields (status, validity boolean, requestIdentifier).
• If verbose logs are useful for debugging, guard them behind a flag (e.g., DEBUG_VAT_LOGS env var) and redact PII.

@martinleblanc
Copy link
Member

@TNGkernelMaster please check the comments above

TNGkernelMaster and others added 4 commits October 21, 2025 09:33
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@TNGkernelMaster
Copy link
Author

@TNGkernelMaster please check the comments above

Hey @martinleblanc I believe all the comments have been addressed. Kindly let me know if you spot anything missing.

@TNGkernelMaster
Copy link
Author

hey @martinleblanc, a kind reminder.

@TNGkernelMaster
Copy link
Author

Hey @martinleblanc - it would be great if we could close this as we will really want to use your library!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants