搜索
首页后端开发php教程微信支付PHP SDK之微信公众号支付代码详解_PHP

这里假设你已经申请完微信支付

1. 微信后台配置  如图

我们先进行测试,所以先把测试授权目录和 测试白名单添加上。测试授权目录是你要发起微信请求的哪个文件所在的目录。

例如jsapi 发起请求一般是jsapi.php所在目录 为测试目录,测试白名单即开发人员的微信号。

正式的支付授权目录不能和测试的一样否则会报错。不填写或者填错授权目录以及测试白名单都会报错。

报错样例:

NaNsystem:access_denied

不在测试白名单

2. 配置 lib/WxPay.Config.php文件

最主要配置一下四项:

const APPID = '';
const MCHID = '';
const KEY = '';
const APPSECRET = '';
APPID 和 APPSECRET都可以在微信后台中找到。
MCHID 在申请微信支付后发来的邮件中可以找到,KEY 则根据邮件提示

去商户平台配置即可。

3. 访问起始 index.php

首先访问 index.php 你可以看到界面

我们首先需要的是 JSAPI支付。但是看代码 index.php 最下面的链接。他默认是个demo的链接,改为我们自定义的即可

<ul>
  <li style="background-color:#FF7F24"><a href="<&#63;php echo 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'].'example/jsapi.php';&#63;>">JSAPI支付</a></li>
  <li style="background-color:#698B22"><a href="<&#63;php echo 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'].'example/micropay.php';&#63;>">刷卡支付</a></li>
  <li style="background-color:#8B6914"><a href="<&#63;php echo 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'].'example/native.php';&#63;>">扫码支付</a></li>
  <li style="background-color:#CDCD00"><a href="<&#63;php echo 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'].'example/orderquery.php';&#63;>">订单查询</a></li>
  <li style="background-color:#CD3278"><a href="<&#63;php echo 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'].'example/refund.php';&#63;>">订单退款</a></li>
  <li style="background-color:#848484"><a href="<&#63;php echo 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'].'example/refundquery.php';&#63;>">退款查询</a></li>
  <li style="background-color:#8EE5EE"><a href="<&#63;php echo 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'].'example/download.php';&#63;>">下载订单</a></li>
</ul>

当然你也可以直接写死为自己的访问链接。

4. JSAPI 支付

必要代码解析:

$logHandler= new CLogFileHandler("../logs/".date('Y-m-d').'.log');
$log = Log::Init($logHandler, 15);

调用日志类 可以通过 $log->DEBUG(‘test‘); 打印调试信息。其实也可以直接使用 $Log::DEBUG(‘test‘); 来调试

$tools = new JsApiPay();
$openId = $tools->GetOpenid();

主要是为了获取 openid 其中GetOpenid() 函数定义在 文件 WxPay.JsApiPay.php 文件中

public function GetOpenid()
 {
 //通过code获得openid
 if (!isset($_GET['code'])){
  //触发微信返回code码
  $baseUrl = urlencode('http://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'].$_SERVER['QUERY_STRING']);
  $url = $this->__CreateOauthUrlForCode($baseUrl);
  Header("Location: $url");
  exit();
 } else {
  //获取code码,以获取openid
   $code = $_GET['code'];
  $openid = $this->getOpenidFromMp($code);
  return $openid;
 }
 }

$baseUrl 其实就是为了在跳转回来这个页面。  可以继续跟踪函数__CreateOauthUrlForCode()  其实就是通过微信的Auth2.0 来获取Openid

参考链接:http://mp.weixin.qq.com/wiki/17/c0f37d5704f0b64713d5d2c37b468d75.html

这就需要你把微信的 网页授权接口也设置好。

获取到 Openid 就可以调用微信支付的统一下单接口了。回到 文件 jsapi.php 如下代码

$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);

这里面的代码:

$input->SetAttach("test");

如果 把值改为 $input->SetAttach("test this is attach");就会存在bug 后面再说,其实这个参数不是必须的干脆可以去掉。

代码:

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

是设置接收支付结果通知的Url 这里是默认的demo 链接我们可以设置成我们的:

