ThinkPHP 5 支付宝微信支付(支付宝H5,微信H5、APP支付、公众号支付)

 Pay.php支付控制器

<?php
// +----------------------------------------------------------------------
// | YFCMS [ WE CAN DO IT MORE SIMPLE ]
// +----------------------------------------------------------------------
// | Copyright (c) 2015-2016 http://xueding.vip All rights reserved.
// +----------------------------------------------------------------------
// | Author: XueDing_ <361169632@qq.com>
// +----------------------------------------------------------------------
namespace appphonecontroller;

use thinkDb;
use thinkRequest;
use thinkSession;
use thinkCookie;
use appphonemodelWeixin;
use appphonemodelWeixin_pay;
use appphonemodelAlipay;

class Pay extends controller
{
    public function _initialize()
    {
        $this->alipay_config = array(
            //应用ID,您的APPID。
            'app_id' => 'your app_id',
            //支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
            'alipay_public_key' => 'your alipay_public_key',
            //商户私钥,您的原始格式RSA私钥
            'merchant_private_key' => 'your merchant_private_key',
            //异步通知地址
            'notify_url' => "your notify_url",
            //同步跳转
            'return_url' => "your return_url",
            //编码格式
            'charset' => "UTF-8",
            //签名方式
            'sign_type' => "RSA2",
            //支付宝网关
            'gatewayUrl' => "https://openapi.alipay.com/gateway.do",
            //支付宝partner,2088开头数字
            'partner' => 'your partner',
            //支付宝密钥
            'md5_key' => 'your key'
        );
        $this->wechat_config = array(
            //您的APPID
            'app_id' => 'your app_id',
            //您的md5_key
            'md5_key' => 'your md5_key',
            //您的mch_id
            'mch_id' => 'your mch_id',
            //您的appsecret
            'appsecret' => 'your appsecret',
            //您的回调地址可以在这里配置使用方法的时候传,也可以在模型里面配置。
            'notify_url' => 'your notify_url',
        );
    }

    /*
    微信h5支付
     */
    public function wechat_pay()
    {
        if (input('post.token') == TOKEN) {
            // 判断用户是在微信浏览器打开还是其他浏览器打开。
            $userAgent = $_SERVER['HTTP_USER_AGENT'];
            if (strpos($userAgent, 'MicroMessenger')) {
                $wechat = new Weixin($this->wechat_config['appsecret'], $this->wechat_config['app_id']);
                $wechat_pay = new Weixin_pay($this->wechat_config['appsecret'], $this->wechat_config['app_id'], $this->wechat_config['md5_key'], $this->wechat_config['mch_id']);
                $code = input('post.code');
                if (session::has('openid')) {
                    $openid = session::get('openid');
                    $total_fee = 1;
                    $out_trade_no = '12345678945641231';
                    $body = "充值金币支付测试";
                    $res = $wechat_pay->pay($openid, $total_fee, $body, $out_trade_no);
                    $arr['errcode'] = '0';
                    $arr['errmsg'] = 'ok';
                    $arr['url'] = '本控制器下的地址/' . 'wx?data=' . $res;
                    $data = json_encode($arr);
                } else {
                    if (!empty($code)) {
                        $res = $wechat->get_access_token($code);
                        $userinfo = $wechat->get_openid_userinfo($res['access_token'], $res['openid']);
                        $openid = $userinfo['openid'];
                        session::set('openid', $openid);
                        $total_fee = 1;
                        $out_trade_no = '12345678945641231';
                        $body = "充值金币支付测试";
                        $res = $wechat_pay->pay($openid, $total_fee, $body, $out_trade_no);
                        $arr['errcode'] = '0';
                        $arr['errmsg'] = 'ok';
                        $arr['url'] = '本控制器下的地址/' . 'wx?data=' . $res;
                        $data = json_encode($arr);
                    } else {
                        $link = 'http://' . $_SERVER['HTTP_HOST'] . '/#/cz'; // 前端充值金币页面地址。
                        cookie::set('url', $link, 300);
                        //$link 这个地址是在微信打开你项目时才会需要的,地址后面带上获取的code进行获取access_token。
                        $res = $wechat->code_shouquan($link);
                        $arr['errcode'] = '0';
                        $arr['errmsg'] = 'ok';
                        $arr['url'] = $res;
                        $data = json_encode($arr);
                    }
                }
            } else {
                //非微信浏览器
                $wechat_pay = new Weixin_pay($this->wechat_config['appsecret'], $this->wechat_config['app_id'], $this->wechat_config['md5_key'], $this->wechat_config['mch_id']);
                //h5支付不用传递openid 此处与微信jsapi支付不同
                $openid = "";
                $total_fee = 1;
                $out_trade_no = '12345678945641231';
                $body = "充值金币h5支付测试";
                $res = $wechat_pay->payh5($openid, $total_fee, $body, $out_trade_no);
                $arr['errcode'] = '0';
                $arr['errmsg'] = 'ok';
                $arr['url'] = $res['mweb_url'];//微信唤起H5支付地址
                $data = json_encode($arr);
            }
        } else {
            $data = '{"errcode":"1001","errmsg":"TOKEN无效"}';
        }
        echo $data;
    }

