您现在的位置是:网站首页 > 脚本编程>

thinkphp3.2.3 整合微信支付(JsApiPay)

2018-02-13247人围观
简介 最近做了一个项目需要整合微信支付,下载了鹅厂出的SDK和文档,就是让你看不懂,使劲绕 这酸爽的劲啊你用了就知道。一般来说文档和sdk越简单越好吗?难道只有使劲重构才能显示出鹅厂程序猿技术的高超嘛?这..这..是不是暴露了我菜鸟的属性?玩笑了.....<_<

最近做了一个项目需要整合微信支付,下载了鹅厂出的SDK和文档,就是让你看不懂,使劲绕 这酸爽的劲啊你用了就知道。一般来说文档和sdk越简单越好吗?难道只有使劲重构才能显示出鹅厂程序猿技术的高超嘛?这..这..是不是暴露了我菜鸟的属性?返回正题。

官方SDK和DEMO下载地址

https://pay.weixin.qq.com/wiki/doc/api/download/WxpayAPI_php.zip

1.微信的支付流程

1550046272758554.png

2.设置支付目录

请确保实际支付时的请求目录与后台配置的目录一致(现在已经支持配置根目录,配置后有一定的生效时间,一般5分钟内生效),否则将无法成功唤起微信支付。

在微信商户平台(pay.weixin.qq.com)设置您的JSAPI支付支付目录,设置路径:商户平台-->产品中心-->开发配置,如图下图所示。JSAPI支付在请求支付的时候会校验请求来源是否有在商户平台做了配置,所以必须确保支付目录已经正确的被配置,否则将验证失败,请求支付不成功。

1550046353680536.png

3.设置授权域名

开发JSAPI支付时,在统一下单接口中要求必传用户openid,而获取openid则需要您在公众平台设置获取openid的域名,只有被设置过的域名才是一个有效的获取openid的域名,否则将获取失败。

1550046403690760.png

4.将官方的SDK重构后放到TP的Library/Vendor目录下(结构如下图)

目录结构.jpg

5.在支付控制器中引入微信支付SDK

public function _initialize()
{   
    vendor('Wxpay.Setpaydata');   
}

该文件是对微信的各个类进行调用实现统一下单(修改的SDK下载地址)。

链接:https://pan.baidu.com/s/113JIubIsvx7Yqxj5sy6baw 

提取码:5l5b 

6.进行支付调用


public function index()
{
    $pay=$_POST['pay'];
    $WIDout_trade_no=$_POST['WIDout_trade_no'];
    $WIDsubject=$_POST['WIDsubject'];
    $WIDtotal_fee=$_POST['WIDtotal_fee'];
    switch($pay)
    {
        case 1:
        //支付宝支付
        $this->doalipay($WIDout_trade_no,$WIDsubject,$WIDtotal_fee);
        break; 
        case 2:
        //调用微信支付
        $WIDtotal_fees=floor($WIDtotal_fee*100);//价格 微信用分计算
        $_SESSION['out_trade_no']=$WIDout_trade_no;//订单号
        $_SESSION['subject']=$WIDsubject;//订单名称
        $_SESSION['total_fee']=$WIDtotal_fees;
        $this->doweixin($WIDout_trade_no,$WIDsubject,$WIDtotal_fee);
        break; 
        default :
        //微信第二次调用
    $code=$_REQUEST['code'];//在没有进行微信登录的情况下进行微信支付 获取到CODE用来获取OPENID。
    $this->doweixin($WIDout_trade_no,$WIDsubject,$WIDtotal_fee,$code);
    break; 
    }
}

7.微信支付将价格等信息传送到前端实现js调用微信支付

public function doweixin($WIDout_trade_no,$WIDsubject,$WIDtotal_fee,$code)
{
    //商户订单号
    $out_trade_no = empty($WIDout_trade_no)?$_SESSION['out_trade_no']:$WIDout_trade_no; //商户网站订单系统中唯一订单号,必填
    //订单名称
    $subject =  empty($WIDsubject)?$_SESSION['subject']:$WIDsubject; //必填
    //付款金额
    $total_fee =  empty($WIDtotal_fee)?$_SESSION['total_fee']:$WIDtotal_fee; //必填
    $WxpaySubmit = new \WxpaySubmit();
    $alipay = $WxpaySubmit->go_pay($subject,$total_fee,$out_trade_no,$code);
    $this->assign("alipay",$alipay);
    $this->assign("out_trade_no",$out_trade_no);
    $this->assign("total_fee",($total_fee/100));
    $this->assign("subject",$subject);
    $this->display("doweixin");
}


8.微信前端代码

<html>
<head>
    <meta http-equiv="content-type" content="text/html;charset=utf-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1"/> 
    <script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
    <title>微信支付</title>
    <script type="text/javascript">
    //调用微信JS api 支付
    var data = {$alipay.jsApiParameters};
    function jsApiCall()
    {
        WeixinJSBridge.invoke(
        'getBrandWCPayRequest',data,
        function(res){
        WeixinJSBridge.log(res.err_msg);
        //alert(res.err_code+res.err_desc+res.err_msg);
        if(res.err_msg == "get_brand_wcpay_request:ok")
        { 
           alert("支付成功!"); 
            window.location.href="{:U('Member/order')}";
        }else if(res.err_msg == "get_brand_wcpay_request:cancel"){ 
         alert("取消支付!"); 
        }else{ 
         alert("支付失败!"); 
        } 
        }
        );
    }
