背景
我们在开发中经常遇到在要在网页端唤起支付的情况,虽然很多时候是在微信浏览器中打开,可以直接用jsapi解决,但实际上有很多时候我们也是要在网页端实现调用二维码进行扫码支付的。这里使用thinkphp5作为案例进行开发。
代码
前端
前端用axios进行请求,大家也尽可使用ajax。
<html>
<head>native支付</head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="/static/vue.js"></script>
<script src="/static/axios.min.js"></script>
<body>
<button onclick="pay()">native购买</button>
<div id="code">
<img src="" id="codeImg">
</div>
<script type="text/javascript">
function pay(){
let that=this;
axios.post('/wechat/nativePay').then((r)=>{
console.log(r.data)
document.getElementById('codeImg').src="/"+r.data;
})
}
</script>
</body>
</html>
后端
合理我返回的是一个二维码的地址,所以在前端是通过给img标签赋值的形式展示的。
function nativePay()
{
$notifyUrl = '异步回调地址';//支付成功异步回调地址
$orderName = '订单名称';
$total_amount =1;
$timestamp = time();
$unified = array(
'appid' => $this->config['appId'],
'attach' => 'pay', //商家数据包,原样返回,如果填写中文,请注意转换为utf-8
'body' => $orderName,
'mch_id' => $this->config['mch_id'],
'nonce_str'=> $this->createNoncestr(),
'notify_url'=>$notifyUrl,//你的回调地址
'out_trade_no'=> date('YmdHis').rand(1000, 9999),
'spbill_create_ip'=> '<你的服务器ip>',
'total_fee' => $total_amount , //单位 转为分
'trade_type' => 'NATIVE',
);
$data = array_filter($unified);//过滤函数
ksort($data);
$str ='';
foreach($data as $k=>$v) {
$str.=$k.'='.$v.'&';
}
$str.='key='.$this->config['key'];
$unified['sign'] = strtoupper(md5($str));
$responseXml = $this->curlPost('https://api.mch.weixin.qq.com/pay/unifiedorder', $this->arrayToXml($unified));
libxml_disable_entity_loader(true);
$unifiedOrder = simplexml_load_string($responseXml, 'SimpleXMLElement', LIBXML_NOCDATA);
if (false === $unifiedOrder) {
die('parse xml error');
}
if ('SUCCESS' != $unifiedOrder->return_code) {
die($unifiedOrder->return_msg);
}
if ('SUCCESS' != $unifiedOrder->result_code) {
die($unifiedOrder->err_code);
}
$codeUrl = (array) ($unifiedOrder->code_url);
if (!$codeUrl[0]) {
exit('get code_url error');
}
$qrcodeImg=$this->code($codeUrl[0]);
return $qrcodeImg;
}
最终效果
点击native购买按钮后会弹出支付二维码
其他
其中涉及到几个函数code(
u
r
l
)
,
c
u
r
l
P
o
s
t
(
url),curlPost(
url),curlPost(param),createNoncestr()
code($url)是用来生成二维码的,TP5生成二维码可以看相关教程
curlPost($param)是接收微信服务器数据的函数,做过微信开发的应该都用过,为了方便大家这里也补充进来
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;
}
createNoncestr()是用来生成随机字符的
public function createNoncestr($length =32){
$chars = "abcdefghijklmnopqrstuvwxyz0123456789";
$str ="";
for ( $i = 0; $i < $length; $i++ ) {
$str.= substr($chars, mt_rand(0, strlen($chars)-1), 1);
}
return $str;
}