$input->SetNotify_url(dirname('http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']).'/notify.php');

当然你也可以选择直接写死。
其中的函数 unifiedOrder($input) 可以到WxPay.Api.php 中文件跟踪,其实就是调用统一下单接口。

在 WxPay.Api.php 中需要更改的一处代码是:

//异步通知url未设置,则使用配置文件中的url
    if(!$inputObj->IsNotify_urlSet()){
      $inputObj->SetNotify_url(WxPayConfig::NOTIFY_URL);//异步通知url
    }

就是当没设置 notifyUrl 的时候回去配置文件中找,但是配置文件中根本没有设置。

所以你可以选择在 配置文件WxPay.Config.php 中加上这个配置,也可以直接写一个默认的notify链接。

函数 GetJsApiParameters() 是获取jsApi支付的参数给变量 $jsApiParameters 方便在下面的Js中调用

jsapi.php 中js的代码:

function jsApiCall()
 {
 WeixinJSBridge.invoke(
  'getBrandWCPayRequest',
  <&#63;php echo $jsApiParameters; &#63;>,
  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();
 }
 }

其中点击立即支付按钮调用的就是 callpay() 函数,他有会调用jsApiCall() 函数打开支付程序。
此后输入密码完成支付。

在完成支付页面点击完成会回到这个支付页面,并弹出 支付成功的提示框

这个其实就是 js函数 jsApiCall 里面的alter 弹出的对话框

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

但是这个并不可信。确认是否支付成功还是应当 通过notify.php 处理业务逻辑。

5. 支付结果通知 notify.php

其实这个页面最主要的代码就两行

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

其中大部分逻辑在 Handle 函数中处理 文件 WxPay.Notify.php

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);

跟踪函数 notify 文件WxPay.Api.php

public static function notify($callback, &$msg)
 {
 //获取通知的数据
 $xml = $GLOBALS['HTTP_RAW_POST_DATA'];
 //如果返回成功则验证签名
 try {
  $result = WxPayResults::Init($xml);
 } catch (WxPayException $e){
  $msg = $e->errorMessage();
  return false;
 }
 
 return call_user_func($callback, $result);
 }

通过 $GLOBALS[‘HTTP_RAW_POST_DATA‘]; 获取同志数据 然后 Init 函数验证签名等。验签成功运行代码

return call_user_func($callback, $result);

即调用了一个回调函数,NotifyCallBack() 函数并传递参数 $result 在NotifyCallBack函数中会调用我们重写的NotifyProcess()函数(此函数在notify.php 中被重写)

NotifyProcess() 判断也没有问题就会 设置返回 success的xml信息

$this->SetReturn_code("SUCCESS");
$this->SetReturn_msg("OK");

并最终调用函数 $this->ReplyNotify($needSign);  echo success的结果

函数ReplyNotify 需要修改一处代码:

final private function ReplyNotify($needSign = true)
 {
 //如果需要签名
 if($needSign == true && 
  $this->GetReturn_code($return_code) == "SUCCESS")
 {
  $this->SetSign();
 }
 WxpayApi::replyNotify($this->ToXml());
 }

$this->GetReturn_code($return_code) == "SUCCESS")

改为

$this->GetReturn_code() == "SUCCESS")

即可。

这样整个流程就结束了。上面提到了 传递订单参数

$input->SetAttach("test");

如果我设置 值为 test this is attach (其实只要有空格就会存在bug)
如图 传递的订单信息

可以看到 attach 信息正常,当然支付也是正常的没有任何问题。

但是发现总是会收到notify 通知,即意味着没有返回给微信服务器正确的结果通知。

打印服务器发来的通知数据

可以看到 attach 是 test+this+is+attach 即空格被转化为加号

打印接收到的签名和程序算出来的签名发现 签名不同,即认为接收结果异常。

所以我们要是想使用attach 这个值就不能有空格,要么干脆不使用这个参数

