PHP版本微信支付开发----电脑网站扫码支付(native)(心得、总结)

news/2024/5/11 13:04:40/文章来源:https://blog.csdn.net/zylsc/article/details/103617495

PHP版本微信支付开发----电脑网站扫码支付(native)(心得、总结)

一、申请微信公众服务号并进行认证

二、下载微信支付demo,修改配置信息

1.开发文档

在这里插入图片描述
我做的项目是电脑网站,所以就选择了native支付

在这里插入图片描述
在这里可以下载demo,我下载了PHP的,这是目录结构
在这里插入图片描述
做过支付宝支付的人可能知道支付宝提供了异步回调和同步回调两种方式,而微信没有提供同步回调,只有异步回调(在此处理你的业务逻辑如数据库的更新)。

2.修改配置文件example/Wxpay.config.php

AppId 这是你的微信公众平台的APPID,去微信公众平台里面查看
MerchantId 这是你申请的商户号
NotifyUrl 这是异步回调地址,要求外网可以访问(不能写localhost域名)、不能带任何参数
Key 这是你的APIkey,在微信开发平台里,超级管理员可以修改
在这里插入图片描述

3.配置文件代码:

<?php
/**
*
* example目录下为简单的支付样例,仅能用于搭建快速体验微信支付使用
* 样例的作用仅限于指导如何使用sdk,在安全上面仅做了简单处理, 复制使用样例代码时请慎重
* 请勿直接直接使用样例对外提供服务
* 
**/
require_once "../lib/WxPay.Config.Interface.php";/**
*
* 该类需要业务自己继承, 该类只是作为deamon使用
* 实际部署时,请务必保管自己的商户密钥,证书等
* 
*/class WxPayConfig extends WxPayConfigInterface
{//=======【基本信息设置】=====================================/*** TODO: 修改这里配置为您自己申请的商户信息* 微信公众号信息配置* * APPID:绑定支付的APPID(必须配置,开户邮件中可查看)* * MCHID:商户号(必须配置,开户邮件中可查看)* */public function GetAppId(){return 'xxxxxxxxxxxx';//jal}public function GetMerchantId(){return 'xxxxxxxxxxx';//jal}//=======【支付相关配置:支付成功回调地址/签名方式】===================================/*** TODO:支付回调url* 签名和验证签名方式, 支持md5和sha256方式**/public function GetNotifyUrl(){return "http://xxx.xxxxxx.com/JudgeOnline/wxpay/example/notify.php";}public function GetSignType(){return "HMAC-SHA256";}//=======【curl代理设置】===================================/*** TODO:这里设置代理机器,只有需要代理的时候才设置,不需要代理,请设置为0.0.0.0和0* 本例程通过curl使用HTTP POST方法,此处可修改代理服务器,* 默认CURL_PROXY_HOST=0.0.0.0和CURL_PROXY_PORT=0,此时不开启代理(如有需要才设置)* @var unknown_type*/public function GetProxy(&$proxyHost, &$proxyPort){$proxyHost = "0.0.0.0";$proxyPort = 0;}//=======【上报信息配置】===================================/*** TODO:接口调用上报等级,默认紧错误上报(注意:上报超时间为【1s】,上报无论成败【永不抛出异常】,* 不会影响接口调用流程),开启上报之后,方便微信监控请求调用的质量,建议至少* 开启错误上报。* 上报等级,0.关闭上报; 1.仅错误出错上报; 2.全量上报* @var int*/public function GetReportLevenl(){return 1;}//=======【商户密钥信息-需要业务方继承】===================================/** KEY:商户支付密钥,参考开户邮件设置(必须配置,登录商户平台自行设置), 请妥善保管, 避免密钥泄露* 设置地址:https://pay.weixin.qq.com/index.php/account/api_cert* * APPSECRET:公众帐号secert(仅JSAPI支付的时候需要配置, 登录公众平台,进入开发者中心可设置), 请妥善保管, 避免密钥泄露* 获取地址:https://mp.weixin.qq.com/advanced/advanced?action=dev&t=advanced/dev&token=2005451881&lang=zh_CN* @var string*/public function GetKey(){return 'xxxxxxxxxxxxxxxxxxxxxxxxxx';//jal//return '6f637dd7fe44a1e8ea19e4599fb2c7ff';//sandbox_sign_key这里有坑}public function GetAppSecret(){return '7813490da6f1265e4901ffb80afaa36f';//native不需要填}//=======【证书路径设置-需要业务方继承】=====================================/*** TODO:设置商户证书路径* 证书路径,注意应该填写绝对路径(仅退款、撤销订单时需要,可登录商户平台下载,* API证书下载地址:https://pay.weixin.qq.com/index.php/account/api_cert,下载之前需要安装商户操作证书)* 注意:* 1.证书文件不能放在web服务器虚拟目录,应放在有访问权限控制的目录中,防止被他人下载;* 2.建议将证书文件名改为复杂且不容易猜测的文件名;* 3.商户服务器要做好病毒和木马防护工作,不被非法侵入者窃取证书文件。* @var path*/public function GetSSLCertPath(&$sslCertPath, &$sslKeyPath){$sslCertPath = '../cert/apiclient_cert.pem';$sslKeyPath = '../cert/apiclient_key.pem';}
}