    /*
    在微信打开的时候唤起微信公众号支付。
    */
    public function wx()
    {
        $data = input('get.data');
        $this->assign('data', $data);
        return view();
    }

    /*
    获取微信code
     */
    public function code()
    {
        $code = input('param.code');
        $this->redirect(cookie::get('url') . '?code=' . $code);
    }

    /*
    微信回调
    */
    public function wechat_notify()
    {
        $ccc = file_get_contents('php://input');
        $Weixin_pay = new Weixin_pay();
        $data = $Weixin_pay->xmlToArray($ccc);
        if ($data['result_code'] == 'SUCCESS' && $data['return_code'] == 'SUCCESS') {
            //获取订单号
            $Ordersn = $data['out_trade_no'];//订单号
            // 处理支付成功后的逻辑业务
        }
    }

    /*
    微信APP支付
     */
    public function app_wechat_pay()
    {
        if (input('post.token') == TOKEN) {
            $wechat_pay = new Weixin_pay($this->wechat_config['appsecret'], $this->wechat_config['app_id'], $this->wechat_config['md5_key'], $this->wechat_config['mch_id']);
            //h5支付不用传递openid 此处与微信jsapi支付不同
            $openid = "";
            $total_fee = 1;
            $body = "充值金币APP支付测试";
            $order_sn = 123456789;//订单号
            $res = $wechat_pay->app_pay($body, $order_sn, $total_fee);
            if ($res['prepay_id']) {//判断返回参数中是否有prepay_id
                $order = $wechat_pay->getOrder($res['prepay_id']);//执行二次签名返回参数
                $arr['errcode'] = '0';
                $arr['errmsg'] = 'ok';
                $arr['order'] = $order;
                $data = json_encode($arr);
            } else {
                $arr['errcode'] = '1003';
                $arr['errmsg'] = $res['err_code_des'];
                $data = json_encode($arr);
            }
        } else {
            $data = '{"errcode":"1001","errmsg":"TOKEN无效"}';
        }
        echo $data;
    }

    /*
    支付宝开始支付
    */
    public function alipay()
    {//发起支付宝支付
        if (input('post.token') == TOKEN) {
            $link = 'http://' . $_SERVER['HTTP_HOST'] . '/#/cz';
            cookie::set('url', $link, 300);
            $res['out_trade_no'] = 123456798123;
            $res['subject'] = '充值';
            $res['body'] = '测试';
            $res['money'] = 0.01;
            $Pay = new Alipay($this->alipay_config['partner'], $this->alipay_config['md5_key']);
            $result = $Pay->alipay([
                'notify_url' => 'your notify_url',
                'return_url' => 'your return_url',
                'out_trade_no' => $res['out_trade_no'],
                'subject' => $res['subject'],
                'total_fee' => $res['money'],
                'body' => $res['body'],
            ]);
            $arr['errcode'] = '0';
            $arr['errmsg'] = 'ok';
            return $result['msg'];
        } else {
            $data = '{"errcode":"1001","errmsg":"TOKEN无效"}';
        }
        echo $data;
    }

