微信扫码支付方式一,比较繁琐和麻烦,而且回调地址是固定的,所以本人产用方式二,进行开发。
流程还得结合文档,上说是首先下单,然后会返回二维码地址,扫码登陆即可,不需要openid。
本人使用laravel+composer组件,
composer组件包括:
"overtrue/wechat": "~4.0",
"endroid/qr-code": "^3.2"
官方给的demo包,因为没有写命名空间的原因,不好导入,因此快速开发的情况下,还是选泽了,escywechat进行开发,也就是以上的微信的composer组件,qr-code组件用来生成微信二维码的。
接下来直接贴下单和生成二维码图片的代码【干货】
public function payOrder(Request $request){
$param = $request ->all();
$payment = Factory::payment($this->config);
//$out_trade_no = $mch_id.date("YmdHis"); //拼一下订单号
$attributes = [
'trade_type' => 'NATIVE', // JSAPI,NATIVE,APP...
'body' => $param['body'],
'detail' => $param['detail'],//$order_find->info, //我这里是通过订单找到商品详情,你也可以自定义
'out_trade_no' => $param['out_trade_no'],//$out_trade_no,
'total_fee' => 1,//$order_find->money*100, //因为是以分为单位,所以订单里面的金额乘以100
'notify_url' => '/wx/paySuccess/', // 支付结果通知网址,如果不设置则会使用配置里的默认地址
];
$result = $payment->order->unify($attributes); //微信下单
//$log_File = config('wechat.defaults.log.file');
Log::info($result); //记录日志
$rand_img = 'pay/'.time().CharController::randChar(8).'.jpg';
if ($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS'){
$qr = QrcodeServices::makeQrcode($result['code_url'],$rand_img);
if($qr ==true){
return Api::responseMessage(0,'请求成功',$rand_img);//返回路径
}else{
return Api::responseMessage(-1,'未知错误'); //失败
}
}else{
return Api::responseMessage(-1,'未知错误'); //失败
}
}
然后qr-code生成二维码的方法,也贴一下吧,方便大家学习
use Endroid\QrCode\ErrorCorrectionLevel;
use Endroid\QrCode\LabelAlignment;
use Endroid\QrCode\QrCode;
use Endroid\QrCode\Response\QrCodeResponse;
public static function makeQrcode($qrcode_content,$save_path,$size=300,$logopath = null,$font=null){
// Create a basic QR code
$qrCode = new QrCode($qrcode_content);
$qrCode->setSize($size);
// Set advanced options
$qrCode->setWriterByName('png');
//$qrCode->setMargin(10);
$qrCode->setEncoding('UTF-8');
$qrCode->setErrorCorrectionLevel(ErrorCorrectionLevel::HIGH);
$qrCode->setForegroundColor(['r' => 0, 'g' => 0, 'b' => 0, 'a' => 0]);
$qrCode->setBackgroundColor(['r' => 255, 'g' => 255, 'b' => 255, 'a' => 0]);
if($font) $qrCode->setLabel($font, 16,base_path('public/fonts/YaHei.ttf'), LabelAlignment::CENTER);
if($logopath){
$qrCode->setLogoPath($logopath);
$qrCode->setLogoWidth(30);
}
//$qrCode->setRoundBlockSize(true);
//$qrCode->setValidateResult(false);
// Save it to a file
$qrCode->writeFile($save_path);
// Create a response object
$response = new QrCodeResponse($qrCode);
return $response->isOk();
}
接下来是回调的处理,阅读源码你可以找到它的回调处理方法:query
/**
* 扫码支付的回调请求【做轮询处理,忽略高并发,】
* @param Request $request
* @return string
*/
public function paySuccess(Request $request)
{
$param = $request ->all();
$payment = Factory::payment($this->config);
$result = $payment->order->queryByOutTradeNumber($param['transaction_id']);
if($result['trade_state'] =="SUCCESS"){
DB::connection('ges') ->table('order')->where('order_sn',$result['out_trade_no'])->update(['order_state'=>2]);//更改状态,已付款
};
return Api::responseMessage(0,'结果',$result);
}
以上就是微信扫码支付的全部,最后我把前台页面也贴出来,主要就是js的轮询,大家共同学习:
<div class="container payContent">
<div class="row">
<div class=" col-sm-12 col-md-12 col-lg-12 d-flex flex-row justify-content-left">
<img class="payImg" src="/img/pay/pay_02.png" alt=""> 收银台
</div>
</div>
</div>
<div class="container box ">
@if(!empty($order["sku_image"]))
<img id="contentImg" src="{{$order["sku_image"]}}" alt="">
@else
<img id="contentImg" src="/img/logo.jpg" alt="">
@endif
<div class="payFont">金额为 :{{$order["price"]}}</div>
<br/>
<div class="state">微信支付</div>
<div class="timer" id="timer"></div>
<button id="success-buttom" class="btn btn-success but success-buttom">确认支付</button>
</div>
<script>
$('.success-buttom').click(function () {
$(".success-buttom").html("二维码生成中..");
$.ajax({
url: '/wx/payOrder',
type: 'post',
data: {
body: '{{$order["sku_name"]}}',
detail: '{{$order["sku_name"]}}',
out_trade_no: '{{$order["order_sn"]}}',
total_fee: '{{$order["price"]}}'
},
success: function (res) {
if (res.code == 0) {
$("#contentImg").attr("src", "/" + res.data);
$(".success-buttom").html("请扫码支付");
$("#success-buttom").removeClass("success-buttom");
//设置每隔1000毫秒执行一次load() 方法
$("#timer").html(0);
var myIntval = setInterval(function () {load()}, 1000);
function load(){
var transaction_id = '{{$order["order_sn"]}}';
$('#timer').html(parseInt($("#timer").html())+1);
$.ajax({
url:'/wx/paySuccess',
type:'post',
data:{transaction_id:transaction_id},
success:function (res) {
if(res.data.trade_state=="SUCCESS"){
clearInterval(myIntval);
$("#contentImg").attr("src", "/img/pay/pay_01.png");
$(".state").html("支付成功");
$("#success-buttom").addClass("orderSuccess");
$("#success-buttom").html("查看订单");
$('.orderSuccess').click(function () {
window.location.href="/order/orderList";
});
}
}
})
}
}
}
});
});
</script>