早就听说微信支付比支付宝支付的坑多,但还得得该填的填,该绕的绕, 最终我们网站的微信支付功能成功上线啦♪(^ ∇ ^*)
首先自报家门,我的PHP版本是7,微信demo用的是php_sdk_v3.0.9
一、手续备齐、按流程走
在进行微信支付开发之前,首先你得拥有微信支付的权限。哦对了,在此之前,你还得有一个公众号(服务号), 在微信公众平台申请。进入微信公众后台后,
左侧有一个微信支付
,如果你想要获得微信支付功能,还需要先进行微信公众号的认证,嘻嘻(此处省略300元
~~~费时费力)
我觉得微信认证过程还蛮麻烦的,我是和老赵一起做的,他负责给我认证材料,我负责上传。
认证完之后,还要申请商户号
,这也是老赵申请的,花费了好几天,然后申请好了之后你会得到微信发给你的商户号,如果你是超级管理员,你就可以在微信支付平台横着走了,你可以给别人(员工)设置不同的权限。在我们本次操作中,老赵是“超级管理员
”,我被授权为“管理员
”(仅次于“超级管理员”的位卑权低小角色>_<) 不得不说的是,一涉及到账号或者权限或者秘钥的页面,都只能超级管理员
查看,这真是太不方便了,以至于这几天我天天求着老赵的微信给我扫码登一下看看┭┮﹏┭┮
二、下载微信支付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';
}
}
三、微信支付的巨坑(速速绕过
) ---- 沙箱环境–>getsignkey
相信大家都看到了这里吧,知道要获取获取验签秘钥APIsignkey
这个东西。但我估计大家也一定在此处吃尽了苦头,耗费了很长时间吧。
微信的开发文档中只说了去https://api.mch.weixin.qq.com/sandboxnew/pay/getsignkey
获取验签秘钥API,但并没有给出具体的实现代码,┭┮﹏┭┮这可真是难为我了,我在这里花了整整两天时间查资料研究怎么获取验签秘钥API,最终我是下载了一个谷歌插件PostMan工具来模拟http请求获得了signkey,
然而,每次我获取到的signkey总是不变的,每次都是一样的值(我每次给出的随机串不同),这令我很郁闷,我感觉我的逻辑没错啊,不应该每次都获得一样的返回值。
我拿着我得到的这个极有可能有毛病的signkey去放到了配置文件中,
替换了GetKey的返回值。然后还将整个demo中所有的wei.qq.com
后面加上了/sandboxnew
,然而,这时候打开native.php页面居然又报错了,说我的沙箱秘钥不正确,让我去https://api.mch.weixin.qq.com/sandboxnew/pay/getsignkey
获取验签秘钥API,真让人感到很无语,我我我…唉,气死我了。我在这里耗费了两天,居然就给我这个结果!我又继续上网查资料,发现有很多很多人都遇到了微信沙箱的各种坑,我心里获得了不少安慰。之后,我决定不用沙箱环境了,非得用沙箱环境仿真吗,非得提交验收吗,答案是NO
,我发现不用沙箱环境在服务器上代码也能跑的起来,也可以支付,那为什么要用那个麻烦的沙箱环境呢,浪费了我那么长时间,实在是忍不下去了。我觉得绕过沙箱环境是提高微信支付开发效率最关键的一步
四、 现在要正式进行编程了,首先是前台的支付页面完成后的跳转
由于微信没有给出同步回调地址,那什么时候完成支付进行页面跳转都需要看我们用js发送请求查询了。
上面是我的订单提交页面(index.php)这个页面比较简单不再多说。点击付款按钮后,就会跳转到下面的扫码支付页面example/native.php,这是我自己模仿微信给出的样例画的一个漂亮的收银台,嘻嘻* ^_^ *
微信的图片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、在支付成功通知中需要查单确认是否真正支付成功(见:not