Signature and Signature Verification
To ensure the integrity and authenticity of data transmission, DianDianPay requires all requests to be signed and all webhook notifications to be signature-verified:
- Request: When calling the DianDianPay API, the request parameters must be signed.
- Notification: When receiving webhook notifications sent by DianDianPay, the signature’s validity must be verified.
Encoding Specifications (Must Follow for Signing/Verification)
To ensure signatures are consistent across different languages and systems, strictly follow these rules:
- Do NOT Unicode-escape non-ASCII characters (such as Chinese or emoji); raw characters must be output.
- Correct example: Chinese outputs as 中文, emoji 😊 outputs as 😊
- Incorrect example: Chinese outputs as \u4e2d\u6587, emoji outputs as \ud83d\ude0a
- Keep URL strings in their original form; do NOT apply URL encoding (percent encoding)
- Correct example: https://example.com/pay?param=abc&token=中文
- Incorrect example: https%3A%2F%2Fexample.com%2Fpay%3Fparam%3Dabc%26token%3D%E4%B8%AD%E6%96%87
Calling the API
Before you invoke the API, please ensure you have done the following preparation:
1. Generate and Prepare RSA Keys
- Algorithm: RSA
- Key Format: PKCS#8
- Key Length: At least 2048 bits
- Generation requirements:
- Generate a key pair (public key and private key)
- Upload and configure the public key into the DianDianPay platform
- Properly keep the private key locally, to be used for signing requests
2. Retrieve Merchant Information
Login to Dashboard
Navigate: Top right settings > Account Settings > Merchant > Obtain your merchant_id (unique merchant identifier)
Signing Requests
The following diagram illustrates how to generate a request signature:

