Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Internet (https://www.clubdelphi.com/foros/forumdisplay.php?f=3)
-   -   Consulta VIES (Números documentos de la UE) (https://www.clubdelphi.com/foros/showthread.php?t=96416)

keys 27-09-2023 13:17:56

Consulta VIES (Números documentos de la UE)
 
Hola a todos.

Estoy intentando realizar en delphi una consulta al servicio VIES. Que sirve para validar Números de documentos de la Unión Europea.https://ec.europa.eu/taxation_custom...al-information

En principio hay dos modos de hacerlo, con un servicio SOAP y otro REST. Estoy pegándome con los dos maneras pero no hay forma de hacerlo. Respecto al servicio REST no encuentro por ningún lado la url donde esta el servicio. Y con el soap al importar los wsdl en delphi dan un error.

¿Alguien ha conseguido descifrarlo?

duilioisola 27-09-2023 15:13:10

Por lo que leí en la web que envías están publicados los endpoints en formato YAML para poder ser leido en la web https://editor.swagger.io/
El fichero YAML indica las "paths" que serían los endpoints y los parámetros que puedes utilizar.
Descarge el fichero y luego en la web que mencionan ves al menú "File" -> "Import File" y seleccionas el fichero.

Parece que hay tres endpoints
/check-vat-number
Ejemplo con CURL
Código:

curl -X 'POST' \
  'https://editor.swagger.io/check-vat-number' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
  "countryCode": "ES",
  "vatNumber": "X3245299E",
  "requesterMemberStateCode": "ES",
  "requesterNumber": "1",
  "traderName": "TEST",
  "traderStreet": "STR",
  "traderPostalCode": "08035",
  "traderCity": "Barcelona",
  "traderCompanyType": "eCommerce"
}'

/check-vat-test-service
/check-status

Contenido del fichero YAML
Código:

swagger: "2.0"
info:
  description: "This is the contract for Vies on-the-Web endpoints.
  The checkVat service supports exact and approximate matching at the same time.
  In order to retrieve the requestIdentifier, the information about requesterMemberStateCode and requesterNumber have to be provided."
  version: "1.0.0"
  title: "Vies on-the-Web Endpoint"
produces:
  - "application/json"
schemes:
  - "https"
paths:
  /check-vat-number:
    post:
      tags:
        - "public"
      summary: "Check a Vat Number for a specific country"
      operationId: "checkVatNumber"
      parameters:
        - name: "body"
          in: "body"
          description: "The request body"
          required: true
          schema:
            $ref: "#/definitions/CheckVatRequest"
      responses:
        "200":
          description: "Successful operation"
          schema:
            $ref: "#/definitions/CheckVatResponse"
        "400":
          description: "Bad Request"
          schema:
            $ref: "#/definitions/CommonResponse"
        "500":
          description: "Internal server error"
          schema:
            $ref: "#/definitions/CommonResponse"
  /check-vat-test-service:
    post:
      tags:
        - "public"
      summary: "Test the check vat service"
      operationId: "checkVatTestService"
      parameters:
        - name: "body"
          in: "body"
          description: "The request body"
          required: true
          schema:
            $ref: "#/definitions/CheckVatRequest"
      responses:
        "200":
          description: "Successful operation"
          schema:
            $ref: "#/definitions/CheckVatResponse"
        "400":
          description: "Bad Request"
          schema:
            $ref: "#/definitions/CommonResponse"
        "500":
          description: "Internal server error"
          schema:
            $ref: "#/definitions/CommonResponse"
  /check-status:
    get:
      tags:
        - "public"
      summary: "Check the status of each member states"
      operationId: "checkStatus"
      responses:
        "200":
          description: "Successful operation"
          schema:
            $ref: "#/definitions/StatusInformationResponse"
        "400":
          description: "Bad Request"
          schema:
            $ref: "#/definitions/CommonResponse"
        "500":
          description: "Internal server error"
          schema:
            $ref: "#/definitions/CommonResponse"
definitions:
  Match:
    type: "string"
    enum:
      - "VALID"
      - "INVALID"
      - "NOT_PROCESSED"
  CheckVatRequest:
    type: "object"
    properties:
      countryCode:
        type: "string"
      vatNumber:
        type: "string"
      requesterMemberStateCode:
        type: "string"
      requesterNumber:
        type: "string"
      traderName:
        type: "string"
      traderStreet:
        type: "string"
      traderPostalCode:
        type: "string"
      traderCity:
        type: "string"
      traderCompanyType:
        type: "string"
  CheckVatResponse:
    type: "object"
    properties:
      countryCode:
        type: "string"
      vatNumber:
        type: "string"
      requestDate:
        type: "string"
        format: "date-time"
      valid:
        type: "boolean"
      requestIdentifier:
        type: "string"
      name:
        type: "string"
      address:
        type: "string"
      traderName:
        type: "string"
      traderStreet:
        type: "string"
      traderPostalCode:
        type: "string"
      traderCity:
        type: "string"
      traderCompanyType:
        type: "string"
      traderNameMatch:
        $ref: "#/definitions/Match"
      traderStreetMatch:
        $ref: "#/definitions/Match"
      traderPostalCodeMatch:
        $ref: "#/definitions/Match"
      traderCityMatch:
        $ref: "#/definitions/Match"
      traderCompanyTypeMatch:
        $ref: "#/definitions/Match"
  CountryStatus:
    type: "object"
    properties:
      countryCode:
        type: "string"
      availability:
        type: "string"
        enum:
          - "Available"
          - "Unavailable"
          - "Monitoring Disabled"
  StatusInformationResponse:
    type: "object"
    properties:
      vow:
        type: "object"
        properties:
          available:
            type: "boolean"
      countries:
        type: "array"
        items:
          $ref: "#/definitions/CountryStatus"
  CommonResponse:
    type: "object"
    properties:
      actionSucceed:
        type: "boolean"
        description: "Indicate if the action succeed or not"
      errorWrappers:
        $ref: "#/definitions/ErrorWrappers"
  ErrorWrappers:
    type: "array"
    description: "Indicate the cause of the error when actionSucceed is false."
    items:
      $ref: "#/definitions/ErrorWrapper"
  ErrorWrapper:
    type: "object"
    description: "Define information about an error"
    properties:
      error:
        type: "string"
        description: "The error code"
      message:
        type: "string"


duilioisola 27-09-2023 16:30:38

Le he dedicado un rato y he llegado hasta aquí:

https://viesapi.eu/vies-rest-api-documentation/

También he llegado a la parte de "Pricing". Aparentemente es un servicio que va de 5 a 20 euros al mes.

La dirección para la API es
Poducción: https://viesapi.eu/api
Test: https://viesapi.eu/api-test

En esa página muestran un ejemplo de pruebas que funciona:
https://test_id:test_key@viesapi.eu/...t/PL7171642051
y devuelve
Código:

<result>
<vies>
<uid>b862fbfeb7f17341</uid>
<countryCode>PL</countryCode>
<vatNumber>7171642051</vatNumber>
<valid>true</valid>
<traderName>MICHAŁ CZAPCZYŃSKI</traderName>
<traderCompanyType>---</traderCompanyType>
<traderAddress>AL. WILANOWSKA 366 M88 02-665 WARSZAWA</traderAddress>
<id>cfa7c7c272ab4ea1</id>
<date>2023-09-27+02:00</date>
<source>http://ec.europa.eu</source>
</vies>
</result>


keys 28-09-2023 08:18:53

Hola.

Lo primero gracias. Hasta ahí es donde yo llego.

En cuento a la primera respuesta la url que sale es https://editor.swagger.io/check-vat-number y esa no puede ser ya que esa es la dirección del editor, no encuentro por ningún otro lado la url correcta.

En cuento a la segunda, ese enlace se trata de una empresa que ha desarrollado su propia api para realizar las consultas y cobra por ello.

Gracias otra vez.

dec 28-09-2023 14:28:24

Hola a todos,

Buscando la URL de marras, me he topado con esta entrada en StackOverflow, donde se muestra la siguiente URL:

Código:

https://ec.europa.eu/taxation_customs/vies/rest-api/ms/[country]/vat/[vat]
En efecto, parece funcionar como se espera, por ejemplo, la siguiente URL, y, mediante un "simple" HTTP GET:

Código:

https://ec.europa.eu/taxation_customs/vies/rest-api/ms/DE/vat/122268496
... ya retorna un JSON que nos da la respuesta de si el VAT es válido o no.

Por otro lado, parece que la URL "base" que se necesita es la siguiente:

Código:

https://ec.europa.eu/taxation_customs/vies/rest-api/
... a la que se podría ya añadir el método que se quiere utilizar:

Código:

https://ec.europa.eu/taxation_customs/vies/rest-api/check-vat-number
Acabo de probarlo y funciona como se espera, esto es, enviando a dicho método (mediante HTTP POST) el JSON / argumento necesario, tal como se define aquí:

Código:

https://ec.europa.eu/assets/taxud/vow-information/swagger_publicVAT.yaml
... y puede verse "mejor" en el editor Swagger, la respuesta es la esperada.

P.D. Puede probarse todo esto fácilmente en REQ BIN.

URL: https://ec.europa.eu/taxation_custom...eck-vat-number

Method: POST

JSON de entrada:

Código:

{
  "countryCode": "DE",
  "vatNumber": "122268496"
}

JSON de salida / respuesta:

Código:

{
    "countryCode": "DE",
    "vatNumber": "122268496",
    "requestDate": "2023-09-28T12:41:19.417Z",
    "valid": true,
    "requestIdentifier": "",
    "name": "---",
    "address": "---",
    "traderName": "---",
    "traderStreet": "---",
    "traderPostalCode": "---",
    "traderCity": "---",
    "traderCompanyType": "---",
    "traderNameMatch": "NOT_PROCESSED",
    "traderStreetMatch": "NOT_PROCESSED",
    "traderPostalCodeMatch": "NOT_PROCESSED",
    "traderCityMatch": "NOT_PROCESSED",
    "traderCompanyTypeMatch": "NOT_PROCESSED"
}

Supongo que puede jugarse un poco con todo esto, porque, en el archivo YAML se puede ver un JSON de entrada para el método de arriba tal que así:

Código:

{
  "countryCode": "string",
  "vatNumber": "string",
  "requesterMemberStateCode": "string",
  "requesterNumber": "string",
  "traderName": "string",
  "traderStreet": "string",
  "traderPostalCode": "string",
  "traderCity": "string",
  "traderCompanyType": "string"
}

Como se ve en el ejemplo que he puesto arriba, no es necesario enviar toda esa información. Con las dos primeras claves se obtiene ya información. Podemos añadir las dos siguientes y también funciona. El resto de claves, imagino, son para utilizarlas sin las anteriores (sin al menos las dos primeras), es decir, para intentar obtener un VAT proporcionando el "traderName" únicamente, etc.

keys 28-09-2023 14:33:21

Acabo de encontrar la url y ahora tengo que hacer que funcione. Cuando lo tenga pondré el código.

https://ec.europa.eu/taxation_customs/vies/rest-api/

y tiene los tres siguientes servicios:

/check-vat-number
/check-vat-test-service
/check-status

A la del estado es fácil hacerla funcionar, ya que no tiene parámetros. Me estoy pegando con el primero.

dec 28-09-2023 14:48:41

Hola a todos,

Cita:

Empezado por keys (Mensaje 552734)
Acabo de encontrar la url y ahora tengo que hacer que funcione. Cuando lo tenga pondré el código.

https://ec.europa.eu/taxation_customs/vies/rest-api/

y tiene los tres siguientes servicios:

/check-vat-number
/check-vat-test-service
/check-status

A la del estado es fácil hacerla funcionar, ya que no tiene parámetros. Me estoy pegando con el primero.

Pues la hemos encontrado casi a la vez. :) Como he puesto en mi anterior mensaje, en efecto, funciona como se espera. Vaya, no lo he probado en Delphi sino en REQ BIN, pero, no veo porqué no funcionaría un HTTP POST similar desde Delphi. Si es que es necesario... porque la primera URL que pongo en mi anterior mensaje (y que usa sólo HTTP GET) acaso podría ser suficiente.

