微信pc Native支付 支付宝pc扫码支付 Demo PHP tp5

官方sdk Demo
支付宝 请求支付代码

public function alipay(){
        $arr =input('param.');
        vendor('alipay-trade-page-pay/aop/AopClient');
        vendor('alipay-trade-page-pay/aop/request/AlipayTradePagePayRequest');
        $amount = $arr['amount'];
        $store_user_id = $arr['store_user_id'];
        $renew_price_id = $arr['renew_price_id'];
        $renew_service_id = $arr['renew_service_id'];
        $rand =  date('YmdHis').substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);

        Renew::insert(['store_user_id'=>$store_user_id,'pay_status'=>0,'create_time'=>time(),'renew_price_id'=>$renew_price_id,'renew_service_id'=>$renew_service_id,'out_trade_no'=>$rand]);

        /** 初始化 **/
        $aop = new \AopClient ();

        /** 支付宝网关 **/
        $aop->gatewayUrl = 'https://openapi.alipay.com/gateway.do';

        /** 应用id,如何获取请参考:https://opensupport.alipay.com/support/helpcenter/190/201602493024 **/
        $aop->appId = '';

        /** 密钥格式为pkcs1,如何获取私钥请参考:https://opensupport.alipay.com/support/helpcenter/207/201602469554  **/
        $aop->rsaPrivateKey = '';

        /** 支付宝公钥,如何获取请参考:https://opensupport.alipay.com/support/helpcenter/207/201602487431 **/
        $aop->alipayrsaPublicKey='';

        /** 签名算法类型 **/
        $aop->signType = 'RSA2';

        /** 请求使用的编码格式 **/ 
        $aop->postCharset='utf-8';

        /** 仅支持JSON  **/
        $aop->format='json';

        /** 实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.page.pay(电脑网站支付) **/
        $request = new  \AlipayTradePagePayRequest ();
       
        /** 设置业务参数 **/
        $request->setBizContent("{" .
            /** 商户订单号,商户自定义,需保证在商户端不重复,如:20200612000001 **/                    
            "\"out_trade_no\":\".$rand.\"," .
                                
            /** 销售产品码,固定值:FAST_INSTANT_TRADE_PAY **/                    
            "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"," .
                                
            /** 订单金额,精确到小数点后两位 **/                   
            "\"total_amount\":\"$amount\"," .
                                
            /** 订单标题 **/                    
            "\"subject\":\"宠物商户商城续费\"," .
                                
            /** 业务扩展参数 **/                     
            //"\"extend_params\":{" .
                    
                    /** 花呗分期参数传值前提:必须有该接口花呗收款准入条件,且需签约花呗分期 **/
                    /** 指定可选期数,只支持3/6/12期,还款期数越长手续费越高 **/
                    // "\"hb_fq_num\":\"3\"," .
                            
                    /** 指定花呗分期手续费承担方式,手续费可以由用户全承担(该值为0),也可以商户全承担(该值为100),但不可以共同承担,即不可取0和100外的其他值。 **/
                    //"\"hb_fq_seller_percent\":\"100\"" .
            //  "}," .       
            /** 订单描述 **/                  
            "\"body\":\"商户商城续费\"" .
        "}");

        /** 注:支付结果以异步通知为准,不能以同步返回为准,因为如果实际支付成功,但因为外力因素,如断网、断电等导致页面没有跳转,则无法接收到同步通知;**/
        /** 支付完成的跳转地址,用于用户视觉感知支付已成功,传值外网可以访问的地址,如果同步未跳转可参考该文档进行确认:https://opensupport.alipay.com/support/helpcenter/193/201602474937 **/
        $request->setReturnUrl("https://www.baidu.com");

        /** 异步通知地址,以http或者https开头的,商户外网可以post访问的异步地址,用于接收支付宝返回的支付结果,如果未收到该通知可参考该文档进行确认:https://opensupport.alipay.com/support/helpcenter/193/201602475759 **/
        $request->setNotifyUrl("https://www.baidu.com");

        /** 调用SDK生成form表单 **/
        $result = $aop->pageExecute ($request); 

        /** 调用SDK生成支付链接,可在浏览器打开链接进入支付页面 **/
        //$result = $aop->pageExecute ($request,'get');

        /** 第三方调用(服务商模式),传值app_auth_token后,会收款至授权token对应商家账号,如何获传值app_auth_token请参考文档:https://opensupport.alipay.com/support/helpcenter/79/201602494631 **/
        //$result = $aop->pageExecute($request,'get',"传入获取到的app_auth_token值");

        /** 获取接口调用结果,如果调用失败,可根据返回错误信息到该文档寻找排查方案:https://opensupport.alipay.com/support/helpcenter/97 **/
        print_r($result);
    }

支付宝异步通知代码

public function alipayNotify(){
        vendor('alipay-trade-page-pay/config');
        vendor('alipay-trade-page-pay/pagepay/service/AlipayTradeService');
        $config = array (	
            //应用ID,您的APPID。
            'app_id' => "",
    
            //商户私钥
            'merchant_private_key' => "",
            
            //异步通知地址
            'notify_url' => "http://www.baidu.com",
            
            //同步跳转
            'return_url' => "http://www.baidu.com",
    
            //编码格式
            'charset' => "UTF-8",
    
            //签名方式
            'sign_type'=>"RSA2",
    
            //支付宝网关
            'gatewayUrl' => "https://openapi.alipay.com/gateway.do",
    
            //支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
            'alipay_public_key' => "",
        );
        $arr =input('param.');
        $alipaySevice = new \AlipayTradeService($config);
        $alipaySevice->writeLog(var_export($arr,true));
        $result = $alipaySevice->check($arr);

        /* 实际验证过程建议商户添加以下校验。
        1、商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号,
        2、判断total_amount是否确实为该订单的实际金额(即商户订单创建时的金额),
        3、校验通知中的seller_id(或者seller_email) 是否为out_trade_no这笔单据的对应的操作方(有的时候,一个商户可能有多个seller_id/seller_email)
        4、验证app_id是否为该商户本身。
        */
        if($result) {//验证成功
            /
            //请在这里加上商户的业务逻辑程序代

            
            //——请根据您的业务逻辑来编写程序(以下代码仅作参考)——
            
            //获取支付宝的通知返回参数,可参考技术文档中服务器异步通知参数列表
            
            //商户订单号

            $out_trade_no = $arr['out_trade_no'];

            //支付宝交易号

            $trade_no = $arr['trade_no'];

            //交易状态
            $trade_status = $arr['trade_status'];


            if($arr['trade_status'] == 'TRADE_FINISHED') {

                //判断该笔订单是否在商户网站中已经做过处理
                    //如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
                    //请务必判断请求时的total_amount与通知时获取的total_fee为一致的
                    //如果有做过处理,不执行商户的业务程序
                        
                //注意:
                //退款日期超过可退款期限后(如三个月可退款),支付宝系统发送该交易状态通知
            }
            else if ($arr['trade_status'] == 'TRADE_SUCCESS') {
                //判断该笔订单是否在商户网站中已经做过处理
                    //如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
                    //请务必判断请求时的total_amount与通知时获取的total_fee为一致的
                    //如果有做过处理,不执行商户的业务程序			
                //注意:
                //付款完成后,支付宝系统发送该交易状态通知
                //修改该笔为已支付成功
                $order_info = Renew::where(['out_trade_no'=>$out_trade_no])->find();
    
                if(count($order_info) > 0){
                    Renew::where(['out_trade_no'=>$out_trade_no])->update(['pay_status'=>1,'pay_time'=>time()]);
                }
            }
            //——请根据您的业务逻辑来编写程序(以上代码仅作参考)——
            echo "success";	//请不要修改或删除
        }else {
            //验证失败
            echo "fail";

        }
    }

微信支付代码 扫码支付 模式二 需注意:微信官方sdk引入tp有点问题 使用绝对路径并且vendor函数引入必须不能有"." vendor(‘wx_php_sdk_pay/example/WxPayNativePay’);引入示例:require_once realpath(dirname(FILE).’/…/lib/WxPay.Config.Interface.php’);

public function wxNativePay(){
        vendor('wx_php_sdk_pay/example/WxPayNativePay');
        vendor('wx_php_sdk_pay/example/phpqrcode/phpqrcode');

        //('wx-php-sdk-pay/lib/WxPay.Api.php');
        //import('wx-php-sdk-pay/WxPay.NativePay.php');

        $arr =input('param.');
        $amount = $arr['amount'];
        $store_user_id = $arr['store_user_id'];
        $renew_price_id = $arr['renew_price_id'];
        $renew_service_id = $arr['renew_service_id'];
        $rand =  date('YmdHis').substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);

        Renew::insert(['store_user_id'=>$store_user_id,'pay_status'=>0,'create_time'=>time(),'renew_price_id'=>$renew_price_id,'renew_service_id'=>$renew_service_id,'out_trade_no'=>$rand]);

        //初始化日志
        // $logHandler= new \CLogFileHandler("../logs/".date('Y-m-d').'.log');
        // $log = Log::Init($logHandler, 15);
        //模式一
        //不再提供模式一支付方式
        /**
        * 流程:
        * 1、组装包含支付信息的url,生成二维码
        * 2、用户扫描二维码,进行支付
        * 3、确定支付之后,微信服务器会回调预先配置的回调地址,在【微信开放平台-微信支付-支付配置】中进行配置
        * 4、在接到回调通知之后,用户进行统一下单支付,并返回支付信息以完成支付(见:native_notify.php)
        * 5、支付完成之后,微信服务器会通知支付成功
        * 6、在支付成功通知中需要查单确认是否真正支付成功(见:notify.php)
        */

        $notify = new \NativePay ();
        // $url1 = $notify->GetPrePayUrl("123456789");

        //模式二
        /**
         * 流程:
         * 1、调用统一下单,取得code_url,生成二维码
         * 2、用户扫描二维码,进行支付
         * 3、支付完成之后,微信服务器会通知支付成功
         * 4、在支付成功通知中需要查单确认是否真正支付成功(见:notify.php)
         */
        $input = new \WxPayUnifiedOrder ();
        $input->SetBody("宠物商户后台续费");
        $input->SetAttach("宠物商户后台续费");
        $input->SetOut_trade_no($rand);
        $input->SetTotal_fee($amount*100);
        $input->SetTime_start(date("YmdHis"));
        $input->SetTime_expire(date("YmdHis", time() + 600));
        $input->SetGoods_tag("宠物商户后台续费");
        $input->SetNotify_url("https://www.baidu.com/wx_notify.php");
        $input->SetTrade_type("NATIVE");
        $input->SetProduct_id("123456789");

        $result = $notify->GetPayUrl($input);
        $url2 = $result["code_url"];

        if(substr($url2, 0, 6) == "weixin"){
            ob_start();
            $file = \QRcode::png($url2);
            $file = ob_get_contents();
            ob_clean();
            $base64_data = base64_encode($file);
            $base64_file = 'data:image/png;base64,'.$base64_data;
            return $base64_file;
        }else{
            header('HTTP/1.1 404 Not Found');
        }
    }

微信异步通知

public function wxNotify(){
        //获取接口数据,如果$_REQUEST拿不到数据,则使用file_get_contents函数获取
        $post =input('param.');
        if ($post == null) {
            $post = file_get_contents("php://input");
        }
    
        if ($post == null) {
            $post = isset($GLOBALS['HTTP_RAW_POST_DATA']) ? $GLOBALS['HTTP_RAW_POST_DATA'] : '';
        }
    
        if (empty($post) || $post == null || $post == '') {
            //阻止微信接口反复回调接口  文档地址 https://pay.weixin.qq.com/wiki/doc/api/H5.php?chapter=9_7&index=7,下面这句非常重要!!!
            $str='';  
            echo $str;
            exit('Notify 非法回调');
        }
    
        /*****************微信回调返回数据样例*******************
         $post = '
            
            
            
            
            
            
            
            
            
            ';
        *************************微信回调返回*****************/
    
        libxml_disable_entity_loader(true); //禁止引用外部xml实体
    
        $xml = simplexml_load_string($post, 'SimpleXMLElement', LIBXML_NOCDATA);//XML转数组
        
        // $post_data = (array)$xml;

        $post_data = json_decode(json_encode($xml),true);
        
        /** 解析出来的数组
            *Array
            * (
            * [appid] => wx1c870c0145984d30
            * [bank_type] => CFT
            * [cash_fee] => 100
            * [fee_type] => CNY
            * [is_subscribe] => N
            * [mch_id] => 1297210301
            * [nonce_str] => gkq1x5fxejqo5lz5eua50gg4c4la18vy
            * [openid] => olSGW5BBvfep9UhlU40VFIQlcvZ0
            * [out_trade_no] => fangchan_588796
            * [result_code] => SUCCESS
            * [return_code] => SUCCESS
            * [sign] => F6890323B0A6A3765510D152D9420EAC
            * [time_end] => 20180626170839
            * [total_fee] => 100
            * [trade_type] => JSAPI
            * [transaction_id] => 4200000134201806265483331660
            * )
        **/
        //订单号
        $out_trade_no = isset($post_data['out_trade_no']) && !empty($post_data['out_trade_no']) ? $post_data['out_trade_no'] : 0;
    
        //查询订单信息
        $order_info = Renew::where(['out_trade_no'=>$out_trade_no])->find();
    
        // file_put_contents(dirname(__FILE__).DIRECTORY_SEPARATOR."../../log.txt", date ( "Y-m-d H:i:s" ) . "  " . json_encode($post_data)."\r\n", FILE_APPEND );
    
        if(count($order_info) > 0){
            
            //平台支付key
            $wxpay_key = '';
    
            //接收到的签名
            $post_sign = $post_data['sign'];
            unset($post_data['sign']);
    
            //重新生成签名
            $newSign = $this->MakeSign($post_data,$wxpay_key);
            // file_put_contents(dirname(__FILE__).DIRECTORY_SEPARATOR."../../log.txt", date ( "Y-m-d H:i:s" ) . "  " . $newSign."\r\n".$post_sign. "\r\n", FILE_APPEND );
            
            //签名统一,则更新数据库
            if($post_sign == $newSign){
                //更新数据库
                if($post_data['return_code'] == 'SUCCESS' && $post_data['result_code'] == 'SUCCESS'){
                    //执行业务逻辑
                    Renew::where(['out_trade_no'=>$out_trade_no])->update(['pay_status'=>1,'pay_time'=>time()]);
                }
            }
        }
    
        //阻止微信接口反复回调接口  文档地址 https://pay.weixin.qq.com/wiki/doc/api/H5.php?chapter=9_7&index=7,下面这句非常重要!!!
        $str='';  
        echo $str;
    
    }

    public function MakeSign($params, $key)
	{
		//签名步骤一:按字典序排序参数
		ksort($params);
		$string = $this->ToUrlParams($params);
		//签名步骤二:在string后加入KEY
		$string = $string . "&key=".$key;
		//签名步骤三:MD5加密或者HMAC-SHA256
		$string = hash_hmac("sha256",$string ,$key);
		//签名步骤四:所有字符转为大写
		$result = strtoupper($string);
		return $result;
	}
	
 
    public function ToUrlParams( $params ){
        $string = '';
        if( !empty($params) ){
            $array = array();
            foreach( $params as $key => $value ){
                $array[] = $key.'='.$value;
            }
            $string = implode("&",$array);
        }
        return $string;
    }

你可能感兴趣的:(php,php,http)