Security

Use the API Signature to authorize and perform API operations.

Each request to the dLocal API must include a signature. The signature is necessary to verify that the information that is being sent is valid and secure.

Signature

Required information

  • API credentials. Access the dLocal Merchant Dashboard with your dLocal account to obtain your API keys credentials.
  • Custom information. Calculate and complete the necessary data such as the payment date information.
  • Hash. Convert all the information (letters and numbers) into an encrypted output of a fixed length using the HMAC-SHA256 algorithm.

How does it work

All calls to the Payins API should be signed using the HMAC-SHA256 algorithm, and the contents of the signature included in the Authorization header as documented below. This header should have as prefix the signature version and the hash function used, which is currently V2-HMAC-SHA256.

Headers

HeaderTypeDescription
X-DateStringISO8601 Datetime with Timezone. Eg: 2018-07-12T13:46:28.629Z.
X-LoginStringAPI key necessary to authenticate your request. Find your keys in the Merchant Dashboard.
X-Trans-KeyStringAPI key necessary to authenticate your request. Find your keys in the Merchant Dashboard.
Content-TypeStringAlways complete application/json
X-VersionStringCurrent API Version number: 2.1
User-AgentStringUsed to identify the application type, operating system, software vendor, or software version of the requesting software user agent.
AuthorizationStringUse the required information mentioned before and set this field with the following structure: V2-HMAC-SHA256, Signature: <hmac(secretKey, "X-Login+X-Date+RequestBody")>

ℹ️

Secret key credential

Do not forget to use your Secret key for masking your signature. Read more information in the Get your API test credentials section.

Example Request

curl -X POST \
    -H 'X-Date: 2018-02-20T15:44:42.310Z' \
    -H 'X-Login: sak223k2wdksdl2' \
    -H 'X-Trans-Key: fm12O7G9' \
    -H 'Content-Type: application/json' \
    -H 'X-Version: 2.1' \
    -H 'User-Agent: MerchantTest / 1.0 ' \
    -H 'Authorization: V2-HMAC-SHA256, Signature: 1bd227f9d892a7f4581b998c21e353b1686a6bdad5940e7bb6aa596c96e0a6ec' \
    -d '{body}'
    https://api.dlocal.com/payments

Examples of HMAC signature generation

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Formatter;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

public final class SignatureCalculator {

    private static final String HMAC_ALGORITHM = "HmacSHA256";
    private static final String CHARSET = "UTF-8";

    public static String calculateSignature(String x_Login, String x_Date, String secretKey, String body)
        throws IOException, InvalidKeyException, NoSuchAlgorithmException {

        // Create byte array with the required data for the signature.
        ByteArrayOutputStream bout = new ByteArrayOutputStream();
        bout.write(x_Login.getBytes(CHARSET));
        bout.write(x_Date.getBytes(CHARSET));
        bout.write(body.getBytes(CHARSET));

        // Calculate the signature.
        SecretKeySpec signingKey = new SecretKeySpec(secretKey.getBytes(), HMAC_ALGORITHM);
        Mac mac = Mac.getInstance(HMAC_ALGORITHM);
        mac.init(signingKey);
        byte[] signature = mac.doFinal(bout.toByteArray());

        // Create a String with the signature value.
        Formatter formatter = new Formatter();
        for (byte b : signature) {
            formatter.format("%02x", b);
        }
        return formatter.toString();
    }
}
$signature = hash_hmac("sha256", "$X-Login$X-Date$RequestBody", $secretKey);
signature = hmac.new(secretKey, X-Login+X-Date+RequestBody, hashlib.sha256).hexdigest()
signature = OpenSSL::HMAC.hexdigest('sha256', secretKey, $X-Login + $X-Date + RequestBody)

ℹ️

Signature testing

We strongly suggest testing your generated signature by making a test payment to make sure your signature is working before moving forward with the integration.


Sensitive data encryption

Sensitive Card data, such as number, expiration date, CVV, and PIN, should be encrypted inside the JSON Request Body using JWE. This standard is being widely used in the market, and most programming languages have libraries to support it.

Decryption Flow

When getting the Card Information, card sensitive data can be received encrypted. Use the following instructions to decrypt it:

  1. Merchant creates an RSA key pair.
  2. Merchant shares the public key with dLocal using an encrypted method. Ask your Technical Account Manager for more information.
  3. dLocal will use this public key to encrypt the sensitive information using JWE and send it in the API response within the encrypted_data field in the card object. The rest of the requests will be sent unencrypted.

Encryption Flow

When sending the card PIN, card sensitive data can be encrypted. Use the following instructions to encrypt it:

  1. dLocal creates an RSA key pair.
  2. dLocal shares the public key to the merchant using an encrypted method. Ask your Technical Account Manager for more information.
  3. The merchant uses this public key to encrypt the number and cvv into a JSON using JWE, and send it in the API request within the encrypted_data field. The rest of the request can be sent unencrypted.

Idempotent Requests

To perform an idempotent request, provide an additional X-Idempotency-Key header to the request.

HeaderTypeDescription
X-Idempotency-KeyStringKey used to perform an idempotent request. Optional.

Example Request

curl -X POST \
    -H 'X-Date: 2018-02-20T15:44:42.310Z' \
    -H 'X-Login: sak223k2wdksdl2' \
    -H 'X-Trans-Key: fm12O7G9' \
    -H 'Content-Type: application/json' \
    -H 'X-Version: 2.1' \
    -H 'User-Agent: MerchantTest / 1.0 ' \
    -H 'X-Idempotency-Key: a8a85bce-5733-4a6c-91b5-553ed4b3de16' \
    -H 'Authorization: V2-HMAC-SHA256, Signature: 1bd227f9d892a7f4581b998c21e353b1686a6bdad5940e7bb6aa596c96e0a6ec' \
    -d '{body}'
    https://api.dlocal.com/payments