    /*
    支付宝回调
    */
    public function alipay_notify()
    {//异步订单通知
        $wx = sys_config_get('payment');
        $Pay = new Alipay($wx['aliwappay']['partner'], $wx['aliwappay']['md5_key']);
        $out_trade_no = input('out_trade_no');
        $trade_status = input('trade_status');
        if ($trade_status == 'TRADE_SUCCESS') {
            // 处理支付成功后的逻辑业务

        } else {
            // 处理支付失败后的逻辑业务
        }
    }
}

模型:Weixin.php

<?php

namespace appphonemodel;

use thinkDb;
use thinkValidate;
use thinkLoader;
use thinkModel;

class Weixin extends model
{
    protected $appScrect;
    protected $appId;

    public function __construct($appScrect = "", $appId = "")
    {
        $this->appScrect = $appScrect;
        $this->appId = $appId;
    }

    /*
     * 因为本项目需求,前端是Vue后台是TP5两个项目不在一个服务器所以我的url是return 回控制器通过接口返回给前端
     * 如果是正常html页面可以使用header("Location: $url"); 以下方法都是
     * */
    public function code_shouquan($link)
    {
        $redirect_uri = urlencode('网址/pay/code');//微信获取网页授权地址
        // 1、引导用户进入授权页面同意授权,获取code
        // 2、通过code换取网页授权access_token
        // 3、如果需要,开发者可以刷新网页授权access_token,避免过期
        // 4、通过网页授权access_token和openid获取用户基本信息(支持UnionID机制)
        $url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" . $this->appId . "&redirect_uri=" . $redirect_uri . "&response_type=code&scope=snsapi_userinfo&state=1234#wechat_redirect";
        return $url;
    }


    public function get_access_token($code)
    {

        //检测缓存中是否有access_token(2小时),如果存在直接返回,不存在则检测缓存中的refresh_token(30天),
        // refresh_token如果存在调用刷新缓存;如果不存在重新发起授权code授权
        $url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" . $this->appId . "&secret=" . $this->appScrect . "&code=" . $code . "&grant_type=authorization_code";
        $res = $this->sendRequest($url);
        return $res;
    }

    public function get_refresh_token($refresh_token)
    {

        $url = "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=" . $this->appId . "&grant_type=refresh_token&refresh_token=" . $refresh_token;
        $res = $this->sendRequest($url);
        return $res;
    }

    public function get_openid_userinfo($access_token, $openid)
    {
        $url = "https://api.weixin.qq.com/sns/userinfo?access_token=" . $access_token . "&openid=" . $openid . "&lang=zh_CN";
        $res = $this->sendRequest($url);
        return $res;
    }

    /*
   发送请求
    */
    public function sendRequest($url)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $output = curl_exec($ch);
        curl_close($ch);
        return json_decode($output, true);
    }
}

Weixin.php

<?php
namespace appphonemodel;
use thinkDb;
use thinkValidate;
use thinkLoader;
use thinkModel;

class Weixin_pay extends model
{
    protected $appScrect;//微信公众平台的appscrect
    protected $appId;//微信公众平台appid
    protected $key;//微信商户平台配置的秘钥
    protected $mch_id;//微信商户号
    protected $values = array();

