Zenki
Zenki Principal Habilitar modo claro/oscuro Habilitar modo claro/oscuro Habilitar modo claro/oscuro Regresar a la página principal

Datos de compra

¿Qué es la firma digital?

Las firmas digitales son una herramienta criptográfica que proporciona una prueba de autenticidad para los mensajes digitales o documentos electrónicos. Las firmas digitales proporcionan:

Autenticación: Prueba de que el remitente ha creado y firmado el mensaje.

Integridad de los mensajes: Prueba de que el mensaje no fue alterado después de la firma.

No repudio: El emisor de la firma no puede negar la firma del documento una vez generada la firma.

El parámetro ‘purchaseData’

Cuando el comprador confirma el pago con Zenki, su sitio web envía la información del pedido a nuestros servidores. Esta información se envía en formato JSON en una sección llamada “purchaseData”. El formato de los datos que debe enviar se detalla a continuación.

Estructura de datos de compra

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
{
  "version": "v1.1.0",
  "country": "US",
  "shopperCartId": "l93hyghr9hojqinx",
  "merchantOrderId": "l93hyghr4yty9jgm",
  "shopperEmail": "hello@zenki.fi",
  "purchaseSummary": {
    "currency": "USD",
    "totalItemsAmount": "0.5",
    "shipmentAmount": "0.25",
    "subtotalAmount": "0.75",
    "taxesAmount": "0.125",
    "localTaxesAmount": "0.125",
    "importCosts": "0.125",
    "discountAmount": "0.25",
    "additionalCharges": {
      "perquisite": "0.125"
    },
    "grandTotalAmount": "1"
  },
  "serviceType": "SERVICE",
  "items": [
    {
      "itemId": "l93hyghr5hp3lxcp",
      "price": "0.5",
      "quantity": "1",
      "productName": "Javascript",
      "thumbnailUrl": "https://tshirts.boutique/wp-content/uploads/2022/09/12124-65.jpg",
      "metadata": {
        "size": "L"
      }
    }
  ],
  "zenkipayKey": "e77e5b666253243e9179ff4d33fe364ec88aacf9240e5e7673e474255e4a900c",
  "metadata": {
    "anotherId": "l93hyghrcjs78929"
  }
}

Campos de datos de compra:

Campo Descripción Formato Requerido
version Versión del modelo de datos, su valor actual debe ser v1.1.0 String Si
country País donde se realizó la compra String Si
shopperCarId El identificador de la cesta de la compra de tu tienda String No
merchantOrderId Identificador de la orden de compra de tu tienda String No
shopperEmail Email del comprador, para autocompletado String No
serviceType Define si la orden es un bien/producto, un servicio o una combinación de ambos SERVICE_TYPE No
purchaseSummary Detalle de los montos que conforman la compra Object (JSON) Si
items Lista de artículos que componen el pedido Lista de Object (JSON) Si
zenkipayKey Clave única de cada comercio String Si
metadata Metadatos relacionados con el pedido Object (JSON) No

SERVICE_TYPE

La propiedad serviceType puede tener cualquiera de los siguientes valores:

  • GOOD Es el valor por defecto, cuando está seleccionado hace referencia a que el pago de la orden es por un bien/producto.
  • SERVICE Cuando está seleccionado hace referencia a un servicio o producto digital que no requiere de ningún tipo de envío.
  • HYBRID Es una combinación de GOOD y SERVICE, en caso que la orden contemple tanto un bien/producto como un servicio.

Campos del atributo purchaseSummary

Campo Descripción Formato Requerido
currency Moneda con la que se realiza el pago String Si
totalItemsAmount Suma del total del costo de los items Number Si
shipmentAmount Costo de envío, en caso de no aplicar su valor debe ser 0 Number Si
subtotalAmount Suma del totalItemsAmount más shipmentAmount Number Si
taxesAmount Impuestos, en caso de no aplicar su valor debe ser 0 Number Si
localTaxesAmount Impuestos locales, en caso de no aplicar su valor debe ser 0 Number Si
importCosts Costos de importación, en caso de no aplicar su valor debe ser 0 Number Si
additionalCharges Cargos adicionales, se compone de un objeto llave/valor que comprende la descripción del cargo/el monto respectivamente Object (JSON) No
discountAmount Descuento de tu comercio, en caso de no aplicar su valor debe ser 0 Number Si
grandTotalAmount Suma de subtotalAmount, taxesAmount, localTaxesAmount, importCosts y cada valor de additionalCharges menos discountAmount Number Si

