PHP---微信支付【Native支付】
最近在整合一些第三方平台代码,首先就是微信支付相关:
微信支付相关文档:
https://pay.weixin.qq.com/wiki/doc/api/index.html
Native支付文档:
https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_1
SDK下载地址:
https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=11_1
扫码支付模式一
适用场景:商店打印二维码支付
<?php const MCHID = ''; // 商户号 const APPID = ''; // 公众号APPID const KEY = ''; // API密钥 const APPSECRET = ''; // APPSECRET include('phpqrcode/phpqrcode.php'); // 扫码支付模式一 // 适用场景:商店打印二维码支付 $product_id = "10000"; $url = generateScanUrl($product_id); QRcode::png($url); // 生成扫码URL function generateScanUrl($product_id){ $params = [ 'appid' => APPID, 'mch_id' => MCHID, 'nonce_str' => uniqid(), // 随机字符串 'time_stamp' => strval(time()), 'product_id' => $product_id ]; $params['sign'] = generateSign($params,KEY); // 签名 $prefix = 'weixin://wxpay/bizpayurl?'; // 微信网关地址 $url = $prefix . http_build_query($params); return $url; } // 生成签名 function generateSign($params,$key,$encrypt = 'md5'){ ksort($params); // 将集合排序 $params['key'] = $key; // 拼接KEY $str = http_build_query($params); // 转化为URL字符串 return strtoupper(md5(urldecode($str))); // md5加密 }
然后访问即可看到支付二维码:
扫码支付二:订单挂钩
<?php const MCHID = '1601870095'; // 商户号 const APPID = 'wx1868670b98dbcd5c'; // 公众号APPID const KEY = 'sadlkjdgLKJ3213KJHKJHfasdf324234'; // API密钥 const APPSECRET = 'sadlkjdgLKJ3213KJHKJHfasdf324234'; // APPSECRET const API_URL = 'https://api.mch.weixin.qq.com/pay/unifiedorder'; // 网关 include('phpqrcode/phpqrcode.php'); // 扫码支付二:订单挂钩 // 需要预支付单号 - 调用统一下单接口 $params = [ 'body' => '我是一个支付的标题', 'detail' => '我是一个支付的描述', 'out_trade_no' => time() . mt_rand(1000,9999), // 生产订单号 通常在加入购物车 还未支付的时候生成 'total_fee' => 100,// 单位是分 'notify_url' => 'http://danzhao.ynzzwl.com/huidiao.php',// 微信回调 - 必须是外网的地址 // 'openid' => '',特定人支付 选填 'appid' => APPID, 'mch_id' => MCHID, // 'spbill_create_ip' => '127.0.0.1' // 防止钓鱼,指定IP 'trade_type' => 'NATIVE' // 交易类型 [JSAPI,NATIVE,APP] ]; $result = prepare($params); $url = $result['code_url']; QRcode::png($url); // 生成支付二维码 // 统一下单 function prepare($config){ $config['nonce_str'] = uniqid(); $config['sign'] = generateSign($config,KEY); // 签名 $xml = toXml($config); // 转化为XML格式 // 统一下单 $result = curlPost('https://api.mch.weixin.qq.com/pay/unifiedorder', $xml); return xmlToArray($result); } // 生成签名 function generateSign($params,$key,$encrypt = 'md5'){ ksort($params); // 将集合排序 $params['key'] = $key; // 拼接KEY $str = http_build_query($params); // 转化为URL字符串 return strtoupper(md5(urldecode($str))); // md5加密 } // toXml function toXml($params){ $xml = "<xml>"; foreach($params as $key => $value){ if(is_numeric($value)){ $xml .= "<$key>$value</$key>"; }else{ $xml .= "<$key><![CDATA[$value]]></$key>"; } } $xml .= "</xml>"; return $xml; } // xml to array function xmlToArray($xml){ if(!$xml){ throw new WxPayException("xml数据异常!"); } libxml_disable_entity_loader(true); // 禁止引用外部xml实体 return json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true); } function curlPost($url = '', $postData = '', $options = array()) { if (is_array($postData)) { $postData = http_build_query($postData); } $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $postData); curl_setopt($ch, CURLOPT_TIMEOUT, 30); //设置cURL允许执行的最长秒数 if (!empty($options)) { curl_setopt_array($ch, $options); } //https请求 不验证证书和host curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); $data = curl_exec($ch); curl_close($ch); return $data; }
支付回调:
<?php // 回调接受微信支付成功回调 // 1、怎么调试 $info = file_get_contents("php://input"); // 2、安全性:a、同一微信多次回调如何处理;别人伪造微信支付回调怎么处理。 // 安全性:别人能够伪造请求,但是不能伪造签名,可以写一个方法来校验签名;其次是比对订单金额; // 或者是指定IP是微信的IP // 判断订单状态是否是已经支付完成,支付完成,下面这些代码都无需执行 $order = xmlToArray($info); $trade['order'] = $order['out_trade_no']; $trade['total_fee'] = $order['total_fee']; // 3、针对微信的消息做处理 // 签名处理 $mySign = generateSign($order,KEY); if($trade['total_fee'] == '10' && $mySign == $order['sign']){ // 更改订单状态 更改订单状态之前需要先去查询订单状态,如果是已支付,就不需要处理了 // 具体代码 // 通知微信我们已接收到信息,不要再给我们发该条订单的请求,不然会给你发9次消息 // 频率:15,15,30,180,1800,1800,1800,3600 echo "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>"; }else{ // 不做任何处理 } function generateSign($params,$key,$encrypt = 'md5'){ // 将集合排序 ksort($params); $params['key'] = $key; // 拼接KEY // 转化为URL字符串 $str = http_build_query($params); // md5 加密 return strtoupper(md5(urldecode($str))); }
微信支付回调非常重要,具体可以参考【官方示例代码】具体位于:示例代码 / example / notify.php
示例:
打完收工!