玩转微信2次开发2_微信支付开发_发送请求(微擎版)

微信支付原理

目前只讲解关于H5页面支付相关

支付流程

我们的订单系统-->收到了订单-->会把订单相关信息发送给微信订单服务器


微信订单服务器收到我们的请求--开始下订单此过程叫做订单预处理--预处理完毕会返回1个预处理ID表示微信这边已经处理完毕


我们可以用这个预处理ID和公众号应用密匙用微信支付js sdk启动微信支付


1:微擎的site基类封装了pay方法,该方法用于向微擎支付中心传递参数 并且打开微擎的支付中心

      简要介绍下该方法所执行的业务,因为目前只针对微信支付,卡卷部分不涉及

      支付中心需要接受以下参数

      商品名称 :title

      模块订单系统的商品订单:ordersn

     商品金额:fee

      优惠:key-value形式

      封装其他参数:模块名字  公众号ID

      如果支付金额《=0 直接调用site对象的payResult模拟支付成功 

                                     该模拟是模拟前端支付成功回调 需用用from==return判断

      微擎自己维护了核心支付表,请查看core_paylog

       该表使用tid(模块的订单主键)和uniacid(公众号)来关联具体模块的订单系统

       查询当前公众号的这个订单是否被支付过 支付过提示 禁止重复支付

                       该业务只用了Message提示错误,但是代码还会向下执行 没有使用exit终止 此处作为BUG

       查询是否配置了支付参数 即公众号的setting信息 没有配置提示出错

                        同样没有执行exit语句 此处为BUG

      最终导航到支付中心:common/paycenter

2:在支付中心我们目前只关注微信支付

    微信支付表单被提交到了app\source\mc\cash.ctrl.php


   该PHP的作用:用于把支付信息存入微擎支付历史记录表

    大概介绍下业务:这个表的作用非常大 可以体验到微擎的设计前端回调

   封装core_paylog的所有字段信息 插入记录表 设置订单状态为0 未支付

  构建支付参数信息 该参数是真正准备传递给微信订单服务器的

     

$ps['tid'] = $log['plid'];//获取支付记录表主键 传递给微信的订单,对应统一支付 api的商户订单号
$ps['user'] = $_W['fans']['from_user'];//支付人
$ps['fee'] = $log['card_fee'];//支付金额,对应统一支付API的total_fee/100
$ps['title'] = $params['title'];//对应统一支付API的body即商品描述
封装加密数据
请求:/payment/wechat/pay.php
3:pay.php的核心业务
首先验证加密是否匹配 匹配继续向下执行 同样进行了1次重复的系统核心订单表的支付结果检测,重复了!
开始构建参数和微信订单服务器通信
4:通信函数wechat_build($params, $wechat)
$params->即第2步封装的参数信息
$wechar-->支付配置信息 里面配置支付相关信息比如 
partnerId:商户号 注册时分配的财付通号
构建通信数据
$package = array();
$package['appid'] = $wechat['appid'];
$package['mch_id'] = $wechat['mchid'];//微信支付分配的商户号
$package['nonce_str'] = random(8);//随机字符串,不长于32位。推荐随机数生成算法
$package['body'] = $params['title'];//商品或支付单简要描述
$package['attach'] = $_W['uniacid'];//该字段主要用于商户携带订单的自定义数据
$package['out_trade_no'] = $params['tid'];//商户订单号
$package['total_fee'] = $params['fee'] * 100;//订单总金额,单位为分,
$package['spbill_create_ip'] = CLIENT_IP;//终端IP
$package['time_start'] = date('YmdHis', TIMESTAMP);//交易起始时间
$package['time_expire'] = date('YmdHis', TIMESTAMP + 600);//交易结束时间
$package['notify_url'] = $_W['siteroot'] . 'payment/wechat/notify.php';//通知回调url
$package['trade_type'] = 'JSAPI';
$package['openid'] = $_W['fans']['from_user'];//trade_type=JSAPI,此参数必传,用户在商户appid下的唯一标
按照密钥算法加密请求数据
即吧所有的请求参数按照URL_QUERY格式封装 比如a=1&b=2
然后再用结果 拼接字符串key=你的微信支付密钥
结果用md5加密
结果作为sing的value
$package['sign'] = strtoupper(md5($string1))
最终生成XML文件:$dat = array2xml($package);
和微信订单系统交互
$response = ihttp_request('https://api.mch.weixin.qq.com/pay/unifiedorder', $dat);
交互成功会返回预处理ID即
$prepayid = $xml->prepay_id;
使用预处理ID准备启用JS支付SDK
继续填充其他参数
以下参数用于启动JSSDK
$wOpt['appId'] = $wechat['appid'];
$wOpt['timeStamp'] = TIMESTAMP;
$wOpt['nonceStr'] = random(8);
$wOpt['package'] = 'prepay_id='.$prepayid;
$wOpt['signType'] = 'MD5';
ksort($wOpt, SORT_STRING);
foreach($wOpt as $key => $v) {
$string .= "{$key}={$v}&";
}
$string .= "key={$wechat['signkey']}";
$wOpt['paySign'] = strtoupper(md5($string));

5:微擎预留了前端通知接口

<script type="text/javascript">
document.addEventListener('WeixinJSBridgeReady', function onBridgeReady() {
WeixinJSBridge.invoke('getBrandWCPayRequest', {
'appId' : '<?php echo $wOpt['appId'];?>',
'timeStamp': '<?php echo $wOpt['timeStamp'];?>',
'nonceStr' : '<?php echo $wOpt['nonceStr'];?>',
'package' : '<?php echo $wOpt['package'];?>',
'signType' : '<?php echo $wOpt['signType'];?>',
'paySign' : '<?php echo $wOpt['paySign'];?>'
}, function(res) {
if(res.err_msg == 'get_brand_wcpay_request:ok') {
location.search += '&done=1';//支付成功以后再次会访问pay.php执行done=1代码块
} else {
//alert('启动微信支付失败, 请检查你的支付参数. 详细错误为: ' + res.err_msg);
history.go(-1);
}
});
}, false);
</script>
该JS是用户在支付成功以后点击手机界面右上角完成按钮会触发get_brand_wcpay_request:ok
看下该钩子的写法
$site = WeUtility::createModuleSite($log['module']);
if(!is_error($site)) {
$method = 'payResult';
if (method_exists($site, $method)) {
$ret = array();
$ret['weid'] = $log['uniacid'];//该钩子获取的信息都是从支付记录中查询到了  不得不说微擎的思路很赞
$ret['uniacid'] = $log['uniacid'];
$ret['result'] = $log['status'] == '1' ? 'success' : 'failed';//该字段会在微信支付成功后触发回调URL更新
$ret['type'] = $log['type'];
$ret['from'] = 'return';//用于识别是JS返回还是微信URL通知,所以我们可以同该参数的from属性识别是否支付成功,该方式不安全,如果用户支付完毕不点击完成直接关闭页面 是接受不到该参数的 即from一直为空 导致系统认定你以为没有支付
$ret['tid'] = $log['tid'];
$ret['user'] = $log['openid'];
$ret['fee'] = $log['fee'];
$ret['tag'] = $tag;
$ret['is_usecard'] = $log['is_usecard'];
$ret['card_type'] = $log['card_type'];
$ret['card_fee'] = $log['card_fee'];
$ret['card_id'] = $log['card_id'];
exit($site->$method($ret));
}



转载于:https://my.oschina.net/u/2508417/blog/532746

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值