| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 |
- <?php
- namespace common\components\delivery\platform\dada;
- class Dada
- {
- // API 配置常量
- const API_VERSION = '1.0';
- const FORMAT = 'json';
- // 测试环境和生产环境基础 URL
- const TEST_BASE_URL = 'https://newopen.qa.imdada.cn';
- const PROD_BASE_URL = 'https://newopen.imdada.cn';
- protected $baseUrl;
- protected $appKey;
- protected $appSecret;
- protected $sourceId;
- protected $shopNo;
- /**
- * 初始化达达适配器
- * 根据运行环境加载对应的配置信息
- */
- public function __construct($token='', $shopId=0, $sourceId=0)
- {
- $isProduction = getenv('YII_ENV') == 'production';
- if ($isProduction) {
- // 生产环境配置
- $this->baseUrl = self::PROD_BASE_URL;
- $this->appKey = 'dadaf2279d901a5ba40';
- $this->appSecret = '828a03677a1c00a3a5b3c59209c4433d';
- } else {
- // 测试环境配置
- $this->baseUrl = self::PROD_BASE_URL; // TODO
- //$this->baseUrl = self::TEST_BASE_URL;
- $this->appKey = 'dadaf2279d901a5ba40';
- $this->appSecret = '828a03677a1c00a3a5b3c59209c4433d';
- }
- $this->shopNo = $shopId;
- $this->sourceId = $sourceId;
- }
- public function setShopNo($shopNo)
- {
- $this->shopNo = $shopNo;
- }
- public function getShopNo()
- {
- return $this->shopNo;
- }
- public function balance()
- {
- $api = 'api/balance/query';
- $params = [
- 'category' => 1, //查询运费账户类型(1:运费账户;2:红包账户,3:所有),默认查询运费账户余额
- 'shop_no' => $this->shopNo,
- ];
-
- $body = json_encode($params);
- $requestParams = $this->buildRequestPayload($api, $body);
- $result = $this->getHttpRequestWithPost($api, json_encode($requestParams));
- $resp = json_decode($result, true);
- if(isset($resp['code']) && $resp['code']==0){
- return [
- 'success' => true,
- 'balance' => $resp['result']['deliverBalance'] * 100, // 乘以100是把金额单位元改成分
- 'message' => '查询余额成功',
- ];
- }
- return [
- 'success' => false,
- 'balance' => 0,
- 'message' => $resp['msg'] ?? '查询余额失败',
- ];
- }
- /**
- * 构建达达 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 加密
- return strtoupper(md5($str));
- }
- /**
- * 发送请求,POST
- * @param $url 指定URL完整路径地址
- * @param $data 请求的数据
- */
- public function getHttpRequestWithPost($api, $data){
- $url = $this->baseUrl . '/' . $api;
- // json
- $headers = array(
- 'Content-Type: application/json',
- );
- $curl = curl_init($url);
- curl_setopt($curl, CURLOPT_URL, $url);
- curl_setopt($curl, CURLOPT_HEADER, false);
- curl_setopt($curl, CURLOPT_POST, true);
- curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
- curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
- curl_setopt($curl, CURLOPT_TIMEOUT, 3);
- curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
- $resp = curl_exec($curl);
- //var_dump( curl_error($curl) );//如果在执行curl的过程中出现异常,可以打开此开关查看异常内容。
- $info = curl_getinfo($curl);
- curl_close($curl);
- if (isset($info['http_code']) && $info['http_code'] == 200) {
- return $resp;
- }
- return '';
- }
- }
|