Zenki
Zenki Home Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

Purchase Data

What are digital signatures?

Digital signatures are a cryptographic tool to provide proof of authenticity for digital messages or electronic documents. Digital signatures provide:

Authentication: Proof that the sender has created and signed the message.

Мessage integrity: Proof that the message was not altered after the signing.

Non-repudiation: Signer cannot deny the signing of the document after the signature is created.

The ‘purchaseData’ parameter

When the shopper confirms the payment with Zenki, your website sends the order information to our servers. This information is sent in JSON format in a section called ‘purchase data’. The format of the data you must send is detailed below.

Purchase Data structure

 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"
  }
}

Purchase data fields:

Field Description Format Required
version Version of the data model, the current value must be v1.1.0 String Yes
country Country where the purchase was made String Yes
shopperCarId Your store’s shopping cart identifier String No
merchantOrderId Identifier of the purchase order of your store String No
shopperEmail Shopper email, used to autocomplete field String No
serviceType Defines if the order is a good/product, a service or a combination of both SERVICE_TYPE No
purchaseSummary Detail of the quantities that make up the purchase Object (JSON) Yes
items List of items that make up the order Object (JSON) list Yes
zenkipayKey Unique key of each merchant String Yes
metadata Order related metadata Object (JSON) No

SERVICE_TYPE

The serviceType property can have any of the following values:

  • GOOD Is the default value, when it is selected it refers to the fact that the payment of the order is for a good/product.
  • SERVICE When selected, it refers to a digital service or product that does not require any type of delivery.
  • HYBRID Is a combination of GOOD and SERVICE, in case the order contemplates both a good/product and a service.

purchaseSummary fields:

Field Description Format Required
currency Currency with which the payment is made String Yes
totalItemsAmount Sum of the total cost of the items Number Yes
shipmentAmount Shipping cost, in case of not applying its value must be 0 Number Yes
subtotalAmount Sum of totalItemsAmount plus shipmentAmount Number Yes
taxesAmount Taxes, in case of not applying its value must be 0 Number Yes
localTaxesAmount Local taxes, in case of not applying its value must be 0 Number Yes
importCosts Import costs, in case of not applying its value must be 0 Number Yes
additionalCharges Additional charges, it is composed of a key/value object that includes the description of the charge/the amount respectively Object (JSON) No
discountAmount Discount of your business, in case of not applying its value must be 0 Number Yes
grandTotalAmount Sum of subtotalAmount, taxesAmount, localTaxesAmount, importCosts and each value of additionalCharges minus discountAmount Number Yes

Purchase item fields:

Field Description Format Required
itemId Item identifier String No
quantity Number of order items Number Yes
price Total price of the items Number Yes
productName Product short name String Yes
productDescription Product description String No
thumbnailUrl URL to product image (thumbnail) String No
metadata Item related metadata Object (JSON) No

How to sign my order data?

Using your RSA private key, you must digitally sign the order information as follows:

1
2
3
4
5
6
7
# This is just an example of pseudocode
# You should implement it according to
# your back end programming language.

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;

