tp5支付宝和微信支付

一、生成二维码给用户进行扫码支付

1、先在vendor目录下加入支付宝和微信支付的引用

2、付款处调用

/**
     * 订单支付接口
     *
     * @api {post} {:url('order/pay')} 前台订单支付二维码接口
     * @apiName pay
     * @apiGroup Order
     * @apiParam {String} type 支付类型 alipay,wxpay
     * @apiParam {String} sn 订单号
     * @apiSuccess (200) {String} /uploads/tmp/testbfb0f121f0114a8238a8888ed116af50.png 支付二维码地址
     *
     */
    public function pay()
    {
        $type     = input('type', 'alipay', 'trim');
        $order_sn = input('sn', '', 'trim');

        if (!$order_sn) {
            return json(['msg' => '订单号错误'], 400);
        }

        $pay   = new Pay();
        $order = db('orders')->where(['order_sn' => $order_sn, 'pay_status' => 0])->find();
        if (!$order) {
            return json(['msg' => '订单没有找到'], 400);
        }
        if ($order['pay_status'] == 1) {
            return json(['msg' => '订单已经支付, 请勿重复支付!'], 400);
        }

        try {
            switch ($type) {
                case 'alipay':
                    $data = [
                        'out_trade_no'    => $order['order_sn'],
                        'subject'         => $order['cust_name'] . "扫码支付",
                        'total_amount'    => $order['payment_amount'],
                        'timeout_express' => "30m",
                    ];
                    $pay->ali_pay($data);
//                    echo "uploads/tmp/testbfb0f121f0114a8238a8888ed116af50.png";
                    break;
                case 'wxpay':
                    $data = [
                        'body'         => $order['cust_name'],
                        'total_fee'    => $order['payment_amount'] * 100,
                        'out_trade_no' => $order['order_sn'],
                        'product_id'   => $order['order_sn'],
                        'trade_type'   => 'NATIVE'
                    ];
                    $pay->wx_pay($data);
//                    echo "uploads/tmp/testbfb0f121f0114a8238a8888ed116af50.png";
                    break;
                case 'under_pay'://线下汇款
                    $bool = db('orders')->where('order_sn',$order_sn)->update(['pay_status'=>1]);
                    if($bool){
                        return json(['msg'=>"订单完成"],200);
                    }else{
                        return json(['msg'=>"订单支付异常"],400);
                    }


            }
        } catch (\Exception $e) {
            return json(['msg' => $e->getMessage()], 400);
        }
    }
View Code

Pay.php文件

<?php

namespace app\index\pay;



use think\Exception;

if (!defined("AOP_SDK_WORK_DIR"))
{
    define("AOP_SDK_WORK_DIR", TEMP_PATH);
}

class Pay
{
    private $config = [];

    public function ali_pay($order)
    {
        vendor('alipay.AopSdk');
        $info         = db('pay_config')
        ->field('fpay_value,public_key,private_key')
        ->where(['ftype' => 'alipay','fstatus'=>1])
        ->find();

        $this->config = array(
            //签名方式,默认为RSA2(RSA2048)
            'sign_type'            => "RSA2",
            //支付宝公钥
            'alipay_public_key'    => $info['public_key'],
            //商户私钥
            'merchant_private_key' => $info['private_key'],
            //应用ID
            'app_id'               => $info['fpay_value'],
            //异步通知地址,只有扫码支付预下单可用
            'notify_url'           => url('index/alipay/notify', '', '', true),//支付后回调接口
            //'notify_url'           => "http://requestbin.net/r/1bjk7931",
            //最大查询重试次数
            'MaxQueryRetry'        => "10",
            //查询间隔
            'QueryDuration'        => "3",
        );

        try {
            $alipay = new AlipayTradeService($this->config);
            $response = $alipay->qrPay($order);
            $alipay->create_erweima($response->qr_code);
        } catch (\Exception $e) {
           throw new Exception($e->getMessage());
        }

    }

    public function wx_pay($order)
    {
        $info = db('pay_config')->where(['ftype' => 'wxpay'])->value('fpay_value');
        vendor('Weixinpay.Weixinpay');
        $info         = json_decode($info, true);
        $this->config = [
            'APPID'      => $info['fappid'], // 微信支付APPID
            'MCHID'      => $info['fmchid'], // 微信支付MCHID 商户收款账号
            'KEY'        => $info['fappkey'], // 微信支付KEY
            'APPSECRET'  => $info['fappsecret'],  //公众帐号secert
            'NOTIFY_URL' => url('index/wxpay/notify', '', '', true), // 接收支付状态的连接  改成自己的域名
        ];

        $wxpay = new \Weixinpay($this->config);
        $wxpay->pay($order);
    }
}
View Code

(1)支付宝相关接口代码

AlipayTradeService.php

<?php

namespace app\index\pay;
use think\Exception;

class AlipayTradeService
{

