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
mysql limit查询优化分析
Nov 12 PHP
解决FastCGI 进程超过了配置的活动超时时限的问题
Jul 03 PHP
ie与session丢失(新窗口cookie丢失)实测及解决方案
Jul 15 PHP
PHP连接access数据库
Mar 27 PHP
Thinkphp无限级分类代码
Nov 11 PHP
PHP在线打包下载功能示例
Oct 15 PHP
PHP5.5安装PHPRedis扩展及连接测试方法
Jan 22 PHP
php基于自定义函数记录log日志方法
Jul 21 PHP
PHP 使用二进制保存用户状态的实例
Jan 29 PHP
微信公众平台开发教程①获取用户Openid及个人信息图文详解
Apr 10 PHP
laravel清除视图缓存的代码
Oct 23 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 向访客和爬虫显示不同的内容
2009/11/09 PHP
windows下开发并编译PHP扩展的方法
2011/03/18 PHP
非常精妙的PHP递归调用与静态变量使用
2012/12/16 PHP
PHP实现下载断点续传的方法
2014/11/12 PHP
举例讲解PHP面对对象编程的多态
2015/08/12 PHP
PHP如何将XML转成数组
2016/04/04 PHP
capacityFixed 基于jquery的类似于新浪微博新消息提示的定位框
2011/05/24 Javascript
javascript 星级评分效果(手写)
2012/12/24 Javascript
jQuery function的正确书写方法
2013/08/02 Javascript
jquery提交form表单简单示例分享
2014/03/03 Javascript
如何获取网站icon有哪些可行的方法
2014/06/05 Javascript
浅析基于WEB前端页面的页面内容搜索的实现思路
2014/06/10 Javascript
举例讲解如何判断JavaScript中对象的类型
2016/04/22 Javascript
jQuery中each()、find()和filter()等节点操作方法详解(推荐)
2016/05/25 Javascript
基于JS实现一个随机生成验证码功能
2019/05/29 Javascript
[01:45]绝对公平!DOTA2队长征召模式详解
2014/04/25 DOTA
python抓取网页图片并放到指定文件夹
2014/04/24 Python
Python爬取网易云音乐热门评论
2017/03/31 Python
Python读取properties配置文件操作示例
2018/03/29 Python
Python数据可视化:饼状图的实例讲解
2019/12/07 Python
python编写微信公众号首图思路详解
2019/12/13 Python
使用python接受tgam的脑波数据实例
2020/04/09 Python
Python3+selenium配置常见报错解决方案
2020/08/28 Python
python Scrapy爬虫框架的使用
2021/01/21 Python
只要五步 就可以用HTML5/CSS3快速制作便签贴特效(图)
2012/06/04 HTML / CSS
Omio波兰:全欧洲低价大巴、火车和航班搜索和比价
2018/02/16 全球购物
马来西亚演唱会订票网站:StubHub马来西亚
2018/10/18 全球购物
比利时的在线灯具店:Lampen24.be
2019/07/01 全球购物
波兰化妆品和护肤品购物网站:eKobieca
2019/08/30 全球购物
2014年安置帮教工作总结
2014/12/11 职场文书
2015年先进个人自荐书
2015/03/24 职场文书
工作时间调整通知
2015/04/24 职场文书
总结会主持词
2015/07/02 职场文书
html5表单的required属性使用
2021/07/07 HTML / CSS
继承Win10缺点!教你关闭Win11烦人的网络搜索
2021/11/23 数码科技
使用CSS连接数据库的方式
2022/02/28 HTML / CSS