基于thinkphp5.0和支付宝面对面扫码支付DEMO制作的扫码支付

简介: 基于thinkphp5.0和支付宝面对面扫码支付DEMO制作的扫码支付

基于thinkphp5.0和支付宝面对面扫码支付DEMO制作的扫码支付

今天接口申请下来,下载了官方demo对着调试了一天,终于实现想要的功能,先看图

20210527153548522.png

选择支付宝支付

01ebd755782e4c909dad0843d3544acf.jpeg

跳出二维码弹窗

01ebd755782e4c909dad0843d3544acf.jpeg

手机支付宝进行扫码支付

20210527153548522.png

支付完成,点击支付完成按钮跳转到订单列表

实现步骤:


1 支付宝接口申请,这个自行申请哦

2 下载官方扫码支付DEMO aopsdkdownload.cn-hangzhou.alipay-pub.aliyun-inc.com/demo/F2FPay…

将其中的f2fpay,aop两个文件夹复制到extend/alipay目录下.

其中的AlipayTradeService.php 我有稍作修改,到时在附件传上来.

3 点击页面的支付按钮后,异步请求二维码

//发起支付宝支付
    public function alipay()
    {
        if (!request()->isAjax()) {
            $this->error('该操作仅支持异步操作');
        }
        $productId = input('productId',0);
        $product = model('Product')->where('id',$productId)->find();
        if (empty($product)) {
            $this->error('产品不存在');
        }
        if ($product['status'] != 1) {
            $this->error('产品已下架');
        }
        $outTradeNo = out_trade_no();
        $data = [
            'notify_url' => url('api/Notify/alipay','',false,true), //回调链接
            'return_url' => '',
            'out_trade_no' => $outTradeNo, //订单号
            'subject' => '爱站SEO '.$product['title'], //产品标题
            'total_fee' => $product['cash'],//订单金额,单位为元
            'body' => $product['remark'], //产品描述
        ];
        $alipay = new Alipay;
        $result = $alipay->qrpay($data);
        if(!$result['code']){
            return $this->error($result['msg']);
        }
        //录入订单数据
        $orderData = [
            'order_num' => $data['out_trade_no'],
            // 'prepay_id' => $prepayId,
            'product_id' => $productId,
            'uid' => session('uid'),
            'count' => 1,
            'pay_fee' => $data['total_fee'] * 100,
            'create_time' => time(),
            'paied_time' => 0,
            'status' => 1,
        ];
        $res = db('Order')->insert($orderData);
        if (!$res) {
            $this->error('订单未成功生成');
        }
        //二维码生成
        $qrcodeImg = make_qrcode($result['msg'],$data['out_trade_no']);
        return [
            'code' => 1,
            'msg' => '请用支付宝支付',
            'qrcodeImg' => $qrcodeImg, //二维码图片地址
            'productInfo' => $product //产品信息
        ];
    }

先检查产品是否可用销售,然后生成订单号,调用Alipay支付请求,订单录入后,生成二维码图片,传给前端.

Alipay.php 我是放在common/pay/目录下的