Step 1: Construct the Content to Be Signed
The syntax for the signing content is as follows:
merchant_id.timestamp.timezone.request_bodyNote: Join fields using a period (.).
merchant_id: Unique merchant identifier, e.g.acct_8NRyElotSWv5F08mtimestamp: This header parameter is required. Indicates the request time, in milliseconds. Example:1742308640331.timezone: Required in request headers, identifying the timestamp’s time zone. Example:Asia/Shanghairequest_body: HTTP request body. See the sample below:
{
"merchant_id": "1",
"env": {
"terminal_type": "WEB",
"client_ip": "143.45.4.222",
"browser_info": {
"user_agent": "Mozilla/5.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/5.1)"
}
},
"order": {
"merchant_order_id": "99999999999",
"shipping": {
"shipping_name": {
"first_name": "KING",
"last_name": "MIsa",
"full_name": "KING MIsa"
},
"shipping_address": {
"country": "US",
"state": "TX",
"city": "Austin",
"address1": "789 Oak Ave",
"address2": "",
"zip_code": "78701"
},
"email": "example@example.com",
"phone": "+864-281-1794",
"carrier": "USPS"
},
"payment_amount": {
"currency": "USD",
"value": 1000
},
"payment_method": {
"payment_type": "CARD",
"payment_data": {
"country": "US",
"card_number": "4111111111111111",
"expiry_year": "30",
"expiry_month": "03",
"cvv": "737",
"card_holder_name": {
"first_name": "KING",
"last_name": "MIsa",
"full_name": "KING MIsa"
},
"billing_address": {
"country": "US",
"state": "TX",
"city": "Austin",
"address1": "789 Oak Ave",
"address2": "",
"zip_code": "78701"
},
"requires_3ds": false
}
},
"metadata": {
"shop": "happy",
"domain": "example.com"
}
},
"redirect_url": "https://example.com/reutrn"
}By following the syntax, the constructed content for the above request body would be:
acct_8NRyElotSWv5F08m.1742308640331.Asia/Shanghai.{"merchant_id":"1","env":{"terminal_type":"WEB","client_ip":"143.45.4.222","browser_info":{"user_agent":"Mozilla/5.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/5.1)"}},"order":{"merchant_order_id":"99999999999","shipping":{"shipping_name":{"first_name":"KING","last_name":"MIsa","full_name":"KING MIsa"},"shipping_address":{"country":"US","state":"TX","city":"Austin","address1":"789 Oak Ave","address2":"","zip_code":"78701"},"email":"example@example.com","phone":"+864-281-1794","carrier":"USPS"},"payment_amount":{"currency":"USD","value":1000},"payment_method":{"payment_type":"CARD","payment_data":{"country":"US","card_number":"4111111111111111","expiry_year":"30","expiry_month":"03","cvv":"737","card_holder_name":{"first_name":"KING","last_name":"MIsa","full_name":"KING MIsa"},"billing_address":{"country":"US","state":"TX","city":"Austin","address1":"789 Oak Ave","address2":"","zip_code":"78701"},"requires_3ds":false}},"metadata":{"shop":"happy","domain":"example.com"}},"redirect_url":"https://example.com/reutrn"}Step 2: Generate the Signature
Use the following syntax to generate the signature:
signature = base64_encode(sha256withRSA(<signing_content>, <private_key>))signature: The generated signature string.base64_encode: Encodes the generated signature in Base64.sha256withrsa: Signs the given content using SHA-256 hash and RSA private key.signing_content: Content constructed as above.private_key: Your RSA private key.
Example of generated signature:
M8jbljAHTkw9Vn/4JnFvsrIQIxU98ktYUFAYVgKJ7403Td4I2J0Aq3Y4qy6u2Og+n9HpL8g9bU9OCcA+iEGPhYoB3uWVJuMtjFLvV6z/Yey2JbmK6gjVKap1CRGmlfzgHHx7Qdvrf6ExsULQMtFeRwp3iczmjuBcq1YhjfooNq5ktbq/oI4UO7DI1OjqCdb1ZBpD6ZgqLAmxuiIkYFUK4AmrpqhvE/jrAzWCVPotm9VoMB4iivVj+sUGOken0/s35YFYgD1PUZPBUAlMCfEr3seq9J/E+oRHSbBrgQPjw+Muv8VQ21K9rvRSf6oUt0rxNITzcnJl/Z9SgRIOsPPEXA==Step 3: Add the Generated Signature to the Request Header
'signature:M8jbljAHTkw9Vn/4JnFvsrIQIxU98ktYUFAYVgKJ7403Td4I2J0Aq3Y4qy6u2Og+n9HpL8g9bU9OCcA+iEGPhYoB3uWVJuMtjFLvV6z/Yey2JbmK6gjVKap1CRGmlfzgHHx7Qdvrf6ExsULQMtFeRwp3iczmjuBcq1YhjfooNq5ktbq/oI4UO7DI1OjqCdb1ZBpD6ZgqLAmxuiIkYFUK4AmrpqhvE/jrAzWCVPotm9VoMB4iivVj+sUGOken0/s35YFYgD1PUZPBUAlMCfEr3seq9J/E+oRHSbBrgQPjw+Muv8VQ21K9rvRSf6oUt0rxNITzcnJl/Z9SgRIOsPPEXA=='Handling Responses
A response consists of response headers and a body. Example code for response headers and body is shown below.
- Example response headers
timezone: Asia/Shanghai
signature:h8zwMT0uBQJa/IDCg4ifIOchBFft9AvLkokjrrIiYtkf8fsk3A8wDqSdB2c66ks9gJqARafZ0MygnWOUU9NbVPCUixHvDFl8Z3238ADzhb29+S4S3fn7XTFV7DUtCMd9aFUvKLXGr6z4/GBog80yynGHDL6Ygjde7xI9D/x/OXiLOBGN1AuopTj7zL6TEvp/646T5PzZg8w9pnWA7r4ZxHplZrG0SKTLtZRloCtLk3kC3EwI0/m8obG4pptiPjY/8PuuLQUzbaPfd57wQP7tLUEhTr0LY2hSRYbdAtHwiPcmMY9QoW0rnHj/a/4nCqZNTrBwqiHJhdsKEZflA2KPjw==
timestamp:1742311500484
DD-Request-Id:req_oVJMRLT7dzs8inRB9xYTYuLo- Example response body:
{
"data": {
"id": "pi_aDNwWGfls1vcPLUHJDykYwmR",
"amount": 7698,
"result": {
"result_code": "FAILED",
"result_status": "F",
"result_message": "card_velocity_exceeded"
},
"currency": "USD",
"merchant_id": "acct_8NRyElotSW15F08m",
"merchant_order_id": "21064044592225646561337"
}
}The following steps show how to process a DianDianPay response using the above example.
Step 1: Obtain DianDianPay’s Public Key
From Dashboard > Developer > API Keys > View Details to get the DianDianPay public key.
Step 2: Construct Content to Be Verified
The syntax for the verification content is:
merchant_id.timestamp.timezone.response_bodymerchant_id: Unique merchant identifier, e.g.,acct_8NRyElotSW15F08mtimestamp: Value from response headers, required, indicating the response time, in milliseconds, e.g.,1742311500484.timezone: Value from response headers, required, e.g.,Asia/Shanghai.response_body: HTTP response body
Following the above, the constructed content would be:
acct_8NRyElotSW15F08m.1742311500484.Asia/Shanghai.{"data":{"id":"pi_aDNwWGfls1vcPLUHJDykYwmR","amount":7698,"result":{"result_code":"FAILED","result_status":"F","result_message":"card_velocity_exceeded"},"currency":"USD","merchant_id":"acct_8NRyElotSW15F08m","merchant_order_id":"21064044592225646561337"}}Step 3: Extract the Signature from the Response Header
You can extract the signature from the signature field in the response headers.
Step 4: Verify the Signature
Verify the signature using the following syntax:
is_signature_valid = sha256withrsa_verify_signature(<signing_content>, base64_decode(received_signature), <public_key>)is_signature_valid: Boolean value indicating whether the signature is valid.- true: The signature is valid.
- false: The signature is invalid (possibly due to mismatched key pairs or incorrectly constructed signing content).
sha256withrsa_verify_signature: The signature verification method.base64_decode: Decodes the received signature from Base64.received_signature: Signature string obtained in step 3.public_key: DianDianPay’s public key obtained in step 1.
