PHP -- 微信公众号支付(H5支付)

 

官方说明:

//公众号配置 及 商户平台配置

 

https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_3
 

 

微信内H5调起支付

 

在微信浏览器里面打开H5网页中执行JS调起支付。接口输入输出数据格式为JSON。

注意:WeixinJSBridge内置对象在其他浏览器中无效。

列表中参数名区分大小,大小写错误签名验证会失败。

 

参数说明:

 

名称 变量名 必填 类型 示例值 描述
公众号id appId String(16) wx8888888888888888 商户注册具有支付权限的公众号成功后即可获得
时间戳 timeStamp String(32) 1414561699 当前的时间,其他详见时间戳规则
随机字符串 nonceStr String(32) 5K8264ILTKCH16CQ2502SI8ZNMTM67VS 随机字符串,不长于32位。推荐随机数生成算法
订单详情扩展字符串 package String(128) prepay_id=123456789 统一下单接口返回的prepay_id参数值,提交格式如:prepay_id=***
签名方式 signType String(32) MD5 签名算法,暂支持MD5
签名 paySign String(64) C380BEC2BFD727A4B6845133519F3AD6 签名,详见签名生成算法

 

返回结果值

 

 

返回值 描述
get_brand_wcpay_request:ok 支付成功
get_brand_wcpay_request:cancel 支付过程中用户取消
get_brand_wcpay_request:fail 支付失败

 

参数详解

appid:固定,登录微信公众号 在功能设置中查看

timeStamp:time() 当前时间

nonceStr:

//随机字符串生成,这个很随意,爱怎么写就怎么写,只要长度小于32位即可。最简单的方法就是设置为你的订单号,也可写一个随机字符串函数

//获取随机字符串的方法

 

function  rand32( $length = 32 ) {
//在32位以内
$length=floor(rand(1,32));//取1-32随机数
// 密码字符集,可任意添加你需要的字符
$chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';//!@#$%^&*()-_ []{}<>~`+=,.;:/?|
$str ='';
 for ( $i = 0; $i < $length ; $i ++ )
 {
// 这里提供两种字符获取方式
// 第一种是使用 substr 截取$chars中的任意一位字符;
// 第二种是取字符数组 $chars 的任意元素
// $str.= substr($chars, mt_rand(0, strlen($chars) – 1), 1);
  $ str .= $chars [ mt_rand(0, strlen ( $chars ) - 1) ];
 }
return $ str ;
}
 
package:
//统一下单接口返回的prepay_id参数值
/*
统一下单参数
out_trade_no //可用  rand32()
body //商品简要描叙,可直接填写商品名称
total_fee  //金钱,注:这单位是分
trade_type  //如:JSAPI,NATIVE,APP 这里直接填写JSAPI
openid  //用户的openid,这个在获取用户资料里面有
notify_url  //回调地址,可用来做一些 自己 订单内 状态的 更新,必须是可以直接访问的url
appid //公众号id
mch_id //商户号id
 
*/
 
paySign:签名
 /**
     * 生成签名
     * @return 签名,本函数不覆盖sign成员变量,如要设置签名需要调用SetSign方法赋值
     */
    public function MakeSign($art) {
        //签名步骤一:按字典序排序参数
        ksort($art);
        $string = ToUrlParams($art);
        //签名步骤二:在string后加入KEY
        $string = $string . "&key=" . \WxPayConfig::KEY;// WxPayConfig::KEY  --  商户号秘钥
        //签名步骤三:MD5加密
        $string = md5($string);
        //签名步骤四:所有字符转为大写
        $result = strtoupper($string);
        return $result;
    }
 
 /**
     * 格式化参数格式化成url参数
     */
    public function ToUrlParams($art) {
        $buff = "";
        foreach ($art as $k => $v) {
            if ($k != "sign" && $v != "" && !is_array($v)) {
                $buff .= $k . "=" . $v . "&";
            }
        }

        $buff = trim($buff, "&");
        return $buff;
    }
 
/**
     * 输出xml字符
     * @throws WxPayException
     * */
    public function ToXml($art) {
        $xml = "";
        foreach ($art as $key => $val) {
            if (is_numeric($val)) {
                $xml.="<" . $key . ">" . $val . "";
            } else {
                $xml.="<" . $key . ">";
            }
        }
        $xml.="
";
        return $xml;
    }
 
/**
     * 以post方式提交xml到对应的接口url
     *
     * @param string $xml  需要post的xml数据
     * @param string $url  url=
     * @param bool $useCert 是否需要证书,默认不需要
     * @param int $second   url执行超时时间,默认30s
     * @throws WxPayException
     */
    private static function postXmlCurl($xml, $url='', $useCert = false, $second = 30)
    {        
        $ch = curl_init();
        //设置超时
        curl_setopt($ch, CURLOPT_TIMEOUT, $second);
        curl_setopt($ch,CURLOPT_URL, $url);
        curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,TRUE);
        curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,2);//严格校验
        //设置header
        curl_setopt($ch, CURLOPT_HEADER, FALSE);
        //要求结果为字符串且输出到屏幕上
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
        //post提交方式
        curl_setopt($ch, CURLOPT_POST, TRUE);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
        //运行curl
        $data = curl_exec($ch);
        //返回结果
        if($data){
            curl_close($ch);
            return $data;
        } else {
            $error = curl_errno($ch);
            curl_close($ch);
        }
    }
 
基本上就这样了
 
 
 
异步返回处理

 

/**
     * 支付异步回调
     */
    public function callback() {
        $data = getNotifyData(); //获取数据 用wechatAppPay类里的getNotifyData()方法,这里数据也被getNotifyData()由xml转化成了数组。
        //判断是否成功
        if ($data['return_code'] == "SUCCESS") {
            $id = $data['out_trade_no'];//获取自己填写的out_trade_no

//数据库状态改变
            $sql = "update lb_userorder set status='5' where concat(id,end_time) = '{$id}';";
            M("userorder")->query($sql); //修改订单状态
            $this->data_log("callback: {$id} success");
        } else {

            $this->data_log("订单号 concat(id,create_time)={$id} 支付失败!");//数据打印
        }
        exit('success');
    }

 

/**
     *
     * 获取支付结果通知数据
     * return array
     */
    public function getNotifyData() {
        //获取通知的数据
        $xml = $GLOBALS['HTTP_RAW_POST_DATA'];//要是拿不到数据,请用 $xml = file_get_contents('php://input');
        $data = array();
        if (empty($xml)) {
            return false;
        }
        $data = xml_to_data($xml);
        if (!empty($data['return_code'])) {
            if ($data['return_code'] == 'FAIL') {
                return false;
            }
        }
        return $data;
    }

 public function xml_to_data($xml) {
        if (!$xml) {
            return false;
        }
        //将XML转为array
        //禁止引用外部xml实体
        libxml_disable_entity_loader(true);
        $data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
        return $data;
    }

 

页面就更简单了

直接那官方的

https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_7&index=6

把里面参数改为自己的就ok了

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(PHP,微信,微信公众号支付,H5支付)