Signature and Verification
To ensure data integrity and authenticity after transmission, Diandian Pay requires all requests to be signed and notification signatures to be verified:
- Requests: When calling Diandian Pay APIs, request parameters must be signed.
- Notifications: When receiving Webhook notifications from Diandian Pay, the signature validity must be verified.
Encoding Standards (Must be followed for signature/verification)
To ensure consistent signatures across different languages and systems, please strictly follow these rules:
- Do not perform Unicode escaping on non-ASCII characters (such as Chinese, emoji, etc.), must maintain original character output.
- Correct example: Chinese characters output as-is as 中文, emoji 😊 outputs as 😊
- Incorrect example: Outputting 中文 as \u4e2d\u6587, emoji as \ud83d\ude0a
- URL strings should remain as-is, do not perform 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
API Calls
Before calling APIs, please ensure you have generated a pair of asymmetric public and private keys that meet the following standards.
- Key Format: PKCS#8
- Key Length: At least 2048 bits
Request Signing
The following diagram illustrates how to sign requests:
Step 1: Build Content to Sign
The syntax for content to sign is as follows:
merchant_id.timestamp.timezone.request_body
Note: Connect with English period (dot) symbols
merchant_id
: Merchant unique identifier, an example value isacct_8NRyElotSWv5F08m
timestamp
: This parameter is required in the request header, representing the timestamp when the request is sent. The field value must be precise to milliseconds. An example value is1742308640331
.timezone
: This parameter is required in the request header, used to identify the timestamp timezone. An example value isAsia/Shanghai
.request_body
: HTTP request body. Please refer to the example code 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 rules for "Building Content", construct the above request body as follows:
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 Signature
The syntax for generating signatures is as follows:
signature = base64_encode(sha256withRSA(<built_content>, <private_key>))
signature
: Generated signature string.base64_encode
: Method to perform Base64 encoding on the generated digital signature.sha256withrsa
: Method to perform digital signature on provided content using SHA-256 hash algorithm and RSA private key.built_content
: Content obtained from Step 1.private_key
: Private key value.
Example of generated signature:
M8jbljAHTkw9Vn/4JnFvsrIQIxU98ktYUFAYVgKJ7403Td4I2J0Aq3Y4qy6u2Og+n9HpL8g9bU9OCcA+iEGPhYoB3uWVJuMtjFLvV6z/Yey2JbmK6gjVKap1CRGmlfzgHHx7Qdvrf6ExsULQMtFeRwp3iczmjuBcq1YhjfooNq5ktbq/oI4UO7DI1OjqCdb1ZBpD6ZgqLAmxuiIkYFUK4AmrpqhvE/jrAzWCVPotm9VoMB4iivVj+sUGOken0/s35YFYgD1PUZPBUAlMCfEr3seq9J/E+oRHSbBrgQPjw+Muv8VQ21K9rvRSf6oUt0rxNITzcnJl/Z9SgRIOsPPEXA==
Step 3: Add Generated Signature to Request Header
'signature:M8jbljAHTkw9Vn/4JnFvsrIQIxU98ktYUFAYVgKJ7403Td4I2J0Aq3Y4qy6u2Og+n9HpL8g9bU9OCcA+iEGPhYoB3uWVJuMtjFLvV6z/Yey2JbmK6gjVKap1CRGmlfzgHHx7Qdvrf6ExsULQMtFeRwp3iczmjuBcq1YhjfooNq5ktbq/oI4UO7DI1OjqCdb1ZBpD6ZgqLAmxuiIkYFUK4AmrpqhvE/jrAzWCVPotm9VoMB4iivVj+sUGOken0/s35YFYgD1PUZPBUAlMCfEr3seq9J/E+oRHSbBrgQPjw+Muv8VQ21K9rvRSf6oUt0rxNITzcnJl/Z9SgRIOsPPEXA=='
Processing Responses
Responses consist of response headers and response body. The following code shows examples of response headers and response body.
- Response header code example:
timezone: Asia/Shanghai
signature:h8zwMT0uBQJa/IDCg4ifIOchBFft9AvLkokjrrIiYtkf8fsk3A8wDqSdB2c66ks9gJqARafZ0MygnWOUU9NbVPCUixHvDFl8Z3238ADzhb29+S4S3fn7XTFV7DUtCMd9aFUvKLXGr6z4/GBog80yynGHDL6Ygjde7xI9D/x/OXiLOBGN1AuopTj7zL6TEvp/646T5PzZg8w9pnWA7r4ZxHplZrG0SKTLtZRloCtLk3kC3EwI0/m8obG4pptiPjY/8PuuLQUzbaPfd57wQP7tLUEhTr0LY2hSRYbdAtHwiPcmMY9QoW0rnHj/a/4nCqZNTrBwqiHJhdsKEZflA2KPjw==
timestamp:1742311500484
DD-Request-Id:req_oVJMRLT7dzs8inRB9xYTYuLo
- Response body code example:
{
"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 demonstrate how to process Diandian Pay's response using the above examples.
Step 1: Obtain Diandian Pay Public Key
Get the Diandian Pay public key through Diandian Dashboard > Developer > API Keys > View Details.
Step 2: Construct Content to Verify
The syntax for "Building Content" is as follows:
merchant_id.timestamp.timezone.response_body
merchant_id
: Merchant unique identifier, an example value isacct_8NRyElotSW15F08m
timestamp
: This parameter is required in the response header, representing the timestamp when the request was sent. The field value must be precise to milliseconds. An example value is1742311500484
.timezone
: This parameter is required in the response header, used to identify the timestamp timezone. An example value isAsia/Shanghai
.response_body
: HTTP response body
By following the syntax rules for "Building Content", construct the above response as follows:
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 Signature from Response Header
The signature can be extracted from the signature
field in the response header.
Step 4: Verify Signature
The syntax for signature verification is as follows:
is_signature_valid = sha256withrsa_verify_signature(<built_content>, base64_decode(received_signature), <public_key>)
is_signature_validate
: A boolean value indicating whether the signature is valid.true: Signature is valid.
false: Signature is invalid. Possible reasons include mismatched private and public keys, or incorrect construction of "built_content".
sha256withrsa_verify_signature
: Method for signature verification.base64_decode
: Method to perform Base64 decoding on the generated digital signature.received_signature
: Target signature obtained from Step 3.public_key
: Diandian Pay public key obtained from Step 1.