    //支付宝网关地址
    public $gateway_url = "https://openapi.alipay.com/gateway.do";

    //异步通知回调地址
    public $notify_url;

    //签名类型
    public $sign_type;

    //支付宝公钥地址
    public $alipay_public_key;

    //商户私钥地址
    public $private_key;

    //应用id
    public $appid;

    //编码格式
    public $charset = "UTF-8";

    public $token = NULL;

    //重试次数
    private $MaxQueryRetry;

    //重试间隔
    private $QueryDuration;

    //返回数据格式
    public $format = "json";

    function __construct($alipay_config)
    {
        $this->appid             = $alipay_config['app_id'];
        $this->sign_type         = $alipay_config['sign_type'];
        $this->private_key       = $alipay_config['merchant_private_key'];
        $this->alipay_public_key = $alipay_config['alipay_public_key'];
        $this->MaxQueryRetry     = $alipay_config['MaxQueryRetry'];
        $this->QueryDuration     = $alipay_config['QueryDuration'];
        $this->notify_url        = $alipay_config['notify_url'];

        if (empty($this->appid) || trim($this->appid) == "") {
            throw new Exception("appid should not be NULL!");
        }
        if (empty($this->private_key) || trim($this->private_key) == "") {
            throw new Exception("private_key should not be NULL!");
        }
        if (empty($this->alipay_public_key) || trim($this->alipay_public_key) == "") {
            throw new Exception("alipay_public_key should not be NULL!");
        }
        if (empty($this->charset) || trim($this->charset) == "") {
            throw new Exception("charset should not be NULL!");
        }
        if (empty($this->QueryDuration) || trim($this->QueryDuration) == "") {
            throw new Exception("QueryDuration should not be NULL!");
        }
        if (empty($this->gateway_url) || trim($this->gateway_url) == "") {
            throw new Exception("gateway_url should not be NULL!");
        }
        if (empty($this->MaxQueryRetry) || trim($this->MaxQueryRetry) == "") {
            throw new Exception("MaxQueryRetry should not be NULL!");
        }
        if (empty($this->sign_type) || trim($this->sign_type) == "") {
            throw new Exception("sign_type should not be NULL");
        }

    }

    //当面付2.0预下单(生成二维码,带轮询)
    public function qrPay($order)
    {
        vendor('alipay.AopSdk');

        $order = json_encode($order,JSON_UNESCAPED_UNICODE);

        $this->writeLog($order);

        $request = new \AlipayTradePrecreateRequest();
        $request->setBizContent($order);
        $request->setNotifyUrl($this->notify_url);

        // 首先调用支付api
        $response = $this->aopclientRequestExecute($request, NULL, NULL);
        $response = $response->alipay_trade_precreate_response;

        if (!empty($response) && ("10000" == $response->code)) {
            return $response;
        } elseif ($this->tradeError($response)) {
            throw new Exception($response->code.":".$response->msg);
        } else {
            throw new Exception($response->code.":".$response->msg."(".$response->sub_msg.")");
        }
    }

    /**
     * 使用SDK执行提交页面接口请求
     * @param unknown $request
     * @param string $token
     * @param string $appAuthToken
     * @return string $$result
     */
    private function aopclientRequestExecute($request, $token = NULL, $appAuthToken = NULL)
    {

        $aop                     = new \AopClient ();
        $aop->gatewayUrl         = $this->gateway_url;
        $aop->appId              = $this->appid;
        $aop->signType           = $this->sign_type;
        $aop->rsaPrivateKey      = $this->private_key;
        $aop->alipayrsaPublicKey = $this->alipay_public_key;
        $aop->apiVersion         = "1.0";
        $aop->postCharset        = $this->charset;

        $aop->format = $this->format;
        // 开启页面信息输出
        $aop->debugInfo = true;
        $response         = $aop->execute($request, $token, $appAuthToken);

        //打开后,将url形式请求报文写入log文件
        $this->writeLog("response: " . var_export($response, true));
        return $response;
    }

    // 交易异常,或发生系统错误
    protected function tradeError($response)
    {
        return empty($response) ||
            $response->code == "20000";
    }

    function writeLog($text)
    {
        // $text=iconv("GBK", "UTF-8//IGNORE", $text);
        //$text = characet ( $text );
        file_put_contents(RUNTIME_PATH."log/log.txt", date("Y-m-d H:i:s") . "  " . $text . "\r\n", FILE_APPEND);
    }

    function create_erweima($content) {
        //$content = urlencode($content);
        qrcode($content);
    }
    /**
     * 验签方法
     * @param $arr 验签支付宝返回的信息,使用支付宝公钥。
     * @return boolean
     */
    function check($arr){
        $aop = new \AopClient();
        $aop->alipayrsaPublicKey = $this->alipay_public_key;
        $result = $aop->rsaCheckV1($arr, $this->alipay_public_key, $this->sign_type);

        return $result;
    }
}
View Code

