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 相关文章推荐
用定制的PHP应用程序来获取Web服务器的状态信息
Oct 09 PHP
PHP小技巧搜集,每个PHPer都来露一手
Jan 02 PHP
一个图形显示IP的PHP程序代码
Oct 19 PHP
php Http_Template_IT类库进行模板替换
Mar 19 PHP
编译php 5.2.14+fpm+memcached(具体操作详解)
Jun 18 PHP
PHP 如何利用phpexcel导入数据库
Aug 24 PHP
PHP上传文件时文件过大$_FILES为空的解决方法
Nov 26 PHP
浅析ThinkPHP中的pathinfo模式和URL重写
Jan 06 PHP
Yii框架中 find findAll 查找出制定的字段的方法对比
Sep 10 PHP
PHP扩展开发入门教程
Feb 26 PHP
Yii实现自动加载类地图的方法
Apr 01 PHP
WHOOPS PHP调试库的使用
Sep 29 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
基于 Swoole 的微信扫码登录功能实现代码
2018/01/15 PHP
Easy.Ajax 部分源代码 支持文件上传功能, 兼容所有主流浏览器
2011/02/24 Javascript
读jQuery之十一 添加事件核心方法
2011/07/31 Javascript
IE和Firefox的Javascript兼容性总结[推荐收藏]
2011/10/19 Javascript
javascript学习笔记(十八) 获得页面中的元素代码
2012/06/20 Javascript
jQuery中[attribute]选择器用法实例
2014/12/31 Javascript
jQuery基于ID调用指定iframe页面内的方法
2016/07/06 Javascript
vue.js表格组件开发的实例详解
2016/10/12 Javascript
jQuery中Nicescroll滚动条插件的用法
2016/11/10 Javascript
Javascript使用function创建类的两种方法(推荐)
2016/11/19 Javascript
jQuery插件扩展实例【添加回调函数】
2016/11/26 Javascript
详解百度百科目录导航树小插件
2017/01/08 Javascript
JS表格组件神器bootstrap table使用指南详解
2017/04/12 Javascript
详解如何让Express支持async/await
2017/10/09 Javascript
javaScript之split与join的区别(详解)
2017/11/08 Javascript
javaScript强制保留两位小数的输入数校验和小数保留问题
2018/05/09 Javascript
js实现跳一跳小游戏
2020/07/31 Javascript
vue render函数动态加载img的src路径操作
2020/10/26 Javascript
[00:56]2014DOTA2国际邀请赛 DK、iG 赛前探访
2014/07/10 DOTA
python批量导出导入MySQL用户的方法
2013/11/15 Python
Python语言实现将图片转化为html页面
2017/12/06 Python
Python构建网页爬虫原理分析
2017/12/19 Python
Django中的ajax请求
2018/10/19 Python
对Pandas MultiIndex(多重索引)详解
2018/11/16 Python
Django 实现图片上传和显示过程详解
2019/07/18 Python
详解Python文件修改的两种方式
2019/08/22 Python
Python面向对象之继承原理与用法案例分析
2019/12/31 Python
购买瑞典当代设计的腕表和太阳眼镜:TRIWA
2016/10/30 全球购物
Perfume’s Club法国站:购买香水和化妆品
2019/05/02 全球购物
瑞士网球商店:Tennis-Point
2020/03/12 全球购物
七年级生物教学反思
2014/01/30 职场文书
领导班子党的群众路线对照检查材料
2014/09/25 职场文书
工作表扬信
2015/01/17 职场文书
放牛班的春天观后感
2015/06/01 职场文书
golang 实现对Map进行键值自定义排序
2021/04/28 Golang
python中subplot大小的设置步骤
2021/06/28 Python