Invocar API de pago

Invocar API de pago

Consideraciones


Para invocar el Api de pagos se debe considerar lo siguiente:
  1. Utilizar el servicio en los endpoints
    1. Sandbox: https://sandbox-checkout.greenpay.me/kount
    2. Producción: https://checkout.greenpay.me/kount
  2. Tener una session y token de una orden de pago que no haya excedido los 30 minutos establecidos para el vencimiento.

Pasos para uso del servicio

1. Incluir el Data Collector

El data collector es una herramienta que Greenpay utiliza para recolectar información asociada a la transacción con el fin de analizar comportamientos fraudulentos.
Para integrar el data collector en las transacciones, se deben seguir los siguientes pasos:
  1. Incluir el script del Data Collector.
  1. Para iniciar el Data Collector, se utiliza la función GDataCollector.init. Esta función recibe un parámetro inicial, que es un string, pudiendo ser 'sand' para entorno de pruebas o 'prod' para producción.
  1. <script type="text/javascript">
      var collector = null;
      var result;
      GDataCollector.init("sand", null, function (result) {
        collector = result;
        collector.setupCallback({
          // fires when collection has finished
          "collect-end": function (params) {
            console.log("collection has ended");
            console.log("SessionId", params.MercSessId);
            result = params.MercSessId;
          },
          // fires when collection has started.
          "collect-begin": function () {
            //console.log('collection has started');
          },
        });
        collector.collectData();
      });
    </script>
  1. Se debe obtener el valor en params.MercSessId. Este valor se utilizará en el objeto con los datos la tarjeta. 

2. Estructura de los datos

2.1 Crear el objeto JSON con los datos de la tarjeta

El objeto JSON que contiene los datos de la tarjeta debe seguir la siguiente estructura:
  1. {
      "card": {
        "cardHolder": "Nombre del titular de la tarjeta",
        "expirationDate": {
          "month": "número del mes, del 1 al 12",
          "year": "últimos dos dígitos del año"
        },
        "cardNumber": "Número_de_la_tarjeta",
        "cvc": "Código de seguridad de la tarjeta"
      },
      "tokenize": true,
      "kountSession": "sesión params.MercSessId generada por el datacollector"
    }

Parámetros obligatorios del JSON:
  1. cardHolder: String.  Nombre del titular de la tarjeta. Debe tener entre 5 y 50 caracteres. 
  2. month: INT. Mes de vencimiento de la tarjeta. Debe estar en el rango de 1 a 12.
  3. year: INT. Año de vencimiento de la tarjeta. Se espera un formato de dos dígitos correspondientes al año de vencimiento.
  4. cardNumber: String. Número de la tarjeta.
  5. CVC: String.  Código de seguridad de la tarjeta.
  6. kountSession: Es el valor params.MercSessId obtenido del Data Collector. 

Parámetros opcionales del JSON:

  1. tokenize: Boolean. Indica si se desea tokenizar la tarjeta después de realizar el pago. (true para tokenizar, false para no tokenizar).

Si el comercio utilizará tokens de tarjeta el objeto JSON deberá tener la siguiente estructura:


Ejemplo del JSON con la estructura para tokens:
  1. {
      "token": "token_obtenido_de_su_BD",
      "kountSession": "sesión params.MercSessId generada por el datacollector"
    }

1.2. Crear objeto JSON con los datos de la tarjeta para procesar con Credix

Para procesar con Credix, es necesario incluir parámetros adicionales en el objeto JSON bajo el nombre 'options', como se indica a continuación:"
  1. {
      "card": {
        "cardHolder": "Nombre del titular de la tarjeta",
        "expirationDate": {
          "month": "número del mes, del 1 al 12",
          "year": "últimos dos dígitos del año"
        },
        "cardNumber": "Número_de_la_tarjeta",
        "cvc": "Código de seguridad de la tarjeta"
      },
      "tokenize": true,
      "options": {
        "numberOfPayments": "3"
      },
      "kountSession": "sesión params.MercSessId generada por el datacollector"
    }

3. Cifrar el objeto tipo JSON que contiene la información de la tarjeta o el token.

Por motivos de seguridad tanto para GreenPay como para proteger su comercio, se requiere nviar la información de la tarjeta o el token encriptada. Para cifrar estos datos, se debe utilizar el algoritmo de encriptación “AES-CTR-128”.  

Si esta información no se cifra el algoritmo "AES-CTR-128" , el servicio de pagos rechazará la solicitud pago.

En el repositorio https://gitlab.com/gp-examples/checkout/checkout_csharp se encuentran ejemplos de cifrado con AES-CTR-128 desarrollados en C#. Uno de ellos se desarrolló sin librerías externas, mientras que otro utiliza la librería BouncyCastleAdemás, se proporciona otro ejemplo desarrollado en NodeJS utilizando la librería Aes JS .

