logdir = Yii::getAlias('@runtime').DIRECTORY_SEPARATOR.'logs'.DIRECTORY_SEPARATOR.'pay'.DIRECTORY_SEPARATOR; dir_create($this->logdir); $this->userInfo = Identify::getUserInfo(); $this->payconfig = Yii::$app->params['pay']; $this->coinconfig = Yii::$app->params['coin']; if($this->payconfig['weixin_pay']) { // 商户号 $merchantId = $this->payconfig['weixin_mchid']; // 从本地文件中加载「商户API私钥」,「商户API私钥」会用来生成请求的签名 $merchantPrivateKeyFilePath = 'file://'.$this->payconfig['weixin_apiclient_key']; $merchantPrivateKeyInstance = Rsa::from($merchantPrivateKeyFilePath, Rsa::KEY_TYPE_PRIVATE); // 「商户API证书」的「证书序列号」 $merchantCertificateSerial = $this->payconfig['weixin_serialnumber']; // 从本地文件中加载「微信支付平台证书」,用来验证微信支付应答的签名 $platformCertificateFilePath = 'file://'.$this->payconfig['weixin_cert']; $platformPublicKeyInstance = Rsa::from($platformCertificateFilePath, Rsa::KEY_TYPE_PUBLIC); // 从「微信支付平台证书」中获取「证书序列号」 $platformCertificateSerial = PemUtil::parseCertificateSerialNo($platformCertificateFilePath); // 构造一个 APIv3 客户端实例 $this->wechatPay = Builder::factory([ 'mchid' => $merchantId, 'serial' => $merchantCertificateSerial, 'privateKey' => $merchantPrivateKeyInstance, 'certs' => [ $platformCertificateSerial => $platformPublicKeyInstance, ], ]); } } public function actionDo() { } //处理来自手机端的支付请求 public function actionDowap() { $initData = $_POST; extract($initData); //解决微信跳转后参数传递问题 $state = Yii::$app->request->get('state'); if(!empty($state)&&$state=='MR8888') { $initData = $_GET; extract($initData); } //购买文档时候,调整回跳地址 if($act=='buydoc') { $doc = DocReal::findOne($id); if($doc->doc_type==2) { $return_url = SiteUrl::colDetail($id,$order_sn); } else { $return_url = SiteUrl::docDetail($id,$order_sn); } } //支付宝 if($pay_method=='apw_pay') { require_once(Yii::getAlias('@payerdrivers').'/alipaywap/wappay/service/AlipayTradeService.php'); require_once(Yii::getAlias('@payerdrivers').'/alipaywap/wappay/buildermodel/AlipayTradeWapPayContentBuilder.php'); $order = $this->_initOrder($initData); $config = array ( //应用ID,您的APPID。 'app_id' => $this->payconfig['apw_appid'], //商户私钥,您的原始格式RSA私钥 'merchant_private_key' => $this->payconfig['apw_merchant_private_key'], //异步通知地址 'notify_url' => $this->payconfig['apw_notify_url'], //同步跳转 'return_url' => $return_url, //编码格式 'charset' => "UTF-8", //签名方式 'sign_type'=>"RSA2", //支付宝网关 'gatewayUrl' => "https://openapi.alipay.com/gateway.do", //支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。 'alipay_public_key' => $this->payconfig['apw_alipay_public_key'], //日志路径 'log_path' => $this->logdir.get_date(TIMESTAMP, "Y-m").'.txt', ); //商户订单号,商户网站订单系统中唯一订单号,必填 $out_trade_no = trim($order_sn); //订单名称,必填 $subject = $order->remark; //付款金额,必填 $total_amount = trim($total_price); //商品描述,可空 $body = ''; //超时时间 $timeout_express="1m"; $payRequestBuilder = new \AlipayTradeWapPayContentBuilder(); $payRequestBuilder->setBody($body); $payRequestBuilder->setSubject($subject); $payRequestBuilder->setOutTradeNo($out_trade_no); $payRequestBuilder->setTotalAmount($total_amount); $payRequestBuilder->setTimeExpress($timeout_express); $payResponse = new \AlipayTradeService($config); $result=$payResponse->wapPay($payRequestBuilder,$config['return_url'],$config['notify_url']); return ; } //微信公众号支付 if($pay_method=='weixin_pay'){ $args = array( 'appId'=>$this->payconfig['weixin_appid'], 'appSecret'=>$this->payconfig['weixin_appsecret'], 'token'=>$this->payconfig['weixin_token'], ); $weixin = new WeiXin($args); $weixin->init(); //JS API接口支付(仅在微信里面) if(isset($_GET['code'])&&$_GET['code']!='') { $order = $this->_initOrder($initData); $result = $weixin->getOauthAccessToken($_GET['code']); try { $pay_money = max($total_price, 0.01); $resp = $this->wechatPay->chain('v3/pay/transactions/jsapi') ->post(['json' => [ 'appid' => $this->payconfig['weixin_appid'], 'mchid' => $this->payconfig['weixin_mchid'], 'out_trade_no' => $order_sn, 'description' => $order->remark, 'notify_url' => $this->payconfig['weixin_notify_url'], 'amount' => [ 'total' => $pay_money*100, 'currency' => 'CNY' ], 'payer' => [ 'openid'=>$result['openid'] ], ]]); if($resp->getStatusCode()==200) { $respBody = json_decode($resp->getBody(),true); $prepay_id = $respBody['prepay_id']; if($prepay_id) { $timestamp = TIMESTAMP; $noncestr = TIMESTAMP; $signstr = $this->getWechartSign($this->payconfig['weixin_appid'], strval($timestamp), strval($noncestr), 'prepay_id='.$prepay_id); $jsApiParameters = json_encode([ 'appId' => $this->payconfig['weixin_appid'], 'timeStamp' => strval($timestamp) , 'package' => 'prepay_id=' . $respBody['prepay_id'], 'paySign' => $signstr, 'nonceStr' => strval($noncestr) ]); ob_clean(); require_once(Yii::getAlias('@app/views').DIRECTORY_SEPARATOR.'pay'.DIRECTORY_SEPARATOR.$pay_method.'.php'); exit; } else { exit('支付失败'); } } else { exit('支付失败'); } } catch (\Exception $e) { exit($e->getMessage()); } } else { $redirectUrl = get_url(); $queryParams = http_build_query($initData); if(strpos($redirectUrl,'?')===false) { $redirectUrl = $redirectUrl.'?'.urldecode($queryParams); } else { $redirectUrl = $redirectUrl.'&'.urldecode($queryParams); } $codeUrl = $weixin->getWebAuthUrl(urlencode($redirectUrl),'snsapi_base','MR8888'); echo ""; } } //微信H5支付 if($pay_method=='wxh5_pay'){ $order = $this->_initOrder($initData); // 官方提供网址 $url = "https://api.mch.weixin.qq.com/v3/pay/transactions/h5"; //拆解为:[scheme=>https,host=>api.mch.weixin.qq.com,path=>/v3/pay/transactions/native] $urlarr = parse_url($url); $time = time(); //时间戳 $noncestr = $time; $appid = $this->payconfig['wxh5_appid'];//appID $mchid = $this->payconfig['wxh5_mchid'];//商户ID //秘钥序列号 可在这个网址中查询 https://myssl.com/cert_decode.html $xlid = $this->payconfig['wxh5_serialnumber']; $data = []; $data['appid'] = $appid; $data['mchid'] = $mchid; $data['description'] = $order->remark;//商品描述 $data['out_trade_no'] = $order_sn;//订单编号,订单号在微信支付里是唯一的 $data['notify_url'] = $this->payconfig['wxh5_notify_url'];//需根据自己的情况修改回调接口,也可以为空 $data['amount']['total'] = max($total_price, 0.01)*100;//金额 单位 分 $data['scene_info']['payer_client_ip'] = $_SERVER['REMOTE_ADDR'];//场景 $data['scene_info']['h5_info']['type'] = "Wap";//场景 $data = json_encode($data); //变为json格式 // echo "
"; // print_r($data); // echo "";die; //签名,包含了$data数据、微信指定地址、随机数和时间 $key = $this->getSign($data,$urlarr['path'],$noncestr,$time); //头部信息 $token = sprintf('mchid="%s",serial_no="%s",nonce_str="%s",timestamp="%d",signature="%s"',$mchid,$xlid,$noncestr,$time,$key); // echo $token;die; $header = array( 'Content-Type:'.'application/json; charset=UTF-8', 'Accept:application/json', 'User-Agent:*/*', 'Authorization: WECHATPAY2-SHA256-RSA2048 '.$token ); //向微信接口地址提交json格式的$data和header的头部信息,得到返回值 $ret = $this->curl_post_https($url,$data,$header); //如果是个code_url网址,则说明成功了。在浏览器里打开该地址测试是否能付钱。 // echo $ret; $resInfo = json_decode($ret, true); // var_dump($resInfo['h5_url']);die; // header("Location: ".$resInfo['h5_url']); echo ""; exit; } //虎皮椒 if($pay_method=='hpwx_pay'||$pay_method=='hpali_pay') { require_once(Yii::getAlias('@payerdrivers').'/xunhupay/api.php'); $order = $this->_initOrder($initData); if($pay_method=='hpwx_pay') { $appid = Yii::$app->params['pay']['hpwx_appid']; $appsecret = Yii::$app->params['pay']['hpwx_appsecret']; $my_plugin_id = Yii::$app->params['pay']['hpwx_pluginid']; $subject = $order->remark; $notify_url = Yii::$app->params['pay']['hpwx_notify_url']; //$return_url = Yii::$app->params['pay']['hpwx_return_url']; } else if($pay_method=='hpali_pay') { $appid = Yii::$app->params['pay']['hpali_appid']; $appsecret = Yii::$app->params['pay']['hpali_appsecret']; $my_plugin_id = Yii::$app->params['pay']['hpali_pluginid']; $subject = $order->remark; $notify_url = Yii::$app->params['pay']['hpali_notify_url']; //$return_url = Yii::$app->params['pay']['hpali_return_url']; } $data=array( 'version' => '1.1',//固定值,api 版本,目前暂时是1.1 'lang' => 'zh-cn', //必须的,zh-cn或en-us 或其他,根据语言显示页面 'plugins' => $my_plugin_id,//必须的,根据自己需要自定义插件ID,唯一的,匹配[a-zA-Z\d\-_]+ 'appid' => $appid, //必须的,APPID 'trade_order_id'=> $order_sn, //必须的,网站订单ID,唯一的,匹配[a-zA-Z\d\-_]+ 'payment' => $pay_method=='hpwx_pay'?'wechat':'alipay',//必须的,支付接口标识:wechat(微信接口)|alipay(支付宝接口) 'total_fee' => max(0,$total_price),//人民币,单位精确到分(测试账户只支持0.1元内付款) 'title' => $subject, //必须的,订单标题,长度32或以内 'time' => TIMESTAMP,//必须的,当前时间戳,根据此字段判断订单请求是否已超时,防止第三方攻击服务器 'notify_url'=> $notify_url, //必须的,支付成功异步回调接口 'return_url'=> $return_url,//必须的,支付成功后的跳转地址 'callback_url'=> APP_URL,//必须的,支付发起地址(未支付或支付失败,系统会会跳到这个地址让用户修改支付信息) 'modal'=>null, //可空,支付模式 ,可选值( full:返回完整的支付网页; qrcode:返回二维码; 空值:返回支付跳转链接) 'nonce_str' => str_shuffle(TIMESTAMP)//必须的,随机字符串,作用:1.避免服务器缓存,2.防止安全密钥被猜测出来 ); $hashkey = $appsecret; $data['hash'] = \XH_Payment_Api::generate_xh_hash($data,$hashkey); $url = 'https://api.xunhupay.com/payment/do.html'; try { $response = \XH_Payment_Api::http_post($url, json_encode($data)); $result = $response?json_decode($response,true):null; if(!$result){ echo_json([ 'error' => 1, 'msg' => 'Internal server error', 'code'=>500 ]); } $hash = \XH_Payment_Api::generate_xh_hash($result,$hashkey); if(!isset( $result['hash'])|| $hash!=$result['hash']){ echo_json([ 'error' => 1, 'msg' => 'Invalid sign!', 'code'=>500 ]); } if($result['errcode']!=0){ echo_json([ 'error' => 1, 'msg' => $result['errmsg'], 'code'=>$result['errcode'] ]); } $pay_url = $result['url']; header("Location: $pay_url"); exit; } catch (\Exception $e) { $result = [ 'error' => 1, 'msg' => $e->getMessage(), 'data' => [], 'code'=>200 ]; echo_json($result); } } } //生成二维码付款图片 public function actionCodeimg() { $initData = $_POST; extract($initData); //微信支付 if($paymethod=='weixin_pay') { if($this->_checkOrder($order_sn,$paymethod)) { $order_sn = getUniOrderNo(); $result = [ 'error' => 2, 'msg' => '需要生成新订单', 'data' => ['order_sn'=>$order_sn], 'code'=>200 ]; echo_json($result); } $order = $this->_initOrder($initData); try { $pay_money = max($total_price, 0.01); $resp = $this->wechatPay->chain('v3/pay/transactions/native') ->post(['json' => [ 'mchid' => $this->payconfig['weixin_mchid'], 'out_trade_no' => $order_sn, 'appid' => $this->payconfig['weixin_appid'], 'description' => $order->remark, 'notify_url' => $this->payconfig['weixin_notify_url'], 'amount' => [ 'total' => $pay_money*100, 'currency' => 'CNY' ], ]]); if($resp->getStatusCode()==200) { $respBody = json_decode($resp->getBody(),true); $code_url = APP_URL.'ajax/qrcode/?url='.$respBody['code_url']; $result = [ 'error' => 0, 'msg' => '操作成功', 'data' => ['code_url'=>$code_url,'order_sn'=>$order_sn], 'code'=>200 ]; echo_json($result); } } catch (\Exception $e) { $result = [ 'error' => 1, 'msg' => $e->getMessage(), 'data' => [], 'code'=>200 ]; echo_json($result); // 进行错误处理 /*echo $e->getMessage(), PHP_EOL; if ($e instanceof \GuzzleHttp\Exception\RequestException && $e->hasResponse()) { $r = $e->getResponse(); echo $r->getStatusCode() . ' ' . $r->getReasonPhrase(), PHP_EOL; echo $r->getBody(), PHP_EOL, PHP_EOL, PHP_EOL; } echo $e->getTraceAsString(), PHP_EOL;*/ } } //支付宝PC if($paymethod=='apd_pay') { require_once(Yii::getAlias('@payerdrivers').'/alipaypage/pagepay/service/AlipayTradeService.php'); require_once(Yii::getAlias('@payerdrivers').'/alipaypage/pagepay/buildermodel/AlipayTradePagePayContentBuilder.php'); if($this->_checkOrder($order_sn,$paymethod)) { $order_sn = getUniOrderNo(); $result = [ 'error' => 2, 'msg' => '需要生成新订单', 'data' => ['order_sn'=>$order_sn], 'code'=>200 ]; echo_json($result); } $order = $this->_initOrder($initData); $config = array ( //应用ID,您的APPID。 'app_id' => $this->payconfig['apd_appid'], //商户私钥 'merchant_private_key' => $this->payconfig['apd_merchant_private_key'], //异步通知地址 'notify_url' => $this->payconfig['apd_notify_url'], //同步跳转 'return_url' => $this->payconfig['apd_return_url'], //编码格式 'charset' => "UTF-8", //签名方式 'sign_type'=>"RSA2", //支付宝网关 'gatewayUrl' => "https://openapi.alipay.com/gateway.do", //支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。 'alipay_public_key' => $this->payconfig['apd_alipay_public_key'], //日志路径 'log_path' => $this->logdir.get_date(TIMESTAMP, "Y-m").'.txt', ); //商户订单号,商户网站订单系统中唯一订单号,必填 $out_trade_no = trim($order_sn); //订单名称,必填 $subject = $order->remark; //付款金额,必填 $total_amount = trim($total_price); //商品描述,可空 $body = ''; //构造参数 $payRequestBuilder = new \AlipayTradePagePayContentBuilder(); $payRequestBuilder->setBody($body); $payRequestBuilder->setSubject($subject); $payRequestBuilder->setTotalAmount($total_amount); $payRequestBuilder->setOutTradeNo($out_trade_no); $payRequestBuilder->setQrPayMode(4); $payRequestBuilder->setQrPayWidth(110); $aop = new \AlipayTradeService($config); $response = $aop->pagePay($payRequestBuilder,$config['return_url'],$config['notify_url']); //输出表单 $result = [ 'error' => 0, 'msg' => '操作成功', 'data' => ['code_url'=>APP_URL.'pay/alicode/?response='.urlencode($response),'order_sn'=>$order_sn], 'code'=>200 ]; echo_json($result); } //虎皮椒 if($paymethod=='hpwx_pay'||$paymethod=='hpali_pay') { require_once(Yii::getAlias('@payerdrivers').'/xunhupay/api.php'); if($this->_checkOrder($order_sn,$paymethod)) { $order_sn = getUniOrderNo(); $result = [ 'error' => 2, 'msg' => '需要生成新订单', 'data' => ['order_sn'=>$order_sn], 'code'=>200 ]; echo_json($result); } $order = $this->_initOrder($initData); if($paymethod=='hpwx_pay') { $appid = Yii::$app->params['pay']['hpwx_appid']; $appsecret = Yii::$app->params['pay']['hpwx_appsecret']; $my_plugin_id = Yii::$app->params['pay']['hpwx_pluginid']; $subject = $order->remark; $notify_url = Yii::$app->params['pay']['hpwx_notify_url']; $return_url = Yii::$app->params['pay']['hpwx_return_url']; } else if($paymethod=='hpali_pay') { $appid = Yii::$app->params['pay']['hpali_appid']; $appsecret = Yii::$app->params['pay']['hpali_appsecret']; $my_plugin_id = Yii::$app->params['pay']['hpali_pluginid']; $subject = $order->remark; $notify_url = Yii::$app->params['pay']['hpali_notify_url']; $return_url = Yii::$app->params['pay']['hpali_return_url']; } $data=array( 'version' => '1.1',//固定值,api 版本,目前暂时是1.1 'lang' => 'zh-cn', //必须的,zh-cn或en-us 或其他,根据语言显示页面 'plugins' => $my_plugin_id,//必须的,根据自己需要自定义插件ID,唯一的,匹配[a-zA-Z\d\-_]+ 'appid' => $appid, //必须的,APPID 'trade_order_id'=> $order_sn, //必须的,网站订单ID,唯一的,匹配[a-zA-Z\d\-_]+ 'payment' => $paymethod=='hpwx_pay'?'wechat':'alipay',//必须的,支付接口标识:wechat(微信接口)|alipay(支付宝接口) 'total_fee' => max(0,trim($total_price)),//人民币,单位精确到分(测试账户只支持0.1元内付款) 'title' => $subject, //必须的,订单标题,长度32或以内 'time' => TIMESTAMP,//必须的,当前时间戳,根据此字段判断订单请求是否已超时,防止第三方攻击服务器 'notify_url'=> $notify_url, //必须的,支付成功异步回调接口 'return_url'=> $return_url,//必须的,支付成功后的跳转地址 'callback_url'=> APP_URL,//必须的,支付发起地址(未支付或支付失败,系统会会跳到这个地址让用户修改支付信息) 'modal'=>null, //可空,支付模式 ,可选值( full:返回完整的支付网页; qrcode:返回二维码; 空值:返回支付跳转链接) 'nonce_str' => str_shuffle(TIMESTAMP)//必须的,随机字符串,作用:1.避免服务器缓存,2.防止安全密钥被猜测出来 ); $hashkey = $appsecret; $data['hash'] = \XH_Payment_Api::generate_xh_hash($data,$hashkey); $url = 'https://api.xunhupay.com/payment/do.html'; try { $response = \XH_Payment_Api::http_post($url, json_encode($data)); $result = $response?json_decode($response,true):null; if(!$result){ echo_json([ 'error' => 1, 'msg' => 'Internal server error', 'code'=>500 ]); } $hash = \XH_Payment_Api::generate_xh_hash($result,$hashkey); if(!isset( $result['hash'])|| $hash!=$result['hash']){ echo_json([ 'error' => 1, 'msg' => 'Invalid sign!', 'code'=>500 ]); } if($result['errcode']!=0){ echo_json([ 'error' => 1, 'msg' => $result['errmsg'], 'code'=>$result['errcode'] ]); } if($paymethod=='hpwx_pay'){ echo_json( [ 'error' => 0, 'msg' => '操作成功', 'data' => ['code_url'=>$result['url_qrcode'],'order_sn'=>$order_sn], 'code'=>200 ]); }else{ echo_json([ 'error' => 0, 'msg' => '操作成功', 'data' => ['code_url'=>APP_URL.'pay/paycode/?response='.urlencode($result['url_qrcode']),'order_sn'=>$order_sn], 'code'=>200 ]); } } catch (\Exception $e) { $result = [ 'error' => 1, 'msg' => $e->getMessage(), 'data' => [], 'code'=>200 ]; echo_json($result); } } } //生成支付宝二维码 public function actionAlicode() { echo $_GET['response']; } //对支付二维码做缩略图 public function actionPaycode() { $fileHash = md5($_GET['response']); $dstrootdir = THUMB_PATH.'paycode'.DIRECTORY_SEPARATOR; dir_create($dstrootdir); $resize = new \app\common\components\ResizeImage($_GET['response'], 110, 110,$fileHash, 0,0,$dstrootdir); $dstimg = $resize->dstimg; ob_clean(); header('Content-type: image/jpeg'); echo file_get_contents($dstimg); exit; } //微信支付回调 public function actionWeixincallback(){ $headers = $this->_getAllHeader(); //$this->payLog(var_export($headers,true)); $inWechatpaySignature = $headers['wechatpay-signature']; $inWechatpayTimestamp = $headers['wechatpay-timestamp']; $inWechatpaySerial = $headers['wechatpay-serial']; $inWechatpayNonce = $headers['wechatpay-nonce']; $inBody = file_get_contents('php://input'); $apiv3Key = $this->payconfig['weixin_v3secret'];// 在商户平台上设置的APIv3密钥 $platformPublicKeyInstance = Rsa::from('file://'.$this->payconfig['weixin_cert'], Rsa::KEY_TYPE_PUBLIC); // 检查通知时间偏移量,允许5分钟之内的偏移 $timeOffsetStatus = 300 >= abs(Formatter::timestamp() - (int)$inWechatpayTimestamp); $verifiedStatus = Rsa::verify( // 构造验签名串 Formatter::joinedByLineFeed($inWechatpayTimestamp, $inWechatpayNonce, $inBody), $inWechatpaySignature, $platformPublicKeyInstance ); if ($timeOffsetStatus && $verifiedStatus) { // 转换通知的JSON文本消息为PHP Array数组 $inBodyArray = (array)json_decode($inBody, true); // 使用PHP7的数据解构语法,从Array中解构并赋值变量 ['resource' => [ 'ciphertext' => $ciphertext, 'nonce' => $nonce, 'associated_data' => $aad ]] = $inBodyArray; // 加密文本消息解密 $inBodyResource = AesGcm::decrypt($ciphertext, $apiv3Key, $nonce, $aad); // 把解密后的文本转换为PHP Array数组 $inBodyResourceArray = (array)json_decode($inBodyResource, true); //$this->payLog(var_export($inBodyResourceArray,true)); if ($inBodyResourceArray['trade_state'] == 'SUCCESS') { // 这里写业务逻辑 if($this->_processOrder($inBodyResourceArray['out_trade_no'],($inBodyResourceArray['amount']['payer_total']/100),1, $inBodyResourceArray['payer']['openid'])) { $result = ['code'=>'SUCCESS','message'=>'成功',]; echo_json($result); } } } } //支付宝PC扫码支付回调 public function actionAlipaydirectnotify() { require_once(Yii::getAlias('@payerdrivers').'/alipaypage/pagepay/service/AlipayTradeService.php'); $config = array ( //应用ID,您的APPID。 'app_id' => $this->payconfig['apd_appid'], //商户私钥 'merchant_private_key' => $this->payconfig['apd_merchant_private_key'], //异步通知地址 'notify_url' => $this->payconfig['apd_notify_url'], //同步跳转 'return_url' => $this->payconfig['apd_return_url'], //编码格式 'charset' => "UTF-8", //签名方式 'sign_type'=>"RSA2", //支付宝网关 'gatewayUrl' => "https://openapi.alipay.com/gateway.do", //支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。 'alipay_public_key' => $this->payconfig['apd_alipay_public_key'], //日志路径 'log_path' => $this->logdir.get_date(TIMESTAMP, "Y-m").'.txt', ); $arr=$_POST; $alipaySevice = new \AlipayTradeService($config); $alipaySevice->writeLog(var_export($_POST,true)); $result = $alipaySevice->check($arr); /* 实际验证过程建议商户添加以下校验。 1、商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号, 2、判断total_amount是否确实为该订单的实际金额(即商户订单创建时的金额), 3、校验通知中的seller_id(或者seller_email) 是否为out_trade_no这笔单据的对应的操作方(有的时候,一个商户可能有多个seller_id/seller_email) 4、验证app_id是否为该商户本身。 */ if($result) {//验证成功 //请在这里加上商户的业务逻辑程序代 //——请根据您的业务逻辑来编写程序(以下代码仅作参考)—— //获取支付宝的通知返回参数,可参考技术文档中服务器异步通知参数列表 //商户订单号 $out_trade_no = $_POST['out_trade_no']; //支付宝交易号 $trade_no = $_POST['trade_no']; //交易状态 $trade_status = $_POST['trade_status']; $total_amount = $_POST['total_amount']; if($_POST['trade_status'] == 'TRADE_FINISHED') { $this->_processOrder($out_trade_no,$total_amount,3); } else if ($_POST['trade_status'] == 'TRADE_SUCCESS') { $this->_processOrder($out_trade_no,$total_amount,3); } //——请根据您的业务逻辑来编写程序(以上代码仅作参考)—— echo "success"; //请不要修改或删除 }else { //验证失败 echo "fail"; } } //支付成功之后的虎皮椒回调处理(微信) public function actionHpwxnotify() { try { require_once(Yii::getAlias('@payerdrivers').'/xunhupay/api.php'); $appid = Yii::$app->params['pay']['hpwx_appid']; $appsecret = Yii::$app->params['pay']['hpwx_appsecret']; $my_plugin_id = Yii::$app->params['pay']['hpwx_pluginid']; $data = $_POST; foreach ($data as $k=>$v){ $data[$k] = stripslashes($v); } if(!isset($data['hash'])||!isset($data['trade_order_id'])){ echo 'failed';exit; } //自定义插件ID,请与支付请求时一致 if(isset($data['plugins'])&&$data['plugins']!=$my_plugin_id){ echo 'failed';exit; } //APP SECRET $appkey =$appsecret; $hash =\XH_Payment_Api::generate_xh_hash($data,$appkey); if($data['hash']!=$hash){ //签名验证失败 echo 'failed';exit; } //商户订单ID $trade_order_id =$data['trade_order_id']; $total_fee = $data['total_fee']; if($data['status']=='OD'){ $this->_processOrder($trade_order_id,$total_fee,88); echo 'success'; exit; }else{ echo 'failed';exit; } } catch(\Exception $e) { $this->payLog($e->getMessage());exit; } } //支付成功之后的虎皮椒回调处理(支付宝) public function actionHpalinotify() { try { require_once(Yii::getAlias('@payerdrivers').'/xunhupay/api.php'); $appid = Yii::$app->params['pay']['hpali_appid']; $appsecret = Yii::$app->params['pay']['hpali_appsecret']; $my_plugin_id = Yii::$app->params['pay']['hpali_pluginid']; $data = $_POST; foreach ($data as $k=>$v){ $data[$k] = stripslashes($v); } if(!isset($data['hash'])||!isset($data['trade_order_id'])){ echo 'failed';exit; } //自定义插件ID,请与支付请求时一致 if(isset($data['plugins'])&&$data['plugins']!=$my_plugin_id){ echo 'failed';exit; } //APP SECRET $appkey =$appsecret; $hash =\XH_Payment_Api::generate_xh_hash($data,$appkey); if($data['hash']!=$hash){ //签名验证失败 echo 'failed';exit; } //商户订单ID $trade_order_id =$data['trade_order_id']; $total_fee = $data['total_fee']; if($data['status']=='OD'){ $this->_processOrder($trade_order_id,$total_fee,99); echo 'success'; exit; }else{ echo 'failed';exit; } } catch(\Exception $e) { $this->payLog($e->getMessage());exit; } } //手机端支付宝回调 public function actionAlipaywapnotify() { require_once(Yii::getAlias('@payerdrivers').'/alipaywap/wappay/service/AlipayTradeService.php'); $config = array ( //应用ID,您的APPID。 'app_id' => $this->payconfig['apw_appid'], //商户私钥,您的原始格式RSA私钥 'merchant_private_key' => $this->payconfig['apw_merchant_private_key'], //异步通知地址 'notify_url' => $this->payconfig['apw_notify_url'], //同步跳转 'return_url' => $this->payconfig['apw_return_url'], //编码格式 'charset' => "UTF-8", //签名方式 'sign_type'=>"RSA2", //支付宝网关 'gatewayUrl' => "https://openapi.alipay.com/gateway.do", //支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。 'alipay_public_key' => $this->payconfig['apw_alipay_public_key'], //日志路径 'log_path' => $this->logdir.get_date(TIMESTAMP, "Y-m").'.txt', ); $arr=$_POST; $alipaySevice = new \AlipayTradeService($config); $alipaySevice->writeLog(var_export($_POST,true)); $this->payLog(var_export($_POST,true)); $result = $alipaySevice->check($arr); /* 实际验证过程建议商户添加以下校验。 1、商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号, 2、判断total_amount是否确实为该订单的实际金额(即商户订单创建时的金额), 3、校验通知中的seller_id(或者seller_email) 是否为out_trade_no这笔单据的对应的操作方(有的时候,一个商户可能有多个seller_id/seller_email) 4、验证app_id是否为该商户本身。 */ if($result) {//验证成功 //请在这里加上商户的业务逻辑程序代 //——请根据您的业务逻辑来编写程序(以下代码仅作参考)—— //获取支付宝的通知返回参数,可参考技术文档中服务器异步通知参数列表 //商户订单号 $out_trade_no = $_POST['out_trade_no']; //支付宝交易号 $trade_no = $_POST['trade_no']; //交易状态 $trade_status = $_POST['trade_status']; $total_amount = $_POST['total_amount']; if($_POST['trade_status'] == 'TRADE_FINISHED') { $this->_processOrder($out_trade_no,$total_amount,3); } else if ($_POST['trade_status'] == 'TRADE_SUCCESS') { $this->_processOrder($out_trade_no,$total_amount,3); } //——请根据您的业务逻辑来编写程序(以上代码仅作参考)—— echo "success"; //请不要修改或删除 }else { //验证失败 echo "fail"; } } //检测订单是否存在 private function _checkOrder($order_sn,$pay_method) { $exist = ShoppingPaycode::find()->where("order_sn='".$order_sn."' and pay_method='".$pay_method."'")->exists(); if($exist) { return true; } else { $paycode = new ShoppingPaycode(); $paycode->order_sn = $order_sn; $paycode->pay_method = $pay_method; $paycode->create_time = TIMESTAMP; $paycode->save(); return false; } } //初始化订单 private function _initOrder($initData) { extract($initData); $order = ShoppingOrder::find()->where("order_sn='".$order_sn."'")->one(); if($order) { return $order; } else { //充值金币 if($act=='coinrecharge'){ $pay_credit = $act.'_'.$coin_num; $order_type = 2; $remark = '充值'.Yii::$app->params['coin']['coin_name']; } //开通VIP if($act=='buyvip'){ $userVipType = UserVipType::findOne($vip_type); $pay_credit = $act.'_'.$vip_type; $order_type = 3; $remark = '开通VIP-'.$userVipType->title; } //购买文档 if($act=='buydoc'){ $pay_credit = $act.'_'.$id; $order_type = 1; $remark = '购买文档'; } //百度搜索词 $baidukw = \app\common\helpers\Cookie::getCookie(Yii::$app->params['baidukwName']); $order = new ShoppingOrder(); $order->user_id = intval($this->userInfo['user_id']); $order->order_sn = $order_sn; $order->pay_credit = $pay_credit; $order->total_price = $total_price; $order->discount_price = $discount_price; $order->remark = $remark; $order->order_type = $order_type; $order->status = 0; $order->ad_words = $baidukw?urldecode($baidukw):''; $order->request_from = REQUEST_FROM; $order->create_time = TIMESTAMP; $order->save(); return $order; } } // 获取header头的方法 private function _getAllHeader() { // 忽略获取的header数据。这个函数后面会用到。主要是起过滤作用 $ignore = array('host','accept','content-length','content-type','connection','accept-encoding'); $headers = array(); //这里大家有兴趣的话,可以打印一下。会出来很多的header头信息。咱们想要的部分,都是‘http_'开头的。所以下面会进行过滤输出。 foreach($_SERVER as $key=>$value){ if(substr($key, 0, 5)==='HTTP_'){ //这里取到的都是'http_'开头的数据。 //前去开头的前5位 $key = substr($key, 5); //把$key中的'_'下划线都替换为空字符串 $key = str_replace('_', ' ', $key); //再把$key中的空字符串替换成‘-’ $key = str_replace(' ', '-', $key); //把$key中的所有字符转换为小写 $key = strtolower($key); //这里主要是过滤上面写的$ignore数组中的数据 if(!in_array($key, $ignore)){ $headers[$key] = $value; } } }//输出获取到的header return $headers; } // 记录日志 public function payLog($word) { $logFile = $this->logdir.get_date(TIMESTAMP, "Y-m").'.txt'; $fp = fopen($logFile, "a"); flock($fp, LOCK_EX) ; fwrite($fp, get_date(TIMESTAMP, "Y-m-d H:i:s").' | '.$word."\r\n"); flock($fp, LOCK_UN); fclose($fp); } //支付成功后处理业务逻辑 public function _processOrder($order_sn,$total_price,$pay_method,$openid='') { $order = ShoppingOrder::find()->where("order_sn='".$order_sn."'")->one(); if($order&&$order->status==0) { $order->status = $order->is_virtual==1?9:1; $order->pay_time = strval(TIMESTAMP); $order->pay_method = $pay_method; if($order->save()) { //充值金币 if(strpos($order->pay_credit,'coinrecharge')!==false) { $coin_num = str_replace('coinrecharge_','',$order->pay_credit); Wallet::coinChange($order->user_id,$coin_num,$order->remark,1); } //开通VIP if(strpos($order->pay_credit,'buyvip')!==false) { $vip_type = str_replace('buyvip_','',$order->pay_credit); $userVipType = UserVipType::findOne($vip_type); $userVipOrder = UserVipOrder::findOne($order->order_id); //付款金额校验 if($userVipType&&$order->total_price==$userVipType->price) { //判断是否是续费 $vipInfo = UserVipOrder::find()->where("user_id='".$order->user_id."' and vip_type=$vip_type and status=1 and (expire_time>=".TIMESTAMP." or expire_time=0) and order_id!='".$order->order_id."'")->orderBy(['order_id'=>SORT_DESC])->limit(1)->one(); if($vipInfo) { $startTime = $vipInfo->expire_time; } else { $startTime = TIMESTAMP; } if(empty($userVipOrder)) { $userVipOrder = new UserVipOrder(); } $userVipOrder->order_id = $order->order_id; $userVipOrder->user_id = $order->user_id; $userVipOrder->vip_type = $vip_type; $userVipOrder->money = $total_price; $userVipOrder->days = $userVipType->days; $userVipOrder->settings = $userVipType->settings; $userVipOrder->expire_time = $userVipType->forever==1?0:$startTime+$userVipType->days*24*3600; $userVipOrder->create_time = TIMESTAMP; $userVipOrder->status = 1; if($userVipOrder->save()) { $vipSettings = string2array($userVipType->settings); //如果有赠送金币 if(intval($vipSettings['coin_num'])>0) { Wallet::coinChange($order->user_id,$vipSettings['coin_num'],'开通会员赠送金币',1); } //处理分销 Wallet::vipCommission($order->user_id,$userVipOrder); } } } //购买文档 if(strpos($order->pay_credit,'buydoc')!==false) { $id = str_replace('buydoc_','',$order->pay_credit); $this->addDownCode($id,$order); } //百度竞价跟踪 $bd_vid = \app\common\helpers\Cookie::getCookie('bd_vid'); if(!empty($bd_vid)) { $higherconfigResult = \app\modules\admin\models\Config::find()->where("name='higherconfig'")->one(); $higherconfig = string2array($higherconfigResult->value); $token = $higherconfig['cpc_token']; if(!empty($token)) { $cv = array( 'logidUrl' => APP_URL.'?bd_vid='.$bd_vid, // 您的落地页url 'newType' => 10 // 转化类型请按实际情况填写 ); $conversionTypes = array($cv); $baiducpc = new \app\common\components\BaiduCpc(); $baiducpc->sendConvertData($token, $conversionTypes); } } } return true; } else { return false; } } //获取订单状态 public function actionOrderstatus() { $order_sn = Yii::$app->request->get('order_sn'); if($order_sn) { $order = ShoppingOrder::find()->where("order_sn='".$order_sn."'")->one(); if(!empty($order)) { if($order->status==1||$order->status==9) { $data = []; //购买文档 if(strpos($order->pay_credit,'buydoc')!==false) { $downCode = DocDowncode::find()->where("openid='".$order_sn."'")->one(); $data['downurl'] = SiteUrl::docDownByCode($downCode->downcode,1); $data['downcode'] = $downCode->downcode; } $result = [ 'error' => 0, 'msg' => '支付成功', 'data' => $data, 'code'=>200 ]; echo_json($result); } } else { $result = [ 'error' => 1, 'msg' => '订单不存在', 'code'=>200 ]; echo_json($result); } } else { $result = [ 'error' => 1, 'msg' => '缺少参数', 'code'=>200 ]; echo_json($result); } } //购买文档 public function addDownCode($doc_id,$order) { try { $doc = DocReal::findOne($doc_id); $downCode = new \app\modules\doc\models\DocDowncode(); $downCode->doc_id = $doc_id; $downCode->user_id = intval($order->user_id); $downCode->openid = $order->order_sn; $downCode->downcode = strval(getDowncode($doc->id)); $downCode->doc_user_id = $doc->user_id; $downCode->type = 2; $downCode->create_time = TIMESTAMP; $downCode->save(); //判断用户VIP权限情况 if($order->user_id) $vipSettings = User::findOne($order->user_id)->vipSettings(); //如果是机构推广文档,标记推广文档订单 if($doc->is_ad) { $store = \app\modules\shopping\models\ShoppingStore::find()->where("user_id=".$doc->user_id)->one(); if($store) { $order->store_id = $store->store_id; $order->save(); } } //将价格转成金币数量 $coin_num = $order->total_price*Yii::$app->params['coin']['coin_recharge_rate']; //生成支付记录 $paylog = new \app\modules\doc\models\DocPaylog(); $paylog->user_id = intval($order->user_id); $paylog->doc_user_id = intval($doc->user_id); $paylog->doc_id = $doc->id; $paylog->cat_id = $doc->cat_id; $paylog->cat_ids = $doc->cat_ids; $paylog->doc_type = $doc->doc_type; $paylog->is_vip = ($doc->is_vip||$vipSettings['buy_doc_discount']<100)?1:0; $paylog->coin_price = $doc->coin_price; $paylog->coin_num = $coin_num; $paylog->agent_id = intval($order->user->referer_id); $paylog->agent_ids = strval($order->user->referer_ids); $paylog->create_time = TIMESTAMP; if($paylog->save()) { $doc->updateCounters(['sales'=>1]); $left_coin = $coin_num; $point_num = intval($order->total_price*Yii::$app->params['point']['rmb_price_rate']); //购买方 $logTitleBuy = '购买'.DocReal::typeOptions($doc->doc_type); if($order->user_id) { Wallet::pointChange($order->user_id,$point_num,$logTitleBuy,1,'point',DocReal::shortTableName(),$doc->id); //处理分销 $left_coin = Wallet::docCommission($order->user_id,$doc,$paylog,$left_coin); } //出售方 $logTitleSell = '出售'.DocReal::typeOptions($doc->doc_type); if($left_coin>0&&$doc->user_id) { //金币变化 Wallet::coinChange($doc->user_id,$left_coin,$logTitleSell,1,'coin_income',DocReal::shortTableName(),$doc->id); //消息通知 MessageOne::soldDoc($logTitleSell,$doc,$left_coin); } return true; } else { $this->payLog($paylog->returnFirstError()); } } catch(\Exception $e) { $this->payLog($e->getMessage());exit; } } //初始化视图 public function initForm($pay_method) { $view = $pay_method; $this->setView($view); $this->setData(array("return_url"=>$this->return_url)); $this->getFormHtml(); } //微信支付签名 public function getSign($data = [], $url, $randstr, $time) { $str = "POST" . "\n" . $url . "\n" . $time . "\n" . $randstr . "\n" . $data . "\n"; $key = file_get_contents($this->payconfig['weixin_apiclient_key']);//在商户平台下载的秘钥 $str = $this->getSha256WithRSA($str, $key); return $str; } //调起支付的签名 public function getWechartSign($appid, $timeStamp, $noncestr, $prepay_id) { $str = $appid . "\n" . $timeStamp . "\n" . $noncestr . "\n" . $prepay_id . "\n"; $key = file_get_contents($this->payconfig['weixin_apiclient_key']); $str = $this->getSha256WithRSA($str, $key); return $str; } public function getSha256WithRSA($content, $privateKey) { $binary_signature = ""; $algo = "SHA256"; openssl_sign($content, $binary_signature, $privateKey, $algo); $sign = base64_encode($binary_signature); return $sign; } function curl_post_https($url,$data,$header){ // 模拟提交数据函数 $curl = curl_init(); // 启动一个CURL会话 curl_setopt($curl, CURLOPT_URL, $url); // 要访问的地址 curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); // 对认证证书来源的检查 curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0); // 从证书中检查SSL加密算法是否存在,如果出错则修改为0,默认为1 curl_setopt($curl, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']); // 模拟用户使用的浏览器 curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); // 使用自动跳转 curl_setopt($curl, CURLOPT_AUTOREFERER, 1); // 自动设置Referer curl_setopt($curl, CURLOPT_POST, 1); // 发送一个常规的Post请求 curl_setopt($curl, CURLOPT_POSTFIELDS, $data); // Post提交的数据包 curl_setopt($curl, CURLOPT_TIMEOUT, 30); // 设置超时限制防止死循环 curl_setopt($curl, CURLOPT_HEADER, 0); // 显示返回的Header区域内容 curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); // 获取的信息以文件流的形式返回 curl_setopt($curl, CURLOPT_HTTPHEADER, $header); $tmpInfo = curl_exec($curl); // 执行操作 if (curl_errno($curl)) { echo 'Errno'.curl_error($curl);//捕抓异常 } curl_close($curl); // 关闭CURL会话 return $tmpInfo; // 返回数据,json格式 } }