Ejemplo en lenguaje PHP

Tiene como objetivo ejemplificar el proceso de conexión, acceso y uso de las propiedades y métodos ofrecidos por el Servicio Web de Integración de TFHKA a través del lenguaje de programación PHP

Lo más importante es establecer los pasos necesarios para realizar una integración exitosa.

Criterios a tomar en cuenta:

  • Establecer ruta y Tokens para conectarnos y utilizar los métodos expuestos por el Servicio Web de Integración de TFHKA.
  • Construir / Armar el objeto Documento Electrónico (Factura) que se desea enviar al Servicio Web de Integración de TFHKA.
  • Enviar el documento al Servicio Web de Integración de TFHKA para su procesamiento.
  • Recibir y procesar la respuesta del Servicio Web de TFHKA en nuestro proyecto, según sea requerido.

Pasos para realizar la integración:

PASO 1: Definir variables con la ruta y los tokens requeridos por el Servicio Web de Integración de TFHKA.

PASO 2: Construir el Documento Electrónico a enviar al Servicio Web de Integración de TFHKA.

PASO 3: Enviar el Documento Electrónico construido en el paso 3 al Servicio Web de Integración de TFHKA.

PASO 4: Recibir y procesar la Respuesta del Servicio Web de Integración de TFHKA.

IMPORTANTE: El Documento procesado será almacenado en la NUBE para que pueda ser consultado en cualquier momento.

Para mayor información y detalles sobre el proceso, puede consultar el Manual de Integración de TFHKA

PASO 1: Definir variables con la ruta y los tokens requerido por el servicio web de TFHKA

A continuación definiremos la ruta y los TOKENS requeridos por el Servicio Web de Integración de TFHKA para enviar documentos electrónicos, así como para utilizar otros métodos públicos expuestos $ruta = “https://demoemision.thefactoryhka.com.pa/ws/obj/v1.0/Service.svc?singleWsdl”; url del servicio

$tokenEmpresa = “SOLICITAR”;

$tokenPassword = “SOLICITAR”;

PASO 2: Construir el documento electrónico a enviar al servicio web de integración de TFHKA

En este ejemplo utilizaremos Clases, Atributos y Métodos creados con la finalidad de organizar mejor la estructura del archivo y del cuerpo de código fuente en general.

Sin embargo, esta estructura no es obligatoria. El desarrollador puede utilizar su propio estilo, siempre y cuando logre establecer los valores requeridos para los diferentes objetos que sub-componen al objeto DocumentoElectrónico a enviar al Servicio Web.

A continuación se define una variable para establecer el Número de Documento Electrónico a enviar

$numeroDocFiscal = “0000000000”;

Mensajero::InfoNumero($numeroDocFiscal);

$factura = new DocumentoElectronico();

$cliente = new Cliente();

$datos = new DatosTransaccion();

$datos→cliente = $cliente;

- Debe establecerse el formato solicitado para la fecha de emisión “yyyy-MM-ddTHH:mm:ss-05:00”

$datos→fechaEmision = (new \DateTime('America/Panama'))→format('Y-m-d\TH:i:s-05:00');

$datos→numeroDocumentoFiscal = $numeroDocFiscal;

$factura→datosTransaccion = $datos;

$item = new Item();

$factura→listaItems = array($item);

$totales = new Totales();

$formaPago = new FormaPago();

$totales→listaFormaPago = array($formaPago);

$factura→totalesSubTotales = $totales;

- Ya teniendo listo el documento, es posible enviarlo al Servicio Web de Integración de TFHKA

PASO 3: Enviar el documento electrónico construido en el paso 3 al servicio web de integración de TFHKA

A continuación definiremos la ruta y los TOKENS requeridos por el Servicio Web de Integración de TFHKA para enviar documentos electrónicos, así como para utilizar otros métodos públicos expuestos.

try {
  $wsPa = new SoapClient($ruta);
  $parametros = array(
    'tokenEmpresa' => $tokenEmpresa,
    'tokenPassword' => $tokenPassword,
    'documento' => $factura,
  );

- A continuación, enviamos el documento al método "Enviar" del Servicio Web de Integración de TFHKA

  $respWsPa = json_decode(json_encode($wsPa->__soapCall('Enviar', array($parametros))), true);
} catch (\Exception $e) {
  die($e);
}

PASO 4: Recibir y procesar la respuesta del servicio web de integración de TFHKA

La respuesta del Servicio Web de TFHKA será enviada inmediatamente.

En este ejemplo, la respuesta del Servicio Web se muestra directamente a través de la pantalla.

En caso de recibir una respuesta positiva para el envío del Documento Electrónico (código 200), se presentará un enlace para observar los detalles a través de la página de Consulta de Facturas por Qr en una pestaña adicional de su navegador web.

La respuesta del Servicio Web de TFHKA incluye: código de la respuesta, resultado, mensaje, cufe y Qr, entre otros.

Para mayor detalle de la respuesta del Servicio Web, podría visualizar el resultado a través de la siguiente instrucción: var_dump($respWsPa[“EnviarResult”]);