A continuación, se detallan los pasos a seguir para cifrar la información de la tarjeta:

  1. Generar dinámicamente un par de llaves AES (Key , Counter), las cuales se utilizarán para cifrar la información de la tarjeta.
    • Cada llave es un arreglo de 16 bytes.
    • El key contiene la llave para cifrar en AES.
    • El Counter es utilizado para el modo CTR de AES.
  • Cifrar el objeto JSON que contiene los datos de la tarjeta y convertir el resultado del cifrado a formato hexadecimal.
    • El valor 'ld' que debe ser enviado en el body de la solicitud de pago, corresponde al string en formato hexadecimal obtenido al cifrar el objeto JSON con AES-CTR-128
  • Cifrar con RSA las llaves AES (key, counter) con la llave pública proporcionada por GreenPay.
    • El string en formato base64 obtenido el cifrar el par de llaves AES, corresponde al valor “lk” que se debe enviar en el “body” de la solicitud de pago.

A continuación se muestra un ejemplo en TypeScript/JavaScript, y las consideraciones para utilizarlo.
  1. Para generar el par de claves AES, se utiliza la biblioteca de JavaScript aes-js. A continuación, se presenta el código de ejemplo:
  1. function generateAESPairs() {
      let key = [];
      var iv = 0;
      for (let k = 0; k < 16; k++) {
        key.push(Math.floor(Math.random() * 255));
      }
      for (let k = 0; k < 16; k++) {
        iv = Math.floor(Math.random() * 255);
      }
      return {
        k: key,
        s: iv,
      };
    }
  1. Para encriptar los datos de la tarjeta se utiliza el algoritmo RSA con la biblioteca de JavaScript jsencrypt. A continuación se muestra un ejemplo:
  1. function pack(obj, session, pair_) {
      var pair = pair_ !== undefined ? pair_ : this.generateAESPairs();
      var textBytes = AesModule.utils.utf8.toBytes(JSON.stringify(obj));
      var aesCtr = new AesModule.ModeOfOperation.ctr(
        pair.k,
        new AesModule.Counter(pair.s)
      );
      var encryptedBytes = aesCtr.encrypt(textBytes);
      var encryptedHex = AesModule.utils.hex.fromBytes(encryptedBytes);
      var returnObj = {
        session: session,
        ld: encryptedHex,
        lk: this.rsa_.encrypt(JSON.stringify(pair)),
      };
      return returnObj;
    }

Los parámetros de la función son 'obj ' (el objeto con los datos de la tarjeta y el kountSession), 'session' (la sesión generada en la orden de compra) y pair_ (un undefined). La función retorna el objeto especificado en el siguiente punto : 

4. Crear un objeto JSON con los datos cifrados previamente.

Se debe crear un objeto JSON que contenga los resultados del proceso de cifrado anterior (lk, ld) y la sesión obtenida en el articulo "Crear una orden de pago"  , este JSON debe estar estructurado de la siguiente forma:


Ejemplo del JSON con la estructura de los datos cifrados
  1. {
      "session": "sesión obtenida en '1. Crear una orden de pago' ",
      "ld": "datos de la tarjeta o token cifrados con AES-CTR-128 en formato HEX",
      "lk": "Llaves AES cifradas con llave pública en formato base64"
    }


Parámetros del JSON:

  1. session: String con la sesión obtenida en la respuesta tras enviar una solicitud de creación de orden de pago.
  2. ld: String en formato HEX genrado al cifrar los datos de la tarjeta con AES-CTR-128.
  3. lk: String en formato BASE64 obtienido al cifrar las llaves AES con la llave pública dada por GreenPay Support team mediante RSA.

5. Enviar la solicitud de pago.

  1. Se debe enviar una solicitud HTTP de tipo POST al endpoint de pagos.
  2. El cuerpo de la solicitud debe contener un objeto JSON con los datos cifrados y la sesión obtenida previamente.
  3. Se debe agregar el header “liszt-token” a la solicitud, con el token obtenido en la solicitud de creación de la orden de pago. Puede ver el siguiente ejemplo.
  4. Tras enviar la solicitud de pago con éxito, recibirás un objeto JSON como respuesta.
  5.  De este objeto JSON, el parámetro a obtener es "body", que contiene la respuesta del pago.
En la siguiente imagen se muestra un ejemplo de la respuesta que se recibe después de enviar una solicitud de pago:

Ejemplo del HTTP Response obtenida del API
  1. {
      "statusCode": 200,
      "body": {
        "status": 200,
        "orderId": "xwr-123455",
        "authorization": "533793",
        "last4": "7777",
        "brand": "Visa",
        "result": {
          "time_local_tran": "165407",
          "systems_trace_audit_number": "000283",
          "success": true,
          "retrieval_ref_num": "701016540713",
          "resp_code": "00",
          "reserved_private4": null,
          "proc_code": "000000",
          "network_international_id": "0003",
          "mti": "0210",
          "merchant_id": 485,
          "date_local_tran": "0110",
          "card_acceptor_terminal_id": "00112478",
          "authorization_id_resp": "533793"
        },
        "errors": [],
        "_signature": "2e9d23b194905314561b8c750f7a74447aa7ce262c9c4d4589a26bc8aad046bce455f5ab2bfb5c9e5e75da2030550b91627d4020c82e5b"
      },
      "headers": {
        "...": "..."
      },
      "request": {
        "uri": {
          "...": "..."
        },
        "method": "post",
        "headers": {
          "...": "..."
        }
      }
    }
 
Ejemplo del HTTP Response checkout con tokenización
  1. {
      "status": 200,
      "orderId": "TEST  1",
      "authorization": "533793",
      "amount": 1,
      "currency": "CRC",
      "result": {
        "time_local_tran": "165407",
        "systems_trace_audit_number": "000283",
        "success": true,
        "retrieval_ref_num": "701016540713",
        "resp_code": "00",
        "reserved_private4": null,
        "proc_code": "000000",
        "network_international_id": "0003",
        "mti": "0210",
        "merchant_id": 1280,
        "date_local_tran": "0110",
        "card_acceptor_terminal_id": "00112478",
        "authorization_id_resp": "533793"
      },
      "errors": [],
      "callback": null,
      "_signature": "4899d010ded0a9538fb131a588bc81cd0e1b0c614ce7e28932c7abd8870f913c374f2af86b7aefff490",
      "last4": "4242",
      "brand": "Visa",
      "tokenizeResp": {
        "status": 201,
        "requestId": "TEST  1",
        "result": {
          "token": "c833e9db-2c0c-4a41-9be9-5253f7d5daf2",
          "last_digits": "4242",
          "khash": "424242HEQ9IFOU6WIPLI",
          "bin": "424242"
        },
        "expiration_date": "2209",
        "brand": "Visa",
        "nickname": "Visa-4242",
        "cardHolder": "Jhon Doe",
        "errors": [],
        "_signature": "3896228bc4bd29b62f84793e9ed78392cd6c70b833f4910eb72273aaaa54d75d08a050f2"
      }
    }

El siguiente ejemplo en JavaScript muestra cómo enviar una solicitud al endpoint de pago y cómo esta función también recupera el "body" del objeto JSON recibido como respuesta
  1. var data = {
      session: "sesión obtenida en '1. Crear una orden de pago' ",
      ld: "datos de la tarjeta cifrados con AES-CTR-128 en formato HEX",
      lk: "Llaves AES cifradas con llave pública en formato base64",
    };

    var unirest = require("unirest");
    //Pays the order creates in GreenPay gateway
    function postCheckout(data, accessToken) {
      return new Promise(function (resolve, reject) {
        unirest
          .post(process.env.CHECKOUT_ENDPOINT)
          .headers({
            Accept: "application/json",
            "Content-Type": "application/json",
            "liszt-token": "accessToken",
          })
          .send(data)
          .end(function (response) {
            if (response.status === 200) {
              console.log("checkout", JSON.stringify(response));
              resolve(response.body);
            } else {
              reject(response.body);
            }
          });
      });
    }


Con la respuesta obtenida, el comercio deberá actualizar la compra del cliente respectivo.



    • Related Articles

    • Crear orden de pago

      Consideraciones La orden de pago se genera para indicar al API de pago que se realizará una transacción, basándose en los datos proporcionados en la orden. Para esto, se debe considerar lo siguiente: Utilizar el servicio en los endpoints: En sandbox: ...
    • Actualizar método de pago

      Para este servicio se debe consumir el siguiente endpoint: https://sandbox-merchant.greenpay.me/subscriptions/update/card_token A continuación, se muestra el paso a paso para cancelar una suscripción en nuestro API de forma exitosa: 1. Crear el ...
    • Respuesta de pago en webhook

      1. Descripción Si el comercio require recibir las respuesta de los pagos o tokenización de tarjetas en un backend, ya sea, para actualizar pedidos, información o simplemente almacenar la respuesta en base de datos como respaldo, entonces debe ...
    • Pago Manual

      Para este servicio se debe consumir el siguiente endpoint: https://sandbox-merchant.greenpay.me/subscriptions/pay A continuación, se muestra el paso a paso para ejecutar un pago manual de una suscripción en nuestro API de forma exitosa: 1. Crear el ...
    • Proceso de pago con Widget

      Consideraciones Al utilizar el widget de pago de Greenpay, es importante tener en cuenta lo siguiente: Es necesario disponer de una cuenta de sandbox o de producción. Para obtener esta cuenta, visite la sección Sobre cuenta de pruebas o sandbox. El ...