keys 02-10-2023 09:53:48

Hola a todos. Pongo una función para validar un documento en el servicio VIES de la UE.

Código Delphi [-]
function ComprobarDocumentoVIES(Pais, Documento: string): false;
var
  LRequest: THTTPClient;

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

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

  //Objeto JSON para enviar los datos
  JSONData := TJSONObject.Create;
  JSONData.AddPair('countryCode', Pais);
  JSONData.AddPair('vatNumber', Documento);
  
  try

    Lrequest.ContentType := 'application/json';

    StringStream := TStringStream.Create(JSONData.ToString, TEncoding.UTF8);
    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
         if JSONData.TryGetValue Boolean ('valid', valido) then //esto lo pongo asi por que el chat no me deja poner los simbolos de mayor y menor delante y detrás de boolean;
          begin
            
             result := valido;
           
          end;

      end;

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


end;

newtron 02-10-2023 10:09:11

^\||/ Gracias a todos. Seguro que nos será de utilidad a bastante gente.

Casimiro Notevi 02-10-2023 10:09:33

No entiendo, qué quieres decir aquí:
Código Delphi [-]
if JSONData.TryGetValue Boolean ('valid', valido) then //esto lo pongo asi por que el chat no me deja poner los simbolos de mayor y menor delante y detrás de boolean;