Campos de atributo items:

Campo Descripción Formato Requerido
itemId Identificador del artículo String No
quantity Número de artículos del pedido Number Si
price Precio total de los artículos Number Si
productName Nombre corto del producto String Si
productDescription Descripción del producto String No
thumbnailUrl URL de la imagen del producto (miniatura) String No
metadata Metadatos relacionados con el artículo Object (JSON) No

¿Cómo firmar los datos de mi pedido?

Utilizando su clave privada RSA, debe firmar digitalmente la información del pedido de la siguiente manera:

1
2
3
4
5
6
7
# Esto es sólo un ejemplo de pseudocódigo
# Deberas aplicarlo de acuerdo a
# tu lenguaje de programación de back-end.

privateKey = readPrivateKeyFile(PATH + PrivateKeyFile)
orderBytes = orderJsonString.readBytes(UTF-8)
orderSignature = rsaSha256SignerLibrary.sign(privateKey, orderBytes)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
const { sign } = require("crypto");
const { existsSync, readFileSync } = require("fs");
const { resolve } = require("path");

(function main() {
  const purchaseData = JSON.stringify({
    version: "v1.1.0",
    country: "US",
    shopperCartId: "l93hyghr9hojqinx",
    merchantOrderId: "l93hyghr4yty9jgm",
    shopperEmail: "hello@zenki.fi",
    purchaseSummary: {
      currency: "USD",
      totalItemsAmount: "0.5",
      shipmentAmount: "0.25",
      subtotalAmount: "0.75",
      taxesAmount: "0.125",
      localTaxesAmount: "0.125",
      importCosts: "0.125",
      discountAmount: "0.25",
      additionalCharges: {
        perquisite: "0.125",
      },
      grandTotalAmount: "1",
    },
    serviceType: "SERVICE",
    items: [
      {
        itemId: "l93hyghr5hp3lxcp",
        price: "0.5",
        quantity: "1",
        productName: "Javascript",
        thumbnailUrl:
          "https://tshirts.boutique/wp-content/uploads/2022/09/12124-65.jpg",
        metadata: {
          size: "L",
        },
      },
    ],
    zenkipayKey:
      "e77e5b666253243e9179ff4d33fe364ec88aacf9240e5e7673e474255e4a900c",
    metadata: {
      anotherId: "l93hyghrcjs78929",
    },
  });
  console.log("\nPurchase data stringified:\n%s", purchaseData);
  const zenkipaySignature = signPurchaseData(purchaseData);
  console.log("\nZenkipay signature:\n%s", zenkipaySignature);

  process.exit();
})();

function signPurchaseData(purchaseData) {
  const privateKey = getPrivateKey();
  const signature = sign("sha256", Buffer.from(purchaseData), {
    key: privateKey,
  });
  return signature.toString("base64");
}

