Algorithm#
- Remove pay_md5sign and sign.
- Sort selected field names in ascending order.
- Omit values considered empty by PHP empty(), including the string "0".
- Join raw name=value pairs with &, then append key=YOUR_APIKEY.
- Compute MD5, then uppercase the hexadecimal digest.
Signed field scopes#
| Operation | Signed fields |
|---|---|
Collection create | pay_memberid, pay_orderid, pay_amount, pay_applydate, pay_bankcode, pay_notifyurl, pay_callbackurl |
Collection query | pay_memberid, pay_orderid |
Payout create | Submitted nonempty form fields, excluding pay_md5sign |
Payout query | mchid, out_trade_no |
Balance query | Normally mchid; Brazil signs every nonempty POST field actually sent |
Collection callback | memberid, orderid, transaction_id, amount, datetime, returncode |
Payout callback | Actual notification fields except sign |
PHP reference implementation#
PHP · Source-defined algorithm
function makeSign($params, $apiKey) {
unset($params['pay_md5sign'], $params['sign']);
ksort($params);
$source = '';
foreach ($params as $name => $value) {
if (!empty($value)) {
$source .= $name . '=' . $value . '&';
}
}
return strtoupper(md5($source . 'key=' . $apiKey));
}Avoid common mismatches#
- Sign raw values before URL encoding; form-encode only for transport.
- Keep the exact amount string: 100.00 and 100 are different signing inputs.
- Do not add type, product fields or attach to the collection signature scope.
- Validate response signatures by removing sign first.