a) Generating a payment link

Build a XML string, cypher it with the SDK appropriate to your technology, submit it to the Link Generation service, decrypt the answer with the same SDK and get a link .

Step 1: XML string


Here is the description of the chain you must build. You can copy and edit the example.

<P>

Parent element within the XML string scheme

Contains the parameters to identify the merchant in Centro de Pagos, which make the request

Merchant identifier to which the payment will be associated.
For sandbox use SNBX

Identifier of the Merchant Branch to which the payment will be associated.
For sandbox use 01SNBXBRNCH

User that generates the request. With this user the payment transaction will be processed.
For sandbox use SNBXUSR01

Access password for user authentication.
For sandbox use SECRETO

It contains the parameters with the instructions of the Merchant for register an intention to collect and link them to a payment link.

Unique / unrepeatable reference of the merchant to reconcile a payment with its business logic. Invoice or order number is suggested.
The value of 50 characters is available to add information.

Amount to pay with 2 decimals separated by a point.

Specify the currency for the charge intention, if affiliations for both pesos and dollars ar available in the branch.
Possible values: MXN or USD .

Fixed value, must be W.

If this element is received with the value 0 , the charge made notification will be sent to the cardholder via email, with Centro de Pagos look and feel.
: 0 ó 1 .

If this item is received, it indicates the installments with which a payment can be made, when several affiliations are set in the branch.
To force the payment to only cash, you must indicate only C .

If this element is received, the token of the campaign that was generated must be informed, so that the created promotion can be applied

If this element is received with the value 1 , the capture of the email will be requested in the payment form.
Valid values: 0 ó 1 .

If this element is present and is received with a date in the future, the intention of collection will be valid until the indicated date.
The default value is 3 months from the intention to collect.

If the element is present, this value will be pre-loaded in the "E-mail" field of the payment form. The cardholder can change it if so wishes. Note: the field st_correo must indicate 1 .

If the element is present with the value A, when displaying the form the rules of automatic enrollment will be considered.
If the element is present with the value M, the checkbox will be displayed to allow enrollment.

Specifies the channel that sends a request for a link. It is mandatory to put the IntegraWPP value.

Specifies the channel that sends a request for a link. It is mandatory to put the IntegraWPP value.

If the affiliation requires it and this element is present, it contains the information necessary to request an authentication to the 3D Secure service.

Specify the cardholder's email of up to one hundred characters.

Specify the cardholder's phone number from up to twenty positions.

Specify the cardholder's address up to sixty characters.

Specify the city of the cardholder's address of up to thirty characters.

Specifies the two-character ISO 3166-2 state key cardholder address.

Specify the postal code of the cardholder's address, up to ten characters.

Specifies the 3 characters ISO 3166-1 numeric keyof thecountry of the cardholder's address.

If this element is present, the children elements will be included data in the payment form and will be returned in the response of the result of a charge. If the "display" attribute is specified with the boolean true , these will be shown in the payment form.

<data id="1" display="true">
  <label>Size</label>
  <value>Large</value>
</data>

Group a pair of elements of type label and value, you must specify the attribute "id" to differentiate them. Maximum 6 data of the label-value type.

Example


In order to familiarise you with the chain suitable for your needs, choose one of our examples.

					<?xml version="1.0" encoding="UTF-8"?>
<P>
  <business>
    <id_company>SNBX</id_company>
    <id_branch>01SNBXBRNCH</id_branch>
    <user>SNBXUSR01</user>
    <pwd>SECRETO</pwd>
  </business>
  <url>
    <reference>INVOICE999</reference>
    <amount>2500.00</amount>
    <moneda>MXN</moneda>
    <canal>W</canal>
    <omitir_notif_default>1</omitir_notif_default>
    <promociones>C,3,6,9</promociones>
    <st_correo>1</st_correo>
    <fh_vigencia>24/11/2021</fh_vigencia>
    <mail_cliente>nospam@gmail.com</mail_cliente>
    <datos_adicionales>
      <data id="1" display="true">
        <label>Size</label>
        <value>Large</value>
      </data>
      <data id="2" display="false">
        <label>Color</label>
        <value>Blue</value>
      </data>
    </datos_adicionales>
  </url>
</P>
					


You will find the XSD and code examples to validate it with your server in GitHub


				

Step 2: Encrypting the string


Once you have built the chain in clear, you can cypher it in AES-128, with the appropriate SDK to your server, which you can obtain in GitHUB.

