zoukankan      html  css  js  c++  java
  • php实现支付宝在线支付和扫码支付demo

    php实现支付宝在线支付和扫码支付demo


    背景:在做一个公众号时增加了h5端,需要接入支付,非微信环境,选择了支付宝,以下简单记录下实现过程,并做了简单的封装,拿来即可使用,注意:本项目只是基于官方demo修改的,需要接入自己项目的需要按需获取到。

    demo的github地址:https://github.com/alisleepy/alipay

    目录结构:

    以下的文件目录无需修改,只修改config.php配置文件和paytest.php和create_qrcode.php文件

    /aop                       //核心库
    /img                       //二维码中心的icon(自己引入的)
    /lib                       //核心库
    /lotusphp_runtime          //没用到    
    /phpqrcode                 //生成二维码的插件(扫码支付时自己引入的,没用官方的)
    /service                   //官方demo的测试文件(没用到)
    AopSdk.php                 //demo项目入口文件,不用修改
    config.php                 //重要,存放配置文件
    create_qrcode.php          //二维码扫码支付demo
    notify_url.php             //异步回调地址(只测试了支付,没用到)
    paytest.php                //在线支付demo
    return_url.php             //同步跳转地址(没用到)
    

    步骤:

    1. 申请支付宝开发者
    2. 创建沙箱应用,获取到appId
    3. 获取公钥秘钥等信息,修改config.php
    4. 修改文件实现支付功能

    在线支付代码:paytest.php

    <?php
    /**
     * 功能:支付宝支付测试文件
     * 版本:v1.0
     * author:wangkk
     * 以下部分就是具体的支付过程,只需要引入自己的配置文件$config数组信息,同时需要获取订单信息即可使用
     */
    
    //引入sdk文件
    require_once dirname ( __FILE__ ).DIRECTORY_SEPARATOR.'aop/AopClient.php';
    require_once dirname ( __FILE__ ).DIRECTORY_SEPARATOR.'aop/request/AlipayTradeWapPayRequest.php';
    //引入配置文件信息
    require_once dirname ( __FILE__ ).DIRECTORY_SEPARATOR.'config.php';
    
    /**
     * 支付宝支付类的封装
     */
    class Alipay{
        //配置文件数据
        public $alipay_config;
        //构造函数,获取数据
        public function __construct($alipay_config){
            //配置项
            $this->gateway_url       = $alipay_config['gatewayUrl'];
    		$this->appid             = $alipay_config['app_id'];
    		$this->private_key       = $alipay_config['merchant_private_key'];
    		$this->alipay_public_key = $alipay_config['alipay_public_key'];
    		$this->charset           = $alipay_config['charset'];
            $this->signtype          = $alipay_config['sign_type'];
            $this->notify_url        = $alipay_config['notify_url'];
            $this->return_url        = $alipay_config['return_url'];
    
    		if(empty($this->appid) || trim($this->appid) == ""){
    			throw new Exception("appid不能为空!");
    		}
    		if(empty($this->private_key) || trim($this->private_key) == ""){
    			throw new Exception("商户密钥不能为空!");
    		}
    		if(empty($this->alipay_public_key) || trim($this->alipay_public_key) == ""){
    			throw new Exception("商户公钥不能为空!");
    		}
    		if(empty($this->charset) || trim($this->charset)== "" ){
    			throw new Exception("编码格式不能为空");
    		}
    		if(empty($this->gateway_url) || trim($this->gateway_url) == ""){
    			throw new Exception("支付网关地址不能为空!");
            }
            if(empty($this->notify_url) || trim($this->notify_url) == ""){
                throw new Exception("异步回调地址不能为空!");
            }
        }
        
        public function pay(){
            //订单号,自定义,唯一
            $out_trade_no = $_GET['out_trade_no'];
    
            /** --------------------------------以下部分需要修改:获取订单信息 start--------------------------------- **/
            //通过订单号获取到订单信息
            // $orderInfo = M('order')->where(['out_trade_no'=>$out_trade_no])->find();
            // if(empty($orderInfo)){
            //     throw new Exception("查无此订单");
            // }
            // //参数列表
            // $body            = $orderInfo['body'];         //商品描述,可为空
            // $subject         = $orderInfo['subject'];      //订单标题,必填
            // $out_trade_no    = $orderInfo['out_trade_no']; //订单号,必填
            // $total_amount    = $orderInfo['total_amount']; //订单金额,必填
            /** --------------------------------以上部分需要修改:获取订单信息 end--------------------------------- **/
            //订单测试信息,真实项目把以下几行删除,使用上边的真实数据
            $body            = '商品描述';         //商品描述,可为空
            $subject         = '订单标题';      //订单标题,必填
            $out_trade_no    = rand(10000,99999); //订单号,必填
            $total_amount    = rand(1,5); //订单金额,必填
    
            $timeout_express = '1m';  //超时,1分钟
            $product_code    = 'QUICK_WAP_WAY';  //手机端支付宝
            if(empty($subject) || trim($subject) == ""){
                throw new Exception("订单标题不能为空");
            }
            if(empty($total_amount) || trim($total_amount) == ""){
                throw new Exception("订单金额不能为空");
            }
            
            //组装订单数据
            $bizContentarr = array(
                'body'            => $body ? $body : '', //商品描述,可以为空
                'subject'         => $subject,
                'out_trade_no'    => $out_trade_no,
                'total_amount'    => $total_amount,
                'timeout_express' => $timeout_express,
                'product_code'    => $product_code,
            );
            $bizContent = json_encode($bizContentarr,JSON_UNESCAPED_UNICODE);
            
            //设置数据
            $aopObj = new AopClient();
            $aopObj->gatewayUrl = $this->gateway_url;
            $aopObj->appId = $this->appid;
            $aopObj->rsaPrivateKey = $this->private_key;
            $aopObj->alipayrsaPublicKey = $this->alipay_public_key;
            $aopObj->apiVersion = '1.0';
            $aopObj->postCharset = $this->charset;
            $aopObj->format = 'json';
            $aopObj->signType = $this->signtype;
    
            //设置请求的数据
            $request = new AlipayTradeWapPayRequest ();
            $request->setBizContent($bizContent);
            $request->setNotifyUrl($this->notify_url);
            $request->setReturnUrl($this->return_url);
            $result = $aopObj->pageExecute($request);
            echo $result;
        }
    }
    
    //获取到配置文件,框架里的话直接放在配置文件中,通过框架方法去获取
    $configInfo = $config;
    $AlipayObj = new Alipay($configInfo);
    $AlipayObj->pay();
    

    扫码支付代码:create_qrcode.php

    <?php
    /**
     * 功能:支付宝生成二维码
     * 版本:v1.0
     * author:wangkk
     * 以下部分就是具体的生成二维码过程,只需要引入自己的配置文件$config数组信息,同时需要获取订单信息即可使用
     */
    
    //引入sdk文件
    require_once dirname ( __FILE__ ).DIRECTORY_SEPARATOR.'aop/AopClient.php';
    require_once dirname ( __FILE__ ).DIRECTORY_SEPARATOR.'aop/request/AlipayTradePrecreateRequest.php';
    //引入配置文件信息
    require_once dirname ( __FILE__ ).DIRECTORY_SEPARATOR.'config.php';
    //引入生成二维码的插件
    require_once dirname ( __FILE__ ).DIRECTORY_SEPARATOR.'phpqrcode/phpqrcode.php';
    
    class CreateQrcode{
        public function __construct($alipay_config){
            //配置项
            $this->gateway_url       = $alipay_config['gatewayUrl'];
    		$this->appid             = $alipay_config['app_id'];
    		$this->private_key       = $alipay_config['merchant_private_key'];
    		$this->alipay_public_key = $alipay_config['alipay_public_key'];
    		$this->charset           = $alipay_config['charset'];
            $this->signtype          = $alipay_config['sign_type'];
            $this->notify_url        = $alipay_config['notify_url'];
            $this->return_url        = $alipay_config['return_url'];
    
    		if(empty($this->appid) || trim($this->appid) == ""){
    			throw new Exception("appid不能为空!");
    		}
    		if(empty($this->private_key) || trim($this->private_key) == ""){
    			throw new Exception("商户密钥不能为空!");
    		}
    		if(empty($this->alipay_public_key) || trim($this->alipay_public_key) == ""){
    			throw new Exception("商户公钥不能为空!");
    		}
    		if(empty($this->charset) || trim($this->charset)== "" ){
    			throw new Exception("编码格式不能为空");
    		}
    		if(empty($this->gateway_url) || trim($this->gateway_url) == ""){
    			throw new Exception("支付网关地址不能为空!");
            }
            if(empty($this->notify_url) || trim($this->notify_url) == ""){
                throw new Exception("异步回调地址不能为空!");
            }
        }
        
        //支付
        public function pay(){
            //订单号,自定义,唯一
            $out_trade_no = $_GET['out_trade_no'];
    
            /** --------------------------------以下部分需要修改:获取订单信息 start--------------------------------- **/
            //通过订单号获取到订单信息
            // $orderInfo = M('order')->where(['out_trade_no'=>$out_trade_no])->find();
            // if(empty($orderInfo)){
            //     throw new Exception("查无此订单");
            // }
            // //参数列表
            // $body            = $orderInfo['body'];         //商品描述,可为空
            // $subject         = $orderInfo['subject'];      //订单标题,必填
            // $out_trade_no    = $orderInfo['out_trade_no']; //订单号,必填
            // $total_amount    = $orderInfo['total_amount']; //订单金额,必填
            /** --------------------------------以上部分需要修改:获取订单信息 end--------------------------------- **/
            //订单测试信息,真实项目把以下几行删除,使用上边的真实数据
            $body            = '商品描述';         //商品描述,可为空
            $subject         = '订单标题';      //订单标题,必填
            $out_trade_no    = rand(10000,99999); //订单号,必填
            $total_amount    = rand(1,5); //订单金额,必填
    
            $aopObj = new AopClient ();
            //设置值
            $aopObj->gatewayUrl = $this->gateway_url;
            $aopObj->appId      = $this->appid;
            $aopObj->rsaPrivateKey = $this->private_key;
            $aopObj->alipayrsaPublicKey = $this->alipay_public_key;
            $aopObj->apiVersion = '1.0';
            $aopObj->postCharset = $this->charset;
            $aopObj->format = 'json';
            $aopObj->signType = $this->signtype;
            
            $request = new AlipayTradePrecreateRequest();
            //组装订单数据
            $timeout_express = '5m';  //超时,1分钟
            $bizContentarr = array(
                'body'            => $body ? $body : '', //商品描述,可以为空
                'subject'         => $subject,
                'out_trade_no'    => $out_trade_no,
                'total_amount'    => $total_amount,
                'timeout_express' => $timeout_express,  //过期时间
            );
            $bizContent = json_encode($bizContentarr,JSON_UNESCAPED_UNICODE);
            $request->setBizContent($bizContent);
            $result = $aopObj->execute($request);
            $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
            $resultCode = $result->$responseNode->code;
            if(!empty($resultCode) && $resultCode == 10000){
                //成功,得到二维码,在这不使用官方的方法,官方使用的是google的,墙内不ok
                $qr_code_url = $result->$responseNode->qr_code;
                $icon = './img/logo.png';//准备好的logo图片
                QRcode::png($qr_code_url,false, 'H',  4, false);
                $code           = ob_get_clean();
                $code           = imagecreatefromstring($code);
                $logo           = imagecreatefrompng($icon);
                $QR_width       = imagesx($code);//二维码图片宽度
                $QR_height      = imagesy($code);//二维码图片高度
                $logo_width     = imagesx($logo);//logo图片宽度
                $logo_height    = imagesy($logo);//logo图片高度
                $logo_qr_width  = $QR_width / 4;
                $scale          = $logo_width/$logo_qr_width;
                $logo_qr_height = $logo_height/$scale;
                $from_width = ($QR_width - $logo_qr_width) / 2;
                //重新组合图片并调整大小
                imagecopyresampled($code, $logo, $from_width, $from_width, 0, 0, $logo_qr_width, $logo_qr_height, $logo_width, $logo_height);
                header ( "Content-type: image/png" );
                ImagePng($code);
                echo $qrcode;die;
            } else {
                echo 'fail';die;
            }
        }
    }
    $alipay_config = $config;
    $CreateQrcodeObj = new CreateQrcode($alipay_config);
    $CreateQrcodeObj->pay();
    

    总结

    终点就是获取公钥秘钥这部分一定不能错,还有就是在真实项目中的话按需引入sdk文件,但aop,lotusphp_runtime这两个文件夹是支付宝核心库,必须引入,AopSdk.php是入口文件,必须引入

  • 相关阅读:
    【Azure 应用服务】由 Azure Functions runtime is unreachable 的错误消息推导出 ASYNC(异步)和 SYNC(同步)混用而引起ThreadPool耗尽问题
    【Azure API 管理】是否可以将Swagger 的API定义导入导Azure API Management中
    【Azure 应用服务】Azure Function 不能被触发
    【Azure 环境】Azure Key Vault (密钥保管库)中所保管的Keys, Secrets,Certificates是否可以实现数据粒度的权限控制呢?
    【Azure 事件中心】为应用程序网关(Application Gateway with WAF) 配置诊断日志,发送到事件中心
    【Azure 事件中心】azure-spring-cloud-stream-binder-eventhubs客户端组件问题, 实践消息非顺序可达
    【Azure API 管理】Azure API Management通过请求中的Path来限定其被访问的频率(如1秒一次)
    【Azure 环境】前端Web通过Azure AD获取Token时发生跨域问题(CORS Error)
    【Azure 应用服务】记一次Azure Spring Cloud 的部署错误 (az spring-cloud app deploy -g dev -s testdemo -n demo -p ./hellospring-0.0.1-SNAPSHOT.jar --->>> Failed to wait for deployment instances to be ready)
    【Azure 应用服务】App Service中抓取 Web Job 的 DUMP 办法
  • 原文地址:https://www.cnblogs.com/alisleepy/p/11200338.html
Copyright © 2011-2022 走看看