function getPrivateKey() {
  const filepath = resolve(__dirname, "keys", "private.pem");
  if (existsSync(filepath)) {
    return readFileSync(filepath, { encoding: "utf-8" });
  }
  throw new Error(`Key not found: ${filepath}`);
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/**
 * @param string $purchase_data
 *
 * @return string
 */
public function generateSignature($purchase_data)
{
  $private_key_file = file_get_contents('/path/to/the/private-key.pem');
  $private_key = openssl_pkey_get_private($private_key_file);
  openssl_sign($purchase_data, $signature, $private_key, 'RSA-SHA256');
  return base64_encode($signature);
}

/**
 * @param string $purchase_data
 * @param string $signature
 *
 * @return boolean Returns TRUE if the signature is correct, FALSE if it's incorrect
 */
public function verifySignature($purchase_data, $signature)
{
  $public_key_file = file_get_contents('/path/to/the//public-key.pem');
  $public_key = openssl_pkey_get_public($public_key_file);
  $decoded_siganture = base64_decode($signature);
  $verify = openssl_verify($purchase_data, $decoded_siganture, $public_key, 'RSA-SHA256');
  return $verify == 1;
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;

/**
 * Fragmento para firmar el mensaje con <strong>Clave privada PKCS #8 </strong>.
 * <p><strong>Nota: </strong></p> Puede que sea necesario realizar cambios si su clave privada está en un formato diferente al de <strong>PKCS #8</strong>.
 */
public class ZenkiSnippet {
    private static final String BEGIN_PRIVATE_KEY = "-----BEGIN PRIVATE KEY-----";
    private static final String END_PRIVATE_KEY = "-----END PRIVATE KEY-----";
    private static final String EMPTY_STRING = "";
    private static final String BREAK_LINE = "\n";

    /**
     * Ejemplo de formato de clave privada base64 (<strong>PKCS #8</strong>).
     **/
    private static final String BASE_64_PRIVATE_KEY = "-----BEGIN PRIVATE KEY-----\n" +
            "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\n" +
            "-----END PRIVATE KEY-----";

    /**
     * Ruta de acceso al archivo de clave privada de muestra (<strong>PKCS #8</strong>).
     **/
    private static final String PRIVATE_KEY_FILE_PATH = "/path/to/my/file";

    // Ejemplo de datos de compra JSON.
    private static final String JSON_PURCHASE_DATA = "{\"version\":\"v1.1.0\",\"country\":\"US\",\"shopperCartId\":\"l93hyghr9hojqinx\",\"merchantOrderId\":\"l93hyghr4yty9jgm\",\"shopperEmail\":\"hello@zenki.fi\",\"purchaseSummary\":{\"currency\":\"USD\",\"totalItemsAmount\":\"0.5\",\"shipmentAmount\":\"0.25\",\"subtotalAmount\":\"0.75\",\"taxesAmount\":\"0.125\",\"localTaxesAmount\":\"0.125\",\"importCosts\":\"0.125\",\"discountAmount\":\"0.25\",\"additionalCharges\":{\"perquisite\":\"0.125\"},\"grandTotalAmount\":\"1\"},\"serviceType\":\"SERVICE\",\"items\":[{\"itemId\":\"l93hyghr5hp3lxcp\",\"price\":\"0.5\",\"quantity\":\"1\",\"productName\":\"Javascript\",\"thumbnailUrl\":\"https:\/\/tshirts.boutique\/wp-content\/uploads\/2022\/09\/12124-65.jpg\",\"metadata\":{\"size\":\"L\"}}],\"zenkipayKey\":\"e77e5b666253243e9179ff4d33fe364ec88aacf9240e5e7673e474255e4a900c\",\"metadata\":{\"anotherId\":\"l93hyghrcjs78929\"}}";

    public static void main(String[] args) throws IOException, InvalidKeySpecException, NoSuchAlgorithmException, SignatureException, InvalidKeyException {

        System.out.println("Signature: " + signMessageWithPkFromFile()); // Snippet to sing message getting private key from file.
        System.out.println("Signature: " + signMessageWithPkBase64()); // Snippet to sing message getting private key from base64 string.
    }

    public static String signMessageWithPkFromFile() throws IOException, InvalidKeySpecException, NoSuchAlgorithmException, SignatureException, InvalidKeyException {
        PrivateKey privateKey = getPKFromFile();
        Signature signatureProvider = Signature.getInstance("SHA256withRSA");
        signatureProvider.initSign(privateKey); // Private key
        signatureProvider.update(JSON_PURCHASE_DATA.getBytes()); // Message to sign (in bytes)

        byte[] signature = signatureProvider.sign(); // Signature

        return Base64.getEncoder().encodeToString(signature); // Signature encoded in base64
    }

    public static String signMessageWithPkBase64() throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException, SignatureException {
        PrivateKey privateKey = getPKFromBase64String();

        Signature signatureProvider = Signature.getInstance("SHA256withRSA");
        signatureProvider.initSign(privateKey); // Private key
        signatureProvider.update(JSON_PURCHASE_DATA.getBytes()); // Mensaje a firmar (en bytes)

        byte[] signature = signatureProvider.sign(); // Signature

        return Base64.getEncoder().encodeToString(signature); // Firma codificada en base64
    }

    private static PrivateKey getPKFromFile() throws IOException, InvalidKeySpecException, NoSuchAlgorithmException {
        byte[] privateKey = Files.readAllBytes(Paths.get(PRIVATE_KEY_FILE_PATH)); // Getting file from filesystem

        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKey, "RSA");
        KeyFactory kf = KeyFactory.getInstance("RSA");
        return kf.generatePrivate(keySpec);
    }

    private static PrivateKey getPKFromBase64String() throws NoSuchAlgorithmException, InvalidKeySpecException {
        String formattedKeyString = removePrivateKeyHeaders(BASE_64_PRIVATE_KEY);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(formattedKeyString), "RSA");
        KeyFactory kf = KeyFactory.getInstance("RSA");
        return kf.generatePrivate(keySpec);
    }

    private static String removePrivateKeyHeaders(String keyString) {
        return keyString
                .replace(BREAK_LINE, EMPTY_STRING)
                .replace(BEGIN_PRIVATE_KEY, EMPTY_STRING)
                .replace(END_PRIVATE_KEY, EMPTY_STRING);

    }
}