    public function __construct($appScrect="",$appId="", $key="",$mch_id =''){
        $this->appScrect=$appScrect;
        $this->appId=$appId;
        $this->key=$key;
        $this->mch_id=$mch_id;

    }
    public function app_pay($body, $out_trade_no, $total_fee){
        $url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
        $notify_url = '';//可以在这填写回调地址也可以增加一个参数传过来。也可以直接在构造里面加一个notify_url地址
        $onoce_str = $this->createNoncestr();
        $data["appid"] = $this->appId;
        $data["body"] = $body;
        $data["mch_id"] = $this->mch_id;
        $data["nonce_str"] = $onoce_str;
        $data["notify_url"] = $notify_url;
        $data["out_trade_no"] = $out_trade_no;
        $data["spbill_create_ip"] = $this->get_client_ip();
        $data["total_fee"] = $total_fee;
        $data["trade_type"] = "APP";
        $sign = $this->getSign($data);
        $data["sign"] = $sign;
        $xml = $this->arrayToXml($data);
        $response = $this->postXmlCurl($xml, $url);
        // return $xml;
        //将微信返回的结果xml转成数组
        $response = $this->xmlToArray($response);
        //返回数据
        return $response;
    }
    //执行第二次签名,才能返回给客户端使用
    public function getOrder($prepayId){
        $data["appid"] = $this->appId;
        $data["noncestr"] = $this->createNoncestr();;
        $data["package"] = "Sign=WXPay";
        $data["partnerid"] = $this->mch_id;
        $data["prepayid"] = $prepayId;
        $data["timestamp"] = time();
        $s = $this->getSign($data, false);
        $data["sign"] = $s;
        return $data;
    }
    /*
    公众号支付
     */
    public function pay($openid,$total_fee,$body,$out_trade_no){
        $url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
        $notify_url = '';
        $onoce_str = $this->createNoncestr();
        $data["appid"] = $this->appId;
        $data["body"] = $body;
        $data["mch_id"] = $this->mch_id;
        $data["nonce_str"] = $onoce_str;
        $data["notify_url"] = $notify_url;
        $data["out_trade_no"] = $out_trade_no;
        $data["spbill_create_ip"] = $this->get_client_ip();
        $data["total_fee"] = $total_fee;
        $data["trade_type"] = "JSAPI";
        $data["openid"] = $openid;
        $sign = $this->getSign($data);
        $data["sign"] = $sign;
        $xml = $this->arrayToXml($data);
        $response = $this->postXmlCurl($xml, $url);
        //将微信返回的结果xml转成数组
        $response = $this->xmlToArray($response);
        $jsapi=array();
        $timeStamp = time();
        $jsapi['appId']=($response["appid"]);    
        $jsapi['timeStamp']=("$timeStamp");
        $jsapi['nonceStr']=($this->createNoncestr());
        $jsapi['package']=("prepay_id=" . $response['prepay_id']);
        $jsapi['signType']=("MD5");
        $jsapi['paySign']=($this->getSign($jsapi));
        $parameters = json_encode($jsapi);
        // halt($jsapi);
        //请求数据,统一下单  
        return $parameters; 
    }

    public function payh5($openid,$total_fee,$body,$out_trade_no){
        $url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
        $notify_url = '';
        $onoce_str = $this->createNoncestr();
        $data["appid"] = $this->appId;
        $data["body"] = $body;
        $data["mch_id"] = $this->mch_id;
        $data["nonce_str"] = $onoce_str;
        $data["notify_url"] = $notify_url;
        $data["out_trade_no"] = $out_trade_no;
        $data["spbill_create_ip"] = $this->get_client_ip();
        $data["total_fee"] = $total_fee;
        $data["trade_type"] = "MWEB";
        $data["scene_info"] = "{'h5_info': {'type':'Wap','wap_url':  $notify_url,'wap_name': '测试充值'}}";
        $sign = $this->getSign($data);
        $data["sign"] = $sign;
        $xml = $this->arrayToXml($data);
        // return $data;
        $response = $this->postXmlCurl($xml, $url);
        //将微信返回的结果xml转成数组
        $response = $this->xmlToArray($response);
        //请求数据,统一下单  
        return $response; 
    }

