159 lines
5.4 KiB
PHP
159 lines
5.4 KiB
PHP
<?php
|
||
|
||
/**
|
||
* @author Any
|
||
* @description KISS
|
||
* @date 2022年7月15日
|
||
* @version 1.0.0
|
||
*
|
||
* _____LOG_____
|
||
*
|
||
*/
|
||
namespace Updc;
|
||
|
||
use Updc\utils\SignatureBuilder;
|
||
|
||
class Updc
|
||
{
|
||
public $appId;
|
||
public $mchId;
|
||
public $url;
|
||
public $privateKeyPassword;
|
||
public $privateKey;
|
||
public $publicKey;
|
||
public $isHttps;
|
||
public $algorithm;
|
||
|
||
|
||
public $client;
|
||
public $request;
|
||
public $config;
|
||
public $cache;
|
||
public $signature;
|
||
|
||
|
||
public function __construct($args) {
|
||
$this->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;
|
||
}
|
||
|
||
}
|
||
|