如果使用包开发,难度会小很多,建议使用:

composer require yansongda/pay

这个包支持alipay和wechat.下面说说微信自己提供的包.


快速搭建指南
①、安装配置nginx+phpfpm+php;
②、将wechat官网给的SDK解压到网站根目录;
③、修改lib/WxPay.Config.php为自己申请的商户号的信息(配置详见说明);
⑤、下载证书替换cert下的文件;
⑥、搭建完成.

SDK目录结构

|-- lib
|-- logs
`--

目录功能简介

lib API接口封装代码
WxPay.Api.php 包括所有微信支付API接口的封装
WxPay.Config.Interface.php 商户配置 , 业务需要从这里继承(请注意保管自己的密钥/证书等)
WxPay.Data.php 输入参数封装
WxPay.Exception.php 异常类
WxPay.Notify.php 回调通知基类
cert 证书存放路径,证书可以登录商户平台 ​​​https://pay.weixin.qq.com/index.php/account/api_cert​​ 下载

注意:
1.证书文件不能放在web服务器虚拟目录,应放在有访问权限控制的目录中,防止被他人下载;
2.建议将证书文件名改为复杂且不容易猜测的文件名;
3.商户服务器要做好病毒和木马防护工作,不被非法侵入者窃取证书文件。

example
样例程序代码路径

example/phpqrcode
开源二维码php代码

logs
日志文件

※配置指南
MCHID = ‘1225312702’;
这里填开户邮件中的商户号

APPID = ‘wx426b3015555a46be’;
这里填开户邮件中的(公众账号APPID或者应用APPID)

KEY = ‘e10adc3949ba59abbe56e057f20f883e’
这里请使用商户平台登录账户和密码登录http://pay.weixin.qq.com 平台设置的“API密钥”,为了安全,请设置为32字符串。

APPSECRET = ‘01c6d59a3f9024db6336662ac95c8e74’
改参数在JSAPI支付(open平台账户不能进行JSAPI支付)的时候需要用来获取用户openid,可使用APPID对应的公众平台登录http://mp.weixin.qq.com 的开发者中心获取AppSecret。

shiyongdemo出错:

微信支付_php

查看log日志:

微信支付_封装_02


打开:

D:\phpStudy\WWW\​​test.com​​\php_wechat_pay\example\WxPay.NativePay.php

把try-catch关闭掉,释放出完整错误消息:

微信支付_文件名_03


微信支付_文件名_04

Fatal error: Uncaught WxPayException: curl出错,错误码:60 in D:\phpStudy\WWW\​​test.com​​​\php_wechat_pay\lib\WxPay.Api.php:593 Stack trace: #0 D:\phpStudy\WWW\​​test.com​​​\php_wechat_pay\lib\WxPay.Api.php(62): WxPayApi::postXmlCurl(Object(WxPayConfig), ‘<![…’, ‘​​https://api.mch​​​…’, false, 6) #1 D:\phpStudy\WWW\​​test.com​​​\php_wechat_pay\example\WxPay.NativePay.php(66): WxPayApi::unifiedOrder(Object(WxPayConfig), Object(WxPayUnifiedOrder)) #2 D:\phpStudy\WWW\​​test.com​​​\php_wechat_pay\example\native.php(54): NativePay->GetPayUrl(Object(WxPayUnifiedOrder)) #3 {main} thrown in D:\phpStudy\WWW\​​test.com​​\php_wechat_pay\lib\WxPay.Api.php on line 593

找到库里面的文件,这个时候我们就要小心了,毕竟是类库,不能随意乱动:

D:\phpStudy\WWW\​​test.com​​\php_wechat_pay\lib\WxPay.Api.php:593

然后就发现事curl报错,因为是在本地测试,所以证书校验不能通过:

微信支付_php_05

注释上面两行,改为以下代码:

curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE);
curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE);

把这证书验证改为false,我们再来看一下:

微信支付_php_06

到这里,试了一下,第一个模式一直提示系统繁忙,付不了款,第二个付款成功。

进去看代码,我只有个hehe了

微信支付_封装_07

微信支付_php_08


但是log里面还有错误,如下:

[2018-12-13 16:40:06][error] [,file:D:\phpStudy\WWW\​​test.com​​​\php_wechat_pay\example\WxPay.NativePay.php,line:69,function:ERROR,file:D:\phpStudy\WWW\​​test.com​​\php_wechat_pay\example\native.php,line:54,function:GetPayUrl]{}

我们把native.php的54行得到的结果打印出来看一下:

微信支付_封装_09


结果如下:

微信支付_文件名_10

我们没有这个url,所以问题就在这里!

D:\phpStudy\WWW\​​test.com​​\php_wechat_pay\lib\WxPay.Api.php

微信支付_文件名_11

写一个获取IP的方法:

//获取浏览器ip地址
public static function real_ip()
{
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);

foreach ($arr as $ip) {
$ip = trim($ip);

if ($ip != 'unknown') {
$realip = $ip;
break;
}
}
}
else if (isset($_SERVER['HTTP_CLIENT_IP'])) {
$realip = $_SERVER['HTTP_CLIENT_IP'];
}
else if (isset($_SERVER['REMOTE_ADDR'])) {
$realip = $_SERVER['REMOTE_ADDR'];
}
else {
$realip = '0.0.0.0';
}
}
else if (getenv('HTTP_X_FORWARDED_FOR')) {
$realip = getenv('HTTP_X_FORWARDED_FOR');
}
else if (getenv('HTTP_CLIENT_IP')) {
$realip = getenv('HTTP_CLIENT_IP');
}
else {
$realip = getenv('REMOTE_ADDR');
}

preg_match('/[\\d\\.]{7,15}/', $realip, $onlineip);
$realip = (!empty($onlineip[0]) ? $onlineip[0] : '0.0.0.0');
return $realip;
}