ThinkPHP5集成微信JSAPI支付

第一次集成微信的JSAPI支付,用的是官方的SDK,里面有demo方法,文件有很多,不是所有的文件都可以用得到,相信有很多小伙伴和我一样会遇到各种各样的小问题
官方的下载链接:https://pay.weixin.qq.com/wiki/doc/api/download/WxpayAPI_php.zip
下面是我这次SDK里用到的文件:

ThinkPHP5集成微信JSAPI支付_第1张图片

把上面的文件放到一个新建的文件夹再放到public目录下,放到public目录后先去修改WxPay.Config.php里的配置,需要修改appid、mchid、key、appsecret四个参数。

然后在入口文件index.php里添加如下代码:

// [ 应用入口文件 ]

// 定义应用目录
define('APP_PATH', __DIR__ . '/../application/');
define("APP_ROOT",dirname(__FILE__));

// 加载框架引导文件
require __DIR__ . '/../thinkphp/start.php';

下面是所需的前后端代码:

前端JS方法

function immediately_pay() {
    // 这里可以写你onclick事件需要获取传到后台的值

    $.ajax({
        type: type,
        url: url,
        data: data,
        dataType: dataType,
        success: function (result) {
            callpay(result);
        }
    });
}

function callpay(result)
{
    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(result);
    }
}

function jsApiCall(result) {
    WeixinJSBridge.invoke('getBrandWCPayRequest', {
        "appId":result.appId,           //公众号名称,由商户传入
        "timeStamp":result.timeStamp,   //时间戳,自1970年以来的秒数
        "nonceStr":result.nonceStr,     //随机串
        "package":result.package,
        "signType":result.signType,     //微信签名方式:
        "paySign":result.paySign        //微信签名
    },
    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("支付成功!");
            // 支付成功可以进行页面跳转
        } else if (res.err_msg == "get_brand_wcpay_request:cancel") {
            alert("用户取消支付!");
        } else {
            alert("支付失败!");
        }
    });
}

后端Controller方法

public function immediately_pay()
{
    ini_set('date.timezone','Asia/Shanghai');

    require_once APP_ROOT."/weixin/WxPay.Api.php";
    require_once APP_ROOT."/weixin/WxPay.JsApiPay.php";
    require_once APP_ROOT."/weixin/log.php";

    //初始化日志
    //$logHandler= new \CLogFileHandler(APP_ROOT."/logs/".date('Y-m-d').'.log');
    //$log = \Log::Init($logHandler, 15);

    //①、获取用户openid
    $tools = new \JsApiPay();

    // 这里是获取openid的方法,因为授权登录后把用户的openid存起来了,所以这里用不到了
    //$openId = $tools->GetOpenid();

    //②、统一下单
    $input = new \WxPayUnifiedOrder();
    $input->SetBody("test");	//商品描述
    $input->SetAttach("test");	//附加数据
    $input->SetOut_trade_no("sdkphp".date("YmdHis"));	//商户订单号
    $input->SetTotal_fee("1");	//标价金额
    $input->SetTime_start(date("YmdHis"));	//交易起始时间
    $input->SetTime_expire(date("YmdHis", time() + 600));	//交易结束时间
    $input->SetGoods_tag("test");	//订单优惠标记
    $input->SetNotify_url("http://paysdk.weixin.qq.com/notify.php");	//异步回调通知地址
    $input->SetTrade_type("JSAPI");	//交易类型

    // 下面是获取授权登录存入数据库里的openid
    // ......        

    $input->SetOpenid($openid);

    $config = new \WxPayConfig();
    $order = \WxPayApi::unifiedOrder($config, $input);
    $jsApiParameters = $tools->GetJsApiParameters($order);

    // 把获得的json数据解析成数组
    $result = json_decode($jsApiParameters);

    return $result;
}

支付成功以后,微信会把相关支付结果和用户信息返回回来,通过回调方法接收处理,进行修改订单状态等业务逻辑,并返回应答。

下面在public下新建一个php页面,写入如下内容:

异步回调方法

require_once "weixin/WxPay.Api.php";
require_once 'weixin/WxPay.Notify.php';
require_once "weixin/WxPay.Config.php";
require_once 'weixin/log.php';

//初始化日志
//$logHandler= new CLogFileHandler("logs/".date('Y-m-d').'.log');
//$log = Log::Init($logHandler, 15);

class PayNotifyCallBack extends WxPayNotify
{
    //查询订单
    public function Queryorder($transaction_id)
    {
        $input = new WxPayOrderQuery();
        $input->SetTransaction_id($transaction_id);

        $config = new WxPayConfig();
        $result = WxPayApi::orderQuery($config, $input);
        Log::DEBUG("query:" . json_encode($result));
        if(array_key_exists("return_code", $result)
            && array_key_exists("result_code", $result)
            && $result["return_code"] == "SUCCESS"
            && $result["result_code"] == "SUCCESS")
        {
            return true;
        }
        return false;
    }

    /**
     *
     * 回包前的回调方法
     * 业务可以继承该方法,打印日志方便定位
     * @param string $xmlData 返回的xml参数
     *
     **/
    public function LogAfterProcess($xmlData)
    {
        Log::DEBUG("call back, return xml:" . $xmlData);
        return;
    }

    //重写回调处理函数
    /**
     * @param WxPayNotifyResults $data 回调解释出的参数
     * @param WxPayConfigInterface $config
     * @param string $msg 如果回调处理失败,可以将错误信息输出到该方法
     * @return true回调出来完成不需要继续回调,false回调处理未完成需要继续回调
     */
    public function NotifyProcess($objData, $config, &$msg)
    {
        $data = $objData->GetValues();
        //TODO 1、进行参数校验
        if(!array_key_exists("return_code", $data)
            ||(array_key_exists("return_code", $data) && $data['return_code'] != "SUCCESS")) {
            //TODO失败,不是支付成功的通知
            //如果有需要可以做失败时候的一些清理处理,并且做一些监控
            $msg = "异常异常";
            return false;
        }
        if(!array_key_exists("transaction_id", $data)){
            $msg = "输入参数不正确";
            return false;
        }

        //TODO 2、进行签名验证
        try {
            $checkResult = $objData->CheckSign($config);
            if($checkResult == false){
                //签名错误
                Log::ERROR("签名错误...");
                return false;
            }
        } catch(Exception $e) {
            Log::ERROR(json_encode($e));
        }

        //TODO 3、处理业务逻辑
        Log::DEBUG("call back:" . json_encode($data));
        $notfiyOutput = array();

        // 这里进行修改订单状态等业务逻辑操作

        //查询订单,判断订单真实性
        if(!$this->Queryorder($data["transaction_id"])){
            $msg = "订单查询失败";
            return false;
        }


        return true;
    }
}

$config = new WxPayConfig();
Log::DEBUG("begin notify");
$notify = new PayNotifyCallBack();
$notify->Handle($config, false);

至此就是我这次集成微信支付JSAPI的过程了,可以正常支付,修改订单状态,如果有更好方法的小伙伴欢迎在下面给我留言评论哦!

你可能感兴趣的:(支付集成)