String used as a key to encrypt the request.

For sandbox use 5DCC67393750523CD165F17E1EFADD21

The developer will receive the productive credentials of the merchant administrator.

Example


								String key = "5DCC67393750523CD165F17E1EFADD21";
String originalString = "[USAR LA CADENA DEL EJEMPLO UNO]";
String encrypted = encrypt(key, originalString);
System.out.println(encrypted);

							
								function aesFunction() {
    var originalString = '[USAR LA CADENA DEL EJEMPLO UNO]';
    var key  = '5DCC67393750523CD165F17E1EFADD21';
    var ciphertext = CryptoJS.AES.encrypt(originalString, key ).toString();
    console.log("ciphertext: " + ciphertext);
}	
                                
							
								<?php
$originalString = '[USAR LA CADENA DEL EJEMPLO UNO]';
$key = '5dcc67393750523cd165f17e1efadd21'; 
$encrypted = AesCipher::encrypt($key,$originalString);
var_dump($encrypted);
?>
							
								<?php
$originalString = '[USAR LA CADENA DEL EJEMPLO UNO]';
$key = '5dcc67393750523cd165f17e1efadd21';
$encrypted = AesCipher::encrypt($key,$originalString);
var_dump($encrypted);
?>
							
								Imports AESCrypto.vb
Dim originalString As String = "[USAR LA CADENA DEL EJEMPLO UNO]"
Dim key As String = "5DCC67393750523CD165F17E1EFADD21"
Dim encryptedString As String = AESCrypto.Encrypt(originalString, key)
Dim finalString As String = encryptedString.Replace("%", "%25").Replace(" ", "%20").Replace("+", "%2B").Replace("=", "%3D").Replace("/", "%2F")
							
								using AESCrypto.cs
string originalString ="[USAR LA CADENA DEL EJEMPLO UNO]";
string key = "5DCC67393750523CD165F17E1EFADD21";
string encryptedString =
  AESCrypto.encrypt(originalString, key);
string finalString = encryptedString.Replace("%", "%25").Replace(" ", "%20").Replace("+", "%2B").Replace("=", "%3D").Replace("/", "%2F");
							
								originalString = "[USAR LA CADENA DEL EJEMPLO UNO]"
key = "5dcc67393750523cd165f17e1efadd21"
ciphertext = AESCipher(key).encrypt(originalString)
print(ciphertext)
							
								originalString = "[USAR LA CADENA DEL EJEMPLO UNO]"
key = "5dcc67393750523cd165f17e1efadd21"
ciphertext = AESCipher(key).encrypt(originalString)
print(ciphertext)
							


				

Step 3: Link Generation Service


To guarantee the security in the transmission of information, Centro de Pagos has HTTPS servers which use the Transport Layer Security TLS protocol v1.2 as a secure transport protocol to carry out transactions. For its part, the merchant must also have TLS v1.2 servers, to ensure the secure exchange of information when making transactions.

https://wppsandbox.mit.com.mx/gen

This Sandbox endpoint receives the request with instructions from the merchant to record an intention to collect. In response to the request to the Link Generation Service, you will get an encrypted response string.

The implementation is based on sending to the service by POST a string in the xml parameter with the following structure:

xml=
<pgs>
  <data0>Fixed string assigned to merchant</data0>
  <data>Encrypted string in AES-128</data>
</pgs>

Fixed chain, assigned to merchant.

For sandbox use SNDBX123

The developer will receive the productive credentials of the merchant administrator.

Example


								try {
	SecureRandom random = new SecureRandom();
	byte[] ivArr = random.generateSeed(16);
	IvParameterSpec ivSpec = new IvParameterSpec(ivArr);
	SecretKeySpec secretKey = new SecretKeySpec(fixKey(key).getBytes(StandardCharsets.UTF_8), "AES");

	Cipher cipher = Cipher.getInstance(CIPHER_NAME);
	cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivSpec);

	byte[] encryptedData = cipher.doFinal((data.getBytes()));

	String encryptedDataInBase64 = Base64.getEncoder().encodeToString(encryptedData);
	String ivInBase64 = Base64.getEncoder().encodeToString(ivArr);
	String resultEnc = encryptedDataInBase64 + ":" + ivInBase64;

	return Base64.getEncoder().encodeToString(resultEnc.getBytes());

} catch (Exception ex) {
	throw new RuntimeException(ex);
}
							
								var CTRGladman = CryptoJS.lib.BlockCipherMode.extend();
