首先呢,需要公司去注册微信平台上的东西,拿到资质,拿到配置信息才可以进行测试。
我们程序猿这里直接从代码开始,不管前面乱七八糟的程序。
下载好文档后把文档放在 exends 目录下 我将文件改名为 wechatpay
现在说一下整体的开发流程
1.写配置文件(APPID,MCHID 等数据) 文档在文件夹下的example->Wxpay.Config.php
2.配置好后开始更改每个文件上的 require_once 路径 防止开发时出没有必要的错误
//require_once "../lib/WxPay.Config.Interface.php";
require_once EXTEND_PATH.'wechatpay/lib/WxPay.Config.Interface.php';
3.开始在自己的支付模块里写逻辑,我在下面会附上我的测试代码片段
4.获取到参数后请求二维码并返回到网页上生成(很关键的一步)
5.检测是否支付成功
直接从第3步开始说起
每个公司的逻辑都不同 但需要获取到二维码传入的参数大致相同,请仔细阅读下面的代码。在此之前,可以阅读一下腾讯给的开发文档。
//扫码支付
public function wechat_pay($user_id,$number,$pice)
{
//扫二维码进行支付
require_once EXTEND_PATH.'wechatpay/lib/WxPay.Api.php'; //载入微信支付相关文件
require_once EXTEND_PATH.'wechatpay/example/WxPay.NativePay.php'; //载入微信支付相关文件
require_once EXTEND_PATH.'wechatpay/example/log.php';//载入微信支付相关文件
require_once EXTEND_PATH.'wechatpay/lib/WxPay.Data.php'; //载入微信支付相关文件
//模式二
/**
* 流程:
* 1、调用统一下单,取得code_url,生成二维码
* 2、用户扫描二维码,进行支付
* 3、支付完成之后,微信服务器会通知支付成功
* 4、在支付成功通知中需要查单确认是否真正支付成功(见:notify.php)
*/
//初始化日志
$logHandler= new \CLogFileHandler(EXTEND_PATH.'wechatpay/example/log.php'.date('Y-m-d').'.log');
$log = \Log::Init($logHandler, 15);
//
$notify = new \NativePay();
$input = new \WxPayUnifiedOrder();
$input->SetBody("充值使我快乐"); //设置商品或支付单简要描述
$input->SetAttach($user_id); //设置附加数据,在查询API和支付通知中原样返回,该字段主要用于商户携带订单的自定义数据 我这里设置成用户ID?
$input->SetOut_trade_no($number); //设置商户系统内部的订单号,32个字符内、可包含字母, 其他说明见商户订单号
$input->SetTotal_fee($pice*100); //设置订单总金额,只能为整数,详见支付金额
$input->SetTime_start(date("YmdHi")); //设置订单生成时间,格式为yyyyMMddHHmmss,如2009年12月25日9点10分10秒表示为20091225091010。其他详见时间规则
$input->SetTime_expire(date("YmdHis", time() + 180)); //设置订单失效时间,格式为yyyyMMddHHmmss,如2009年12月27日9点10分10秒表示为20091227091010。其他详见时间规则
//$input->SetGoods_tag("test"); //设置商品标记,代金券或立减优惠功能的参数,说明详见代金券或立减优惠
$input->SetNotify_url("http://localhost/huoniao/extends/wechatpay/example/native_notify.php");//设置接收微信支付异步通知回调地址
$input->SetTrade_type("NATIVE"); //设置取值如下:JSAPI,NATIVE,APP,详细说明见参数规定
$input->SetProduct_id("0"); //设置trade_type=NATIVE,此参数必传。此id为二维码中包含的商品ID,商户自行定义。
///var_dump($input);die;
$result = $notify->GetPayUrl($input);
//var_dump($result);die;
return urlencode($result['code_url']);
//需要生成变量的值
//1.充值的用户ID $user_id 用户表的唯一标识
//2.订单号 $number
//3.金额(微信是以分为单位1的) $pice
//4.商品ID 不传 默认为0 有业务逻辑需要的朋友可以写进来
}
接下来在控制器里调用上述的这个方法,并传参。这里把订单号先写入session,查询是否支付成功时用。
//订单号
$data['number'] = time().str_pad(mt_rand(1, 99999), 5, '0', STR_PAD_LEFT);
//将订单号存入session 做查询跳转使用
$_SESSION['user']['user_info']['order_number'] = $data['number'];
$code = $this->wechat_pay($user_id,$data['number'],$data['price']);
if($code)
{
//这里你们可以在判断的时候做一些$code的验证规则
json(['code' => 1 , msg => '$code']);
}else{
json(['code' => 2 , msg => '二维码获取失败,错误码002']);
}
因为是测试代码,所以前端请求过来的是死值,你们在开发的时候千万不要这样写,因为极不安全,容易被他人篡改信息,可能会造成难以挽回的损失。
接下来看前端请求控制器返回生成二维码与查询是否交易成功的片段。
写一下简单的流程
在用户输入金额点击提交按钮后,获取提交数据走Ajax去 wechatpay 成功获取到二维码并先显示后,js不停的请求一个查询的方法是否支付成功,没成功就一直停留,成功后提示并跳转页面 。
这里需要在腾讯文档里改一个东西,因为会一直获取失败,我找了好久最终发现是他们写的CURL有点问题 文件应该是wechatpay->lib->WxPay.Api.php 557行 我直接把这个方法复制下来给你们看
private static function postXmlCurl($config, $xml, $url, $useCert = false, $second = 30)
{
$ch = curl_init();
$curlVersion = curl_version();
$ua = "WXPaySDK/3.0.9 (".PHP_OS.") PHP/".PHP_VERSION." CURL/".$curlVersion['version']." "
.$config->GetMerchantId();
//设置超时
curl_setopt($ch, CURLOPT_TIMEOUT, $second);
$proxyHost = "0.0.0.0";
$proxyPort = 0;
$config->GetProxy($proxyHost, $proxyPort);
//如果有配置代理这里就设置代理
if($proxyHost != "0.0.0.0" && $proxyPort != 0){
curl_setopt($ch,CURLOPT_PROXY, $proxyHost);
curl_setopt($ch,CURLOPT_PROXYPORT, $proxyPort);
}
curl_setopt($ch,CURLOPT_URL, $url);
//curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,TRUE);
//curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,2);//严格校验
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE);
curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE);//严格校验2
curl_setopt($ch,CURLOPT_USERAGENT, $ua);
//设置header
curl_setopt($ch, CURLOPT_HEADER, FALSE);
//要求结果为字符串且输出到屏幕上
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
//var_dump($ch);die;
if($useCert == true){
//设置证书
//使用证书:cert 与 key 分别属于两个.pem文件
//证书文件请放入服务器的非web目录下
$sslCertPath = "";
$sslKeyPath = "";
$config->GetSSLCertPath($sslCertPath, $sslKeyPath);
curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');
curl_setopt($ch,CURLOPT_SSLCERT, $sslCertPath);
curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');
curl_setopt($ch,CURLOPT_SSLKEY, $sslKeyPath);
}
//post提交方式
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
//运行curl
//var_dump(curl_exec($ch));
$data = curl_exec($ch);
//返回结果
if($data){
curl_close($ch);
//var_dump($data);die;
return $data;
}else{
$error = curl_errno($ch);
curl_close($ch);
throw new WxPayException("curl出错,错误码:$error");
}
}
改完成之后获取二维码应该是没问题了,接下来看HTML代码。你要是连这都看不懂,那我真的没脾气,请出门右拐。
接下来看我是怎么写这个查询的方法的,其实很简单,微信支付文档已经写好了,我们直接用就好。主要还是在于session里的订单号。
记得一定要在控制器里写上这句话,因为这个文件就是查询文件
require_once EXTEND_PATH.'wechatpay/example/WxPay.MicroPay.php';//载入微信支付相关文件
public function query()
{
//查询订单状态
$qurey = new \MicroPay();
$order = $_SESSION['user']['user_info']['order_number'];
$num ='';
$data = $qurey->query($order,$num);
//var_dump($data);
//var_dump($_SESSION['user']['user_info']['order_number']);
if($data['trade_state_desc'] == '支付成功'){
return json(['code' => 1,'msg'=>'支付成功']);
}
}
如此大功告成。这里我在查询完成之后没有清楚session数据,你们记得清除一哈。
上面的东西都是我半年前写过的项目里的东西了,今天心血来潮,写了个博客。还望各位大佬们多多指教。