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是入口文件,必须引入

转载于:https://www.cnblogs.com/alisleepy/p/11200338.html

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
具体可以看我的博客文章 https://blog.csdn.net/zyqytsoft/article/details/107161356 由于支付宝签约接口有千6的手续费 网上查了一下 支付宝免签约即时到帐的实现方案 基本都是在转账备注里按格式写入固定格式数据 然后后台抓取数据入账 *** ## 后台的数据实时数据抓取主要2种方式 *** **一、登录pc端web页面的后台 实时刷新和抓取数据通过备注入账** 这里主要有2个问题 1)现在支付宝的post登录非常难处理,所以一般还是浏览器登录抓取数据 不过浏览器登录有个cookie过期的问题 支付宝在一段时间后会退出登录 2)解决的办法主要是2点 第一点、模拟人工操作点击页面和定时刷新页面 不过这个只能延长退出登录的时间 实际测试一下一般能保证20小时左右不退出 第二点,通过判断浏览器地址判断是否退出状态 然后写个post脚本不管是微信通知邮件通知反正通知提醒重新登录一下 **二、通过手机端的消息栏支付宝消息触发post脚本** 这个方式测试了一下不太可行 手机的消息只有金额没有备注 结论:采用pc端数据抓取结合模拟人工操作演出退出登录时长同时做好退出登录的消息提醒,实测20小时需要登录一次还是能够接受的 *** ## 前端生成付款二维码 接口1: alipays://platformapi/startapp?appId=20000123&actionType=scan&biz_data={"s": "money","u": "商户id","a": "金额","m":"备注"} 接口2: alipays://platformapi/startapp?appId=09999988&actionType=toAccount&goBack=NO&amount=金额&userId=商户id&memo=备注 *** 说明 alipays://platformapi/startapp?appId=09999988&actionType=toAccount&goBack=NO&amount=1.00&userId=2088501156491651&memo=备注2088501156491651 具体的链接:alipays://platformapi/startapp?appId=09999988&actionType=toAccount&goBack=NO&amount=金额&userId=用户id&memo=备注 这里的链接 “用户id” 并非支付宝收款账号,PC登录到支付宝右键查看源代码,搜索关键字 “uid”,出现的就是你的支付宝的用户id,这里的appid不要去动他这是对应的appid来打开支付宝对应操作 =======================l 二维码例子 alipays://platformapi/startapp?appId=20000123&actionType=scan&biz_data={"s": "money","u": "2088501156491651","a": "1","m":"CSDN,一块测试,20200609093339863"} 以上文本生成一个二维码 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200706163825652.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3p5cXl0c29mdA==,size_16,color_FFFFFF,t_70#pic_center) 支付宝扫一扫就可以看到效果 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200706163947524.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3p5cXl0c29mdA==,size_16,color_FFFFFF,t_70#pic_center)*** ## 后台抓取的客户端我写了一个DEMO *** 下载地址 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200706164118645.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3p5c

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值