PHP使用Laravel-Pay组件快速接入微信JSAPI支付(微信公众号支付)
本文为系列文章,接下来分别会讲解如何接入微信 与 支付宝 支付并完成支付的保姆式教程,各支付代码示例细节详见页尾链接。
前言
本篇介绍微信 H5、JSAPI(公众号)、APP、小程序支付、Native支付(手机扫网站二维码进行支付)、需要的基础资料
一、前期准备与花费明细(仅供参考)
项目名 | 花费 | 功能 |
---|
公众号认证 | 300 | JSAPI支付 | 微信开放平台认证 | 300 | APP支付、网站扫码支付(Native支付) | 微信小程序认证 | 300 | 小程序支付 | 微信商户平台认证 | 300 | H5基础支付 |
注意: 这里必须要开通的是微信商户平台。剩下的更你的实际业务需求进行开通。
使用composer下载laravel-pay组件
composer require yansongda/pay -vvv
laravel-pay官网地址:https://pay.yansongda.cn/docs/v2/installation.html laravel-pay Git项目地址:https://github.com/yansongda/pay/tree/v2
二、支付类型
1.微信公众号支付(JSAPI支付)
支付原理:
1.前端获取微信code
2.前端发送code到我方后台换openid
3.带着openid请求我方后台拉起支付
4.前端更具后台返回值判断是否拉起 微信付款页面
5.用户在手机上进行付款操作
6.用户付款结束后,微信服务器向我方服务器发送请求,告诉我们用户已经支付完了
7.我方后台通过支付完成异步回调修改数据库中的订单支付状态值。
8.End
代码如下(示例):
前端html支付示例
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<button onclick="wechatPay()">点我拉起微信支付</button>
</body>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.js"></script>
<script>
var code = getQueryVariable('code');
var openid;
if(code){
$.ajax({
type : "POST",
url : "http://请求后端获取openid路由地址",
data : {
'_token':"{{ csrf_token() }}",
'code':code
},
success : function(result) {
openid = result.data.openid;
}
});
}else{
var appid = "公众号appid";
var redirect_uri = "填获取code后重定向的地址";
var state = '';
var url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid="+ appid +"&redirect_uri="+ redirect_uri +"&response_type=code&scope=snsapi_base&state="+ state +"#wechat_redirect";
window.location.href = url;
}
function getQueryVariable(variable)
{
var query = window.location.search.substring(1);
var vars = query.split("&");
for (var i=0;i<vars.length;i++) {
var pair = vars[i].split("=");
if(pair[0] == variable){return pair[1];}
}
return(false);
}
function wechatPay() {
if(!open_id){
alert('500:获取openid失败');
return false;
}
$.ajax({
type : "POST",
url : "请求我方后台接口,向微信服务器发起支付请求wechatPay.php",
data : {
'_token':"{{ csrf_token() }}",
"open_id" : open_id,
},
success : function(res) {
if (res.success) {
if (typeof WeixinJSBridge == "undefined"){
if( document.addEventListener ){
document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
}else if (document.attachEvent){
document.attachEvent('WeixinJSBridgeReady', onBridgeReady);
document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
}
}else{
onBridgeReady(res.data);
}
}
if(res.show_msg){
alert(res.msg)
}
}
});
}
function onBridgeReady(data){
WeixinJSBridge.invoke(
'getBrandWCPayRequest', {
"appId":data.appId,
"timeStamp":data.timeStamp,
"nonceStr":data.nonceStr,
"package":data.package,
"signType":data.signType,
"paySign":data.paySign
},
function(res){
if(res.err_msg == "get_brand_wcpay_request:ok" ){
window.location = "访问我方自主查询支付结果页面";
}
});
}
</script>
</html>
后端PHP拉起支付以及用户支付成功后异步回调示例
<?php
namespace App\Http\Controllers\H5;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Yansongda\Pay\Log;
use Yansongda\Pay\Pay;
class WechatPayController extends Controller
{
private $wechatPay = [
'appid' => '',
'app_id' => '这里填公众号 APPID',
'app_secret' => '这里填公众号开发者密码AppSecret',
'miniapp_id' => '',
'mch_id' => '微信商户平台的商户号',
'key' => '商户平台的商户号秘钥',
'notify_url' => 'https://www.xxx.com/wechatPay/wechatPayNotify',
'cert_client' => './cert/apiclient_cert.pem',
'cert_key' => './cert/apiclient_key.pem',
'log' => [
'file' => './login/wechat.log',
'level' => 'debug',
'type' => 'single',
'max_file' => 30,
],
'http' => [
'timeout' => 5.0,
'connect_timeout' => 5.0,
],
];
protected function send($code = 200,$success = false,$show_msg = false,$msg = '',$data=[]){
return [
'code' => $code,
'success' => $success,
'show_msg' => $show_msg,
'msg' => $msg,
'data' => $data
];
}
public function wechatMpPay(Request $request)
{
$open_id = $request->open_id;
$order_pay = [
'openid' => $open_id,
'out_trade_no' => time(),
'total_fee' => 1,
'body' => '支付测试Demo',
];
$pay = Pay::wechat($this->wechatPay)->mp($order_pay);
if($pay){
return $this->send(200,true,false,'成功',$pay);
}
return $this->send(500,false,false,'支付接口异常');
}
public function wechatPayNotify()
{
$pay = Pay::wechat($this->wechatPay);
try {
$data = $pay->verify();
Log::debug('Wechat notify', $data->all());
file_put_contents('wechat_log.txt',$data->all());
if ($data->return_code == "SUCCESS" && $data->result_code == "SUCCESS") {
file_put_contents('wechat_log.txt','支付成功啦!');
$str = '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';
return $str;
}
} catch (\Exception $exception) {
Log::debug('Wechat BUG', $exception->getMessage());
file_put_contents('wechat_log.txt','支付回调异常:'.$exception->getMessage());
}
$str = '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';
return $str;
}
public function isPaySuccess($order_id)
{
$isPaySuccess = Order::where([
['id',$order_id],
['is_pay',1]
])->first();
if($isPaySuccess){
return redirect()->route('h5.goods.goodsList',$isPaySuccess['students_id'])->with('success','支付成功');
}else{
return redirect()->route('h5.goods.goodsList',$isPaySuccess['students_id'])->with('error','error');
}
}
public function getWechatMpOpenid(Request $request){
$code = (string)$request->code;
$appid = $this->wechatPay['app_id'];
$secret = $this->wechatPay['app_secret'];
$url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid={$appid}&secret={$secret}&code={$code}&grant_type=authorization_code";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
$response = curl_exec($ch);
curl_close($ch);
$response = json_decode($response,true);
return [
'code'=>200,
'data'=>[
'openid'=>$response['openid'],
'array'=>$response
]
];
}
}
该处使用的url网络请求的数据。
微信官方后台
1.微信公众平台配置我方项目域名,如下图,若与下图不符,请检查你的公众号是否没有进行认证处理

要是你不想花钱测试支付,可以在侧边栏 开发→开发者工具→公众平台测试账号 中申请测试账号,并进行支付测试,需要注意:你在微信官方给测试账号中支付的花销是退不回来的!!!退不回来的!!!退不回来的!!! 2.微信公众号在侧边栏 微信支付 与商户号进行绑定操作。 3.登录微信商户平台,开通JSAPI支付产品 4.在微信商户平台进行商户号与微信公众号的绑定操作与相关配置。
|