| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141 |
- <?php
- namespace common\components\delivery\platform\didi;
- use common\components\delivery\helpers\HttpClient;
- use Yii;
- /**
- * 滴滴商户授权
- *
- * 文档参考:
- * 获取授权链接:/gateway?api=freight.open.platform.channel.standard.authUrl
- * 取消授权:/gateway?api=freight.open.platform.channel.standard.cancelAuth
- */
- class Auth
- {
- // API 接口名称
- const API_AUTH_URL = 'freight.open.platform.channel.standard.authUrl';
- const API_CANCEL_AUTH = 'freight.open.platform.channel.standard.cancelAuth';
- /**
- * 获取授权页面链接
- *
- * 用户发单前,需要先进行授权绑定账号,获取此链接跳转到滴滴h5页面进行授权
- *
- * @param string $thirdUid 接入方用户id
- * @param string $cityId 城市id(国标码,市级别)。与lat/lng二选一传递
- * @param string $lat 纬度
- * @param string $lng 经度
- * @return array ['success' => bool, 'authUrl' => string, 'error' => string]
- */
- public function getAuthUrl($thirdUid, $cityId = '', $lat = '', $lng = '')
- {
- // 此接口不需要传token参数
- $didi = new Didi();
-
- // 校验:城市编码与经纬度二选一
- if (empty($cityId) && (empty($lat) || empty($lng))) {
- return [
- 'success' => false,
- 'error' => '参数错误:城市编码(cityId)与经纬度(lat,lng)必须二选一传递'
- ];
- }
- $params = [
- 'thirdUid' => (string)$thirdUid,
- ];
-
- if ($cityId) {
- $params['cityId'] = (string)$cityId;
- }
- if ($lat) {
- $params['lat'] = (float)$lat;
- }
- if ($lng) {
- $params['lng'] = (float)$lng;
- }
- $payload = $didi->buildRequestPayload($params);
- $url = $didi->getApiUrl(self::API_AUTH_URL);
- $response = HttpClient::post($url, $payload);
-
- return $this->parseResponse($response);
- }
- /**
- * 取消授权
- *
- * 用户不再使用滴滴平台发单,取消授权后token失效,后续再使用需要重新授权
- *
- * @param string $accessToken 授权token
- * @return array ['success' => bool, 'result' => int, 'error' => string]
- */
- public function cancelAuth($accessToken)
- {
- // 实例化 Didi 类传入 token,buildRequestPayload 会自动处理 token
- $didi = new Didi($accessToken);
-
- // 入参说明无业务参数
- $payload = $didi->buildRequestPayload(self::API_CANCEL_AUTH, []);
- $url = $didi->getApiUrl(self::API_CANCEL_AUTH);
-
- $response = HttpClient::post($url, $payload);
-
- return $this->parseResponse($response);
- }
- /**
- * 解析 API 响应
- *
- * @param array $response
- * @return array
- */
- protected function parseResponse($response)
- {
- // 检查 HttpClient 返回的错误结构
- if (isset($response['code']) && isset($response['body']) && !isset($response['errno'])) {
- return [
- 'success' => false,
- 'error' => 'HTTP Request Failed: ' . ($response['error'] ?? $response['body']),
- 'code' => $response['code']
- ];
- }
- // 检查滴滴业务错误码 (errno)
- if (isset($response['errno'])) {
- if ($response['errno'] != 0) {
- return [
- 'success' => false,
- 'error' => $response['errmsg'] ?? 'Unknown API error',
- 'errno' => $response['errno']
- ];
- }
-
- $data = $response['data'] ?? [];
-
- // 构造统一返回格式
- $result = [
- 'success' => true,
- 'data' => $data,
- ];
-
- // 提取关键字段到顶层,方便调用
- if (isset($data['authUrl'])) {
- $result['authUrl'] = $data['authUrl'];
- }
- if (isset($data['result'])) {
- $result['result'] = $data['result'];
- }
-
- return $result;
- }
- // 未知格式
- return [
- 'success' => false,
- 'error' => 'Invalid response format',
- 'raw' => $response
- ];
- }
- }
|