<?php
namespace app\common\pay;
use think\Validate;
use think\Log;
/**
* 支付宝扫码支付
*/
class Alipay
{
    public function qrpay($data = [])
    {
        $validate = new Validate([
            ['out_trade_no','require|alphaNum','订单编号输入错误|订单编号输入错误'],
            ['total_fee','require|number|gt:0','金额输入错误|金额输入错误|金额输入错误'],
            ['subject','require','请输入标题'],
            ['body','require','请输入描述'],
            ['notify_url','require','异步通知地址不为空'],
        ]);
        if (!$validate->check($data)) {
            return ['code'=>0,'msg'=>$validate->getError()];
        }
        // 支付超时,线下扫码交易定义为5分钟
        $timeExpress = "5m";
        import('alipay.f2fpay.model.builder.AlipayTradePrecreateContentBuilder', EXTEND_PATH);
        import('alipay.f2fpay.service.AlipayTradeService', EXTEND_PATH);
        // 创建请求builder,设置请求参数
        $qrPayRequestBuilder = new \AlipayTradePrecreateContentBuilder();
        $qrPayRequestBuilder->setOutTradeNo($data['out_trade_no']);
        $qrPayRequestBuilder->setTotalAmount($data['total_fee']);
        $qrPayRequestBuilder->setTimeExpress($timeExpress);
        $qrPayRequestBuilder->setSubject($data['subject']);
        $qrPayRequestBuilder->setBody($data['body']);
        // 调用qrPay方法获取当面付应答
        $config = config('alipay');
        if (!empty($data['notify_url'])) {
            $config['notify_url'] = $data['notify_url'];
        }
        $qrPay = new \AlipayTradeService($config);
        $qrPayResult = $qrPay->qrPay($qrPayRequestBuilder);
        //  根据状态值进行业务处理
        switch ($qrPayResult->getTradeStatus()){
            case "SUCCESS":
                // echo "支付宝创建订单二维码成功:"."<br>---------------------------------------<br>";
                $response = $qrPayResult->getResponse();
                return ['code'=>1,'msg'=>$response->qr_code];
                break;
            case "FAILED":
                // echo "支付宝创建订单二维码失败!!!"."<br>--------------------------<br>";
                return ['code'=>0,'msg'=>'支付宝创建订单二维码失败!!!'];
                break;
            case "UNKNOWN":
                // echo "系统异常,状态未知!!!"."<br>--------------------------<br>";
                return ['code'=>0,'msg'=>'系统异常,状态未知!!!'];
                break;
            default:
                return ['code'=>0,'msg'=>'不支持的返回状态,创建订单二维码返回异常!!!'];
                break;
        }
        return ;
    }
    public function notify_alipay()
    {
        import('alipay.aop.AopClient');
        $config = config('alipay');
        $out_trade_no = input('post.out_trade_no');
        $transaction_id = input('post.trade_no');
        $aop = new \AopClient;
        $aop->appId = $config['app_id'];
        $aop->rsaPrivateKey = $config['merchant_private_key'];
        $aop->alipayrsaPublicKey = $config['alipay_public_key'];
        $aop->signType = $config['sign_type'];
        $result = $aop->rsaCheckV1($_POST,'',$config['sign_type']);
        if ($result) {
            if(input('trade_status') == 'TRADE_FINISHED' || input('trade_status') == 'TRADE_SUCCESS') {
                // 处理支付成功后的逻辑业务
                $order = db('Order')->where(['order_num'=>$out_trade_no])->find();
                if (!$order) {
                    Log::write('order not exists');
                    return 'order not exists';
                }
                //订单状态错误 1 未付款 其他状态均为已处理的状态
                if ($order['status'] != 1) {
                    Log::write('order is completed:'.$order['status']);
                    return true;
                }
                if ($order['pay_fee'] != input('post.total_amount') * 100) {
                    Log::write('total_amount is error:'.$order['pay_fee'].','.input('post.total_amount'));
                    return 'total_amount is error';
                }
                $order['transaction_id'] = $transaction_id;
                $order['paied_time'] = time();
                $order['status'] = 2;
                db('Order')->update($order);
                //支付成功的逻辑
                return 'success';
            }
            Log::write('trade_status is error:'.input('trade_status'));
            return 'fail';
        }
        Log::write('sign verify is error:'.var_export($_POST));
        return 'fail';
    }
}

主要有qrpay二维码扫描支付的请求,notify_alipay接收异步通知的处理逻辑

这里用到的接口配置,我是放在/application/extra/alipay.php 下面

<?php
return [
        //签名方式,默认为RSA2(RSA2048)
        'sign_type' => "RSA2",
        //支付宝公钥
        'alipay_public_key' => "",
        //商户私钥
        'merchant_private_key' => "",
        //编码格式
        'charset' => "UTF-8",
        //支付宝网关
        'gatewayUrl' => "https://openapi.alipay.com/gateway.do",
        //应用ID
        'app_id' => "",
        //异步通知地址,只有扫码支付预下单可用
        'notify_url' => "http://www.baidu.com",
        //最大查询重试次数
        'MaxQueryRetry' => "10",
        //查询间隔
        'QueryDuration' => "3",
        //日志文件
        'log_file' => RUNTIME_PATH.'/log/'.date('Ym').'/'.date('d').'.log',
];

