appId = isset($args['appId']) ? $args['appId'] : null; $this->mchId = isset($args['mchId']) ? $args['mchId'] : null; $this->url = isset($args['url']) ? $args['url'] : null; $this->privateKeyPassword = isset($args['privateKeyPassword']) ? $args['privateKeyPassword'] : null; $this->privateKey = isset($args['privateKey']) ? $args['privateKey'] : null; $this->publicKey = isset($args['publicKey']) ? $args['publicKey'] : null; $this->isHttps = isset($args['isHttps']) ? $args['isHttps'] : null; $this->algorithm = isset($args['algorithm']) ? $args['algorithm'] : null; return $this->init(); } private function init() { $this->client = new \Updc\bean\Client(); $this->client->__set("appId",$this->appId); $this->client->__set("url",$this->url); $this->client->__set("privateKeyPassword",$this->privateKeyPassword); $this->client->__set("privateKey",$this->privateKey); $this->client->__set("publicKey",$this->publicKey); $this->client->__set("isHttps",$this->isHttps); //设置加密算法类型 $this->client->__set("algorithm", $this->algorithm); $this->request = new \Updc\bean\GateWayRequest; $this->cache = \Yii::$app->cache ? \Yii::$app->cache : new \yii\caching\DummyCache(); $this->signature = SignatureBuilder::build($this->algorithm,$this->publicKey,$this->privateKey,$this->privateKeyPassword); return $this; } /** * return array * throw Exception */ public function apiRequest($args, $debug = true) { $method = $args['method']; $method_name = $args['method_name']; $biz_content = $args['biz_content']; //服务名 $this->request->__set("apiInterfaceId",$method); //方法名 $this->request->__set("methodName",$method_name); //版本号 $this->request->__set("version","1.0.1"); $this->request->__set("bizContent",$biz_content); $this->client->__set("gateWayRequest",$this->request); $r = $this->client->apiRequest(); if($r != 1){ //响应验签 throw new \Exception('数据验签未通过'); } $req = $this->client->__get("requestBody"); $debug && \Yii::info('[UpdcRequest]'.$req,'PaymentUpdc'); $res = $this->client->__get("responseBody"); $debug && \Yii::info('[UpdcResponse]'.$res,'PaymentUpdc'); $res = json_decode($res, true); if(!isset($res['code']) || $res['code'] != '00000'){ $msg = isset($res['msg']) ? "[{$res['code']}]{$res['msg']}" : "[{$res['code']}]error"; throw new \Exception($msg); } if(!isset($res['response'])){ throw new \Exception('缺少response参数'); } $response = $res['response']; if(!isset($response['subCode']) || $response['subCode'] != '00000'){ $msg = isset($response['subMsg']) ? "[{$response['subCode']}]{$response['subMsg']}" : "[{$response['subCode']}]error"; throw new \Exception($msg); } if(!isset($response['msgBody'])){ throw new \Exception('缺少msgBody参数'); } $msgBody = $response['msgBody']; if(!isset($msgBody['retCode']) || $msgBody['retCode'] != '00000'){ $msg = isset($msgBody['retMsg']) ? "[{$msgBody['retCode']}]{$msgBody['retMsg']}" : "[{$msgBody['retCode']}]error"; throw new \Exception($msg); } return $response['msgBody']; } /** * 商户交易订单号,需保证在商户端不重复;格式:15 位商户号+8 位交易日期+9 位序数字列号 */ public function getMerOrderNo($cx_mch_id = 0, $retry = 0, $retry_max = 3) { $ckey_prefix = "_updc_mron_{$cx_mch_id}"; $mch_id = $this->mchId; $date = date('Ymd'); $timestamp = intval(microtime(true) * 1000); $today_start = strtotime(date('Y-m-d')) * 1000; $sn = $timestamp - $today_start; $chars = '1234567890'; $max = strlen($chars) - 1; while (true){ if(strlen($sn) >= 9)break; $start = mt_rand(0, $max); $sn .= $chars[$start]; } $order_no = $mch_id . $date . $sn; $ckey = $ckey_prefix . $order_no; $cval = $this->cache->get($ckey); if($cval !== false){ usleep(100); $retry += 1; return $retry <= $retry_max ? $this->getMerOrderNo($cx_mch_id, $retry, $retry_max) : null; } $this->cache->set($ckey, $order_no, 86400); return $order_no; } public function filterSpecialChar($content) { preg_match_all('/[\x{4e00}-\x{9fa5}a-zA-Z0-9]/u', $content, $matches); $result = join("", $matches[0]); return $result; } }