PHP实现微信支付(jsapi支付)流程步骤详解


Posted in PHP onMarch 15, 2018

最近接触到一个项目,涉及到微信支付,搞微信开发这么久以来,还没搞过支付,之前也就搞过公众号发红包,感谢前辈们的探索,我看了他们的博文,让我少走了很多弯路。

前期准备:

1.微信认证服务号,并且开通了微信支付

2.微信支付SDK,下载地址:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1

3.登录微信支付平台https://pay.weixin.qq.com/index.php/account/api_cert下载支付证书

方法步骤:

1.demo文件处理

(1)将官方的demo下载下来,文件名为WxpayAPI_php_v3,把这文件重命名为wxpay,为了后边书写目录方便;

(2)打开lib文件夹下的WxPay.Api.php文件,在537行有一段curl网络请求配置代码:

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,2);//严格校验

为了禁止 cURL 验证对等证书(peer's certificate)。

(3)打开lib文件夹下的WxPay.Config.php文件,第25行开始,根据自己的账号完成基本信息设置;

const APPID = '公众账号APPID'; 
const MCHID = '商户号'; 
const KEY = '商户支付密钥'; 
const APPSECRET = '公众帐号secert';

(4)打开lib文件夹下的WxPay.Notify.php文件,第79行的代码:

if($needSign == true && 
 $this->GetReturn_code($return_code) == "SUCCESS") 
{ 
 $this->SetSign(); 
}

改成:

if($needSign == true && 
 $this->GetReturn_code() == "SUCCESS") 
{ 
 $this->SetSign(); 
}

(5)打开cert证书目录,将里边的两个证书换成自己的支付证书。

2.公众号后台设置

(1)配置网页授权域名,我的域名是(xy.chuyin.ren);

PHP实现微信支付(jsapi支付)流程步骤详解

(1)配置支付授权目录,域名是(xy.chuyin.ren),我将demo放到此域名指向的目录的weixinopen/文件夹下,demo中jsapi.php文件位于example/目录下,所以支付授权目录为:xy.chuyin.ren/weixinopen/wxpay/example/

PHP实现微信支付(jsapi支付)流程步骤详解

3.支付流程

打开example目录下的jsapi.php文件,支付发起和处理,都是在这里完成。

(1)获取用户openid

之前配置好了自己的APPID和APPSecert,所以这里不用处理。

//①、获取用户openid 
$tools = new JsApiPay(); 
$openId = $tools->GetOpenid();

这里首先初始化的一个JsApiPay()类得到一个对象,文件对应example/目录下的WxPay.JsApiPay.php,调用GetOpenid()方法,会自动获取自己的openID。

(2)统一下单

//②、统一下单 
$input = new WxPayUnifiedOrder(); 
$input->SetBody("test"); 
$input->SetAttach("test"); 
$input->SetOut_trade_no(WxPayConfig::MCHID.date("YmdHis")); 
$input->SetTotal_fee("1"); 
$input->SetTime_start(date("YmdHis")); 
$input->SetTime_expire(date("YmdHis", time() + 600)); 
$input->SetGoods_tag("test"); 
$input->SetNotify_url("http://paysdk.weixin.qq.com/example/notify.php"); 
$input->SetTrade_type("JSAPI"); 
$input->SetOpenid($openId); 
$order = WxPayApi::unifiedOrder($input); 
echo '<font color="#f00"><b>统一下单支付单信息</b></font><br/>'; 
printf_info($order); 
$jsApiParameters = $tools->GetJsApiParameters($order);

对应WxPay.Api.php的第24行的unifiedOrder()方法,配置订单信息和支付回调函数,这里需要修改几个参数:

A. 商品名称:

$input->SetBody("test");

B. 订单号

$input->SetOut_trade_no(WxPayConfig::MCHID.date("YmdHis"));

C. 支付金额

$input->SetTotal_fee("1");

D. 支付验证链接

设置为你的notify.php文件所在的位置,所以我这里设置为:http://xy.chuyin.ren/weixinopen/wxpay/example/notify.php

也可以写其他地址,当然要在支付授权域名之下,支付成功之后就会自动回调到该链接指定的方法里边,可以在里边进行判断和数据库操作.

$input->SetNotify_url(http://paysdk.weixin.qq.com/example/notify.php);

E. 附加参数

$input->SetAttach("test");

附加参数,可填可不填,填写的话,里边字符串最好不要出现空格。

这时候,点击支付应该就可以成功支付了。

(3)发起支付

<script type="text/javascript"> 
//调用微信JS api 支付 
function jsApiCall() 
{ 
 WeixinJSBridge.invoke( 
  'getBrandWCPayRequest', 
  <?php echo $jsApiParameters; ?>, 
  function(res){ 
   WeixinJSBridge.log(res.err_msg); 
   alert(res.err_code+res.err_desc+res.err_msg); 
  } 
 ); 
} 
function callpay() 
{ 
 if (typeof WeixinJSBridge == "undefined"){ 
  if( document.addEventListener ){ 
   document.addEventListener('WeixinJSBridgeReady', jsApiCall, false); 
  }else if (document.attachEvent){ 
   document.attachEvent('WeixinJSBridgeReady', jsApiCall); 
   document.attachEvent('onWeixinJSBridgeReady', jsApiCall); 
  } 
 }else{ 
  jsApiCall(); 
 } 
} 
</script>

点击立即支付按钮调用的就是 callpay() 函数,他有会调用jsApiCall() 函数打开支付程序。

PHP实现微信支付(jsapi支付)流程步骤详解

jsApiCall() 函数会监听每一步动作:

PHP实现微信支付(jsapi支付)流程步骤详解

 res.err_msg 为get_brand_wcpay_request:cancel 表明前端判断的取消支付,es.err_msg 为get_brand_wcpay_request:ok 表明前端判断的支付成功,我们可以根据这个将支付跳转到成功页面。

(4)支持成功回调

通过前端jsApiCall()函数可以监听支付结果,但是这个并不可信。确认是否支付成功还是应当通过notify.php 处理业务逻辑。前边配置好了支付验证链接SetNotify_url(),支付完成后,微信服务器会根据链接自动请求你的notify.php文件,打开这个文件,其实这个文件最主要的代码就两行:

$notify = new PayNotifyCallBack(); 
$notify->Handle(false);

由此跟踪到WxPay.Notify.php类文件的Handle()函数:

/** 
 * 
 * 回调入口 
 * @param bool $needSign 是否需要签名输出 
 */ 
final public function Handle($needSign = true) 
{ 
 $msg = "OK"; 
 //当返回false的时候,表示notify中调用NotifyCallBack回调失败获取签名校验失败,此时直接回复失败 
 $result = WxpayApi::notify(array($this, 'NotifyCallBack'), $msg); 
 if($result == false){ 
  $this->SetReturn_code("FAIL"); 
  $this->SetReturn_msg($msg); 
  $this->ReplyNotify(false); 
  return; 
 } else { 
  //该分支在成功回调到NotifyCallBack方法,处理完成之后流程 
  $this->SetReturn_code("SUCCESS"); 
  $this->SetReturn_msg("OK"); 
 } 
 $this->ReplyNotify($needSign); 
}

主要代码:

$result = WxpayApi::notify(array($this, 'NotifyCallBack'), $msg);

然后来到WxPay.Api.php文件的第411行,notify()函数:

/** 
 * 
 * 支付结果通用通知 
 * @param function $callback 
 * 直接回调函数使用方法: notify(you_function); 
 * 回调类成员函数方法:notify(array($this, you_function)); 
 * $callback 原型为:function function_name($data){} 
 */ 
public static function notify($callback, &$msg) 
{ 
 //获取通知的数据 
 $xml = $GLOBALS['HTTP_RAW_POST_DATA']; 
 //file_put_contents('log.txt',$xml,FILE_APPEND); 
 //如果返回成功则验证签名 
 try { 
  $result = WxPayResults::Init($xml); 
 } catch (WxPayException $e){ 
  $msg = $e->errorMessage(); 
  return false; 
 } 
  
 return call_user_func($callback, $result); 
}

这里面的$xml=$GLOBALS['HTTP_RAW_POST_DATA'],就是支付成功后用户返回给你的一个结果,他是一个xml格式的字符串。

PHP实现微信支付(jsapi支付)流程步骤详解

我们可以将这里返回的xml数据记录下来,然后打开看看$out_trade_no就是在支付之前我自己设置的订单号码,$attach就是设置的附加参数。

得到了这个订单号,然后我就直接在下面写支付成功后的逻辑了,比如改变数据库中的数据等等。

这样 微信支付的 JsApi支付就大致分析完成了。

PHP实现微信支付(jsapi支付)流程步骤详解

这是集成了官方的SDK实现的,如果不使用SDK,可以使用更简单的方法,见:PHP实现微信支付(jsapi支付)和退款(无需集成支付SDK)

总结

以上所述是小编给大家介绍的PHP实现微信支付(jsapi支付)流程步骤详解,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

PHP 相关文章推荐
如何删除多级目录
Oct 09 PHP
dedecms系统的广告设置代码 基础版本
Apr 09 PHP
PHP 文件系统详解
Sep 13 PHP
探讨php中遍历二维数组的几种方法详解
Jun 08 PHP
解析PHP可变函数的经典用法
Jun 20 PHP
浅谈PHP中Stream(流)
Jun 08 PHP
PHP中strncmp()函数比较两个字符串前2个字符是否相等的方法
Jan 07 PHP
PHP实现实时生成并下载超大数据量的EXCEL文件详解
Oct 23 PHP
Laravel框架搜索分页功能示例
Feb 01 PHP
thinkPHP框架通过Redis实现增删改查操作的方法详解
May 13 PHP
确保Laravel网站不会被嵌入到其他站点中的方法
Oct 18 PHP
PHP设计模式(观察者模式)
Jul 07 PHP
PHP实现的数组和XML文件相互转换功能示例
Mar 15 #PHP
PHP实现用户异地登录提醒功能的方法【基于thinkPHP框架】
Mar 15 #PHP
laravel框架关于搜索功能的实现
Mar 15 #PHP
PHP实现浏览器中直接输出图片的方法示例
Mar 14 #PHP
PHP实现生成推广海报的方法详解
Mar 14 #PHP
PHP基于phpqrcode类生成二维码的方法详解
Mar 14 #PHP
PHP判断是否是微信打开,浏览器打开的方法
Mar 14 #PHP
You might like
PHP+SQL 注入攻击的技术实现以及预防办法
2011/01/27 PHP
php实现httpclient类示例
2014/04/08 PHP
PHP多线程之内部多线程实例分析
2015/03/09 PHP
PHP实现中文圆形印章特效
2015/06/19 PHP
php去掉文件前几行的方法
2015/07/29 PHP
orm获取关联表里的属性值
2016/04/17 PHP
PHP数据库编程之MySQL优化策略概述
2017/08/16 PHP
WordPress免插件实现面包屑导航的示例代码
2020/08/20 PHP
Javascript SHA-1:Secure Hash Algorithm
2006/12/20 Javascript
js防止DIV布局滚动时闪动的解决方法
2014/10/30 Javascript
浅谈js中变量初始化
2015/02/03 Javascript
javascript实现无法关闭的弹框
2016/11/27 Javascript
在ABP框架中使用BootstrapTable组件的方法
2017/07/31 Javascript
JS简单实现动态添加HTML标记的方法示例
2018/04/08 Javascript
小程序根据手机机型设置自定义底部导航距离
2019/06/04 Javascript
详解webpack引用jquery(第三方模块)的三种办法
2019/08/21 jQuery
纯js实现无缝滚动功能代码实例
2020/02/21 Javascript
Python 常用 PEP8 编码规范详解
2017/01/22 Python
Python多线程实现同步的四种方式
2017/05/02 Python
Python django使用多进程连接mysql错误的解决方法
2018/10/08 Python
django 使用全局搜索功能的实例详解
2019/07/18 Python
python3 requests库实现多图片爬取教程
2019/12/18 Python
Python面向对象原理与基础语法详解
2020/01/02 Python
tensorboard实现同时显示训练曲线和测试曲线
2020/01/21 Python
python实现引用其他路径包里面的模块
2020/03/09 Python
HTML5 播放 RTSP 视频的实例代码
2019/07/29 HTML / CSS
Sasa莎莎海外旗舰店:香港莎莎美妆平台
2018/03/21 全球购物
动态密码技术
2012/10/18 面试题
大学生饮食连锁店创业计划书
2014/01/17 职场文书
测绘工程专业求职信
2014/07/15 职场文书
车辆年审委托书范本
2014/09/18 职场文书
先进党支部申报材料
2014/12/24 职场文书
2016新年感言
2015/08/03 职场文书
使用python求解迷宫问题的三种实现方法
2022/03/17 Python
青岛市的收音机研制与生产
2022/04/07 无线电
Java 写一个简单的图书管理系统
2022/04/26 Java/Android