keys 02-10-2023 10:11:58

Cita:

Empezado por Casimiro Notevi (Mensaje 552777)
No entiendo, qué quieres decir aquí:
Código Delphi [-]
if JSONData.TryGetValue Boolean ('valid', valido) then //esto lo pongo asi por que el chat no me deja poner los simbolos de mayor y menor delante y detrás de boolean;

que hay que poner <boolean>, Si esto lo pongo dentro del chat, marcando sintaxis delphi lo quita.:rolleyes:

Para TicketBAI puede ser útil, ya que las haciendas están validando que son corectos los documentos intracomunitarios.

Casimiro Notevi 02-10-2023 11:27:27

Probando con un espacio:
Código Delphi [-]
if JSONData.TryGetValue < Boolean > ('valid', valido) then
Probando sin espacios:
Código Delphi [-]
if JSONData.TryGetValue < Boolean> ('valid', valido) then
Parece que es el < delante de la B, seguramente es parte de algún emoticono.

keys 02-10-2023 11:30:06

Cita:

Empezado por Casimiro Notevi (Mensaje 552782)
Probando con un espacio:
Código Delphi [-]
if JSONData.TryGetValue < Boolean > ('valid', valido) then

Sin espacios se lo come
Código Delphi [-]
if JSONData.TryGetValue('valid', valido) then

Para la pró:rolleyes:xima vez ya se.


La franja horaria es GMT +2. Ahora son las 20:18:02.

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