index/alipay/notify.php---扫码支付后调用接口

<?php

namespace app\index\controller;

use app\index\pay\AlipayTradeService as JKAlipayTradeService;
use think\Controller;

class Alipay extends Controller
{
    /**
     * notify_url接收页面
     */
    public function notify()
    {
        // 引入支付宝
        vendor('Alipay.AopSdk');
        $info         = db('pay_config')
            ->field('fpay_value,public_key,private_key')
            ->where(['ftype' => 'alipay','fstatus'=>1])
            ->find();

        $config = array(
            //签名方式,默认为RSA2(RSA2048)
            'sign_type'            => "RSA2",
            //支付宝公钥
            'alipay_public_key'    => $info['public_key'],
            //商户私钥
            'merchant_private_key' => $info['private_key'],
            //应用ID
            'app_id'               => $info['fpay_value'],
            //异步通知地址,只有扫码支付预下单可用
            'notify_url'           => url('index/alipay/notify', '', '', true),
            //最大查询重试次数
            'MaxQueryRetry'        => "10",
            //查询间隔
            'QueryDuration'        => "3",
        );
        $alipaySevice = new JKAlipayTradeService($config);
        $alipaySevice->writeLog(var_export($_POST,true));
        //$result = $alipaySevice->check($_POST);
        $out_trade_no = $_POST['out_trade_no'];

        if ($_POST['trade_status'] == 'TRADE_FINISHED' || $_POST['trade_status'] == 'TRADE_SUCCESS') {

            if ($order = db('orders')->where("order_sn", $out_trade_no)->find()) {
                if ($order['pay_status'] != 1) {
                    db("orders")
                        ->where("order_sn", $out_trade_no)
                        ->update(['pay_status' => 1,'status'=>2]);
                    // 付款单创建
                    db('payment_bills')->insert([
                        'cust_code'=>$order['cust_code'],
                        'cust_name'=>$order['cust_name'],
                        'payment_type'=>'alipay',
                        'amount'=>$order['payment_amount'],
                        'payment_time'=>date('Y-m-d H:i:s'),
                        'trade_no'=>$_POST['trade_no'],
                        'status'=>1,
                        'created_at'=>date('Y-m-d H:i:s'),
                        'updated_at'=>date('Y-m-d H:i:s'),
                    ]);
                }
            }
        }
        echo "success";
    }

}
View Code

(2)微信相关接口代码

index/wxpay/notify

<?php


namespace app\index\controller;


use think\Controller;

class Wxpay extends Controller
{
    /**
     * notify_url接收页面
     */
    public function notify()
    {
        // 获取xml
        $xml=file_get_contents('php://input', 'r');
        //转成php数组 禁止引用外部xml实体
        libxml_disable_entity_loader(true);
        $data= json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA));
        file_put_contents('./notify.text', $data);

        // 导入微信支付sdk
        Vendor('Weixinpay.Weixinpay');
        $info = db('pay_config')->where(['ftype' => 'wxpay'])->value('fpay_value');
        $info         = json_decode($info, true);
        $config = [
            'APPID'      => $info['fappid'], // 微信支付APPID
            'MCHID'      => $info['fmchid'], // 微信支付MCHID 商户收款账号
            'KEY'        => $info['fappkey'], // 微信支付KEY
            'APPSECRET'  => $info['fappsecret'],  //公众帐号secert
            'NOTIFY_URL' => url('index/wxpay/notify', '', '', true), // 接收支付状态的连接  改成自己的域名
        ];

        $wxpay  = new \Weixinpay($config);
        $result = $wxpay->notify();

        if ($result) {
            // 验证成功 修改数据库的订单状态等 $result['out_trade_no']为订单id
            $map = [
                'order_sn' => $result['out_trade_on'],
                'status'   => 2
            ];
            if ($order = db('orders')->where($map)->find()) {
                if ($order['pay_status'] != 1) {
                    db("orders")->where("order_sn", $result['out_trade_on'])->update(['pay_status' => 1]);
                }

                // 付款单创建
                db('payment_bills')->insert([
                    'cust_code'=>$order['cust_code'],
                    'cust_name'=>$order['cust_name'],
                    'payment_type'=>'wxpay',
                    'amount'=>$order['payment_amount'],
                    'account'=>isset($data['openid'])?$data['openid']:"",
                    'payment_time'=>date('Y-m-d H:i:s'),
                    'trade_no'=>isset($result['transaction_id'])?$result['transaction_id']:'',
                    'status'=>1,
                    'created_at'=>date('Y-m-d H:i:s'),
                    'updated_at'=>date('Y-m-d H:i:s'),
                ]);
            }
        }
    }
}
View Code

二、用户提供二维码进行支付

 

posted @ 2019-09-29 16:43  艾薇-Ivy  阅读(2851)  评论(0编辑  收藏  举报