var Encryptor = CTRGladman.Encryptor = CTRGladman.extend({
     processBlock: function (words, offset) {
         // Shortcuts
         var cipher = this._cipher
         var blockSize = cipher.blockSize;
         var iv = this._iv;
         var counter = this._counter;

         // Generate keystream
         if (iv) {
             counter = this._counter = iv.slice(0);

             // Remove IV for subsequent blocks
             this._iv = undefined;
         }

incCounter(counter);

var keystream = counter.slice(0);
         cipher.encryptBlock(keystream, 0);

         // Encrypt
         for (var i = 0; i < blockSize; i++) {
             words[offset + i] ^= keystream[i];
         }
     }
 });

 CTRGladman.Decryptor = Encryptor;
							
								static function encrypt($key, $data) {
    $ivlen = openssl_cipher_iv_length('AES-128-CBC');
    $iv = openssl_random_pseudo_bytes($ivlen);
    $encodedEncryptedData = base64_encode(openssl_encrypt($data, 'aes-128-cbc', AesCipher::fixKey($key), OPENSSL_RAW_DATA, $iv));
    $encodedIV = base64_encode($iv);
    $encryptedPayload = $encodedEncryptedData.":".$encodedIV;

    return base64_encode($encryptedPayload);
}
							
								static function encrypt($key, $data) {
    $ivlen = openssl_cipher_iv_length('AES-128-CBC');
    $iv = openssl_random_pseudo_bytes($ivlen);
    $encodedEncryptedData = base64_encode(openssl_encrypt($data, 'aes-128-cbc', AesCipher::fixKey($key), OPENSSL_RAW_DATA, $iv));
    $encodedIV = base64_encode($iv);
    $encryptedPayload = $encodedEncryptedData.":".$encodedIV;

    return base64_encode($encryptedPayload);
}
							
								'' Esta implementación utiliza http://restsharp.org v105
    Dim encodedString As String = HttpUtility.UrlEncode("SNDBX123[USAR LA CADENA DEL EJEMPLO UNO]")
    Dim postParam As String = "xml=" & encodedString
    Dim client = New RestClient("https://wppsandbox.mit.com.mx/gen")
    Dim request = New RestRequest(Method.POST)
    request.AddHeader("cache-control", "no-cache")
    request.AddHeader("content-type", "application/x-www-form-urlencoded")
    request.AddQueryParameter(postParam, ParameterType.RequestBody)
    Dim response As IRestResponse = client.Execute(request)
    Dim content = response.Content
							
								// Esta implementación utiliza http://restsharp.org v105
string encodedString = 
  HttpUtility.UrlEncode("<pgs><data0>SNDBX123</data0><data>[USAR LA CADENA DEL EJEMPLO UNO]</data></pgs>");
string postParam = "xml=" + encodedString;
var client = new RestClient("https://wppsandbox.mit.com.mx/gen");
var request = new RestRequest(Method.POST);
request.AddHeader("cache-control", "no-cache");
request.AddHeader("content-type", "application/x-www-form-urlencoded");
request.AddQueryParameter(postParam, ParameterType.RequestBody);

IRestResponse response = client.Execute(request);
var content = response.Content;
							
								def encrypt(self, raw):
padded_plain_text = self._padPKCS5(raw)
iv = Random.new().read(AES.block_size)
cipher = AES.new(self.key, AES.MODE_CBC, iv)
ivEncoded = b64encode(iv)
dataEncoded = b64encode(cipher.encrypt(padded_plain_text))
return b64encode(dataEncoded+':'+ivEncoded)
							
								def encrypt(self, raw):
padded_plain_text = self._padPKCS5(raw)
iv = Random.new().read(AES.block_size)
cipher = AES.new(self.key.encode("utf8"), AES.MODE_CBC, iv)
ivEncoded = b64encode(iv)
dataEncoded = b64encode(cipher.encrypt(padded_plain_text.encode("utf8")))
return b64encode(dataEncoded+':'.encode("utf8")+ivEncoded)
							


				

Step 4: Deciphering the response of the Generation Service


Once the service response is obtained, you can decrypt it with the appropriate SDK to your server, and within <nb_url> you will find the payment link or URL, that you must share with your client to receive your payment.