    public static function getNonceStr($length = 32)
    {
        $chars = "abcdefghijklmnopqrstuvwxyz0123456789";
        $str ="";
        for ( $i = 0; $i < $length; $i++ )  {
            $str .= substr($chars, mt_rand(0, strlen($chars)-1), 1);
        }
        return $str;
    }

    //   /*生成签名*/
    public function getSign($Obj){
        foreach ($Obj as $k => $v){
            $Parameters[$k] = $v;
        }
        //签名步骤一:按字典序排序参数
        ksort($Parameters);
        $String = $this->formatBizQueryParaMap($Parameters, false);
        //echo '【string1】'.$String.'</br>';
        //签名步骤二:在string后加入KEY
        $String = $String."&key=".$this->key;
        //echo "【string2】".$String."</br>";
        //签名步骤三:MD5加密
        $String = md5($String);
        //echo "【string3】 ".$String."</br>";
        //签名步骤四:所有字符转为大写
        $result_ = strtoupper($String);
        //echo "【result】 ".$result_."</br>";
        return $result_;
    }
 
 
    /**
    *  作用:产生随机字符串,不长于32位
    */
    public function createNoncestr( $length = 32 ){
        $chars = "abcdefghijklmnopqrstuvwxyz0123456789"; 
        $str ="";
        for ( $i = 0; $i < $length; $i++ )  { 
            $str.= substr($chars, mt_rand(0, strlen($chars)-1), 1); 
        } 
        return $str;
    }
 
 
    //数组转xml
    public function arrayToXml($arr){
        $xml = "<xml>";
        foreach ($arr as $key=>$val){
            if (is_numeric($val)){
                $xml.="<".$key.">".$val."</".$key.">";
            }else{
                $xml.="<".$key."><![CDATA[".$val."]]></".$key.">"; 
            }
        }
        $xml.="</xml>";
        return $xml;
    }
 
       
    /**
    *  作用:将xml转为array
    */
    public function xmlToArray($xml){  
        //将XML转为array       
        $array_data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
        return $array_data;
    }
 
 
    /**
    *  作用:以post方式提交xml到对应的接口url
    */
    public function postXmlCurl($xml,$url,$second=30){  
        //初始化curl       
        $ch = curl_init();
        //设置超时
        curl_setopt($ch, CURLOPT_TIMEOUT, $second);
        //这里设置代理,如果有的话
        //curl_setopt($ch,CURLOPT_PROXY, '8.8.8.8');
        //curl_setopt($ch,CURLOPT_PROXYPORT, 8080);
        curl_setopt($ch,CURLOPT_URL, $url);
        curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE);
        curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE);
        //设置header
        curl_setopt($ch, CURLOPT_HEADER, FALSE);
        //要求结果为字符串且输出到屏幕上
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
        //post提交方式
        curl_setopt($ch, CURLOPT_POST, TRUE);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
        //运行curl
        $data = curl_exec($ch);
        //返回结果
 
        if($data){
            curl_close($ch);
            return $data;
        }else{
            $error = curl_errno($ch);
            echo "curl出错,错误码:$error"."<br>";
            curl_close($ch);
            return false;
        }
    }
 
 
    /*
    获取当前服务器的IP
    */
    public function get_client_ip(){
        if(getenv('HTTP_CLIENT_IP') && strcasecmp(getenv('HTTP_CLIENT_IP'),'unknown')) {

            $ip = getenv('HTTP_CLIENT_IP');

        } elseif(getenv('HTTP_X_FORWARDED_FOR') && strcasecmp(getenv('HTTP_X_FORWARDED_FOR'),'unknown')) {

            $ip = getenv('HTTP_X_FORWARDED_FOR');

        } elseif(getenv('REMOTE_ADDR') && strcasecmp(getenv('REMOTE_ADDR'),'unknown')) {

            $ip = getenv('REMOTE_ADDR');

        } elseif(isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], 'unknown')) {

            $ip = $_SERVER['REMOTE_ADDR'];

        }

        return preg_match ( '/[d.]{7,15}/', $ip, $matches ) ? $matches [0] : '';
    }
     
 
    /**
    *  作用:格式化参数,签名过程需要使用
    */
    public function formatBizQueryParaMap($paraMap, $urlencode){
        $buff = "";
        ksort($paraMap);
        foreach ($paraMap as $k => $v){
            if($urlencode){
                $v = urlencode($v);
            }
            $buff .= $k . "=" . $v . "&";
        }
        $reqPar;
        if (strlen($buff) > 0){
            $reqPar = substr($buff, 0, strlen($buff)-1);
        }
        return $reqPar;
    }
    
        public function MakeSign($unifiedorder)
    {
        $this->values=$unifiedorder;
        //签名步骤一:按字典序排序参数
        // ksort($this->values);
        $string = $this->ToUrlParams();
        //halt($string);
        //签名步骤二:在string后加入KEY
        $string = $string . "&key=".$this->key;
        //签名步骤三:MD5加密
        $string = md5($string);
        //签名步骤四:所有字符转为大写
        $result = strtoupper($string);
        return $result;
    }

    public function ToUrlParams()
    {
        $buff = "";
        foreach ($this->values as $k => $v)
        {
            if($k != "sign" && $v != "" && !is_array($v)){
                $buff .= $k . "=" . $v . "&";
            }
        }
        $buff = trim($buff, "&");
        return $buff;
    }


          function array2xml($array)
    {
        $xml='<xml>';
        foreach($array as $key=>$val){
            if(is_numeric($key)){
                $key="item id="$key"";
            }else{
                //去掉空格,只取空格之前文字为key
                list($key,)=explode(' ',$key);
            } 
            $xml.="<$key>";
            $xml.=is_array($val)?$this->_array2xml($val):$val;
            //去掉空格,只取空格之前文字为key
            list($key,)=explode(' ',$key);
            $xml.="</$key>";
            
        }
            $xml.="</xml>";

        return $xml;
    }

       function xml2array($xml)
    {    
        //禁止引用外部xml实体
        libxml_disable_entity_loader(true);
        $values = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);  
        return $values;
    }

    
    public  function request_post($url = '', $param = '')
    {
        if (empty($url) || empty($param)) {
            return false;
        }
        $postUrl = $url;
        $curlPost = $param;
        $ch = curl_init(); //初始化curl
        curl_setopt($ch, CURLOPT_URL, $postUrl); //抓取指定网页
        curl_setopt($ch, CURLOPT_HEADER, 0); //设置header
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //要求结果为字符串且输出到屏幕上
        curl_setopt($ch, CURLOPT_POST, 1); //post提交方式
        curl_setopt($ch, CURLOPT_POSTFIELDS, $curlPost);
        $data = curl_exec($ch); //运行curl
        curl_close($ch);
        return $data;
    }

    function curl_post_ssl($url, $vars, $second=30,$aHeader=array())
    {
        $ch = curl_init();
        //curl_setopt($ch,CURLOPT_VERBOSE,'1');
        curl_setopt($ch,CURLOPT_TIMEOUT,$second);
        curl_setopt($ch,CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch,CURLOPT_URL,$url);
        curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false);
        curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,false);
        curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');
        curl_setopt($ch,CURLOPT_SSLCERT,'/data/cert/php.pem');
        curl_setopt($ch,CURLOPT_SSLCERTPASSWD,'1234');
        curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');
        curl_setopt($ch,CURLOPT_SSLKEY,'/data/cert/php_private.pem');
        if( count($aHeader) >= 1 ){
                curl_setopt($ch, CURLOPT_HTTPHEADER, $aHeader);
        }
        curl_setopt($ch,CURLOPT_POST, 1);
        curl_setopt($ch,CURLOPT_POSTFIELDS,$vars);
        $data = curl_exec($ch);
        curl_close($ch);
        if($data){
            return $data;
        }else{
            return false;
        }
    }
}