Mensajero:MostrarRespuesta($respWsPa);

  • DEFINICIÓN DE CLASES PARA ARMAR EL DOCUMENTO ELECTRÓNICO A ENVIAR, ASÍ COMO SUS ELEMENTOS COMPONENTES:
class DocumentoElectronico

{

  public $codigoSucursalEmisor  = "0000";

  public $tipoSucursal = "1";

  public $datosTransaccion;

  public $listaItems;

  public $totalesSubTotales;

}

class Cliente

{

  public $tipoClienteFE = "01";

  public $tipoContribuyente = "2";

  public $numeroRUC = "155596713-2-2015";

  public $digitoVerificadorRUC = "59";

  public $razonSocial = "FE general";

  public $direccion = "Av. Balboa";

  public $codigoUbicacion = "1-2-3";

  public $corregimiento = "Guabito";

  public $distrito = "Changuinola";

  public $provincia = "Bocas del Toro";

  public $telefono1 = "997-8243";

  public $telefono2 = "";

  public $telefono3 = "";

  public $correoElectronico1 = "fep@gmail.com";

  public $pais = "PA";

  public $paisOtro = "";

}

class DatosTransaccion

{

  public $tipoEmision = "01";

  public $tipoDocumento = "01";

  public $numeroDocumentoFiscal;

  public $puntoFacturacionFiscal = "001";

  public $fechaEmision;

  public $naturalezaOperacion = "01";

  public $tipoOperacion = "1";

  public $destinoOperacion = "1";

  public $formatoCAFE = "1";

  public $entregaCAFE = "1";

  public $envioContenedor = "1";

  public $procesoGeneracion = "1";

  public $tipoVenta = "1";

  public $informacionInteres = "Prueba de Información de interés";

  public $cliente;

}

class Item

{

  public $descripcion = "Cuadernos";

  public $codigo = "T";

  public $unidadMedida = "und";

  public $cantidad = "2.00";

  public $fechaFabricacion = "2020-12-25";

  public $unidadMedidaCPBS = "cm";

  public $precioUnitario = "69.00";

  public $precioUnitarioDescuento = "0.00";

  public $precioAcarreo = "1.01";

  public $precioSeguro = "12.01";

  public $precioItem = "138.00";

  public $valorTotal = "171.72";

  public $codigoGTIN = "0";

  public $cantGTINCom = "0.99";

  public $codigoGTINInv = "0";

  public $cantGTINComInv = "1.00";

  public $tasaITBMS = "03";

  public $valorITBMS = "20.70";

  public $tasaISC = "0.00";

  public $valorISC = "0.00";

  public $codigoCPBS = "1410";

}

class Totales

{

  public $totalPrecioNeto = "138.00";

  public $totalITBMS = "20.70";

  public $totalISC = "0.00";

  public $totalMontoGravado = "20.70";

  public $totalDescuento = "";

  public $totalAcarreoCobrado = "";

  public $valorSeguroCobrado = "";

  public $totalFactura = "171.72";

  public $totalValorRecibido = "171.72";

  public $vuelto = "0.00";

  public $tiempoPago = "1";

  public $nroItems = "1";

  public $totalTodosItems = "171.72";

  public $listaFormaPago;

}

class FormaPago

{

  public $formaPagoFact = "02";

  public $valorCuotaPagada = "171.72";

  public $descFormaPago = "";

}

Definición de clases para mostrar información en el Front de esta pagina de ejemplo

class Mensajero

{

  public static function Encabezado()

  {

    echo ("<div class='encabezado'>The Factory HKA C.A.</div><div class='encabezado6'>EJEMPLO DE INTEGRACIÓN DIRECTA PHP (v7 o superior)</div>");

  }

  public static function InfoNumero($numero)

  {

    echo ("<span class='texto3'>Número de Documento Fiscal a enviar:</span><span class='texto4'>"

      . $numero

      . "</span>

          <br>

          <center>

            <div class='encabezado2'>          

              <ul>

                <li>Puede cambiar el Número de Documento Fiscal a enviar en la línea 67 del código fuente de esta página.</li>

                <li>Guarde el cambio realizado y haga Click en el siguiente botón para actualizar y enviar nuevamente.</li>

              </ul>

            </div>

            <div class='encabezado4'>

              <button onClick='window.location.reload();'>Actualizar</button>

            </div>

          </center>");

  }

  public static function MostrarRespuesta($respWsPa)

  {

    echo "

            <center>

              <div class='encabezado5'>

                <span class='texto2'>RESULTADOS</span>

                 <hr>

                 <p class='encabezado3'>

                      <u>CÓDIGO</u>:&nbsp;" . $respWsPa["EnviarResult"]['codigo']

      . "<br>

                      <u>RESULTADO</u>:&nbsp;" . $respWsPa["EnviarResult"]['resultado']

      . "<br>

                      <u>MENSAJE</u>:&nbsp;" . $respWsPa["EnviarResult"]['mensaje']

      . "<br>

                      <u>CUFE</u>:&nbsp;" . $respWsPa["EnviarResult"]['cufe']

      . "</p>

              </div>

            </center>";

    if ($respWsPa["EnviarResult"]['codigo'] == "200" || $respWsPa["EnviarResult"]['codigo'] == "102") {

      echo "

              <center>

                <div class='encabezado4'>

                  <a href='"

        . $respWsPa["EnviarResult"]['qr']

        . "' target='_blank'>

                      Consultar Información

                  </a>

                </div>

              </center>";

    }

  }

}

Definición de estilos CSS a utilizar en el Front de esta pagina de ejemplo

<style type="text/css">

