微信小程序 支付功能 服务器端(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[1]]></cash_fee>
<fee_type><![CDATA[CNY]]></fee_type>
<is_subscribe><![CDATA[N]]></is_subscribe>
<mch_id><![CDATA[1392378802]]></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[20170301030852]]></time_end>
<total_fee>1</total_fee>
<trade_type><![CDATA[JSAPI]]></trade_type>
<transaction_id><![CDATA[4004312001201703011727741547]]></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();
    }

原文地址:https://www.cnblogs.com/xiaoliwang/p/9381672.html

时间: 2024-08-29 17:55:12

微信小程序 支付功能 服务器端(TP5.1)实现的相关文章

微信小程序支付功能 C# .NET开发

微信小程序支付功能的开发的时候坑比较多,不过对于钱的事谨慎也是好事.网上关于小程序支付的实例很多,但是大多多少有些问题,C#开发的更少.此篇文档的目的是讲开发过程中遇到的问题做一个备注,也方便其他开发的同学作为参考! 1.首先建议把官方文档支付部分看上三遍,每个细节都不要放过,因为任何一个点和微信要求不符都会导致支付不成功.https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=3_1 2.经过验证的微信支付功能,会需要一些商

微信小程序 支付功能(前端)的实现

只提供微信小程序端代码: 1 var app = getApp(); 2 Page({ 3 data: {}, 4 onLoad: function (options) { 5 // 页面初始化 options为页面跳转所带来的参数 6 var that = this 7 //登陆获取code 8 wx.login({ 9 success: function (res) { 10 console.log(res.code) 11 //获取openid 12 that.getOpenId(res.

微信小程序支付

关于微信小程序支付功能,他的官方文档真的写的很清楚了!但是整理吸收一下还是不错的 官网呈上:https://developers.weixin.qq.com/miniprogram/dev/api/wx.requestPayment.html 核心流程:下面的图和交互流程描述写的真是不能再清晰了 商户系统和微信支付系统主要交互: 1.小程序内调用登录接口,获取到用户的openid,api参见公共api[小程序登录API] 2.商户server调用支付统一下单,api参见公共api[统一下单API

10行代码实现小程序支付功能!丨实战

前面给大家讲过一个借助小程序云开发实现微信支付的,但是那个操作稍微有点繁琐,并且还会经常出现问题,今天就给大家讲一个简单的,并且借助官方支付api实现小程序支付功能. 传送门: 借助小程序云开发实现小程序支付功能 老规矩,先看本节效果图 我们实现这个支付功能完全是借助小程序云开发实现的,不用搭建自己的服务器,不用买域名,不用备案域名,不用支持https.只需要一个简单的云函数,就可以轻松的实现微信小程序支付功能. 核心代码就下面这些: 一.创建一个云开发小程序 关于如何创建云开发小程序,这里我就

微信小程序 --- 完成小程序支付功能

最近开发小程序,一直在看小程序的支付.经过一天的努力,小程序支付功能最终实现了. 下面感谢 csdn 博主:千堆雪惹尘埃 发布的 " 小程序与php 实现微信支付 " 原文地址: http://blog.csdn.net/admin1008611/article/details/73240458 下面是我自己写的代码:使用的 thinkphp:其他的可以参考修改: 服务端: 获取用户的 openid: public function get_openid(){ $data = arra

PHP实现微信小程序支付

本文仅记录了微信小程序支付开发的基本流程和代码,具体业务需自行修改.tp5框架下演示: 参考: 微信小程序支付:业务流程 SDK与DEMO:  下载页 PHPPayDemo: demo 小程序端: goPay(e){ var that = this; //发起预支付,获取所需参数 wx.request({ url: app.globalData.host + '/api/wx_pay/createOrder', //请求地址 data: { openid: wx.getStorageSync('

微信小程序支付及退款流程详解

微信小程序的支付和退款流程 近期在做微信小程序时,涉及到了小程序的支付和退款流程,所以也大概的将这方面的东西看了一个遍,就在这篇博客里总结一下. 首先说明一下,微信小程序支付的主要逻辑集中在后端,前端只需携带支付所需的数据请求后端接口然后根据返回结果做相应成功失败处理即可.我在后端使用的是php,当然在这篇博客里我不打算贴一堆代码来说明支付的具体实现,而主要会侧重于整个支付的流程和一些细节方面的东西.所以使用其他后端语言的朋友有需要也是可以看一下的.很多时候开发的需求和相应问题的解决真的要跳出语

php对接微信小程序支付

前言:这里我就假装你已经注册了微信小程序,并且基本的配置都已经好了.注: 个人注册小程序不支持微信支付,所以我还是假装你是企业或者个体工商户的微信小程序,其他的商户号注册,二者绑定,授权,支付开通,就阅读文档吧,这里我先负责实战. 微信小程序支付开发文档: https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=7_3&index=1 基本流程: 1. 申请商户平台账号 https://pay.weixin.qq.com/in

asp写的微信小程序支付demo-服务器端是asp+mdb的

这个微信小程序支付demo代码是我用asp写的,微信小程序端加上服务器端用的asp和mdb数据库,下面是代码分享: <view class="container"> <view class='view'>订单说明:{{paydata.title}}</view> <view class='view inputview'> 支付金额:<input bindinput="bindKeyInput" type=&quo