基于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


目录
相关文章
|
11月前
|
JSON 小程序 数据可视化
手把手带你开发一款云开发版点餐小程序,微信扫码点餐,用户端和后厨端都有
手把手带你开发一款云开发版点餐小程序,微信扫码点餐,用户端和后厨端都有
268 0
|
6月前
|
存储 API 对象存储
【 uniapp - 黑马优购 | 登录与支付(2)】如何实现三秒后跳转和微信支付
【 uniapp - 黑马优购 | 登录与支付(2)】如何实现三秒后跳转和微信支付
50 0
|
XML 移动开发 JavaScript
【畅购商城】微信支付模块之微信支付二维码
【畅购商城】微信支付模块之微信支付二维码
151 0
【畅购商城】微信支付模块之微信支付二维码
|
小程序
电商商城小程序项目完整源码(微信小程序)
电商商城小程序项目完整源码(微信小程序)
351 0
电商商城小程序项目完整源码(微信小程序)
|
小程序
微信小程序怎么开店,微信小程序店铺怎么制作?
微信小程序怎么开店,微信小程序店铺怎么制作?
136 2
|
数据安全/隐私保护
征婚交友源码,如何把控好注册登录的初体验?
征婚交友源码,如何把控好注册登录的初体验?
|
小程序 JavaScript API
微信小程序——天气查询案例
微信小程序——天气查询案例
301 0
微信小程序——天气查询案例
|
XML SQL JavaScript
微信扫码登陆网站类似 58同城(基于微信开发生成带参数的二维码的讲解)
微信扫码登陆网站类似 58同城(基于微信开发生成带参数的二维码的讲解)
187 0
|
开发者
GitHub开源的阿里支付宝支付功能和微信支付功能
GitHub开源的阿里支付宝支付功能和微信支付功能
GitHub开源的阿里支付宝支付功能和微信支付功能
如何开发创建微信、支付宝、百度等多合一小程序?
那么要是能有一个平台,能一下子生成多个平台的小程序就好了,那么小编告诉你,阿里云已经帮你实现了。
9168 0