微信小程序 支付功能 服务器端(TP5.1)实现
首先下载微信支付SDK ,将整个目录的文件放在 /application/extend/WxPay 目录下
在使用SDK之前我们需要对 WxPay.Config.php 进行配置

<?php namespace app\api\service; use app\api\model\Order as OrderModel;
use app\lib\exception\OrderException;
use app\lib\exception\TokenException;
use think\Exception;
use think\Loader;
use think\Log; require_once '/extend/WxPay/WxPay.Api.php'; class Pay
{
private $orderNo;
private $orderID; //实例化时传入订单ID 此ID由第三方服务器自己定义
function __construct($orderID)
{
if (!$orderID)
{
throw new Exception('订单号不允许为NULL');
}
$this->orderID = $orderID;
} public function pay()
{
// 根据订单ID 查到订单下对应商品
// 对商品库存检测等操作
// Todo ... return $this->makeWxPreOrder($status['orderPrice']);
} // 构建微信支付订单信息
private function makeWxPreOrder($totalPrice)
{
//获得当前用户 openid
$openid = Token::getCurrentTokenVar('openid');
if (!$openid)
{
throw new TokenException();
}
//创建订单信息
$wxOrderData = new \WxPayUnifiedOrder(); //需要引入微信提供的SDK
$wxOrderData->SetOut_trade_no($this->orderNo); //订单编号,第三方自定义
$wxOrderData->SetTrade_type('JSAPI'); //交易类型,一般是JSAPI
$wxOrderData->SetTotal_fee($totalPrice * 100); //设置总金额,单位为0.01元
$wxOrderData->SetBody('零食商贩'); //设置展示信息
$wxOrderData->SetOpenid($openid); //openid
$wxOrderData->SetNotify_url(config('wx.pay_back_url')); //回调地址 return $this->getPaySignature($wxOrderData);
} /**
* 向微信请求订单号并生成签名
*/
private function getPaySignature($wxOrderData)
{ $wxOrder = \WxPayApi::unifiedOrder($wxOrderData);
//返回结果中包含 prepay_id ,此ID作为用户拉起支付时凭证,
//同时此ID作为将来服务器向客户端推送消息的标识,因此需要保存在数据库订单表中
// 失败时不会返回result_code
if($wxOrder['return_code'] != 'SUCCESS' || $wxOrder['result_code'] !='SUCCESS'){
Log::record($wxOrder,'error');
Log::record('获取预支付订单失败','error');
}
//
$this->recordPreOrder($wxOrder);
$signature = $this->sign($wxOrder);
return $signature;
} private function recordPreOrder($wxOrder){
// 将 prepay_id 保存在数据库中
OrderModel::where('id', '=', $this->orderID)
->update(['prepay_id' => $wxOrder['prepay_id']]);
} /**
* 签名
* @return [array] [返回数组中要包含小程序发起支付请求的所有参数 包含:小程序ID、时间戳、随机串、数据包(prepay_id)、签名方式、签名 6个参数]
*
*/
private function sign($wxOrder)
{
//调用SDK 生成签名
$jsApiPayData = new \WxPayJsApiPay();
//Appid
$jsApiPayData->SetAppid(config('wx.app_id'));
//timeStamp
$jsApiPayData->SetTimeStamp((string)time());
//nonceStr
$rand = md5(time() . mt_rand(0, 1000));
$jsApiPayData->SetNonceStr($rand);
//package
$jsApiPayData->SetPackage('prepay_id=' . $wxOrder['prepay_id']);
//signType
$jsApiPayData->SetSignType('md5');
//生成签名
$sign = $jsApiPayData->MakeSign();
//获取数组
$rawValues = $jsApiPayData->GetValues();
$rawValues['paySign'] = $sign;
return $rawValues;
}
}
接着在控制器中调用该类下的 pay 方法 ,并创建回调函数
当用户支付完成后,微信服务器会以POST请求到指定回调地址,改地址微信服务器会默认屏蔽掉?后面字符串部分,数据通过XML形式放在body中,格式:
<xml><appid><![CDATA[wxaaf1c852597e365b]]></appid>
<bank_type><![CDATA[CFT]]></bank_type>
<cash_fee><![CDATA[]]></cash_fee>
<fee_type><![CDATA[CNY]]></fee_type>
<is_subscribe><![CDATA[N]]></is_subscribe>
<mch_id><![CDATA[]]></mch_id>
<nonce_str><![CDATA[k66j676kzd3tqq2sr3023ogeqrg4np9z]]></nonce_str>
<openid><![CDATA[ojID50G-cjUsFMJ0PjgDXt9iqoOo]]></openid>
<out_trade_no><![CDATA[A301089188132321]]></out_trade_no> //这个是我们服务器向微信服务器发送的订单号,该订单号由我们自己生成,根据该订单号可以做相应的业务
<result_code><![CDATA[SUCCESS]]></result_code> //支付结果
<return_code><![CDATA[SUCCESS]]></return_code>
<sign><![CDATA[944E2F9AF80204201177B91CEADD5AEC]]></sign>
<time_end><![CDATA[]]></time_end>
<total_fee>1</total_fee>
<trade_type><![CDATA[JSAPI]]></trade_type>
<transaction_id><![CDATA[]]></transaction_id>
</xml>
- 第一种方法我们可以自己解析这个XML 然后获得需要的数据
- 第二种方法我们可以通过重写微信SDK中 WxPay.Notify.php 中 NotifyProcess 方法来处理这个数据

