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 utiliza Greenpay para recolectar información asociada a la transacción con el fin de analizar comportamientos de fraude. Para incluir el data collector en las transacciones se debe hacer lo siguiente.
  1. Incluir el script del data collector.
    <script src="https://static.greenpay.me/collector/1.0.1/GDataCollector.min.js"></script>
  2. Iniciar el Data collector. El GDataCollector.init recibe en el primer parámetro un string, que puede ser 'sand' o 'prod', para sandbox o producción respectivamente.
    <script>
    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>
  3. 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 objeto json con lo datos de la tarjeta

El objeto json con los datos de la tarjeta debe tener la siguiente estructura.

{
"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 del nombre del dueño de la tarjeta.
  2. month: De tipo INT. Número que indica el mes de vencimiento de la tarjeta, este parámetro debe tener cifras entre 1 y 12.
  3. year: De tipo INT. Número que indica el año de vencimiento de la tarjeta, este parámetro debe tener cifras de 2 dígitos, los últimos 2 dígitos del año en que vence la tarjeta.
  4. cardNumber: String del número de la tarjeta
  5. cvc: String del código de seguridad de la tarjeta.
  6. kountSession: Es el valor params.MercSessId que se obtienen del data collector (Ver la sección de consideraciones en el punto C).

Parámetros opcionales del JSON:

  1. tokenize: De tipo Boolean. Parámetro que indica si se desea tokenizar la tarjeta después de realizar el pago. (true = tokeniza, false= no tokeniza).

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


Ejemplo del JSON con la estructura para tokens

{
"token":"token_obtenido_de_su_BD",
   "kountSession" :"sesión params.MercSessId generada por el datacollector"
}

1.2. Crear objeto json con lo datos de la tarjeta para procesar con Credix

Cuando se vaya a procesar con Credix, se tiene que agregar otro parámetros al json llamado options, como se muestra a continuación.


{
"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 razones de seguridad, tanto para GreenPay como para proteger su comercio se requiere que la información de la tarjeta o el token se envié encriptada. Para cifrar estos datos, se debe utilizar el algoritmo de encriptación “AES-CTR-128”, si esta información no se cifra con este algoritmo, el servicio de pagos rechazará la solicitud pago.

En https://gitlab.com/gp-examples/checkout/checkout_csharp se encuentran unos ejemplos de cifrado con AES-CTR-128 desarrollados en C#, uno se desarrolló sin librerías externas y otro utiliza la librería “BouncyCastle”. Además de otro desarrollado en NodeJS con la librería Aes JS .

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

  • 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 el contador para el modo CTR de AES.
  • Cifrar el objeto JSON con los datos de la tarjeta, y convertir el resultado del cifrado a formato hexadecimal.
    • El string en formato hexadecimal corresponde al valor “ld” que se debe enviar en el “body” de la solicitud de pago
    • El valor “ld” que debe enviar en el body de la solicitud de pago, corresponde al string en formato hexadecimal que se obtiene al cifrar el objeto JSON que contiene la información de la tarjeta con AES-CTR-128
  • Cifrar con RSA las llaves AES (key, counter) con la llave pública provista por “GreenPay support team”.
    • El string en formato base64 que se obtiene de cifrar el par de llaves AES, corresponde al valor “lk” que se debe enviar en el “body” de la solicitud de pago.
    • El valor “lk” que se debe enviar en el body de la solicitud de pago corresponde a la codificación en base64 del cifrado de las llaves AES.


A continuación se muestra consigo 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, y el código de ejemplo siguiente:
    public 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
    }
    }
  2. Para encriptar los datos de la tarjeta se utiliza el algoritmo RSA con la biblioteca de JavaScript jsencrypt,  y el código de ejemplo siguiente:
    Los parámetros de la función son obj (el objeto con los datos de la tarjeta y el kountSession), session (la sesión que se genera en la orden de compra) y pair_ (un undefined). La función retorna el objeto especificado en el siguiente punto Crear un objeto de tipo JSON con los datos cifrado anteriormente.

    public 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;
    }

4. Crear un objeto de tipo JSON con los datos cifrados anteriormente.

Se debe crear un objeto de tipo 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

{
"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 el body de la respuesta del envío de una solicitud de creación de una orden de pago.
  2. ld: String en formato HEX que se obtiene al cifrar los datos de la tarjeta con AES-CTR-128.
  3. lk: String en formato BASE64 que se obtiene al cifrar las llaves AES con la llave pública provista por GreenPay Support team. Este cifrado se realiza con RSA.

5. Enviar la solicitud de pago.

Se debe enviar una solicitud HTTP de tipo POST al endpoint de pagos con el objeto json que contiene los datos cifrados y la sesión obtenida en el paso anterior, este JSON se envía en el cuerpo de la solicitud.

A esta solicitud se le debe agregar el header “liszt-token”, este header debe contener el token obtenido en la solicitud de creación de una orden de pago.

Una vez se ha enviado la solicitud de pago y esta se haya realizado con éxito, se obtiene un objeto de tipo JSON como respuesta.

Al recibir esta respuesta, el parámetro a obtener del objeto JSON es el “body”, ya que este 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
{
"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": [],
"callback": "http://yourcallback.url/getcheckoutform/response",
"_signature": "2e9d23b194905314561b8c750f7a74447aa7ce262c9c4d4589a26bc8aad046bce455f5ab2bfb5c9e5e75da2030550b91627d4020c82e5b
a55f6c7ac4b692b8191655f17831b2bca8bf85eade12d5918bcd9b10fe41bfc1f9115baf6c3b9de13cac7170e350bcc4a46bb58d2abc18396c8377b5e5544809aa
41beab114d717ec6"
},
"headers": {
"...": "..."
},
"request": {
"uri": {
"...": "..."
},
"method": "post",
"headers": {
"...": "..."
}
}
}

 
Ejemplo del HTTP Response checkout con tokenización
{
"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": "4899d010ded0a9538fb131a588bc81cd0e1b0c614ce7e28932c7abd8870f913c374f2af86b7aefff490bcd728ee535e3ff1dee0f3f10b282fda102321acd1db665c6dc8af6c48a01b2d38d9f2c86a6
75a6de86deb1caec7402ea1b468f337df01bc22ef0bf64f6df9b032e79bed75a9827455bfe3559715807be47716ecd4ec9",
"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": "3896228bc4bd29b62f84793e9ed78392cd6c70b833f4910eb72273aaaa54d75d08a050f2b2195451b0428e4cf85afa51e0985e4ba75e0363ea86633e9bcf9f5846c504f76abf96f5b0d988e
042d5a59107192798bd520847f6665e98d7e34bfe27c917ed53562a936b80e13356e230b0ac3361f1e826cc2f32f1c79f2aa6cd40"
}
}


A continuación, se muestra un ejemplo en javascript del envío de la solicitud al endpoint de pago. Esta función también obtiene el “body” del objeto tipo JSON que se recibe como respuesta.

Ejemplo de código para enviar el request

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 Una orden de pago se crea para indicar al API de pago que se efectuará una transacción por el motivo de los datos indicados en la orden. Para esto se debe tener las siguientes consideraciones: Utilizar el servicio en los endpoints: En ...
    • 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 ...
    • Proceso de pago con Widget

      En esta sección se muestra una guía paso a paso de cómo integrarse al servicio de pagos por medio del widget. Para utilizar esta funcionalidad es necesario haber creado una orden de pago, para crear la orden pago puede revisar el articulo "Crear una ...
    • 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 ...