function callpay()
{
    if (typeof WeixinJSBridge == "undefined"){
        if( document.addEventListener ){
            document.addEventListener('WeixinJSBridgeReady', jsApiCall, false);
        }else if (document.attachEvent){
            document.attachEvent('WeixinJSBridgeReady', jsApiCall); 
            document.attachEvent('onWeixinJSBridgeReady', jsApiCall);
        }
    }else{
        jsApiCall();
    }
}
</script>
</head>
<body>
    <div>
<p>商品名称:{$subject}<p>
<p>支付金额:{$total_fee}元<p>
<p>订单号:{$out_trade_no}<p>
</div>
<div align="center">
<button style="width:210px; height:50px; border-radius: 15px;background-color:#000; border:0px #000 solid; cursor: pointer;  color:white;  font-size:16px;" type="button"onclick="callpay()" >立即支付</button>
</div>
</body>
</html>

9.微信支付回调及相关函数

//微信支付回调
public function wxnotify()
{
	$xml = $GLOBALS['HTTP_RAW_POST_DATA']; 
	// 这句file_put_contents是用来查看服务器返回的XML数据 测试完可以删除了 
	file_put_contents('./log/log.txt',$xml,FILE_APPEND); 
	$data = $this->xmlToArray($xml); 
	// 保存微信服务器返回的签名sign 
	$data_sign = $data['sign']; 
	// sign不参与签名算法 
	unset($data['sign']); 
	$sign = $this->makeSign($data); 
	// 判断签名是否正确 判断支付状态 
	if ( ($sign===$data_sign) && ($data['return_code']=='SUCCESS') && ($data['result_code']=='SUCCESS') )
	{ 
		$result = $data; 
		// 这句file_put_contents是用来查看服务器返回的XML数据 测试完可以删除了 
		file_put_contents('./log/log1.txt',$xml,FILE_APPEND);   
		$parameter = array(
			'orderid' => $data['out_trade_no'],//订单单号 
			'paystatus' =>1,
			'trade_no' =>$data['transaction_id'],//交易单号 
			'paytype' =>"微信支付",/
		);
		if(!D("Payset")->checkorderstatus($data['out_trade_no']))
		{
			D("Payset")->orderhandle($parameter);
		}else{ 
			$result = false; 
		} 
		// 返回状态给微信服务器 
		if ($result) { 				$str='<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>'; 
		}else{ 
			$str='<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[签名失败]]></return_msg></xml>'; 
		 } 
			echo $str;
	}
}
//加密校验
protected function makeSign($data){ 
	 //获取微信支付秘钥 
	 $key = "BshYcLAcAnJwx0cLDokeeEPlZVCpbT9Q"; 
	 // 去空 
	 $data=array_filter($data); 
	 //签名步骤一:按字典序排序参数 
	 ksort($data); 
	 $string_a=http_build_query($data); 
	 $string_a=urldecode($string_a); 
	 //签名步骤二:在string后加入KEY 
	 //$config=$this->config; 
	 $string_sign_temp=$string_a."&key=".$key; 
	 //签名步骤三:MD5加密 
	 $sign = md5($string_sign_temp); 
	 // 签名步骤四:所有字符转为大写 
	 $result=strtoupper($sign); 
	 return $result; 
}

//xml转换数组
function xmlToArray($xml)
{
    //考虑到xml文档中可能会包含<![CDATA[]]>标签,第三个参数设置为LIBXML_NOCDATA
    if (file_exists($xml)) {
        libxml_disable_entity_loader(false);
        $xml_string = simplexml_load_file($xml,'SimpleXMLElement', LIBXML_NOCDATA);
    }else{
        libxml_disable_entity_loader(true);
        $xml_string = simplexml_load_string($xml,'SimpleXMLElement', LIBXML_NOCDATA);
    }
        $result = json_decode(json_encode($xml_string),true);
        return $result;
}

10.支付回调修改数据库以及相关信息

<?php
namespace Home\Model;
use Think\Model;
class PaysetModel extends Model {
Protected $autoCheckFields = false;
   //在线交易订单支付处理函数
//函数功能:根据支付接口传回的数据判断该订单是否已经支付成功;
//返回值:如果订单已经成功支付,返回true,否则返回false;
public function checkorderstatus($order)
{
    //$orderid 订单号
    $M=M("Shop_order");
    $status=$M->where("ordersn=".$order)->getField("ispay");
    if($status==1)
    {
        return true;
    }else{
        return false;
    }
}   
public function orderhandle($parameter)
{
    $map['ordersn']=$parameter['orderid'];
    $data['status']=$parameter['paystatus'];
    $data['trade_no']=$parameter['trade_no'];
    $data['paytype']=empty($parameter['paytype'])?"支付宝支付":$parameter['paytype'];
    $data['ispay']=1;
    $M=M("Shop_order");
    $status=$M->where($map)->save($data);
    //减库存
    $id=$M->where($map)->getField("id");
    //查询出该订单号下的商品
    $goodlist=M("Shop_order_goods")->where("orderid=".$id)->field("goods_id,num")->select();
    foreach ($goodlist as $k => $v) {
        $r=M("Shop")->where("id=".$v['goods_id'])->getField('num');
        $d['num']=$r-$v['num'];
        $e=M("Shop")->where("id=".$v['goods_id'])->save($d);
    }
  }
}
?>


打赏本站,你说多少就多少

精彩评论

微信关注

Copyright © 2013-2019 千奇博客 保留所有权利 辽ICP备13008238号