Alipay.php

<?php
namespace appphonemodel;

use thinkValidate;
use thinkLog;
use thinkModel;
use libAlipaySubmit;

class Alipay extends Model
{
    protected $partner;
    protected $md5_key;

    public function __construct($partner = "", $md5_key = "")
    {
        $this->partner = $partner;
        $this->md5_key = $md5_key;
    }

    public static $alipay_config = [
        // 'partner'         => '',//支付宝partner,2088开头数字
        // 'seller_id'         => '',//支付宝partner,2088开头数字
        // 'key'             => '',//支付宝密钥
        'sign_type' => 'MD5',
        'input_charset' => 'utf-8',
        'cacert' => '',
        'transport' => 'http',
        'payment_type' => '1',
        'service' => '',//https://docs.open.alipay.com/api_1  看你需要哪个API接口
        'anti_phishing_key' => '',
        'exter_invoke_ip' => '',
        'app_pay' => 'Y',
    ];

    public function alipay($data = [])
    {//发起支付宝支付
        $validate = new Validate([
            ['out_trade_no', 'require|alphaNum', '订单编号输入错误1|订单编号输入错误2'],
            ['total_fee', 'require|number|gt:0', '金额输入错误|金额输入错误|金额输入错误'],
            ['subject', 'require', '请输入标题'],
            ['body', 'require', '请输入描述'],
            ['notify_url', 'require', '异步通知地址不为空'],
        ]);
        if (!$validate->check($data)) {
            return ['code' => 0, 'msg' => $validate->getError()];
        }
        $config = self::$alipay_config;
        $config['partner'] = $this->partner;
        $config['seller_id'] = $this->partner;
        $config['key'] = $this->md5_key;
        vendor('alipay.alipay');
        $parameter = [
            "service" => $config['service'],
            "partner" => $config['partner'],
            "seller_id" => $config['seller_id'],
            "payment_type" => $config['payment_type'],
            "notify_url" => $data['notify_url'],
            "return_url" => $data['return_url'],
            "anti_phishing_key" => $config['anti_phishing_key'],
            "exter_invoke_ip" => $config['exter_invoke_ip'],
            "out_trade_no" => $data['out_trade_no'],
            "subject" => $data['subject'],
            "total_fee" => $data['total_fee'],
            "body" => $data['body'],
            "_input_charset" => $config['input_charset'],
            'app_pay' => 'Y',

        ];
        $alipaySubmit = new AlipaySubmit($config);
        return ['code' => 1, 'msg' => $alipaySubmit->buildRequestForm($parameter, "get", "确认")];
    }
}

?>

支付宝需要的submit文件:点击下载

wx.html在使用微信客户端支付时需要的页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>微信公众号支付</title>
</head>
<body>
<script>
    function getOrder() {
        onBridgeReady();
    }
    function onBridgeReady() {
        var data = {$data};
        WeixinJSBridge.invoke(
            'getBrandWCPayRequest', data,
            function (res) {
                if (res.err_msg == "get_brand_wcpay_request:ok") {
                    // 使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回    ok,但并不保证它绝对可靠。
                    location.href = 'http://book.yueyuecms.com/#/me'
                } else {
                    // alert(res.err_code+res.err_desc+res.err_msg); // 显示错误信息
                    location.href = 'http://book.yueyuecms.com/#/me'
                }
            }
        );
    }
    if (typeof WeixinJSBridge == "undefined") {
        if (document.addEventListener) {
            document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
        } else if (document.attachEvent) {
            document.attachEvent('WeixinJSBridgeReady', onBridgeReady);
            document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
        }
    } else {
        onBridgeReady();
    }
</script>
</body>
</html>
Author:XueDing_
Email:361169632@qq.com
注明出处:https://www.cnblogs.com/best-always/p/10291310.html
原文地址:https://www.cnblogs.com/best-always/p/10291310.html