四、 现在要正式进行编程了,首先是前台的支付页面完成后的跳转

由于微信没有给出同步回调地址,那什么时候完成支付进行页面跳转都需要看我们用js发送请求查询了。

在这里插入图片描述

微信的图片logo是在这个页面下载的,也可以点击点击直接下载


1.native.php代码如下:
<?php
/**
*
* example目录下为简单的支付样例,仅能用于搭建快速体验微信支付使用
* 样例的作用仅限于指导如何使用sdk,在安全上面仅做了简单处理, 复制使用样例代码时请慎重
* 请勿直接直接使用样例对外提供服务
* 
**/require_once "../lib/WxPay.Api.php";
require_once "WxPay.NativePay.php";
require_once 'log.php';//初始化日志
$logHandler= new CLogFileHandler("../logs/".date('Y-m-d').'.log');
$log = Log::Init($logHandler, 15);$notify = new NativePay();
//模式二
/*** 流程:* 1、调用统一下单,取得code_url,生成二维码* 2、用户扫描二维码,进行支付* 3、支付完成之后,微信服务器会通知支付成功* 4、在支付成功通知中需要查单确认是否真正支付成功(见:notify.php)*///jal
$amount = isset($_POST['WIDtotal_amount'])?$_POST['WIDtotal_amount']:"";
$body = isset($_POST['WIDsubject'])?$_POST['WIDsubject']:"";
$total_fee = intval(doubleval($amount)*100);
$product_id = isset($_POST['goods_id'])?$_POST['goods_id']:"";
$attach = isset($_POST['word'])?$_POST['word']:"test";
$out_trade_no = isset($_POST['WIDout_trade_no'])?$_POST['WIDout_trade_no']:"phpsdk".date("YmdHis");
$input = new WxPayUnifiedOrder();
$input->SetBody($body);
$input->SetAttach($attach);
$input->SetOut_trade_no($out_trade_no);
$input->SetTotal_fee($total_fee);
$input->SetTime_start(date("YmdHis"));
$input->SetTime_expire(date("YmdHis", time() + 600));
$input->SetGoods_tag("test");
//$input->SetNotify_url("http://paysdk.weixin.qq.com/notify.php");
$input->SetNotify_url("http://xxx.xxxxxxx.com/JudgeOnline/wxpay/example/notify.php");//这里写你的回调地址
$input->SetTrade_type("NATIVE");
$input->SetProduct_id($product_id);$result = $notify->GetPayUrl($input);
$url2 = $result["code_url"];
?><html>
<head><meta http-equiv="content-type" content="text/html;charset=utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1" /><script src="../../template/bs3/jquery.min.js"></script><link rel="icon" href="img/logo.png"><title>微信支付</title><script src="https://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container"><div class="row"><div style="padding: 10px 30px"><img src="img/logo.png" alt="" style="height: 35px;vertical-align:middle"><span style="font-size: large; font-weight: 600">微信收银台</span></div></div><div class="row" style="background-color: lightgrey; padding: 10px 30px;"><div style="display: inline-block;"><div>订单编号:<span><?php echo $out_trade_no?></span></div><div>订单名称:<span><?php echo $body?></span></div></div><div style="float: right; display: inline-block;padding: 10px">应付金额:¥<span><?php echo $amount?></span></div></div><div class="row" style="margin: 20px 30px; padding: 10px 20px; border-color: orange; border-style: solid;border-width: medium"><div style="display: inline-block"><img src="img/WePayLogo.png" alt="" style="height: 50px;vertical-align: middle"><img src="img/right.png" alt="" style="height: 30px; vertical-align: middle"><span style="color: lightgrey">亿万用户的选择,更快更安全</span></div><div style="float: right; display: inline-block; padding: 10px">支付<span style="color: orange"><?php echo $amount?></span></div></div><div class="row" style="text-align: center"><img alt="扫码支付" src="qrcode.php?data=<?php echo urlencode($url2);?>" style="width:250px;height:250px;"/><div>支付提示:<span id="query_result" style="color: red">WAITING...</span></div><input id="out_trade_no" type="hidden"  value="<?php echo $out_trade_no;?>"><img src="img/scan.png" alt="" style="width: 250px; height: 90px"></div>
</div>
<script>var t1;var sum=0;$(document).ready(function () {t1=setInterval("ajaxstatus()", 3000);//三秒查询一次});function ajaxstatus() {sum++;if(sum>600){ window.clearInterval(t1);return false;}//如果查询次数过多就放弃if(sum>180){m=sum % 10;if(m!=0){return false;}}if ($("#out_trade_no").val() != 0) {//此处很关键,用ajax异步查询orderqueryajax.php页面,看看这笔订单是否已完成支付$.post("orderqueryajax.php", { out_trade_no:$("#out_trade_no").val() }, function (data) {data = $.trim(data);$("#query_result").html(data);//一直更新查询结果if (data=="SUCCESS") {$("#query_result").html("支付成功,即将跳转...");//如果查询到的结果是成功支付,就进行页面跳转<?phpif (isset($_POST['history_go']) && $_POST['history_go'] == 3){echo 'window.setTimeout("history.go(-3);",2000);';//此处只是为了判断是页面返回两页还是三页}elseecho 'window.setTimeout("history.go(-2);",2000);';?>}});}}</script>
</body>
</html>

3. 后台orderqueryajax.php页面,其实这个页面是我仿照已有的example/orderquery.php抄的啦,嘿嘿

<?php
/**
*
* ajax异步查询订单是否完成
* 
**/
require_once "../lib/WxPay.Api.php";
require_once 'log.php';
require_once "WxPay.Config.php";//初始化日志
$logHandler= new CLogFileHandler("../logs/".date('Y-m-d').'.log');
$log = Log::Init($logHandler, 15);$v = $_POST["out_trade_no"];
if(isset($v) && $v != ""){$out_trade_no = $v;$input = new WxPayOrderQuery();$input->SetOut_trade_no($out_trade_no);$config = new WxPayConfig();$result = WxPayApi::orderQuery($config, $input);if ($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS'){//返回查询结果echo $result['trade_state'];}else{echo "FAIL";}
}
?>

这些写好后,就可以提交到服务器上跑一下啦

哦对了,如果你的代码在服务器上跑不起来的话,连最初demo里面的二维码都无法显示的话,那应该是你的php.ini里面的curl扩展功能没有开,我当时就是因为curl没开,导致在服务器上打开就是500错误,或者检查白名单是否添加;iis话在服务器上打开错误提示信息,根据提示找解决办法就行了

五、支付完成后异步回调,处理业务逻辑如:更新数据库

这一部分功能我是在example/notify.php中处理的

<?php
/**
*
* example目录下为简单的支付样例,仅能用于搭建快速体验微信支付使用
* 样例的作用仅限于指导如何使用sdk,在安全上面仅做了简单处理, 复制使用样例代码时请慎重
* 请勿直接直接使用样例对外提供服务
* 
**/require_once "../lib/WxPay.Api.php";
require_once '../lib/WxPay.Notify.php';
require_once "WxPay.Config.php";
require_once 'log.php';
require_once("../../include/memcache.php");
//初始化日志
$logHandler= new CLogFileHandler("../logs/".date('Y-m-d').'.log');
$log = Log::Init($logHandler, 15);class PayNotifyCallBack extends WxPayNotify
{//查询订单public function Queryorder($transaction_id){$input = new WxPayOrderQuery();$input->SetTransaction_id($transaction_id);$config = new WxPayConfig();$result = WxPayApi::orderQuery($config, $input);Log::DEBUG("query:" . json_encode($result));if(array_key_exists("return_code", $result)&& array_key_exists("result_code", $result)&& $result["return_code"] == "SUCCESS"&& $result["result_code"] == "SUCCESS"){return true;}return false;}/**** 回包前的回调方法* 业务可以继承该方法,打印日志方便定位* @param string $xmlData 返回的xml参数***/public function LogAfterProcess($xmlData){Log::DEBUG("call back, return xml:" . $xmlData);return;}//重写回调处理函数/*** @param WxPayNotifyResults $data 回调解释出的参数* @param WxPayConfigInterface $config* @param string $msg 如果回调处理失败,可以将错误信息输出到该方法* @return true回调出来完成不需要继续回调,false回调处理未完成需要继续回调*/public function NotifyProcess($objData, $config, &$msg){$data = $objData->GetValues();//TODO 1、进行参数校验if(!array_key_exists("return_code", $data) ||(array_key_exists("return_code", $data) && $data['return_code'] != "SUCCESS")) {//TODO失败,不是支付成功的通知//如果有需要可以做失败时候的一些清理处理,并且做一些监控$msg = "异常异常";return false;}if(!array_key_exists("transaction_id", $data)){$msg = "输入参数不正确";return false;}//TODO 2、进行签名验证try {$checkResult = $objData->CheckSign($config);if($checkResult == false){//签名错误Log::ERROR("签名错误...");return false;}} catch(Exception $e) {Log::ERROR(json_encode($e));}//TODO 3、处理业务逻辑Log::DEBUG("call back:" . json_encode($data));$notfiyOutput = array();//查询订单,判断订单真实性if(!$this->Queryorder($data["transaction_id"])){$msg = "订单查询失败";return false;}//可以在此处写入数据库$trade_no = $data['transaction_id'];$trade_status = $data['result_code'];$receipt_amount = $data['total_fee'];$gmt_payment = date("Y-m-d H:i:s");$buyer_logon_id = "";$buyer_user_id = "";$total_amount = $data['total_fee'];$out_trade_no = $data['out_trade_no'];$body = "";$subject= pdo_query("select subject from trade WHERE out_trade_no = ?", $out_trade_no)[0][0];$sql = "update trade set trade_no = ?,trade_status = ?,valid=1,receipt_amount = ?, gmt_payment = ?,buyer_logon_id = ?, buyer_user_id = ? where out_trade_no = ? limit 1; 
";$res =  pdo_query($sql,$trade_no, $trade_status,$receipt_amount,$gmt_payment, $buyer_logon_id, $buyer_user_id,$out_trade_no);$sql = "update goods set goods_number = goods_number-1, goods_trade_number = goods_trade_number+1 where goods_name=?";pdo_query($sql, $subject);return true;}
}$config = new WxPayConfig();
Log::DEBUG("begin notify");
$notify = new PayNotifyCallBack();
$notify->Handle($config, false);

如果你的回调中的代码没有生效,但你的回调地址又没有写错的话,估计你是和我遇着同样的坑了,且不得不填。极有可能是因为微信给你发的支付通知信息你没收到,解决方法我写在这篇文里面了,微信支付开发中的坑---- php废弃$GLOBALS[‘HTTP_RAW_POST_DATA’]
————————————————
版权声明:本文为CSDN博主「爱玲姐姐」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/jal517486222/article/details/84928429

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_891453.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2019年SEOer必备黑科技浏览器插件——5118站长工具箱

今天要为大家介绍一款SEOer必备黑科技——5118站长工具箱 5118站长工具箱是一款十分厉害的浏览器插件&#xff0c;是隐藏在浏览器右上角专业的SEO助手&#xff0c;用于SEOer做SEO的专业辅助工具。 下面我们看下这款黑科技都有哪些功能&#xff1a; SEO大数据分析&#xff1a…

Z-blog 搬家完成后网站内链接无法正常访问怎么解决

网站搬站后发现网站首页是可以打开的而内容页是无法正常访问的。 解决办法&#xff1a; 进入网站后台左侧导航栏点击进入插件管理-静态管理中心-选中“静态”-下滑保存。 重新进入静态管理中心-在选择伪静态-下滑保存即可。 如果发现您的网站还是无法正常访问&#xff0c;需…

JMeter中级篇-8-网站性能测试用例1设计

前面我们学会了如何获取录制web的脚本&#xff0c;如何写一个基本的测试用例&#xff0c;除了基本篇倒数第二篇&#xff0c;简单介绍了下设置负载场景&#xff0c;其实并没有太详细去介绍如何根据一个性能测试场景去设计性能测试用例&#xff0c;接下来三篇&#xff0c;我想从一…

JMeter中级篇-9-网站性能测试用例2设计

这篇&#xff0c;我们继续在前一篇性能测试用例基础之上&#xff0c;添加一点改变(添加断言)&#xff0c;同样逐步分析每一个条件&#xff0c;来设计JMeter上的性能测试用例。 网站性能测试案例2&#xff1a; 1.用户人数10人&#xff0c;一分钟之后&#xff0c;全部对服务器进…

JMeter中级篇-10-网站性能测试用例3设计(debug)

这篇我们继续在前面一篇基础上&#xff0c;介绍执行性能测试过程中一些从服务器上返回的数据的收集和保存&#xff0c;方便进行调试和问题定位。 网站性能测试案例3&#xff1a; 1.用户人数10人&#xff0c;2分钟之后&#xff0c;10个用户全部进入系统。 2.用户分别访问3个页…

任意网站商品上货监控提醒(提醒尺码颜色sku)

紧俏的商品总是缺货&#xff0c;只要一补货上架很快就被人抢购一空。怎样才知道商品什么时候上架&#xff0c;选择用木头浏览器监控商品上架提醒&#xff0c;还可以深入监控到具体的尺码颜色型号等sku。 1、先打开需要监控的商品页面&#xff0c;观察一下有货的尺码与无货的尺码…

备份、还原或移动 SharePoint 网站

(转载 http://office.microsoft.com/zh-cn/sharepointdesigner/HA100699392052.aspx) 适用于: Microsoft Office SharePoint Designer 2007 假设您的工作组刚刚在工作组网站上向多个文档库发布了他们最新的季度报告&#xff0c;而您在这个关键时刻希望备份网站。或者假设您的工…

自学网站

不要瞎找了&#xff0c;你要的自学网站我都给你整理好了&#xff01; 2016-05-13 兿林 金阳光自动化测试 专科生加油吧 一个有爱的大专生平台 微信&#xff1a;cs-jy8 生活在这个充满竞争&#xff0c;血腥味十足分分钟钟就会别人取代的大数据移动互联时代&#xff0c;大家一有…

SQL手工注入网站笔记

SQL手工注入网站笔记 目标网站&#xff1a;http://testphp.vulnweb.com/listproducts.php?cat1 1.判断注入点&#xff1a; http://testphp.vulnweb.com/listproducts.php?cat1’ http://testphp.vulnweb.com/listproducts.php?cat1 and 11 永真条件&#xff0c;回显正常 h…

2012.08.11青岛浩鑫机械网站被收录了,分享一下经验!

前些日子&#xff0c;刚做的网站&#xff0c;刚开始不知道怎么做才能收录&#xff0c;到QQ群里搜SEO群加&#xff0c;咨询他们&#xff0c;然后得出的结论&#xff1a; 青岛浩鑫机械厂-中国喷水织机生产基地!SEO信息百度权重 Google 反链数:0 响应时间: 469毫秒域名IP…

IIS6.0怎么架设一个网站

IIS6.0架设一个网站&#xff0c;其实还是很简单的&#xff0c;只要按照操作步骤&#xff0c;就能实现。 第一步&#xff0c;安装IIS6.0。 IIS6.0一般都是装在windows2003系统上&#xff0c;所以要先下载IIS6.0文件包&#xff0c;20M左右&#xff0c;下载完成后&#xff0c;打开…

网站排名记录[2013.01.02]

橡胶坝 围油栏 橡胶水坝

Python爬虫网站多页电影名和评论

爬取豆瓣电影的电影数据&#xff0c;具体爬取的是电影名和被评论的内容 import requests import re for i in range(1,6):index(i-1)*20url"https://movie.douban.com/review/best/?start{}".format(index)d{"User-Agent": "Mozilla/5.0 (Windows NT…

互联网网站的架构演进

简单介绍了从单机网站到微服务网站的演进&#xff0c;从概念上讲述了什么是微服务。 资源链接https://www.slidestalk.com/s/internet_architecture_revolution 更多优质资源 (示说网&#xff09;点击登录即可免费下载

【网站可用性自动化监测】python+seleium

【网站可用性自动化监测】pythonseleium 前倾提要&#xff1a;做了网络安全后重保期间需要对用户系统每日进行监测&#xff0c;相关监测脚本网上其实也有很多&#xff0c;但能自己个性化做一下也挺好&#xff0c;太久没做小程序需要写下代码巩固。本次程序开发目的是重保期间每…

快速入门 Codeforces 算法比赛/练习 网站

Codeforces是一家为计算机编程爱好者提供在线评测系统的俄罗斯网站。同时也是广大ACM编程爱好者所喜爱&#xff0c;被使用的网站之一&#xff0c;但是有很多编程小白刚接触此类算法网站&#xff0c;不太熟悉如何使用&#xff0c;这里博主给出快速入门Codeforces的图文教程。 C…

浅谈web网站架构演变过程

前言 我们以javaweb为例&#xff0c;来搭建一个简单的电商系统&#xff0c;看看这个系统可以如何一步步演变。 该系统具备的功能&#xff1a; 用户模块&#xff1a;用户注册和管理商品模块&#xff1a;商品展示和管理交易模块&#xff1a;创建交易和管理 阶段一、单机构建网站…

nodejs 进行网站监听时 不用在cmd停止后重启 网页刷新就能改变页面内容的工具

一、nodejs的软件需求——supervisor 我们使用nodejs开启服务器时&#xff0c;我们会在cmd里输入node xxx.js进行开启服务器。 很多时候我们会根据页面的逻辑和对项目的要求&#xff0c;进行对xxx.js文件内容的修改&#xff0c;但这时如果我们修改内容后保存&#xff0c;我们…

Web2.0网站介绍——个性化主页服务网站

随着Web2.0网站的不断涌现&#xff0c;越来越多的用户希望自己使用的服务具有极高的可定制性&#xff0c;在这种需求下&#xff0c;出现了越来越多的个性化主页服务网站。这些个性化 主页服务具有极高的可定制性&#xff0c;并且提供很多个性化的功能可供选择&#xff0c;这里就…

大型网站架构演变和知识体系

之前也有一些介绍大型网站架构演变的文章&#xff0c;例如LiveJournal的、ebay的&#xff0c;都是非常值得参考的&#xff0c;不过感觉他们讲的更多的是每次演变的结果&#xff0c;而没有很详细的讲为什么需要做这样的演变&#xff0c;再加上近来感觉有不少同学都很难明白为什么…