¿Cómo funciona el proceso de firmado?
- Para validar que la información sea enviada desde la persona que corresponda, esta se verifica a través de una firma generada por el algoritomo HMAC SHA256.
- Para generar esta firma se necesita una Clave Electrónica Token Secret que es generada al crear el servicio en Pago Fácil.
- Como bien dice su nombre, esta clave ES SECRETA y no debe ser compartida con nadie, ya que esto podría causar que la información del estado de la transacción no sea fidedigna hacia el comercio.
- Este proceso no es complejo pero es importante seguir los pasos en orden para que no se vuelva frustrante.
Proceso de Firmado
- Se debe de obtener un arreglo con todas las variables que comiencen con x_ desde el body del POST
- Este arreglo se debe de ordenar de manera alfabética.
- Una vez obtenido el arreglo, se crea un string con todas las variables y sus valores concatenados.
- El string resultante se firma con el algoritmo SHA256 mencionado anteriormente.
Ejemplos de código para firmado
Los siguientes códigos no ignoran objetos;por lo que, se le deben pasar sólo los parámetros de la transacción que figuran como obligatorios.
const crypto = require('crypto');
function signPayload(payload, secret, prefix = "x_", signature = "signature") {
//El arreglo SIEMPRE debe de estar ordenado antes de firmar.
let sortedArray = Object.entries(payload).sort();
let payloadFirmado = "";
let firma = prefix + signature;
let mensaje = "";
for (let index = 0; index < sortedArray.length; index++) {
console.log(sortedArray[index]);
if (sortedArray[index][0] != firma) {
mensaje += sortedArray[index][0] + sortedArray[index][1];
}
}
let hmac = crypto.createHmac('sha256', secret);
hmac.setEncoding('hex');
hmac.write(mensaje);
hmac.end();
payloadFirmado = hmac.read();
return payloadFirmado;
}
const crypto = require('crypto-js');
function signPayload(payload, secret, prefix = "x_", signature = "signature") {
//El arreglo SIEMPRE debe de estar ordenado antes de firmar.
let sortedArray = Object.entries(payload).sort();
let payloadFirmado = "";
let firma = prefix + signature;
let mensaje = "";
for (let index = 0; index < sortedArray.length; index++) {
console.log(sortedArray[index]);
if (sortedArray[index][0] != firma) {
mensaje += sortedArray[index][0] + sortedArray[index][1];
}
}
let hash = crypto.HmacSHA256(mensaje, secret);
payloadFirmado = hash.toString(crypto.enc.Hex);
return payloadFirmado;
}
def sign(fields, [email protected])
Digest::HMAC.hexdigest(fields.sort.join, key, Digest::SHA256)
end
function firmarArreglo($arreglo) {
//Ordeno Arreglo
ksort($arreglo);
//Concateno Arreglo
$mensaje = $this->concatenarArreglo($arreglo);
//Firmo Mensaje
$mensajeFirmado = $this->firmarMensaje($mensaje, $this->ct_token_secret);
//Guardo y retorno el mensaje firmado
$this->ct_firma = $mensajeFirmado;
return $mensajeFirmado;
}
function firmarMensaje($mensaje, $claveCifrado) {
$mensajeFirmado = hash_hmac('sha256', $mensaje, $claveCifrado);
return $mensajeFirmado;
}
public function concatenarArreglo($arreglo) {
$resultado = "";
foreach ($arreglo as $field => $value) {
$resultado .= $field . $value;
}
return $resultado;
}
<?php
require_once(__DIR__ . '/vendor/autoload.php');
use PSTPagoFacil\SignatureHelper; //using Pago Fácil SignatureHelper Library
$tokenService = 'TOKEN_SERVICE'; // put your Token Service here
$tokenSecret = 'TOKEN_SECRET'; // put your Token Secret here
$x_reference = (int) microtime(true); //Just a random number as an example
$x_session_id = (int) microtime(true); //Just a random number as an example
$sHelper = new SignatureHelper($tokenSecret);
// Building the trx
$trxBody = [
"x_account_id"=> $tokenService,
"x_amount"=> 1000,
"x_currency"=> "CLP",
"x_reference"=> $x_reference,
"x_customer_email"=> "[email protected]",
"x_url_complete"=> "https://postman-echo.com/post",
"x_url_cancel"=> "https://postman-echo.com/post",
"x_url_callback"=> "https://postman-echo.com/post",
"x_shop_country"=> "CL",
"x_session_id"=> "$x_session_id"
];
// Signing trx with
$firma = $sHelper->signPayload($trxBody);
$x_signature = $sHelper->signPayload($trxBody);
$trxBody["x_signature"] = $x_signature;
// Posting Signed trx with Pago Fácil SignatureHelper Library
$payload = json_encode($trxBody);
// print_r($payload); //payload ready to be sent
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://apis-dev.pgf.cl/trxs",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => $payload,
CURLOPT_HTTPHEADER => [
"Accept: application/json",
"Content-Type: application/json"
],
]);
// Requesting the Response
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
$jsonResponse = json_decode($response);
print_r ($jsonResponse); //here you can see the JSON Response Object
/* 0 gateway
1 webpay
2 khipu max 5mm
3 multicaja error
4 pago 46
5 mach
*/
// $url = $jsonResponse->data->payUrl[0]->url; // here you choose your payUrl
// echo $url,"\n\n";
}
import requests
import hashlib
import hmac
import json
import time
import webbrowser
import tokens
import pprint
encoding = 'utf-8'
x_account_id = tokens.tokenServiceDev #Put your Token Service
x_amount = str(b'1000', encoding)
x_currency = str(b'CLP', encoding)
x_reference = str(time.time()) #Just a random number as an example
x_customer_email = str(b'[email protected]', encoding)
x_url_complete = str(b'https://www.pagofacil.cl', encoding)
x_url_cancel = str(b'https://www.pagofacil.cl', encoding)
x_url_callback = str(b'https://callback.domain.com', encoding)
x_shop_country = str(b'CL', encoding)
x_session_id = str(b'1', encoding) #Just a random number as an example
object='x_account_id'+x_account_id+'x_amount'+x_amount+'x_currency'+x_currency+'x_customer_email'+x_customer_email+'x_reference'+x_reference+'x_session_id'+x_session_id+'x_shop_country'+x_shop_country+'x_url_callback'+x_url_callback+'x_url_cancel'+x_url_cancel+'x_url_complete'+x_url_complete
payload = object.encode('utf-8')
key = tokens.tokenSecretDev #Put your Token Secret
# Generate the hash.
signature = hmac.new(key,payload,hashlib.sha256).hexdigest()
x_signature = signature
url = tokens.dev # Put the Enviroment Endpoint (dev or Prod)
payload = {
'x_account_id' : x_account_id ,
'x_amount' : int(x_amount),
'x_currency' : x_currency,
'x_reference' : x_reference ,
'x_customer_email' : x_customer_email,
'x_url_complete' : x_url_complete,
'x_url_cancel' : x_url_cancel,
'x_url_callback' : x_url_callback ,
'x_shop_country' : x_shop_country,
'x_session_id' : x_session_id,
'x_signature' : x_signature
}
jpayload = json.dumps(payload)
headers = {
'accept': "application/json",
'content-type': "application/json"
}
response = requests.request("POST", url, data=jpayload, headers=headers)
"""
0 gateway
1 webpay
2 khipu max 5mm
3 multicaja
4 pago 46
5 mach
"""
chosenPayUrl = response.json()['data']['payUrl'][0]['url'] # here you choose your payUrl
pprint.pprint(response.json())#Here you can see the response
webbrowser.open(chosenPayUrl)
Author
- Luis Marcelo Poblete Sandoval (Collaborator)
Updated 11 months ago