Generate a signature
Learn how to create a signature for your API requests. This is required for all requests to dLocal’s API.
What is a signature, and why is it required?
A signature acts as a security mechanism to verify your identity and protect your data when making requests to dLocal’s API. Think of it as a digital fingerprint, created by combining your API credentials, the current timestamp, and the data you're sending. This ensures that every request originates from an authorized source and hasn't been tampered with in transit.
How to generate a signature
The steps below apply to the standard HMAC-based authentication (not certificate-based). For certificate-based authentication, please refer to Mutual TLS Certificates.
-
Get your credentials
You'll need yourx-login
,x-trans-key
, andsecret key
. You can learn how to find find them in the Get API credentials article. -
Prepare the data to sign
Concatenate yourx-login
, the current timestamp (x-date
), and the request body. Concatenate the values as:x-login + x-date + requestBody
(all as strings, no delimiters). -
Generate the signature
Use HMAC SHA256 with yoursecret key
to hash the data you have prepared following the previous step. -
Add the signature to your request
Include it in the Authorization header.
Required headers
Header | Type | Description |
---|---|---|
X-Date | String | ISO8601 Datetime with Timezone. Example: 2018-07-12T13:46:28.629Z |
X-Login | String | Identifies the merchant making the request. Find your keys in the Merchant Dashboard |
X-Trans-Key | String | Used along with x-login to authenticate the request. Find your keys in the Merchant Dashboard |
Content-Type | String | Always complete application/json |
X-Version | String | Current API Version number: 2.1 |
User-Agent | String | Identifies the application type, operating system, or software version of the requesting user agent |
Authorization | String | Use the format: V2-HMAC-SHA256, Signature: <hmac(secretKey, "X-Login+X-Date+RequestBody")> |
Signature differences for Payins and Payouts
Note. You can start with the basic signature method above. The differences below are relevant when you're ready to implement both payment types.
Payins signatures
For payment operations (accepting payments):
- Use the HMAC-SHA256 algorithm with the format:
V2-HMAC-SHA256, Signature: <signature>
- Signature data includes:
x-login
+x-date
+RequestBody
- Include as the
Authorization
header in your request
Payouts signatures
For disbursement operations (sending money):
- Use the HMAC-SHA256 algorithm with the signature in hexadecimal lowercase format
- Signature data uses the request payload as the data to be hashed
- The signature must be included in the
Payload-Signature
header
Important. Always check the specific documentation for Payins or Payouts to ensure you're using the correct signature format.
Using the signature in headers
For Payins
curl -X POST \
-H 'X-Date: {x-date}' \
-H 'X-Login: {x-login}' \
-H 'X-Trans-Key: {x-trans-key}' \
-H 'Content-Type: application/json' \
-H 'X-Version: 2.1' \
-H 'User-Agent: MerchantTest / 1.0 ' \
-H 'Authorization: V2-HMAC-SHA256, Signature: {Signature}' \
-d '{body}'
https://api.dlocal.com/payments
For Payouts
The signature process differs slightly; specifically, the signature data uses the request payload as the data to be hashed.
You can find detailed requirements in our Payouts Security documentation.
Examples of HMAC signature generation
Our GitHub repository hosts a variety of signature examples, which can be a valuable resource for understanding implementation details and for reference in your development process.
Check out signature examples on GitHub >
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)
import * as crypto from 'crypto';
class SignatureCalculator {
calculateSignature(timestamp: string, body?: string): string {
let message: string = process.env.DLOCAL_X_LOGIN + timestamp;
if (body) {
message += body;
}
const hmac = crypto.createHmac('sha256', process.env.DLOCAL_SECRET_KEY);
hmac.update(message, 'utf-8');
const signature: string = hmac.digest('hex');
return `V2-HMAC-SHA256, Signature: ${signature}`;
}
}
// Example usage
const calculator = new SignatureCalculator();
const timestamp = new Date().toISOString(); // Corrected the timestamp
const body = "yourRequestBody";
const result = calculator.calculateSignature(timestamp, body);
console.log(result);
function calculateSignature(timestamp, body) {
let message = process.env.DLOCAL_X_LOGIN + timestamp;
if (body) {
message += body;
}
const hmac = crypto.createHmac('sha256', process.env.DLOCAL_SECRET_KEY);
hmac.update(message, 'utf-8');
const signature = hmac.digest('hex');
return `V2-HMAC-SHA256, Signature: ${signature}`;
}
// Example usage
const timestamp = new Date().toISOString(); // Set timestamp to current time
const body = "yourRequestBody";
const result = calculateSignature(timestamp, body);
console.log(result);
static string SignatureCalculator(string x_Login, string x_Date, string secretKey, string body)
{
string concatenatedData = x_Login + x_Date + body;
byte[] data = Encoding.UTF8.GetBytes(concatenatedData);
byte[] keyBytes = Encoding.UTF8.GetBytes(secretKey);
using (var hmacsha256 = new HMACSHA256(keyBytes))
{
byte[] hashBytes = hmacsha256.ComputeHash(data);
StringBuilder signatureBuilder = new StringBuilder();
foreach (byte b in hashBytes)
{
signatureBuilder.Append(b.ToString("x2"));
}
return signatureBuilder.ToString();
}
}
Updated 21 days ago