填写公钥,私钥,异步通知地址,我自己添加了一个日志文件,为了结合请求的日志记录write_log使用.

alipay.rar


目录
相关文章
|
存储 安全 API
阿里云oss存储简介和如何使用
阿里云OSS存储服务是一种安全、稳定、高效的云存储服务,适用于各种规模的应用和业务场景。它具备出色的持久性和可用性,可以为用户提供高可靠、低成本的存储解决方案。阿里云OSS存储具有广泛的应用场景
4869 0
|
2月前
|
弹性计算 Linux 网络安全
零基础也会!阿里云轻量应用服务器使用教程2026年最新,200M带宽收费价格表
阿里云轻量应用服务器是面向新手、个人开发者及中小企业的高性价比云服务,2核2G+200M带宽低至38元/年,支持WordPress、宝塔等一键应用镜像,集成防火墙、快照、HTTPS等功能,操作简单,适合建站、博客、测试等轻负载场景。
380 1
|
11月前
|
人工智能 安全 语音技术
幼师必备AI教学神器:AI大模型赋能幼儿园课堂
输入幼儿年龄、性别、个案情况概述等关键内容,一键快速生成五大领域评价、幼儿发展评价、幼儿区域活动评价、幼儿游戏评价等评价内容,助力教师高效科学开展幼儿评价工作。
|
11月前
|
人工智能 安全 API
身份验证API的实战指南(Python & PHP 示例)
本文介绍了基于身份证信息的实名认证API,适用于金融、电商、政务、医疗等领域的身份核验场景。内容包含Python与PHP调用示例及返回结果解析,助力开发者快速集成安全合规的身份验证功能。
739 0
|
11月前
|
JSON 供应链 API
1688 买家订单,订单物流,订单回传接口系列(1688 寻源通 API)
1688寻源通API为开发者提供买家订单、订单物流及订单回传三大接口,助力企业实现订单管理、物流跟踪与信息反馈的自动化。买家订单接口可查询订单详情;订单物流接口支持实时跟踪物流状态;订单回传接口确保企业系统与平台数据同步。结合Python示例代码,企业可轻松集成这些功能,优化内部管理、提升客户体验并支持数据驱动决策。适用于电商订单管理、物流服务和数据分析等场景。
|
机器学习/深度学习 移动开发 测试技术
《手把手教你》系列技巧篇(五十一)-java+ selenium自动化测试-字符串操作-下篇(详解教程)
【5月更文挑战第15天】自动化测试中进行断言的时候,我们可能经常遇到的场景。从一个字符串中找出一组数字或者其中的某些关键字,而不是将这一串字符串作为结果进行断言。这个时候就需要我们对字符串进行操作,宏哥这里介绍两种方法:正则和字符串切片函数split()。
223 2
|
机器学习/深度学习 人工智能 自然语言处理
NeurIPS 2024:真实世界复杂任务,全新基准GTA助力大模型工具调用能力评测
在NeurIPS 2024会议上,GTA(General Tool Agents Benchmark)基准测试被提出,旨在评估大型语言模型(LLM)在真实世界复杂任务中的工具调用能力。GTA采用真实用户查询、真实部署工具和多模态输入,全面评估LLM的推理和执行能力。结果显示,现有LLM在真实世界任务中仍面临巨大挑战,为未来研究提供了重要方向。
514 13
【Simulink】飞轮储能系统的建模与MATLAB仿真(永磁同步电机作为飞轮驱动电机)
【Simulink】飞轮储能系统的建模与MATLAB仿真(永磁同步电机作为飞轮驱动电机)
|
网络安全 Docker 容器
failed to create network error response from daemon filed to setup ip tables问题
failed to create network error response from daemon filed to setup ip tables问题
1060 0

热门文章

最新文章