Example


								try {
	String cadena = new String(Base64.getDecoder().decode(data));
	data = cadena;
	String[] parts = data.split(":");

	byte[] decodedEncryptedData = Base64.getDecoder().decode(parts[0]);

	byte[] ivBytes = Arrays.copyOfRange(decodedEncryptedData, 0, 16);
	Cipher cipher = Cipher.getInstance(CIPHER_NAME);
	// IvParameterSpec(ivBytes);//Base64.getDecoder().decode(parts[1]));
	IvParameterSpec iv = new IvParameterSpec(Base64.getDecoder().decode(parts[1]));
	SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "AES");

	cipher.init(Cipher.DECRYPT_MODE, secretKey, iv);

	byte[] original = cipher.doFinal(decodedEncryptedData);

	return new String(original);
} catch (Exception ex) {
	throw new RuntimeException(ex);
}
							
								decrypt: function (cipher, ciphertext, key, cfg) {
    // Apply config defaults
    cfg = this.cfg.extend(cfg);

    // Convert string to CipherParams
    ciphertext = this._parse(ciphertext, cfg.format);

    // Decrypt
    var plaintext = cipher.createDecryptor(key, cfg).finalize(ciphertext.ciphertext);

    return plaintext;
}
							
								static function decrypt($key, $data) {
     $data = base64_decode($data);
     $parts = explode(':', $data); //Separate Encrypted data from iv.
     $encrypted = $parts[0];
     $iv = $parts[1];
     //$ivlen = openssl_cipher_iv_length('AES-128-CBC');
     //$iv = openssl_random_pseudo_bytes($ivlen);
     $decryptedData = openssl_decrypt(base64_decode($encrypted), 'aes-128-cbc', AesCipher::fixKey($key), OPENSSL_RAW_DATA, base64_decode($iv));
     return $decryptedData;
}
							
								static function decrypt($key, $data) {
   $data = base64_decode($data);
   $parts = explode(':', $data); //Separate Encrypted data from iv.
   $encrypted = $parts[0];
   $iv = $parts[1];
   //$ivlen = openssl_cipher_iv_length('AES-128-CBC');
   //$iv = openssl_random_pseudo_bytes($ivlen);
   $decryptedData = openssl_decrypt(base64_decode($encrypted), 'aes-128-cbc', AesCipher::fixKey($key), OPENSSL_RAW_DATA, base64_decode($iv));
   return $decryptedData;
}
							
								Imports AESCrypto.vb
Dim originalString As String = "Este es el texto a procesar"
originalString = originalString.Replace("%25", "%").Replace("%20", " ").Replace("%2B", "+").Replace("%3D", "=").Replace("%2F", "/")
Dim key As String = "5DCC67393750523CD165F17E1EFADD21"
Dim decryptedString As String = AESCrypto.Decrypt(key, originalString)
							
								using AESCrypto.cs
string originalString ="Este es el texto a procesar";
string key = "5DCC67393750523CD165F17E1EFADD21";
string decryptedString = 
  AESCrypto.decrypt(key, originalString);
							
								def decrypt(self, enc):
enc = b64decode(enc)
dataArr = enc.split(":")
iv = b64decode(dataArr[1])
enc = b64decode(dataArr[0])
cipher = AES.new(self.key, AES.MODE_CBC, iv)
return self._unpadPKCS5(cipher.decrypt(enc)).decode('utf-8')
							
								def decrypt(self, enc):
enc = b64decode(enc)
dataArr = enc.split(b":")
iv = b64decode(dataArr[1])
enc = b64decode(dataArr[0])
cipher = AES.new(self.key.encode("utf8"), AES.MODE_CBC, iv)
return self._unpadPKCS5(cipher.decrypt(enc).decode('utf-8'))
							



					
Catalog of values, element nb_response
nb_response Description Solution
Empty The request was processed correctly
The request is invalid The string structure is invalid, contains invalid characters or is not correctly encrypted Use XSD validation
The data of merchant, branch or user are invalid Authentication failed or user / branch / company status is not active. Contact MIT Attention Center
The company does not have this service authorized, please contact your administrator Failed configuration or user / branch / company status is not correct. Contact MIT Attention Center
It was not possible to generate the reference, please try later An error occurred while processing the request (exception). Contact MIT Attention Center

Step 5: Payment link


From the decrypted answer, you get the payment link in the element nb_url . With the link you can invoke the payment form with GET in a web browser, Webview of an App, or embedding within the commerce portal in an iframe. Thus, you have the freedom to select the best that suits your technology. To find more visit Publish a payment link

Example


¡Wow!
To obtain a payment link, decrypt the response obtained in the previous step.


Continue here:

How to generate a link?