```
<?php
namespace app\api\controller;
use think\Controller;
use think\Db;
use think\Session;
class Wxpay extends \think\Controller
{
// 扫码支付回调
public function callback()
{
//$this->writelog('--收到一次服务端','微信支付');
return "1";
}
public function wxpaywxok(){
// halt("22");exit();
$content=session('wxpaydata');
$sn=$content['out_trade_no'];
$ispay=Db::table('wp_balance')->where('balance_sn',$sn)->value('bptype');
// 启动事务
Db::startTrans();
if($ispay==1){
exit();
}else{
// ******************
$notify_fee =$content['price']; //实际支付金额
$times =time(); //支付时间
$sdorderno=$sn; //用户自己的订单号
$uid=Db::table('wp_balance')->where('balance_sn',$sdorderno)->value('uid');
$money=Db::table('wp_userinfo')->where('uid',$uid)->value('usermoney');
$money1=$money+$notify_fee;
//用户表
$res1= Db::table('wp_userinfo')->where('uid',$uid)->setField('usermoney',$money1);
if($res1!=0){
//充值表
$aaaa=['isverified'=>1,'cltime'=>$times,'bptype'=>1,'bptime'=>$times,'bpprice'=>$notify_fee,'remarks'=>'会员充值','bpbalance'=>$money1,'btime'=>$times,'reg_par'=>0];
$ispay=Db::table('wp_balance')->where('balance_sn',$sn)->value('bptype');
if($ispay==1){
// 回滚事务
Db::rollback();
exit();
}
$res2= Db::table('wp_balance')->where('balance_sn',$sdorderno)->update($aaaa);
if($res2!=0){
// 提交事务
Db::commit();
session('wxpaydata',null);
return $this->fetch('refurn');
}else{
// 回滚事务
Db::rollback();
exit();
}
}else{
// 回滚事务
Db::rollback();
exit();
}
}
}
// 公众号支付
public function wxpaywx(){
header('Content-type:text/html;charset=utf-8');
$res = $this->request->param();
$price=$res['bpprice'];
$bpid=$res['bpid'];
$data['price']=$price;
$data['out_trade_no']='HA9876'.time();
//充值表
Db::table('wp_balance')->where('bpid',$bpid)->setField('balance_sn',$data['out_trade_no']);
session('wxpaydata',$data);
//halt($data);exit();
header('Location:http://www.xkhcmb.cn/wxpay/example/jsapi.php');
}
public function query(){
$data = $this->request->param();
// $this->writelog('--post1='.$data['nonce_str'],'原生微信1');
$url='https://api.mch.weixin.qq.com/pay/orderquery';
//统一下单参数构造
$unifiedorder = array(
'appid' => 'wx82915a4679072381',
'mch_id' =>'1526299621',
'nonce_str' => $data['nonce_str'],
'out_trade_no' =>$data['out_trade_no'],
);
$unifiedorder['sign'] = $this->makeSign($unifiedorder);
//请求数据,统一下单
$xmldata = $this->array2xml($unifiedorder);
$res = $this->curl_post_ssl($url, $xmldata);
$content = $this->xml2array($res);
//halt($content);exit();
if($content['trade_state']=='SUCCESS'){
$sn=$content['out_trade_no'];
$ispay=Db::table('wp_balance')->where('balance_sn',$sn)->value('bptype');
// 启动事务
Db::startTrans();
if($ispay==1){
return ['status'=>0, 'message'=>'支付失败'];
}else{
// ******************
$notify_fee =$content['total_fee']/100; //实际支付金额
$times =time(); //支付时间
$sdorderno=$sn; //用户自己的订单号
$uid=Db::table('wp_balance')->where('balance_sn',$sdorderno)->value('uid');
$money=Db::table('wp_userinfo')->where('uid',$uid)->value('usermoney');
$money1=$money+$notify_fee;
//用户表
$res1= Db::table('wp_userinfo')->where('uid',$uid)->setField('usermoney',$money1);
if($res1!=0){
//充值表
$aaaa=['isverified'=>1,'cltime'=>$times,'bptype'=>1,'bptime'=>$times,'bpprice'=>$notify_fee,'remarks'=>'会员充值','bpbalance'=>$money1,'btime'=>$times,'reg_par'=>0];
$ispay=Db::table('wp_balance')->where('balance_sn',$sn)->value('bptype');
if($ispay==1){
// 回滚事务
Db::rollback();
return ['status'=>0, 'message'=>'支付失败'];
}
$res2= Db::table('wp_balance')->where('balance_sn',$sdorderno)->update($aaaa);
if($res2!=0){
// 提交事务
Db::commit();
return ['status'=>1, 'message'=>'支付成功'];
}else{
// 回滚事务
Db::rollback();
return ['status'=>0, 'message'=>'支付失败'];
}
}else{
// 回滚事务
Db::rollback();
return ['status'=>0, 'message'=>'支付失败'];
}
}
}else{
return ['status'=>0, 'message'=>'支付失败'];
}
}
// 扫码支付
public function wxpay(){
$res = $this->request->param();
$price=$res['bpprice'];
$bpid=$res['bpid'];
//统一下单参数构造
$unifiedorder = array(
'appid' => 'wx82915a4679072381',
'mch_id' =>'1526299621',
'nonce_str' => $this->getNonceStr(),
'body' => '会员充值',
'out_trade_no' =>'HA9876'.time(),
'total_fee' => $price*100,
//'total_fee' => 1,
'spbill_create_ip' => $this->getip(),
'notify_url' => 'http://www.xkhcmb.cn/api/wxpay/callback/',
'trade_type' => 'NATIVE',
);
$unifiedorder['sign'] = $this->makeSign($unifiedorder);
//充值表
Db::table('wp_balance')->where('bpid',$bpid)->setField('balance_sn',$unifiedorder['out_trade_no']);
//请求数据,统一下单
$xmldata = $this->array2xml($unifiedorder);
$url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
$res1 = $this->curl_post_ssl($url, $xmldata);
//halt('11');exit();
$content = $this->xml2array($res1);
if($content['return_code']=='SUCCESS'){
$this->assign('aaaa',$content['code_url']);
$this->assign('out_trade_no',$unifiedorder['out_trade_no']);
$this->assign('money',$unifiedorder['total_fee']/100);
$this->assign('nonce_str',$unifiedorder['nonce_str']);
return $this->fetch('index');
}else{
halt('支付类型有误!请联系技术人员');exit();
}
}
//-------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------用到的函数------------------------------------------------------
/**
* 将一个数组转换为 XML 结构的字符串
* @param array $arr 要转换的数组
* @param int $level 节点层级, 1 为 Root.
* @return string XML 结构的字符串
*/
protected function array2xml($arr, $level = 1) {
$s = $level == 1 ? "<xml>" : '';
foreach($arr as $tagname => $value) {
if (is_numeric($tagname)) {
$tagname = $value['TagName'];
unset($value['TagName']);
}
if(!is_array($value)) {
$s .= "<{$tagname}>".(!is_numeric($value) ? '<![CDATA[' : '').$value.(!is_numeric($value) ? ']]>' : '')."</{$tagname}>";
} else {
$s .= "<{$tagname}>" . $this->array2xml($value, $level + 1)."</{$tagname}>";
}
}
$s = preg_replace("/([\x01-\x08\x0b-\x0c\x0e-\x1f])+/", ' ', $s);
return $level == 1 ? $s."</xml>" : $s;
}
/**
* 将xml转为array
* @param string $xml xml字符串
* @return array 转换得到的数组
*/
protected function xml2array($xml){
//禁止引用外部xml实体
libxml_disable_entity_loader(true);
$result= json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
return $result;
}
/**
*
* 产生随机字符串,不长于32位
* @param int $length
* @return 产生的随机字符串
*/
protected function getNonceStr($length = 32) {
$chars = "abcdefghijklmnopqrstuvwxyz0123456789";
$str ="";
for ( $i = 0; $i < $length; $i++ ) {
$str .= substr($chars, mt_rand(0, strlen($chars)-1), 1);
}
return $str;
}
/**
* 生成签名
* @return 签名
*/
protected function makeSign($data){
//获取微信支付秘钥
$key ='AAAwwwxkhcmbcnwwwxkhcmbcnBBB1234';
// 去空
$data=array_filter($data);
//签名步骤一:按字典序排序参数
ksort($data);
$string_a=http_build_query($data);
$string_a=urldecode($string_a);
//签名步骤二:在string后加入KEY
$string_sign_temp=$string_a."&key=".$key;
//签名步骤三:MD5加密
$sign = md5($string_sign_temp);
// 签名步骤四:所有字符转为大写
$result=strtoupper($sign);
return $result;
}
/**
* 获取IP地址
* @return [String] [ip地址]
*/
protected function getip() {
static $ip = '';
$ip = $_SERVER['REMOTE_ADDR'];
if(isset($_SERVER['HTTP_CDN_SRC_IP'])) {
$ip = $_SERVER['HTTP_CDN_SRC_IP'];
} elseif (isset($_SERVER['HTTP_CLIENT_IP']) && preg_match('/^([0-9]{1,3}\.){3}[0-9]{1,3}$/', $_SERVER['HTTP_CLIENT_IP'])) {
$ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif(isset($_SERVER['HTTP_X_FORWARDED_FOR']) AND preg_match_all('#\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}#s', $_SERVER['HTTP_X_FORWARDED_FOR'], $matches)) {
foreach ($matches[0] AS $xip) {
if (!preg_match('#^(10|172\.16|192\.168)\.#', $xip)) {
$ip = $xip;
break;
}
}
}
return $ip;
}
/**
* 微信支付发起请求
*/
protected function curl_post_ssl($url, $xmldata, $second=30,$aHeader=array()){
$ch = curl_init();
//超时时间
curl_setopt($ch,CURLOPT_TIMEOUT,$second);
curl_setopt($ch,CURLOPT_RETURNTRANSFER, 1);
//这里设置代理,如果有的话
//curl_setopt($ch,CURLOPT_PROXY, '10.206.30.98');
//curl_setopt($ch,CURLOPT_PROXYPORT, 8080);
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false);
curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,0);
curl_setopt($ch, CURLOPT_SSLVERSION, 1);
//curl_setopt($ch,CURLOPT_CAINFO,$config['rootca']);
if( count($aHeader) >= 1 ){
curl_setopt($ch, CURLOPT_HTTPHEADER, $aHeader);
}
curl_setopt($ch,CURLOPT_POST, true);
curl_setopt($ch,CURLOPT_POSTFIELDS,$xmldata);
$data = curl_exec($ch);
if($data){
curl_close($ch);
return $data;
}else {
$error = curl_errno($ch);
echo "call faild, errorCode:$error\n";
curl_close($ch);
return false;
}
}
public function writelog($text, $aType='')
{
$text = $this->characet1($text);
file_put_contents (dirname ( __FILE__ )."/fb1log_".$aType._. date( "Y-m-d" ).".txt", date ( "Y-m-d H:i:s" ) . " " . $text . "\r\n", FILE_APPEND );
}
function characet1($data)
{
if (! empty ( $data ))
{
$fileType = mb_detect_encoding ( $data, array (
'UTF-8',
'GBK',
'GB2312',
'LATIN1',
'BIG5'
) );
if ($fileType != 'UTF-8')
{
$data = mb_convert_encoding ( $data, 'UTF-8', $fileType );
}
}
return $data;
}
//支付跳转
public function refurn()
{
return $this->fetch();
}
}
```