123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277 |
- <?php
- namespace app\expand\controller;
- use app\common\service\HelperService;
- use app\common\service\wechat\decode\WXBizDataCrypt;
- use app\common\service\wechat\UnifiedOrder_pub;
- use think\Config;
- use think\Validate;
- use think\Log;
- /**
- * 小程序支付接口
- * Class WeChat
- * @package app\expand\controller
- */
- class Xcx extends BaseAuth
- {
- private $_Account = null;
- private $_APPID = null;
- private $_MCHID = null;
- private $_SUBMCHID = null;
- private $_SUBAPPID = null;
-
- private $_PayTip = "";
- public function __construct(){
- parent::__construct();
-
- if($this->_inWhiteList == true){
- return ;
- }
- $this->_Account = $this->getKey($this->_apiCode);
- //验证是否具有访问这个接口的权限
- if(!isset($this->_Account['Xcx_pay_appId'])
- || !isset($this->_Account['Xcx_mchId'])
- || !isset($this->_Account['Xcx_pay_key'])){
- HelperService::returnJson(['code'=>400,'msg'=>'Xcx interface unauthorized access','data'=>$this->_Account]);
- }
- $this->_APPID = $this->_Account['Xcx_pay_appId'];
- $this->_MCHID = $this->_Account['Xcx_mchId'];
- $this->_SUBMCHID = isset($this->_Account['Xcx_sub_mchId'])?$this->_Account['Xcx_sub_mchId']:"";
- $this->_SUBAPPID = isset($this->_Account['Xcx_pay_sub_appId'])?$this->_Account['Xcx_pay_sub_appId']:"";
- $this->_PayTip = isset($this->_Account['Xcx_tip'])?$this->_Account['Xcx_tip']:"";
-
- Config::set('WECHAT_APPID',$this->_APPID);
- Config::set('WECHAT_MCHID',$this->_MCHID);
- Config::set('WECHAT_SUB_MCHID',$this->_SUBMCHID);
- Config::set('WECHAT_SUB_APPID',$this->_SUBAPPID);
- Config::set('WECHAT_PAY_KEY',$this->_Account['Xcx_pay_key']);
- }
- /**
- * 平台版支付接口
- */
- public function platformXcxPay(){
-
- $params = $this->_params;
- $rule = [
- 'order_no|订单号'=>'require',
- 'total_fee|支付金额'=>'require',
- 'openid|小程序的openid'=>'require',
- 'tip|商品信息'=>'max:500'
- ];
-
- $validate = new Validate($rule);
- if(!$validate->check($params)){
- HelperService::returnJson(['code'=>400,'msg'=>$validate->getError(),'data'=>[]]);
- }
-
- require_once(APP_PATH.'/common/service/wechat/WxPayPubHelper.php');
-
- $unifiedOrder = new UnifiedOrder_pub();
- //设置统一支付接口参数
- //$unifiedOrder->setParameter("openid", "{$params['openid']}"); //商品描述
- $body = $this->_PayTip;
- if(!empty($params['tip'])){
- $body = $params['tip'];
- }
- if(empty($body)){
- $body = $this->_apiCode;
- }
- $unifiedOrder->setParameter("body",$body."[". substr($params['order_no'],-8)."]"); //商品描述
- $unifiedOrder->setParameter("attach",$body); //商品描述
- //自定义订单号,此处仅作举例
- $out_trade_no = $this->_apiCode."_".$params['order_no']."_".rand(10,99);
- $unifiedOrder->setParameter("out_trade_no", $out_trade_no); //商户订单号
- $unifiedOrder->setParameter("total_fee", $params['total_fee']); //总金额
- $unifiedOrder->setParameter("sub_openid", $params['openid']); //总金额
- $httpHeader = HelperService::getHttpHeader();
- $unifiedOrder->setParameter("notify_url", "{$httpHeader}{$_SERVER['HTTP_HOST']}/v1/notifyXcxPay"); //通知地址
- $unifiedOrder->setParameter("trade_type", "JSAPI"); //交易类型
- $prepay_id = $unifiedOrder->getPrepayId();
-
- $appId = empty($this->_SUBAPPID)?$this->_APPID:$this->_SUBAPPID;
-
- $returnData = [
- 'appId'=>$appId,
- 'timeStamp'=>time(),
- 'nonceStr'=> uniqid(),
- 'package'=>"prepay_id=$prepay_id",
- 'signType'=>'MD5',
- ];
- $returnData['paySign'] = $unifiedOrder->getSign($returnData);
-
- HelperService::returnJson([
- 'data'=>$returnData,
- 'msg'=>'success',
- 'code'=>200
- ]);
-
- }
-
- /**
- * 获取微信相关信息
- */
- public function getOpenInfo(){
-
- $params = $this->_params;
- $rule = [
- 'code|js获取的code'=>'require',
- ];
-
- $validate = new Validate($rule);
- if(!$validate->check($params)){
- HelperService::returnJson(['code'=>400,'msg'=>$validate->getError(),'data'=>[]]);
- }
-
- if(empty($this->_Account['Xcx_secret'])){
- HelperService::returnJson(['code'=>400,'msg'=>'Xcx getOpenInfo unauthorized access','data'=>$this->_Account]);
- }
-
- $secret = $this->_Account['Xcx_secret'];
- $appId = empty($this->_SUBAPPID)?$this->_APPID:$this->_SUBAPPID;
-
- $url = "https://api.weixin.qq.com/sns/jscode2session?appid={$appId}&secret={$secret}&js_code={$params['code']}&grant_type=authorization_code";
- $openInfoJson = file_get_contents($url);
- $openInfo = @json_decode($openInfoJson,true);
-
- if($openInfo===false || !empty($openInfo['errcode'])){
- HelperService::returnJson([
- 'data'=>$openInfoJson,'msg'=>'fail','code'=>400
- ]);
- }
-
- HelperService::returnJson([
- 'data'=> array_merge($openInfo,['appId'=>$appId]),'msg'=>'success','code'=>200
- ]);
- }
- public function getMobileInfo() {
- $params = $this->_params;
- $rule = [
- 'code|js获取的code'=>'require',
- 'encryptedData'=>'require',
- 'iv'=>'require'
- ];
- $validate = new Validate($rule);
- if(!$validate->check($params)){
- HelperService::returnJson(['code'=>400,'msg'=>$validate->getError(),'data'=>[]]);
- }
- if(empty($this->_Account['Xcx_secret'])){
- HelperService::returnJson(['code'=>400,'msg'=>'Xcx getOpenInfo unauthorized access','data'=>$this->_Account]);
- }
- $secret = $this->_Account['Xcx_secret'];
- $appId = empty($this->_SUBAPPID)?$this->_APPID:$this->_SUBAPPID;
- $url = "https://api.weixin.qq.com/sns/jscode2session?appid={$appId}&secret={$secret}&js_code={$params['code']}&grant_type=authorization_code";
- $openInfoJson = file_get_contents($url);
- $openInfo = @json_decode($openInfoJson,true);
- if($openInfo===false || !empty($openInfo['errcode'])){
- HelperService::returnJson([
- 'data'=>$openInfoJson,'msg'=>'fail','code'=>400
- ]);
- }
- $pc = new WXBizDataCrypt($appId, $openInfo['session_key']);
- $errCode = $pc->decryptData($params['encryptedData'], $params['iv'], $data);
- if ($errCode == 0) {
- $data = json_decode($data,true);
- HelperService::returnJson([
- 'data'=> array_merge($data,['appId'=>$appId]),'msg'=>'success','code'=>200
- ]);
- }
- HelperService::returnJson([
- 'data'=>[],'msg'=>'获取手机号失败请重试','code'=>400
- ]);
- }
- /**
- * 异步通知小程序支付
- */
- public function notifyXcxPay(){
-
- $this->getInput();
- $param = $this->_oldParams;
-
- $this->_sysParams['request_ts'] = time();
-
- Log::record($param);
- $params = (array)@simplexml_load_string($param, 'SimpleXMLElement', LIBXML_NOCDATA);
- if(empty($params)){
- HelperService::returnJson(['code' => 400, 'msg' => "参数错误",'data'=>['baseParams'=>$param]]);
- }
- try {
- $arr = ['total_fee', 'out_trade_no'];
- foreach ($arr as $key=>$value) {
- if (!isset($params[$value])) {
- HelperService::returnJson(['code' => 400, 'msg' => "参数错误({$key})",'data'=>['baseParams'=>$param]]);
- }
- }
- $tradeNoArr = explode('_', $params['out_trade_no']);
- if(count($tradeNoArr)<2){
- HelperService::returnJson(['code' => 400, 'msg' => "参数错误(trade)",'data'=>['baseParams'=>$param]]);
- }
- $companyCode = $tradeNoArr[0];
- $this->_Account = $this->getKey($companyCode,false);//不验证参数
- $orderNo = isset($tradeNoArr[1]) ? $tradeNoArr[1] : 0;
- //开发分发给不同的支付主体
- if(!isset($this->_Account['Xcx_pay_notify_url'])
- || empty($this->_Account['Xcx_pay_notify_url'])){
- HelperService::returnJson(['code' => 400, 'msg' => "回调地址不存在",'data'=>['baseParams'=>$param]]);
- }
- if(!is_array($this->_Account['Xcx_pay_notify_url'])){
- HelperService::returnJson(['code' => 400, 'msg' => "回调地址不是数组",'data'=>['baseParams'=>$param]]);
- }
- $notifyUrlArr = $this->_Account['Xcx_pay_notify_url'];
- foreach($notifyUrlArr as $url){
- $is_ssl = strpos($url, 'https://')!==false?true:false;
- $data = [
- 'order_no'=>$orderNo,
- 'total_price'=>"{$params['total_fee']}",
- 'out_trade_no'=>"{$params['out_trade_no']}"
- ];
- $times = 3;
- while($times--){
- $res = HelperService::httpPost($url,json_encode($data),$is_ssl);
- HelperService::addLog(['item'=>$url,'data'=>$data,'result'=>$res,'times'=>$times],$url,'XCXPAY_DETAIL');
- //file_put_contents('ABC_TEMP' ,var_export(['item'=>$url,'data'=>$data,'result'=>$res,'times'=>$times],true),FILE_APPEND);
- if($res != false){
- break;
- }
- }
-
- if($times ==0){
- Log::record("小程序支付推送异常=>url:".$url."=>res:". json_encode($res)."=>data:". json_encode($data));
- }
- }
- die('success');
- }catch (\Exception $ex){
- file_put_contents('xcxPayRecord-Exception.mp',"[".date('Y-m-d H:i:s')."]".$ex->getMessage().json_encode($params)."\n\n",FILE_APPEND);
- }
- }
- }
|