/**
 * Snippet to sign message with <strong>PKCS #8 private key</strong>.
 * <p><strong>Note: </strong></p> Changes might be required if your private key is in a format different that <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";

    /**
     * Sample base64 private key (<strong>PKCS #8</strong>) format.
     **/
    private static final String BASE_64_PRIVATE_KEY = "-----BEGIN PRIVATE KEY-----\n" +
            "MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQCQ4h+g7C3Yu0XYF1JzrwG1Ob+qPVWeunrlufzhPGkRqf1vMXTkvwWEYrWdqaiUldOYejxmgLkO3g2ppBK+E/+2oS5qKM1kprssxEPJpxH4ZTS1xMmrsg/65HKIMYDLpixVUlX/GaTN+vrEulYfQtMFeEPQmJoysNZ+fjn21Flo09J2njIwLSarsryL0nvFvUc7GIMcRU35lcV5E5vpI45FWEoa6OJrgsMEioRi3tZHMxOKXXisj4aG2X0NsyBmd81/+jcbNZV3d5uPp8hbn9gBSEpR3a4hX+H7CHeGC+VjlO/rSiWrhd29O6mWnSYC7DV3JAGtRn/cCzq99X6Sg7uwpnS6cbUl4TOD4NaF3u/HcyfY1fu0AXeiyx6bIUASglHCjyWqL0r/SVOHKbOkHVDDmYqid14P4QQeZUwUqYWoH+Mi1+j6CR8OciRqWH3EtzS+Qc/xujqybqtGz8fKWtxodxtOZ7InPYpt0GLPU+7Kfq5ifkG806gHlWmtMfrqQpdpuHWuKqK0TEcRKh9GMmFhtVp/wYXJphA05MTij6FJjhfYg22sRStGkZziJXeLWLdEI5hhKr4NMUsSBrw1csOlP+7e58EMvmE3gZrd+KVRLkp4WgxO9ixzmvkX2v6AefXzw3MPfExxI++Ld9+tnXzw/9gsodvSOPZUZABj8zYjwQIDAQABAoICABOO4vQnTd0XEsukAlZphpJ/VDdYBkniJJsEa3XAYPKofvTWuU/z1XvUk23QLFi6jRDlV2gC8nhmU3PWGU2dh4SQ56IfFfMDavsVF42ORyfACciL4ymRZQTad/eYrylOqmduMPu563x+6AFMojmgHLp9TLJJF2/GXX4/7fU7H0K+bYfjvSSxw6mj/D3n0RuVfJsmqPRVCrypkjnRAtgLG7aSv5Y4X/Bhe5AOXua17Dk6VOX1zkeFLIThsTb7OmF6xLwE/BFpP18cP1y6Kprrzg4GQzof8dTBi9EGiJQI4RN7VJPvs3wfGxrjhfY2Cp6UYndN3ggVH0eGIIzqKgb/T4PKJtWo3ZdNVBMc4ltB3TuCEfybHb4svjMN6i/OXDPjznGwBcpdxrxxNduk7THYmtyeHmrSauAkUciG/mHR9LAhKqy6Az8G9UOb0SKQaUa1s1zbuskyjiJuw0Jmh1+1YQz9Qu/sYipU/IDL5RbdXfubl33zK7lHiC+dUbYBuqAQLssgIiXvpnaDKnduCDxBYrSrfbY0vxTtVnkP5SQ7hzYYhaqOGehwlXVhFFBhPqSGa1vcorwhckhs/FdHGgWSSjtb/E+R5Hi9H7dbidbPWS7sS/3yXjYOyTFhUDfgN09DTE2FcQkgv/aQF9AuHSvJbxKc3kLoyv/Nr/nljdefBy29AoIBAQDOH+Hj6vP7W+Zc//U9t2Xy4+S/UAVlAIJOQeK4Gy1cySgUK/q2v0RUHPFBgVto0G1pdB6o33u/j8oYmZy9/rtkkssaUf6Xkubiy/3jTQ19K4os6r9BXFODQeDIYOzhs7M8VvqM53Mi18iL50Mz+saJp2BA4j+9vLoWYHkonhwUh+l/VVlzsT3iDsRK8bI4O6rNIAXOj85wIyQUvdiuNamWhoYWNQxJEbSOvJvCU87wYaEsBo8mbv7v8qhlfZX20e5ksb0bv9CJx9FkZ5yHDG43xnqMgcUe6DOsoKP0IuKd9NLK4ZovJecCyOQMbIYdrIyHer5deSqCXkCQmAftLzGPAoIBAQCz8LtHaMpO12ZkdSHTd/F6yDsf1VeOem53ypXYSdbwR/H/1lfG/UUwPBZy1c9aDgCuc7h5v6Psnmg+QrFR6wrFl4d+oAJaeg2LNwUjn5FDSyIcBiD8Fd7+sTbAxlG/Kb0tkvTvIapglXvn6yIH6Vay0W6O7NRofXS/jfuZEjalT7sNiks6tTZcTVlFZBX4YiHK2NMs8OXfVjzfPfwsnPjlbnOQxUTZlO1ZB0v8GLfGpDg4koWIZC7Ub4ZwC0yhXVa5OBwl/ubpq3hdk/NtBoTC3dxXkCPITJuHZsy5ToJSxZU+os21SjWEmCnWiHu3LGE7I6a4bD6nhksqbUYJIQ2vAoIBAFw1uxIA26DI3ecgwg8X6k2cUYqcO62Rarmjk88UqVhmzL0pZ4E1U1XllK/fNItRIoEYZ1bYkz2BD8GthocgW6iEWsOthp08JHm1FCEJKU2jmq65XVHaAaooYGyDn7TgdQA7UN6T89fUfGzJyjCIsSSHcfHUxPsWYJD+G3VmNd2hZ32FKv0sfyiPvpRgR4AMgT4+YxqjDpDvx4ZX34UfkHw8NePdW1+cwg9QpMVsRJkYs8dEL+nbocSp41dztRCznVgCgzzUtG/Oqgemqkln8C6XZd9RdmN7MRK60l229XYAPgRwpE8PP6bpQ8ujCORheoRpDpw2RiQIEg4dVP5wLFUCggEBAIB57K3i4zgB0ej+PQWpSTCakKR9BkQDpKZBblX8+subAu3hU9EPevwimwCpKqCpCNGGbHv5WgiTXei+Y68SvCEyvRqrEqMZLFxvD2tM/kHm/la2BY0X7J07WNWxhCKSobFNkTbAec72TH7dwvGVKEMLB/5imJJ2qQowTSkQ+RV1ZSAY0vf69PJYg9noyUsMfgZAZB9dbTPWdiYLMueDuK7P+xGt2CfmjsUXUaiQ2X6qOD4kV9V3enxRmNKdLry0UTx0FJ0IcET9GjbucUsx8U7VbALVNsdH83Bs9NWGecSxsIsFYQ0FDEs8/fpgfrzdohrArMRW/TFN0JNdbDkOcZ8CggEAXnghKq+YHS/RRFC77ESSdxX+/Def8Zt+eOUIaEEGlA6KK+jG06yl8ipQCVoaKtdqngW9QpoSpt7SMPHehAES3xQC844o1ItbGk/IqK4jXMU2p+sjF6yUmzkPmAEnUkW3jh2UqYlFQNK2HA0baxCitRojv7ihADF1/+6MFwNwwd8B2ProNbwYvK2CHQkOBkhsjEEJllXhbVWXTzVyaatII0fKZj17ni04qp/UoDtp6+AB4sD87Ra7g03SSJQm2UtnRy+GoBZ/AcOFS3y4ii+SS3tFPthEXe9GF4s7ZI8iCJy1Hq/1pjMfa1ZesrUcHbkn2k0rI/xcLhScFHafYElS0w==\n" +
            "-----END PRIVATE KEY-----";

    /**
     * Path for sample private key file (<strong>PKCS #8</strong>) format.
     **/
    private static final String PRIVATE_KEY_FILE_PATH = "/path/to/my/file";

    // Sample JSON purchase data.
    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()); // Message to sign (in bytes)

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

        return Base64.getEncoder().encodeToString(signature); // Signature encoded in 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);

    }
}

Testing your signatures

In order for you to validate that the implementation for signing your purchase orders is correct, use the following private key and order information provided below to validate that your code produces the same digital signature.

Private Key:

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

Purchase data stringified:

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=

You can continue with integration with your server.