baseUrl = self::PROD_BASE_URL; $this->appKey = 'dadaf2279d901a5ba40'; $this->appSecret = '828a03677a1c00a3a5b3c59209c4433d'; $this->sourceId = '499021274'; } else { // 测试环境配置(需要替换为实际的测试环境凭证) $this->baseUrl = self::TEST_BASE_URL; $this->appKey = 'dadaf2279d901a5ba40'; $this->appSecret = '828a03677a1c00a3a5b3c59209c4433d'; $this->sourceId = '499021274'; } $this->isSandbox = !$isProduction; } /** * 构建达达 API 请求参数 * * 根据达达 API 规范构建完整的请求参数,包括签名 * 参数说明详见接口协议文档 * * @param string $apiMethod 接口方法名(不包括基础 URL) * @param string $body 业务参数 JSON 字符串 * @return array 完整的 POST 请求参数 */ protected function buildRequestPayload($apiMethod, $body = '') { // 获取当前时间戳(单位:秒) $timestamp = (string)time(); // 构建待签名的参数(不包括 signature) $params = [ 'app_key' => $this->appKey, 'v' => self::API_VERSION, 'format' => self::FORMAT, 'source_id' => $this->sourceId, 'timestamp' => $timestamp, 'body' => $body, ]; // 计算签名(按达达 API 规范) $signature = $this->generateSignature($params); // 加入签名到请求参数 $params['signature'] = $signature; return $params; } /** * 生成达达 API 签名 * * 达达签名算法: * 1. 将所有参数(除 signature 外)按 key 升序排列 * 2. 拼接为 key1value1key2value2...keyNvalueN 的形式 * 3. 在字符串后面加上 app_secret * 4. 对结果进行 MD5 加密,得到 32 位大写字符串 * * @param array $params 待签名参数(不包括 signature) * @return string 签名值(32 位大写) */ protected function generateSignature($params) { // 按 key 升序排列参数 ksort($params); // 拼接参数字符串 $str = ''; foreach ($params as $key => $value) { // 跳过 null 值,但保留空字符串(如 body 为空时) if ($value === null) { continue; } $str .= $key . $value; } // 加上 app_secret $str = $this->appSecret . $str . $this->appSecret; // MD5 加密,返回 32 位大写字符串 return strtoupper(md5($str)); } }