该方法两个参数,第一个参数就是服务器返回的XML数组化后的值()
我们可以重写该类
require_once '/application/extend/WxPay/WxPay.Notify.php';
class WxNotify extends \WxPayNotify
{ public function NotifyProcess($data, &$msg)
{
if ($data['result_code'] == 'SUCCESS') {
$orderNo = $data['out_trade_no'];
//开启事务,避免因服务器阻塞,微信多个请求同时到达,出现重复执行业务代码
Db::startTrans();
try {
$order = Order::where('order_no', '=', $orderNo)->lock(true)->find();
//如果订单处于未支付状态下才执行里面的业务代码
if ($order->status == 1) {
//查库存
//改支付状态
//减库存
}
Db::commit();
} catch (Exception $ex) {
Db::rollback();
Log::error($ex);
// 如果出现异常,向微信返回false,请求重新发送通知
return false;
}
}
//如果处理成功,需要向微信服务器发送 TRUE, 告诉微信停止请求回调地址
return true;
}
}
在控制器的回调函数中调用该子类
注意:不能直接调用 NotifyProcess 方法,因为我们无法传递该方法的参数,该参数是由父类中方法生成,需要调用父类中 handle 方法来执行 NotifyProcess 中代码
public function receiveNotify()
{
$notify = new WxNotify();
$notify->handle();
}
微信小程序 支付功能 服务器端(TP5.1)实现的更多相关文章
- 微信小程序支付功能 C# .NET开发
微信小程序支付功能的开发的时候坑比较多,不过对于钱的事谨慎也是好事.网上关于小程序支付的实例很多,但是大多多少有些问题,C#开发的更少.此篇文档的目的是讲开发过程中遇到的问题做一个备注,也方便其他开发 ...
- 微信小程序支付功能前端流程
只是分享一下小程序支付功能的前端流程和代码, 仅供参考(使用的是uni app). handleCreate () { /** 第一步:前台将商品数据发送到后台,后台创建订单入库并返回订单id等信息 ...
- 微信小程序支付功能讲解(1)
前言:虽然小程序做过很多,但是一直觉得微信支付功能很是神秘,现在终于有机会接触心里还是有点小激动的,经过一番折腾发现支付也不过如此,在此记录下支付功能的实现过程 小程序的官方文档介绍到发起微信支付即调 ...
- 微信小程序支付功能讲解(2)
小程序支付 业务流程时序图 官方文档 步骤: 1. Openid 在小程序初次加载的时候就已经获取(详情见 小程序登录) 2. 生成商户订单 1.商品信息由小程序端提供 2.提供支付统一下单接口所需参 ...
- 微信小程序支付功能讲解
前言:虽然小程序做过很多,但是一直觉得微信支付功能很是神秘,现在终于有机会接触心里还是有点小激动的,经过一番折腾发现支付也不过如此,在此记录下支付功能的实现过程 小程序的官方文档介绍到发起微信支付即调 ...
- 微信小程序 支付功能(前端)的实现
只提供微信小程序端代码: var app = getApp(); Page({ data: {}, onLoad: function (options) { // 页面初始化 options为页面跳转 ...
- Python实现微信小程序支付功能
由于最近自己在做小程序的支付,就在这里简单介绍一下讲一下用python做小程序支付这个流程.当然在进行开发之前还是建议读一下具体的流程,清楚支付的过程. 1.支付交互流程 当然具体的参数配置可以参考官 ...
- 微信小程序支付功能完整流程
支付流程 整个支付流程分为四个步骤: 获取令牌token 创建订单 预支付,获取支付参数对象pay 发起微信支付 收尾工作.跳转到订单页面,删除购物车中已购买的商品 请求方式:POST 整个支付过程中 ...
- 微信小程序支付功能
API:wx.requestPayment() { } https://blog.csdn.net/qishubiao/article/details/80804052
随机推荐
- Python基础10_函数
直接贴笔记 : #!/usr/bin/env python # coding:utf-8 # 定义函数时要写成良好的注释习惯 通常用三个单引号 def test(x): ''' 计算一个y=2*x+1 ...
- C#获取文件类型
Form1.cs using System;using System.Collections.Generic;using System.ComponentModel;using System.Data ...
- Shiro 整合SpringMVC 并实现权限管理,登录和注销
Shiro 整合SpringMVC 并且实现权限管理,登录和注销 Apache Shiro是Java的一个安全框架.目前,使用Apache Shiro的人越来越多,因为它相当简单,对比Spring S ...
- 深入理解Java中停止线程
一.停止线程会带来什么? 对于单线程中,停止单线程就是直接使用关键字return或者break,但是在停止多线程时是让线程在完成任务前去开启另外一条线程,必须放弃当前任务,而这个过程是不可预测,所以必 ...
- 超级简单的数据压缩算法—LZW算法
1. 前文回顾 在字符串算法—数据压缩中,我们介绍了哈夫曼压缩算法(Huffman compression),本文将介绍LZW算法. 2. LZW算法 这个算法很简单,为了方便讲述,我们将采用16进制 ...
- PythonStudy——内存管理之垃圾回收 Memory management Garbage collection
内存管理 引用计数:垃圾回收机制的依据 # 1.变量的值被引用,该值的引用计数 +1# 2.变量的值被解绑,该值的引用计数 -1# 3.引用计数为0时就会被垃圾回收机制回收 标记清除:解决循环引用问题 ...
- memcached-redis
http://www.runoob.com/memcached/memcached-cas.html https://github.com/memcached/memcached/blob/maste ...
- 1.2.3 Excel中姓名处理,将名加密星号
在对应的单元格中我们输入公式: =IF(LEN(A22)>2,REPLACE(A22,2,LEN(A22)-1,"**"),REPLACE(A22,2,LEN(A22)-1, ...
- Hanlp自然语言处理中的词典格式说明
使用过hanlp的都知道hanlp中有许多词典,它们的格式都是非常相似的,形式都是文本文档,随时可以修改.本篇文章详细介绍了hanlp中的词典格式,以满足用户自定义的需要. 基本格式 词典分为词频词性 ...
- Excel技巧--实现交叉查询
如上图,要实现某个地区和某个产品的销售额查询显示.可以使用Match和Index函数的使用来实现: 1.产品名称和城市栏,制作成列表可选:使用“数据”-->“数据验证”的方法. 2.先在旁边空位 ...