  .texto2 {

    color: #990000;

    font-size: 1rem;

  }

  .texto3 {

    color: #002d99;

    font-size: 1.8rem;

    padding-left: 265px;

  }

  .texto4 {

    color: #d52d06;

    font-size: 1.5rem;

    padding-left: 10px;

  }

  .texto6 {

    color: #fff;

    font-size: 1.5rem;

    padding-left: 50px;

  }

  .encabezado {

    margin: 10 0 5px 0;

    padding: 15px;

    border-top: 1px solid #E9ECEF;

    background: #5077a3;

    background: -webkit-linear-gradient(to bottom right, rgb(2, 66, 179) 0%, rgb(0, 47, 134) 100%);

    background: linear-gradient(to bottom right, rgb(2, 66, 179) 0%, rgb(0, 47, 134) 100%);

    box-shadow: 0px 1px 3px -1px rgba(41, 70, 97, 0.2);

    position: relative;

    border-bottom: 1px solid #E9ECEF;

    color: #fff;

    font-size: 1.9rem;

    padding-left: 60px;

  }

  .encabezado2 {

    width: 60%;

    margin-top: 20px;

    border: 2px solid #c8dbff;

    background-color: #eef6ff;

    position: relative;

    color: #002d99;

    font-size: 1rem;

    border-radius: 10px;

    padding: 5px;

    line-height: 30px;

    text-align: left;

    text-indent: 50px;

  }

  .encabezado3 {

    width: 100% margin-top: 10px;

    background-color: #eef6ff;

    position: relative;

    color: #002d99;

    font-size: 1rem;

    border-radius: 5px;

    padding: 5px;

    line-height: 30px;

    text-align: left;

    padding-left: 40px

  }

  .encabezado4 {

    width: 60%;

    margin-top: 20px;

    border: 2px solid #c8dbff;

    border-radius: 10px;

  }

  .encabezado5 {

    width: 60%;

    margin-top: 50px;

    border: 2px solid #c8dbff;

    border-radius: 10px;

  }

  .encabezado6 {

    margin: 10 0 30px 0;

    padding: 0 30px;

    border-top: 1px solid #c8dbff;

    background-color: #eef6ff;

    box-shadow: 0px 1px 3px -1px rgba(41, 70, 97, 0.2);

    position: relative;

    border-bottom: 1px solid #c8dbff;

    color: #990000;

    font-size: 1.6rem;

    text-indent: 50px;

  }

  ul {

    list-style: none;

  }

  li {

    margin: 0px 0px 1px 0px;

  }

  button {

    position: relative;

    display: inline-block;

    padding: 8px 10px;

    background-image: linear-gradient(to bottom right, rgb(2, 66, 179) 0%, rgb(0, 47, 134) 100%);

    background-image: -webkit-linear-gradient(to bottom right, rgb(2, 66, 179) 0%, rgb(0, 47, 134) 100%);

    text-decoration: none;

    color: #fff;

    font-size: 15px;

    font-family: sans-serif;

    font-weight: 100;

    border-radius: 5px;

    float: right;

  }

  button:hover {

    background: -webkit-linear-gradient(to bottom right, rgb(1, 85, 232) 0%, rgb(0, 81, 232) 100%);

    background: linear-gradient(to bottom right, rgb(1, 85, 232) 0%, rgb(0, 81, 232) 100%);

    color: #fff;

  }

  a {

    position: relative;

    display: inline-block;

    padding: 8px 10px;

    background-image: linear-gradient(to bottom right, rgb(2, 66, 179) 0%, rgb(0, 47, 134) 100%);

    background-image: -webkit-linear-gradient(to bottom right, rgb(2, 66, 179) 0%, rgb(0, 47, 134) 100%);

    text-decoration: none;

    color: #fff;

    font-size: 15px;

    font-family: sans-serif;

    font-weight: 100;

    border-radius: 5px;

    float: right;

  }

  a:hover {

    background: -webkit-linear-gradient(to bottom right, rgb(1, 85, 232) 0%, rgb(0, 81, 232) 100%);

    background: linear-gradient(to bottom right, rgb(1, 85, 232) 0%, rgb(0, 81, 232) 100%);

    color: #fff;

  }

  hr {

    border: 2px solid #c8dbff;

    background-color: #eef6ff;

  }

</style>