Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   General/Noticias (https://www.clubdelphi.com/foros/forumdisplay.php?f=64)
-   -   Verificación de VAT comunitario (https://www.clubdelphi.com/foros/showthread.php?t=97564)

newtron 15-11-2022 17:25:06

Validar DNI/CIF
 
Hola a tod@s.

Estoy teniendo un pequeño problema y es que en los programas de facturación, sobre todo los que generan datos para el sii, no controlo si el dni/cif es correcto en caso de ser extranjero. El operario se equivoca al teclearlo, luego no entra en el sii y no hay forma de buscar al cliente si son clientes de paso.

En el caso de dnis/cifs nacionales no es problema porque hay formas de calcular si el número es correcto pero mi pregunta es si hay alguna forma de hacer una consulta a algún sitio (webservice) en el que se pueda introducir un dni/cif extranjero, especificando el país, y que te diga si es correcto.

Gracias y un saludo.

mRoman 15-11-2022 17:51:54

Pues algo muy complicado lo que requieres.

Me encontré una página (https://expinterweb.mites.gob.es/rea/pub/consulta.htm) que válida empresas acreditadas, pero solo de España, yo vivo en México, así que la página para tal fin seria esta asi que...no lo sé, tendrías q tener un catálogo de páginas de cada país para consultar los datos...algo complicado si tus volúmenes de empresas o personas extranjeras son muchas.

Talvez tendrías que ir elaborando tu propio catálogo de empresas con sus identificadores empresariales para cada cliente/pais e ir almacenando los datos, claro, con el riesgo de que tu usuario ingrese mal los datos consultados, que se reduciría el margen de error si COPIA y PEGA esos datos de las páginas.

En fin, espero te sirvan mis comentarios.

Saludos.

Casimiro Noteví 15-11-2022 18:41:15

Aquí está para Europa.
https://ec.europa.eu/taxation_customs/tin/#/check-tin

newtron 15-11-2022 20:00:26

Todos los comentarios son instructivos mRoman, gracias por el tuyo.

Gracias también a ti Casimiro, le echaré un vistazo a esa web. El problema es que "mi tema" se queda cojo porque, aunque los intracomunitarios sean muchos (quizás la mayoría), por el sur de España se mueve mucho marroquí (por ejemplo) y mucho inglés que ya no son comunitarios así que aunque le de solución parcial sigo teniendo el problema. A ver qué se me ocurre y/o si tiene solución este asunto.

Gracias de nuevo y un saludo.

Garada 15-11-2022 22:37:56

¿Realmente el SII te echa para atrás los ID de extranjeros?

Creo recordar que bastaba con identificar el país y en el ID marcarlo como "otra identificacion"

Dudo que Hacienda pueda comprobar que un ID extranjero sea correcto como puede ser con los NIF que aparte del digito de control ya sabe el nombre.

newtron 16-11-2022 10:45:05

Pues ahora que lo dices... después de poner el post me quedé dandole vueltas precisamente a ese detalle. Igual los únicos que controlan son los comunitarios y no los extranjeros. Es un tema que tengo que confirmar.

Gracias y un saludo.

iMia 30-01-2023 10:42:51

Validador nif de la agencia tibutaria (AEAT)
 
Requisitos:
- Importar la wsdl: "https://www2.agenciatributaria.gob.es/static_files/common/internet/dep/aplicaciones/es/aeat/burt/jdit/ws/VNifV2.wsdl"
- Tener capicom.dll registrada (regsvr32 C:\...\capicom.dll) y
- Importar el componente capicom.DLL creará el fuente CAPICOM_TBL
- Open ssl. (libeay.pas y openSsslUtils.pas).


Un form "TMain",
un TEdit "edNif", un TEdit "edNombre"
un TEdit "edCertificado", un TmaskEdit "mskCertPass"
un boton "btnValidarESNif"

opcional:
un TEdit "edResultado", un TEdit "edDNIValidado", un TEdit "edNombreValidado"


uses

Código:


uses
  // Windows API
  Winapi.Windows, Winapi.Messages, WinApi.WinInet,
  // System
  System.SysUtils, System.Variants, System.Classes, System.IniFiles, System.UITypes, System.Win.ComObj,
  System.Net.URLClient, System.Net.HttpClient, System.Net.HttpClientComponent,

  // Rest - JSON
  REST.Json,
  // Soap
  Soap.SOAPHTTPClient, Soap.SOAPHTTPTrans, Soap.InvokeRegistry, Soap.Rio,
  // aeat NIF VAlidador
  VNifV21; // Módulo creado al importar el wsdl


  CAPICOM_TLB, // Unidad creada al importar la dll de capicom.

  libeay32, OpenSSLUtils;

declarar el tipo:

Código:

type
  PCCERT_CONTEXT = type Pointer;

Código:


function TMain.validarESNif(): VNifV2Sal;
var
  nifValidatorWS: VNifV2;
  VNifV2Entrada: VNifV2Ent;
  VNifV2Salida: VNifV2Sal;
  contri: Contribuyente;
  HTTPRIO: THTTPRIO;
begin
  HTTPRIO := THTTPRIO.create(self);
  HTTPRIO.HTTPWebNode.OnBeforePost := HTTPWebNode1BeforePost;
    nifValidatorWS := GetVNifV2(false, '', HTTPRIO);
    if nifValidatorWS <> nil then
  begin
    contri := Contribuyente.Create;
    contri.Nif := edDni.text;
    contri.Nombre := edNombre.text;
    setLength(VNifV2Entrada, 1);
    VNifV2Entrada[0] := contri;
    try
      VNifV2Salida := nifValidatorWS.VNifV2(VNifV2Entrada);
    except
      on E: EDOMParseError do
        ShowMessage('Sin respuesta: ' + #10 + #13 + E.message);
    end;
  end;
  result := VNifV2Salida;
end;

procedure TMain.HTTPWebNode1BeforePost(const HTTPReqResp: THTTPReqResp; Data: Pointer);
begin
    SetCertificate(trim(edCertificado.text), mskCertPass.text, Data);
end;

procedure TMain.IdSSLIOHandlerGetPassword(var Password: string);
begin
  Password := mskCertPass.text;
end;

procedure TMain.btnValidarESNifClick(Sender: TObject);
var
  VNifV2Salida: VNifV2Sal;
begin
  VNifV2Salida := validarESNif();
  if VNifV2Salida <> nil then
  begin
    edResultado.Text := VNifV2Salida[0].Resultado;
    edDNIValidado.Text := VNifV2Salida[0].Nif;
    edNombreValidado.Text := VNifV2Salida[0].Nombre; // No importa por que por la LODP no devuelven el nombre. Dejan lo que se envía.
  end
  else ShowMessage('No se ha podido validar el NIF: ' + edDni.Text);
end;


newtron 30-01-2023 10:53:36

Gracias iMia.

¿Podrías decirnos qué tipos de documentos valida esto?

Saludos.

iMia 30-01-2023 11:41:40

Cita:

Empezado por newtron (Mensaje 550198)
Gracias iMia.

¿Podrías decirnos qué tipos de documentos valida esto?

Saludos.


Valida que el NIF/nombre sean correctos (en España)

Saludos

Pd.:
en genérico es es uso de un certificado con http, y con capicom, y no tener que pagar componentes de terceros (blackbox, inet, etc...)

Neftali [Germán.Estévez] 30-01-2023 11:54:50

Cita:

Empezado por newtron (Mensaje 549220)
...no controlo si el dni/cif es correcto en caso de ser extranjero.

Creo que ninguno controlamos eso. Y ellos tampoco.

Cita:

Empezado por Garada (Mensaje 549227)
¿Realmente el SII te echa para atrás los ID de extranjeros?
Creo recordar que bastaba con identificar el país y en el ID marcarlo como "otra identificacion"

Veo ahora que [Garada] ya lo ha comentado.

newtron 30-01-2023 12:01:00

Perfecto.

Gracias a todos.

serpic 15-03-2023 19:23:17

Hola iMia, grácias por compartir el código.
He conseguido recrear el programa grácias a la información que has aportado.
Lo que no entiendo es como asignar el certificado que me interesa.
Veo que llamas a la función SetCertificate(trim(edCertificado.text), mskCertPass.text, Data) pero me da error y no se si es una función propia tuya o de algún componente.
Me puedes ayudar ?
Grácias

iMia 16-03-2023 08:30:56

Hola Serpic,

Tienes razón, no puse la función de asignación del certificado

Ahí va..

Código Delphi [-]

procedure TMainForm.SetCertificate(const FileName, Password: string; var Data: Pointer);
var
  Cert : ICertificate2;
  CertContext : ICertContext;
  PCertContext : PCCERT_CONTEXT;
begin
  try
    Cert := CoCertificate.Create;
  except
    on E: EOleSysError  do
      raise Exception.Create('CAPICOM.DLL no está registrada correctamente.')
  end;

  Cert.Load(FileName, Password, CAPICOM_KEY_STORAGE_EXPORTABLE, CAPICOM_LOCAL_MACHINE_KEY);
  CertContext := Cert as ICertContext;
  CertContext.Get_CertContext(Integer(PCertContext));
  if InternetSetOption(Data, INTERNET_OPTION_CLIENT_CERT_CONTEXT, PCertContext, 4096) = False then
    raise Exception.Create ( 'Error al asignar el certificado de cliente' )
end;

Como se ve en el código inicial, hay que importar la libreria CAPICOM.DLL (y registrarla en cada equipo que se vaya a utilizar la app) y generar el TLB y así se pueden utilizar las constantes de CAPICOM

Saludos...


P.D.: Espero no tengas los problemas que estoy experimentando en alqunas máquinas. en el Hilo: https://www.clubdelphi.com/foros/sho...d.php?p=550756

Saludos.

iMia 16-03-2023 12:17:57

Cita:

Empezado por iMia (Mensaje 550766)
Hola Serpic,

Tienes razón, no puse la función de asignación del certificado

Ahí va..

Código Delphi [-]

procedure TMainForm.SetCertificate(const FileName, Password: string; var Data: Pointer);
var
  Cert : ICertificate2;
  CertContext : ICertContext;
  PCertContext : PCCERT_CONTEXT;
begin
  try
    Cert := CoCertificate.Create;
  except
    on E: EOleSysError  do
      raise Exception.Create('CAPICOM.DLL no está registrada correctamente.')
  end;

  Cert.Load(FileName, Password, CAPICOM_KEY_STORAGE_EXPORTABLE, CAPICOM_LOCAL_MACHINE_KEY);
  CertContext := Cert as ICertContext;
  CertContext.Get_CertContext(Integer(PCertContext));
  if InternetSetOption(Data, INTERNET_OPTION_CLIENT_CERT_CONTEXT, PCertContext, 4096) = False then
    raise Exception.Create ( 'Error al asignar el certificado de cliente' )
end;

Como se ve en el código inicial, hay que importar la libreria CAPICOM.DLL (y registrarla en cada equipo que se vaya a utilizar la app) y generar el TLB y así se pueden utilizar las constantes de CAPICOM

Saludos...


P.D.: Espero no tengas los problemas que estoy experimentando en alqunas máquinas. en el Hilo: https://www.clubdelphi.com/foros/sho...d.php?p=550756

Saludos.

Atención!!
la llamada de carga del certificado es incorrecta...

deberia ser:

Código Delphi [-]
Cert.Load(FileName, Password, CAPICOM_KEY_STORAGE_EXPORTABLE, CAPICOM_CURRENT_USER_KEY);

muli 12-02-2024 00:03:41

Tambien da error a la compilar

Código Delphi [-]
En esta function  VNifV2(const VNifV2Ent: VNifV2Ent): VNifV2Sal; stdcall;

No encuentra VNifV2Ent): VNifV2Sal;

Y aqui 

  InvRegistry.RegisterDefaultSOAPAction(TypeInfo(VNifV2), '');
  InvRegistry.RegisterInvokeOptions(TypeInfo(VNifV2), ioDocument);
  InvRegistry.RegisterInvokeOptions(TypeInfo(VNifV2), ioLiteral);

[dcc32 Error] VNifV21.pas(97): E2134 Type 'VNifV2' has no type info

keys 13-03-2024 08:30:49

Para poder hacer operaciones intracomunitarias una empresa tiene que estar dada de alta en el VIES. Existe un servicio web para validar si una empresa esta o no dentra del VIES https://ec.europa.eu/taxation_custom...vat-validation es una manera de validar si un cif intracomunitario es correcto o no.

keys 13-03-2024 08:54:21

Pongo el código por si a alguien le interesa.

Código Delphi [-]

 //Pais son las letras del codigo del pais
function ComprobarDocumentoVIES(Pais, Documento: string): boolean;
var
  LRequest: THTTPClient;

  LResponse: TStringStream;
  JSONData: TJSONObject;
  StringStream: TStringStream;
  valido : Boolean;
begin

  result := false;
  LRequest := THTTPClient.Create;
  LResponse := TStringStream.Create;


  JSONData := TJSONObject.Create;

  JSONData.AddPair('countryCode', Pais);
  JSONData.AddPair('vatNumber', Documento);

  
    Lrequest.ContentType := 'application/json';
    StringStream := TStringStream.Create(JSONData.ToString, TEncoding.UTF8);
    LRequest.SecureProtocols := [THTTPSecureProtocol.TLS12];
    LRequest.Post('https://ec.europa.eu/taxation_customs/vies/rest-api/check-vat-number', StringStream , LResponse);
    JSONData := TJSONObject.ParseJSONValue(LResponse.DataString) as TJSONObject;

    if Assigned(JSONData) then
      begin
        // Obtener el valor del campo deseado de la respuesta que es el valid
         if JSONData.TryGetValue('valid', valido) then
          begin
            result := valido;
          end;
      end;

    JsonData.destroy;
    LResponse.Free;
    LRequest.Free;
    StringStream.Destroy;
 

end;

newtron 13-03-2024 09:06:54

^\||/ Gracias compañero.

Neftali [Germán.Estévez] 13-03-2024 09:15:23

Cita:

Empezado por keys (Mensaje 554900)
Pongo el código por si a alguien le interesa.


Nosotros hasta ahora lanzábamos la página para validar manualmente, pero no está de más tener accesible la API.
Gracias.

iMia 13-03-2024 11:21:29

El Wsdl ...

https:// ec.europa.eu/taxation_customs/vies/checkVatTestService.wsdl

keys 13-03-2024 11:23:17

Cita:

Empezado por iMia (Mensaje 554906)
El Wsdl ...

https:// ec.europa.eu/taxation_customs/vies/checkVatTestService.wsdl

Yo con el wsdl no conseguí hacerlo. Hice la llamada directamente al servicio con JSON.

iMia 13-03-2024 12:05:58

Cita:

Empezado por iMia (Mensaje 554906)
El Wsdl ...

https:// ec.europa.eu/taxation_customs/vies/checkVatTestService.wsdl

Perdón, puse el wsdl de test.
Este es el bueno;


https:// ec.europa.eu/taxation_customs/vies/checkVatService.wsdl

iMia 13-03-2024 12:06:50

Cita:

Empezado por keys (Mensaje 554907)
Yo con el wsdl no conseguí hacerlo. Hice la llamada directamente al servicio con JSON.

Pues me ha gustado mucho com lo has hecho directamente sin tener que importar el wsdl !!!

iMia 13-03-2024 16:08:40

enga va....

- importado el wsdl (ojo con los textos de más de 250 caracteres....)
- Ojoj que el pais lo he puesto con calzador... hay que parametrizarlo.

Código Delphi [-]

procedure TMainForm.btnValidarEUCIFClick(Sender: TObject);
var
  cv: checkVat;
  cvResp: checkVatResponse;
  cvWS: checkVatPortType;
  strMessage: string;

begin
  cv := checkVat.create();
  cv.countryCode := 'ES';
  cv.vatNumber := edDNI.Text;

  try
    cvWS := GetcheckVatPortType(false, '', nil);
    if cvWS <> nil then
    begin
      cvResp := cvWS.checkVat(cv);
      if cvResp.valid then
      begin
        strMessage := 'Valido!' + CRLF;
        strMessage := strMessage + 'CIF: ' + cvResp.vatNumber + CRLF;
      end
      else
        strMessage := 'NO ES VÁLIDO!';
      ShowMessage(strMessage);
    end;
  except
      on E: ERemotableException do
      begin
        ShowMessage('Sin respuesta: ' + #10 + #13 + E.message);
      end;
  end;
end;

iMia 14-01-2025 12:36:30

Hoy 14/01/2025 no está funcionando el servicio...
Da error que no hay respuesta... (no se puede parsear la respuesta)
Esperemos que lo arreglen pronto...
Si sigue fallando es que deben haber dado de baja el servicio y lo han movido a otro servicio/servidor o cambiado algo... miraré mañana si sigue fallando...

YellowStone 07-02-2025 18:34:49

Creo que no es que el servicio esté movido, a día de hoy sigue funcionando, el problema es que se satura, y entonces devuelve un "<faultcode>", que normalmente viene con un "<faultstring>" con algo así como "TOO MANY CONCURRENTS". Al rato vuelve a ir.

edari 20-06-2025 09:40:00

Consulta NIF Intracomunitario
 
Buenos días,


Como complemento a la consulta a la AEAT de los NIFS nacionales para tener localizados los que están identificados o no quiero empezar a hacer lo mismo con los clientes intracomunitarios y preparar un xml que pueda enviar a algún sitio para que me los valide


No encuentro mucha documentación oficial de como hacerlo pero sí he llegado al hilo común donde teníamos todo lo de Verifactu mezclado y en eso estoy


Genero un fichero tal que así

Código PHP:

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:urn="urn:ec.europa.eu:taxud:vies:services:checkVat:types">
<soapenv:Body>                                                                    
<urn:checkVat>
<urn:countryCode>DE</urn:countryCode>
<urn:vatNumber>DE12345678</urn:vatNumber>
</urn:checkVat>
</soapenv:Body>
</soapenv:Envelope>

Y lo intento subir con
Código PHP:

curl.exe --tlsv1.2 --data-binary @VIESEJEMPLO.XML --cert-type P12 --cert Certificado.p12:CONTRASEÑA -"Content-Type: application/xml;charset=UTF8" -X POST http://ec.europa.eu/taxation_customs/vies/services/checkVatService -o RESPUESTA.XML 

Y no consigo respuesta


Alguien me pueda ayudar?


Gracias

gcqZW 20-06-2025 10:11:35

Nosotros lo hacemos así, no se si te servirá:

Código PHP:

try {
        
$client = new SoapClient("https://ec.europa.eu/taxation_customs/tin/services/checkTinService.wsdl", [
            
'trace' => 0,
            
'exceptions' => true,
        ]);

        
$params = [
            
'countryCode' => $codigo_pais,
            
'tinNumber' => $nif,
        ];

        
$response $client->__soapCall('checkTin', [$params]);
        if (
$response->validStructure) {
            if (
$response->validSyntax) {
                
$nif_valido[$id_res] = 1;
                if (
$codigo_pais == 'ES') {
                    
$res_dni[$id_res]['dni_tipo'] = '07';
                }
            } else {
                
$nif_valido[$id_res] = 0;
            }
        } else {
            
$nif_valido[$id_res] = 0;
        }
    } catch (
SoapFault $e) {
        
// Manejo de errores
        
enviarLog('ERROR'$opcion$vista'Error en la petición al webservice de validación de NIF: ' $e->getMessage());
        
$nif_valido[$id_res] = 0;
    } 


edari 20-06-2025 10:45:04

Pues no mucho, pero gracias en cualquier caso...a alguien seguro que le vale

Neftali [Germán.Estévez] 20-06-2025 12:04:46

Lo uno con este otro hilo que parece que va de lo mismo.
https://www.clubdelphi.com/foros/showthread.php?t=95967

Por favor, hagamos búsquedas sobre el tema a preguntar antes de crear nuevos hilos.
Y revisad bien los foros; La consulta de un NIF intracomunitario (el título es correcto) no tiene que ver expresamente con LeyAntifraude, creo que se puede usar en muchos más ámbitos.

Decanato 03-07-2025 19:58:10

Verificación de VAT comunitario
 
Buenas tardes. Alguien ha tenido la necesidad de verificar un NIF comunitario??? Yo lo estoy intentando a través de http://ec.europa.eu/taxation_customs...heckVatService pero no debo estar montando bien el XML de entrada. Alguien que lo haya utilizado y pueda colgar aquí un ejemplo???

Gracias

Neftali [Germán.Estévez] 04-07-2025 09:04:20

Cita:

Empezado por Decanato (Mensaje 566083)
Buenas tardes. Alguien ha tenido la necesidad de verificar un NIF comunitario??? Yo lo estoy intentando a través de http://ec.europa.eu/taxation_customs...heckVatService pero no debo estar montando bien el XML de entrada. Alguien que lo haya utilizado y pueda colgar aquí un ejemplo???

Por favor, utilicemos las búsquedas antes de crear hilos nuevos.
Uno con el hilo ya existente sobre el tema....

revisa los códigos anteriores

edari 04-07-2025 10:54:33

Cita:

Empezado por Decanato (Mensaje 566083)
Buenas tardes. Alguien ha tenido la necesidad de verificar un NIF comunitario??? Yo lo estoy intentando a través de http://ec.europa.eu/taxation_customs...heckVatService pero no debo estar montando bien el XML de entrada. Alguien que lo haya utilizado y pueda colgar aquí un ejemplo???

Gracias




Yo también lo necesitaría y tampoco avanzo nada


Tienes más arriba en este hilo el xml que yo genero sin éxito a ver como de diferentes son los dos pero vamos


Tampoco he encontrado documentación oficial de la cual tirar




Seguiremos buscando

keys 04-07-2025 11:25:21

Yo con xml no lo logré. Con JSON si. tienes el ejemplo en este mismo tema más atrás.

edari 04-07-2025 12:12:23

Vi tu solución pero no trabajo con Delphi y no sé como "transportarlo" a generar el xml

gcqZW 04-07-2025 12:19:36

Por que usáis el VAT y no el TIN???

edari 04-07-2025 12:50:06

Porque es la único al que he llegado

Logan05 09-07-2025 11:51:22

¿Alguien podría poner un xml de ejemplo?

estoy intentándolo con https://ec.europa.eu/taxation_custom...inService.wsdl pero no consigo avanzar

YellowStone 09-07-2025 16:22:06

Cita:

Empezado por Logan05 (Mensaje 566235)
¿Alguien podría poner un xml de ejemplo?

estoy intentándolo con https://ec.europa.eu/taxation_custom...inService.wsdl pero no consigo avanzar


<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<tns1:checkVat xmlns:tns1="urn:ec.europa.eu:taxud:vies:services:checkVat:types">
<tns1:countryCode>FR</tns1:countryCode>
<tns1:vatNumber>FR12345678910</tns1:vatNumber>
</tns1:checkVat>
</soap:Body>
</soap:Envelope>


vatNumber creo que no hace falta ponerle los 2 digitos del pais por delante, pero si los pones tampoco pasa nada.

ermendalenda 09-07-2025 17:28:39

Cita:

Empezado por YellowStone (Mensaje 566240)
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<tns1:checkVat xmlns:tns1="urn:ec.europa.eu:taxud:vies:services:checkVat:types">
<tns1:countryCode>FR</tns1:countryCode>
<tns1:vatNumber>FR12345678910</tns1:vatNumber>
</tns1:checkVat>
</soap:Body>
</soap:Envelope>


vatNumber creo que no hace falta ponerle los 2 digitos del pais por delante, pero si los pones tampoco pasa nada.

Creo que lo hago igual aunque poniendole otros prefijos que no afectan.
Código PHP:

  <?xml  version="1.0" encoding="utf-8" ?>   - <Extranjero:Envelope xmlns:Extranjero="http://schemas.xmlsoap.org/soap/envelope/">   - <Extranjero:Body>   - <Datos:checkVat xmlns:Datos="urn:ec.europa.eu:taxud:vies:services:checkVat:types">     <Datos:countryCode>FR</Datos:countryCode>     <Datos:vatNumber>12345678910</Datos:vatNumber>    </Datos:checkVat>   </Extranjero:Body>   </Extranjero:Envelope>



La franja horaria es GMT +2. Ahora son las 10:35:53.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi