支付对接类(扫码支付,H5支付,网关支付)

写在最前面的话:

最近由于业务需求,每日需要对接各种各样的支付通道(扫码支付,H5支付,网关支付)(又分为微信支付,支付宝支付,银联支付,京东支付等等),虽然每个公司的文档或业务逻辑都不一样,但是都大同小异,所以整理了一份通用的支付对接类,愿可以帮助到需要的朋友,本人能力有限,也有可能有考虑不周的地方,或者需要改进的,如果你有更好的想法或者建议,可以在下方留言,或者联系本人!
    private $payType   = 21;
    private $payMethod = 2;
    private $prefix    = 'HH_';
    private $channel   = "某某支付";
    private $scanApi   = 'scanPayApi';      //扫码支付
    private $h5Api     = 'h5PayApi';        //H5支付
    private $getwayApi = 'gatewayPayApi';   //网关支付

  /**------------------------以下更换为自己的逻辑------------------------------*/
    public function index( Request $request  )
    {
        if ( $request -> has( [ 'amount' , 'uid' , 'goods_id' ] ) )
        {
            $amount           = $request -> input( 'amount' );
            $uid              = $request -> input( 'uid' );
            $goods_id         = $request -> input( 'goods_id' );

            /**
             *
             此处编写自己的逻辑

            $url              = env( 'JYPAY_GETWAY' );

            $u[ "id" ]         = $data[ 'orderId' ];
            $u[ "uid" ]        = $uid;
            $u[ "name" ]       = XMAgentUserData ::getPersonalDetails( $uid )[ 0 ][ 'name' ];
            $u[ "goods_id" ]   = $goods_id;
            $u[ "pay_amount" ] = $amount;
            $u[ "ip_address" ] = $this->getIp();
            $u[ "pay_name" ]   = "华悦支付";
            OrderForm ::insertData( $u );
            return redirect() -> away( $url );

             *
             */
        }
        return response() -> json( [
            'code' => 1001 ,
            'msg'  => 'no' ,
        ] );
    }

    public function notify( Request $request )
    {
        $data = $this->dataReturn($request);
        if ($data['tradeStatus'] == 1 && $sign == $data['sign'])
        {
            $url = env( 'RESPONSE_PAY' ) . $data[ 'fxddh' ] . '&uid=' . $u[ 0 ][ 'uid' ];
            $this->requestCurl($url);
            return 'success';

        }
        return response() -> json( [
            'code' => 1001 ,
            'msg'  => 'no' ,
        ] );
    }

    public function callback()
    {
        return "This is a lonely page";
    }

    /**处理支付前要统一或必备的参数,建议放签名的数据
     * 
     * @param $amount
     *
     * @return array
     */
    public function dataPooled( $amount )
    {
        $data = [
            "fxid"        => env( 'JYPAY_MERCHANT_NUM' ) ,  //商户号
            "fxddh"       => $this -> prefix . $this -> payType . time() , //商户订单号
            "fxdesc"      => "test" ,                           //商品名
            "fxfee"       => $amount ,                          //支付金额 单位元
            "fxnotifyurl" => env( 'JYPAY_NOTIFY' ) ,        //异步回调 , 支付结果以异步为准
            "fxbackurl"   => env( 'JYPAY_RETURN' ) ,        //同步回调 不作为最终支付结果为准,请以异步回调为准
            "fxpay"       => $this -> payType ,                 //支付类型 此处可选项以网站对接文档为准
            "fxip"        => $this -> getIp()                   //支付端ip地址
        ];
        return $data;
    }

    /** 处理异步回调后的数据
     * 
     * @param Request $request
     *
     * @return array
     */
    public function dataReturn( Request $request )
    {
        $data = [
            'fxid'     => $request -> input( 'fxid' ) ,
            'fxddh'    => $request -> input( 'fxddh' ) ,
            'fxorder'  => $request -> input( 'fxorder' ) ,
            'fxdesc'   => $request -> input( 'fxdesc' ) ,
            'fxfee'    => $request -> input( 'fxfee' ) ,
            'fxstatus' => $request -> input( 'fxstatus' ) ,
            'fxtime'   => $request -> input( 'fxtime' ) ,
            'fxsign'   => $request -> input( 'fxsign' ) ,
        ];
        return $data;
    }

 /**------------------------以下是常用的。有需求更改,无需求可不动------------------------------*/

    /**切换支付API通道
     * 默认为H5支付
     *
     * @param string $type
     *
     * @return mixed
     */
    public function apiSwitch( $type = '' )
    {
        switch ( $type ) {
            case 1:
                return $this -> scanApi;
            case 2:
                return $this -> getwayApi;
            default:
                return $this -> h5Api;

        }
    }

   /**------------------------以下是公共的,可直接使用------------------------------*/

    /** url编码和解码
     *  默认为解码,
     * 
     * @param        $strOrUrl
     * @param string $type
     *
     * @return string
     */
    public function urlCode( $strOrUrl ,$type = '' )
    {
        return empty($type) ? urldecode($strOrUrl): urlencode($strOrUrl);
    }
    
    /** 解码
     *
     * @param      $json
     * @param bool $assoc
     *
     * @return mixed
     */
    public function jsonDecode( $json ,$assoc = false)
    {
        return json_decode($json,$assoc);
    }

    /**编码
     *
     * @param $str
     *
     * @return false|string
     */
    public function jsonEncode($str)
    {
        return json_encode($str);
    }

    /**数组拼接字符串
     *
     * @param $array
     *
     * @return bool|string
     */
    public function arrayJoinStr( $array )
    {
        $md5str = "";
        foreach ( $array as $key => $val ) {
            $md5str .= $key . "=" . $val . "&";
        }
        return $md5str;
    }

    /**拼接后字符串去除最后的&符号
     *
     * @param $str
     *
     * @return bool|string
     */
    public function strTrim( $str )
    {
        return substr( $str , 0 , -1 );
    }

    /**大小写转换,默认为大写,有值则小写
     *
     * @param        $str
     * @param string $type
     *
     * @return string
     */
    public function strCase( $str ,$type = '')
    {
        return empty($type) ? strtoupper($str) : strtolower($str);
    }


    /**数组按照键名排序
     *
     * @param $array
     *
     * @return bool
     */
    public function dataSort( &$array )
    {
        return ksort($array);
    }


    /**加密
     *
     * @param $str
     *
     * @return string
     */
    public function dataMd5( $str )
    {
        return md5( $str );
    }

    /**16进制编码转字符串
     *
     * @param $hex
     *
     * @return string
     */
    public function hexToString( $hex )
    {
        $string = '';
        for ( $i = 0 ; $i < strlen( $hex ) - 1 ; $i += 2 ) {
            $string .= chr( hexdec( $hex[ $i ] . $hex[ $i + 1 ] ) );
        }
        return $string;
    }

    /**字符串转16进制编码
     *
     * @param $string
     *
     * @return string
     */
    public function stringToHex( $string )
    {
        $hex = '';
        for ( $i = 0 ; $i < strlen( $string ) ; $i ++ ) {
            $hex .= dechex( ord( $string[ $i ] ) );
        }
        return $hex;
    }

    /**获取真实IP
     * @return array|false|string
     */
    public function getIp()
    {
        if ( getenv( "HTTP_CLIENT_IP" ) && strcasecmp( getenv( "HTTP_CLIENT_IP" ) , "unknown" ) )
            $ip = getenv( "HTTP_CLIENT_IP" );
        else if ( getenv( "HTTP_X_FORWARDED_FOR" ) && strcasecmp( getenv( "HTTP_X_FORWARDED_FOR" ) , "unknown" ) )
            $ip = getenv( "HTTP_X_FORWARDED_FOR" );
        else if ( getenv( "REMOTE_ADDR" ) && strcasecmp( getenv( "REMOTE_ADDR" ) , "unknown" ) )
            $ip = getenv( "REMOTE_ADDR" );
        else if ( isset( $_SERVER[ 'REMOTE_ADDR' ] ) && $_SERVER[ 'REMOTE_ADDR' ] && strcasecmp( $_SERVER[ 'REMOTE_ADDR' ] , "unknown" ) )
            $ip = $_SERVER[ 'REMOTE_ADDR' ];
        else
            $ip = "unknown";
        return ( $ip );
    }

    /** @模拟请求
     *
     * @param        $url
     * @param array  $postArray
     * @param string $method
     * @param string $content_type
     *
     * @return bool|string
     *
     */
    public function requestCurl( $url , $postArray = [] , $method = 'GET' , $content_type = '' )
    {
        $str = '';
        if ( !empty( $url ) ) {
            try {
                $ch = curl_init();
                curl_setopt( $ch , CURLOPT_URL , $url );
                curl_setopt( $ch , CURLOPT_HEADER , 0 );
                curl_setopt( $ch , CURLOPT_RETURNTRANSFER , 1 );
                curl_setopt( $ch , CURLOPT_TIMEOUT , 30 ); //30秒超时
                curl_setopt( $ch , CURLOPT_FOLLOWLOCATION , 1 );
                curl_setopt( $ch , CURLOPT_HTTPHEADER , $this -> getHeaderContentType( $content_type ) );
                if ( strtoupper( $method ) == 'POST' ) {
                    curl_setopt( $ch , CURLOPT_POST , 1 );
                    curl_setopt( $ch , CURLOPT_POSTFIELDS , $this -> dataBuild( $postArray ) );
                }
                curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); //是否验证对等证书,1则验证,0则不验证
                curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
                $str = curl_exec( $ch );
                curl_close( $ch );
            } catch ( Exception $e ) {
                $str = '';
            }
        }
        return $str;
    }

    /**
     * 数组生成一个经过 URL-encode 的请求字符串
     * ["name"=>"callback" , "value"=>"test"] => name=callback&value=test
     *
     * @param $array
     *
     * @return string
     */
    public function dataBuild( $array )
    {
        return is_array($array) ? http_build_query($array) : $array;
    }


    /**
     * @XML数据格式
     * @XJSON数据格式
     * @Xform表单数据编码 k=>v
     *
     * @param $type
     *
     * @return array
     */
    public function getHeaderContentType( $type )
    {
        switch ($type){
            case 'xml':
                $type =  "application/xml; charset=utf-8";
            case 'json':
                $type =  "application/json; charset=utf-8";
            case 'html':
                $type =  "text/html; Charset=utf-8";
            default:
                $type =  "application/x-www-form-urlencoded; charset=utf-8";
        }
        return [ "Content-Type:$type" ];
    }

    public function generateStr( $length = 4 )
    {
        if ( $length < 1 || $length > 30 ) {
            return false;
        }
        $chars = [
            'a' , 'b' , 'c' , 'd' , 'e' , 'f' , 'g' , 'h' , 'k' , 'm' , 'n' , 'p' , 'x' , 'y' , 'z' ,
            'A' , 'B' , 'C' , 'D' , 'E' , 'F' , 'G' , 'H' , 'K' , 'M' , 'N' , 'P' , 'X' , 'Y' , 'Z' ,
            1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9
        ];
        $str   = join( '' , array_rand( array_flip( $chars ) , $length ) );
        return $str;
    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,968评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,601评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,220评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,416评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,425评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,144评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,432评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,088评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,586评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,028评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,137评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,783评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,343评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,333评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,559评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,595评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,901评论 2 345