(等待微信修复这个bug, 也可能是我这边有哪个地方不会? - -#)

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

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
PHP的当前状态:查看网络开发趋势PHP的当前状态:查看网络开发趋势Apr 13, 2025 am 12:20 AM

PHP在现代Web开发中仍然重要,尤其在内容管理和电子商务平台。1)PHP拥有丰富的生态系统和强大框架支持,如Laravel和Symfony。2)性能优化可通过OPcache和Nginx实现。3)PHP8.0引入JIT编译器,提升性能。4)云原生应用通过Docker和Kubernetes部署,提高灵活性和可扩展性。

PHP与其他语言:比较PHP与其他语言:比较Apr 13, 2025 am 12:19 AM

PHP适合web开发,特别是在快速开发和处理动态内容方面表现出色,但不擅长数据科学和企业级应用。与Python相比,PHP在web开发中更具优势,但在数据科学领域不如Python;与Java相比,PHP在企业级应用中表现较差,但在web开发中更灵活;与JavaScript相比,PHP在后端开发中更简洁,但在前端开发中不如JavaScript。

PHP与Python:核心功能PHP与Python:核心功能Apr 13, 2025 am 12:16 AM

PHP和Python各有优势,适合不同场景。1.PHP适用于web开发,提供内置web服务器和丰富函数库。2.Python适合数据科学和机器学习,语法简洁且有强大标准库。选择时应根据项目需求决定。

PHP:网络开发的关键语言PHP:网络开发的关键语言Apr 13, 2025 am 12:08 AM

PHP是一种广泛应用于服务器端的脚本语言,特别适合web开发。1.PHP可以嵌入HTML,处理HTTP请求和响应,支持多种数据库。2.PHP用于生成动态网页内容,处理表单数据,访问数据库等,具有强大的社区支持和开源资源。3.PHP是解释型语言,执行过程包括词法分析、语法分析、编译和执行。4.PHP可以与MySQL结合用于用户注册系统等高级应用。5.调试PHP时,可使用error_reporting()和var_dump()等函数。6.优化PHP代码可通过缓存机制、优化数据库查询和使用内置函数。7

PHP:许多网站的基础PHP:许多网站的基础Apr 13, 2025 am 12:07 AM

PHP成为许多网站首选技术栈的原因包括其易用性、强大社区支持和广泛应用。1)易于学习和使用,适合初学者。2)拥有庞大的开发者社区,资源丰富。3)广泛应用于WordPress、Drupal等平台。4)与Web服务器紧密集成,简化开发部署。

超越炒作:评估当今PHP的角色超越炒作:评估当今PHP的角色Apr 12, 2025 am 12:17 AM

PHP在现代编程中仍然是一个强大且广泛使用的工具,尤其在web开发领域。1)PHP易用且与数据库集成无缝,是许多开发者的首选。2)它支持动态内容生成和面向对象编程,适合快速创建和维护网站。3)PHP的性能可以通过缓存和优化数据库查询来提升,其广泛的社区和丰富生态系统使其在当今技术栈中仍具重要地位。

PHP中的弱参考是什么?什么时候有用?PHP中的弱参考是什么?什么时候有用?Apr 12, 2025 am 12:13 AM

在PHP中,弱引用是通过WeakReference类实现的,不会阻止垃圾回收器回收对象。弱引用适用于缓存系统和事件监听器等场景,需注意其不能保证对象存活,且垃圾回收可能延迟。

解释PHP中的__ Invoke Magic方法。解释PHP中的__ Invoke Magic方法。Apr 12, 2025 am 12:07 AM

\_\_invoke方法允许对象像函数一样被调用。1.定义\_\_invoke方法使对象可被调用。2.使用$obj(...)语法时,PHP会执行\_\_invoke方法。3.适用于日志记录和计算器等场景,提高代码灵活性和可读性。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
3 周前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解锁Myrise中的所有内容
4 周前By尊渡假赌尊渡假赌尊渡假赌

热工具

Atom编辑器mac版下载

Atom编辑器mac版下载

最流行的的开源编辑器

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

功能强大的PHP集成开发环境

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

WebStorm Mac版

WebStorm Mac版

好用的JavaScript开发工具

VSCode Windows 64位 下载

VSCode Windows 64位 下载

微软推出的免费、功能强大的一款IDE编辑器