Comprobación de las firmas

Para que pueda validar que la implementación para la firma de sus órdenes de compra es correcta, utilice la siguiente clave privada y la información de la orden proporcionada a continuación para validar que su código produce la misma firma digital.

Private Key:

1
2
3
-----BEGIN PRIVATE KEY-----
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
-----END PRIVATE KEY-----

Datos de la compra como cadena de texto:

1
{"version":"v1.1.0","country":"US","shopperCartId":"l93hyghr9hojqinx","merchantOrderId":"l93hyghr4yty9jgm","shopperEmail":"hello@zenki.fi","purchaseSummary":{"currency":"USD","totalItemsAmount":"0.5","shipmentAmount":"0.25","subtotalAmount":"0.75","taxesAmount":"0.125","localTaxesAmount":"0.125","importCosts":"0.125","discountAmount":"0.25","additionalCharges":{"perquisite":"0.125"},"grandTotalAmount":"1"},"serviceType":"SERVICE","items":[{"itemId":"l93hyghr5hp3lxcp","price":"0.5","quantity":"1","productName":"Javascript","thumbnailUrl":"https://tshirts.boutique/wp-content/uploads/2022/09/12124-65.jpg","metadata":{"size":"L"}}],"zenkipayKey":"e77e5b666253243e9179ff4d33fe364ec88aacf9240e5e7673e474255e4a900c","metadata":{"anotherId":"l93hyghrcjs78929"}}

Zenkipay signature:

1
PsFEJpunOmvPmOiRyfyBWnrKpsZ4FNSSTp1s6rCIvV6YIe+tJC7RxwgXgaVVMJHikyMjJXuZIiIB0lSs0nPe0ln50hDAk+IFz6j06wEbj7rzG4ZLQMOYaHFnNLjO/KQlxm6IUhhkZ5LtbaKChOw7+VOTM0fJBlvtWlVxl0TYS3qc2JOvY2f5/3892hKus+Qj3sSX56Y6xaHv0hHvV7MZlP9Mnvlg/AYlh03MukpvhRiIPfdOQeknWYwNuU6OZjNeO782bEbi7c8wKB3m3Ckjh+WkJ+l2nJyU6tHFBg3Lyg28xy6wWf+UfoyHBx2kHTVzrP5i0ybQPNEl0Gb95ORTb61UoZCnXDrVD4SRxHFd//V0qN1eT233hgof65eAAHu0k+t0OVJWuVrfk2olHlFBDo1DTyhiwAmX74o57a+8YxdrmMbxRmuVTb8iXrtcihxcsLINC1FhT3QfQdXDhpS+WYILcgpQ0SRFHKCAHP6HjFG6T2hO4NnG6rNut6DsjWCIZI8MJdZSMYDQ+n7wJ63jzKGc1NW83U5cUWtZhhBwUo221U9/3XXMBb3bnY8Ej5gHreRodXCyOowjutP+XICwevvuJa4BAEYJ6DJmqxWBL1pBcNKoLTtGqYzXJg1HFZ2qPzdR9jZSsk15q+Wg/BlRXaeIe0WA495w1FwPS+SRjU0=

Puedes continuar con integración con tu servidor.