文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

tp6微信支付apiv3

2023-09-03 21:20

关注

公司要整一个扫码支付然后有个后台能查看交易记录,然后百度搜寻,决定使用laytp2.0框架搭后台。

  参考了以下文档:

https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_1_1.shtml

​​​​​​https://github.com/wechatpay-apiv3/wechatpay-php

https://www.laytp.com/doc/laytp/1.html

配置啥的不阐述了,代码大致流程:获取code,code获取openid,jsapi下单获取prepay_id,然后配置支付参数组装验签,调用微信支付,支付成功后回调,成功跳转页面。

前端代码:

form.on('submit(pay)', function (data) {    var buttonAnim = layui.button.load({elem: '.pay'});    //判断有没有code    var code = GetQueryString('code');    //有code    if (code !== undefined && code !== '' && code !== null) {        var openid = GetQueryString('openid');        data.field.openid = openid;        $.ajax({            url: '/payment.wechat/jsApiPay',            type: 'post',            dataType: 'json',            contentType: "application/json",            data: JSON.stringify(data.field),            success: function (inf) {                if (inf.code === 0) {                    let order = inf.data                    $.get('/payment.wechat/payConfig',                    {prepay_id: inf.data.prepay_id},                    function (sign) {                        WeixinJSBridge.invoke('getBrandWCPayRequest', sign,                         function(res){if (res.err_msg == "get_brand_wcpay_request:ok") {    window.location.href='xxxxxxxx/wechatSuccess.html?amount='+order.amount+'&out_trade_no='+order.order_sn+'&success_time='+order.create_time;} else if (res.err_msg == 'get_brand_wcpay_request:cancel') {    alert('支付已取消');} else {    alert(JSON.stringify(res));}                        });                    })                } else {                    console.log(res.code)                    console.log(res.msg)                }            }          })    } else {        //没有code        //微信获取code        $.ajax({            url: '/payment.wechat/getCode',            type: 'get',            dataType: 'json',            contentType: "application/json",            crossDomain: true,            success: function (res) {                console.log(res)            }        });    }    buttonAnim.stop();    return false;});//截取当前路径的参数function GetQueryString(name) {    var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");    var r = window.location.search.substr(1).match(reg);    if (r != null) {        //解决中文乱码        return decodeURI(r[2]);    }    return null;}

后端代码:

//获取codepublic function getCode(){    $url = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid=' . $this->appid.'&redirect_uri='.urlencode('xxxxxx/payment.wechat/index').'&response_type=code&scope=snsapi_base&state=syno' . time() . '#wechat_redirect';    return redirect($url);}//获取openidpublic function index(){    //判断有没有code    $code = $this->request->param('code');    if (isset($code) && $code !== '') {        $wechatConfig = Config::get('wechat');        $url = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid=' . $this->appid . '&secret=' . $this->secret. '&code=' . $code . '&grant_type=authorization_code';        $res = curl($url); //正常返回 access_token、openid等参数        if (isset($res['openid'])) {            return redirect('/payment/wechat/?openid=' . $res['openid'] . '&code=' . $code);        } else {            return redirect('/payment/wechat/');        }    } else {        return redirect('/payment/wechat/');    }}//构造 APIv3 客户端实例public function APIv3(){    $merchantId = $this->mchid; // 商户号    // 从本地文件中加载「商户API私钥」,「商户API私钥」会用来生成请求的签名    $merchantPrivateKeyFilePath = $this->keyCert;    $merchantPrivateKeyInstance = Rsa::from($merchantPrivateKeyFilePath, Rsa::KEY_TYPE_PRIVATE);    // 「商户API证书」的「证书序列号」    $merchantCertificateSerial = $this->serialNo;    // 从本地文件中加载「微信支付平台证书」,用来验证微信支付应答的签名    $platformCertificateFilePath = $this->wechatpayCert;    $platformPublicKeyInstance = Rsa::from($platformCertificateFilePath, Rsa::KEY_TYPE_PUBLIC);    // 从「微信支付平台证书」中获取「证书序列号」    $platformCertificateSerial = PemUtil::parseCertificateSerialNo($platformCertificateFilePath);    // 构造一个 APIv3 客户端实例    $instance = Builder::factory([        'mchid' => $merchantId,        'serial' => $merchantCertificateSerial,        'privateKey' => $merchantPrivateKeyInstance,        'certs' => [$platformCertificateSerial => $platformPublicKeyInstance],    ]);    return $instance;}//JSAPI下单获取prepay_idpublic function jsApiPay(){    Db::startTrans();    try {        $parameter = request()->post();        //下单        $order = new Order();        $orderSn = "订单号";        $data = [            'appid' => $this->appid, //公众号的服务号APPID            'mchid' => $this->mchid, //商户号            'description' => $parameter['product_name'], //商品描述            'out_trade_no' => $orderSn, //商户订单号            'attach' => 'ceshi_'.time(), //附加数据,在查询API和支付通知中原样返回            'notify_url' => 'xxxxx/payment.wechat/notifyUrl', //异步接收微信支付结果通知的回调地址            'amount' => ['total' => $parameter['amount'] * 100], //订单总金额,单位为分            'payer' => ['openid' => $parameter['openid']]  //用户标识,用户在直连商户appid下的唯一标识        ];        $instance = $this->APIv3();        $resp = $instance->chain('v3/pay/transactions/jsapi')->post(['json' => $data]);             $prepay_id = json_decode($resp->getBody(), true)['prepay_id'];         if (isset($prepay_id)) {            $arr = [];            $arr['prepay_id'] = $prepay_id;            $arr['order_sn'] = $orderSn;            $arr['amount'] = $parameter['amount'];            $orderInfo = $order->where('order_sn',$orderSn)->find();            $arr['create_time'] = $orderInfo['create_time'];            Db::commit();            return $this->success('成功获取prepay_id', $arr);        } else {              throw new \Exception('获取prepay_id失败');        }    } catch (\Exception $e) {        Db::rollback();        // 进行错误处理    }//获取支付参数public function payConfig(){    $config = $this->sign(request()->get('prepay_id'));    return json($config);}//签名public function sign($prepay_id){    $merchantPrivateKeyFilePath = $this->keyCert;    $merchantPrivateKeyInstance = Rsa::from($merchantPrivateKeyFilePath);    $params = [        'appId' => $this->appid,        'timeStamp' => (string)Formatter::timestamp(),        'nonceStr' => Formatter::nonce(),        'package' => 'prepay_id=' . $prepay_id,    ];    $params += ['paySign' => Rsa::sign(        Formatter::joinedByLineFeed(...array_values($params)),        $merchantPrivateKeyInstance    ), 'signType' => 'RSA'];    return $params;}//支付成功回调处理public function notifyUrl(){    $inBody = file_get_contents('php://input');// 请根据实际情况获取,例如: file_get_contents('php://input');    $apiv3Key = 'xxxxxx';// 在商户平台上设置的APIv3密钥    // 转换通知的JSON文本消息为PHP Array数组    $inBodyArray = (array)json_decode($inBody, true);    // 加密文本消息解密    $inBodyResource = AesGcm::decrypt($inBodyArray['resource']['ciphertext'], $apiv3Key, $inBodyArray['resource']['nonce'], $inBodyArray['resource']['associated_data']);    // 把解密后的文本转换为PHP Array数组    $inBodyResourceArray = (array)json_decode($inBodyResource, true);    if ($inBodyResourceArray['trade_state'] == 'SUCCESS') {        Db::startTrans();        try {            //操作付款状态            $order = new Order();            $order->update(['pay_status' => 1, 'pay_time' => date('Y-m-d H:i:s')], ['order_sn' => $inBodyResourceArray['out_trade_no']]);            //交易明细记录            $tradeRecord = new TradeRecord();            $tradeRecord->insertGetId([                'order_sn' => $inBodyResourceArray['out_trade_no'],                 'trade_no' => $inBodyResourceArray['transaction_id'],                 'total_amount' => $inBodyResourceArray['amount']['total'] / 100,                 'type' => 1, //0支出 1收入                 'pay_type' => 1, //0支付宝 1微信                 'content' => $inBodyResource,                 'trade_state' => $inBodyResourceArray['trade_state'],                 'create_time' => date('Y-m-d H:i:s')             ]);             $wechatTrade = new WechatTrade();             $wechatTrade->insertGetId([                 'order_sn' => $inBodyResourceArray['out_trade_no'],                 'transaction_id' => $inBodyResourceArray['transaction_id'],                 'trade_state' => $inBodyResourceArray['trade_state'],                 'openid' => $inBodyResourceArray['payer']['openid'],                 'trade_type' => $inBodyResourceArray['trade_type'],                 'total_amount' => $inBodyResourceArray['amount']['total'] / 100,                 'create_time' => date('Y-m-d H:i:s')             ]);             Db::commit();             //返回成功             echo ' ';            } catch (\Exception $e) {                Db::rollback();                // 进行错误处理                echo $e->getMessage(), PHP_EOL;            }        }    }

来源地址:https://blog.csdn.net/delzzz/article/details/128672843

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