个人做微信支付和支付宝支付的代码

    自己做的微信支付和支付宝支付的代码,留着以后可能会用


<?php
/**
 * a:porter 
 * 此文件包含支付宝支付和微信支付,如不需要微信支付可以先不看
 * app支付调用服务器接口流程:
 *     客户端集成好支付宝后,点击支付,提交订单id到服务器
 *     主要访问接口为   aliGetSign()
 *     支付成功后回调为  alipaySuccess();
 * 
 */
require_once($GLOBALS['G_SP']["controller_path"] . "/apiBase.php"); // 引入apiBase
class pay extends apiBase{
    
    public $config = array(
        'alipay' => array(
            'partner' => "x",
            //签约支付宝账号或卖家支付宝帐户
            'seller'  => "x@lovexpp.com",
        ),
        'weixin' => array(
            'ios' => array(
                'APP_ID'  => 'x',
                'MCH_ID'  => 'x',
                'API_KEY' => 'x',
            ),
            'android' => array(
                'APP_ID'  => 'x',
                'MCH_ID'  => 'x',
                'API_KEY' => 'x',
            ),
        ),

    );

    public function __construct(){
        parent::__construct();
    }
    /**
     * a: porter
     * c: 订单状态
     */
    public function orderStatus(){
        $order_id = $this->spArgs('order_id');
        if(!$order_id || !is_numeric($order_id)){
            $this->areturn(3);
        }
        $order = spClass('x_order')->find("id = $order_id");
        if(!$order){
            $this->areturn(3);
        }
        $this->areturn(1 , $order['status']);
    }


    /**
    +-----------------------------------------------------------------
    * 支付宝
    +-----------------------------------------------------------------
     */
    
    /**
     * a: porter
     * c: 付款成功,支付宝回调方法
     */
    public function alipaySuccess(){
        $notify_id = $_POST['notify_id'];
        // 验证此次回调的有效性 
        $checkUrl = "https://mapi.alipay.com/gateway.do?service=notify_verify&partner=" . $this->config['alipay']['partner'] . "&notify_id=" . $notify_id;
        if(file_get_contents($checkUrl) != true){
            echo 'failed';
            exit();
        }
        $order_id = $_POST['out_trade_no'];
        // 判断是否成功
        // 如果成功,修改订单状态
        $order = spClass('x_order')->find("id = $order_id");
        // 完成支付的  ,订单状态改为已支付
        if(spClass('x_order')->update("id = $order_id" , array('status'=>1))){
            echo 'success';
            exit();
        }
        echo 'failed';
    }

    /**
     * a: porter
     * c: 支付宝得到签名
     
     */
    public function aliGetSign(){
        $order_id = $this->spArgs('order_id');
        if(!$order_id || !is_numeric($order_id)){
            $this->areturn(3);
        }
        // 查询出订单的信息
        $order = spClass('x_order')->spLinker()->find("id = $order_id");
        if(!$order){
            $this->areturn(3);
        }
        
        //获取待签名字符串
        $content = $this->aliGetData($order['x_cost']['theme'] , $order['id'] , $order['x_cost']['theme'] , $order['price']);
        //生成签名
        $mySign = urlencode($this->aliSign($content));
        $res = $content . "&sign=\"" . $mySign . "\"&"
                . "sign_type=\"RSA\"";
        //返回参数格式
        $this->areturn(1 , array('sign'=>$res));
        // 对订单信息加密,得到sign
    }

     /**
      * 获取客户端创建交易请求的参数
      * @param  [string] $subject [商品名]
      * @param  [int] $orderId [订单id]
      * @param  [string] $body    [商品描述]
      * @param  [float] $price   [价格]
      * @return [string]          [组合后的请求参数]
      */
    function aliGetData($subject , $orderId , $body , $totalFee){
        $totalFee = 0.01;
        //组装待签名数据
        $signData = "partner=\"". $this->config['alipay']['partner'] ."\"";
        $signData .= "&";
        $signData .= "seller_id=" . "\"" . $this->config['alipay']['seller'] . "\"";
        $signData .= "&";
        $signData .= "out_trade_no=" . "\"" . $orderId ."\"";
        $signData .= "&";
        $signData .= "subject=" . "\"" . $subject ."\"";
        $signData .= "&";
        $signData .= "body=" . "\"" . $body ."\"";
        $signData .= "&";
        $signData .= "total_fee=" . "\"" . $totalFee ."\"";
        // 服务器异步通知页面路径
        // $signData .= "&notify_url=" . "\"" . "http://notify.msp.hk/notify.htm"
        $signData .= "&notify_url=" . "\"" . "http://test.a.lovexpp.com/pay-alipaySuccess.html"
                . "\"";

        // 服务接口名称, 固定值
        $signData .= "&service=\"mobile.securitypay.pay\"";

        // 支付类型, 固定值
        $signData .= "&payment_type=\"1\"";

        // 参数编码, 固定值
        $signData .= "&_input_charset=\"utf-8\"";

        // 设置未付款交易的超时时间
        // 默认30分钟,一旦超时,该笔交易就会自动被关闭。
        // 取值范围:1m~15d。
        // m-分钟,h-小时,d-天,1c-当天(无论交易何时创建,都在0点关闭)。
        // 该参数数值不接受小数点,如1.5h,可转换为90m。
        $signData .= "&it_b_pay=\"30m\"";

        // extern_token为经过快登授权获取到的alipay_open_id,带上此参数用户将使用授权的账户进行支付
        // $signData .= "&extern_token=" . "\"" . extern_token . "\"";

        // 支付宝处理完请求后,当前页面跳转到商户指定页面的路径,可空
        $signData .= "&return_url=\"m.alipay.com\"";

        // 调用银行卡支付,需配置此参数,参与签名, 固定值 (需要签约《无线银行卡快捷支付》才能使用)
        //$signData .= "&paymethod=\"expressGateway\"";

        
        return $signData;
        
    }
    /**
     * a: porter
     * c: 将组合后的参数sign
     * @param  [string] $data [组合后的参数]
     * @return [string]       [sign]
     */
    function aliSign($data) {
        //读取私钥文件
        $priKey = file_get_contents('./common/cert/alipay_rsa_private_key.pem');

        //转换为openssl密钥,必须是没有经过pkcs8转换的私钥
        $res = openssl_get_privatekey($priKey);

        //调用openssl内置签名方法,生成签名$sign
        openssl_sign($data, $sign, $res);

        //释放资源
        openssl_free_key($res);
        
        //base64编码
        $sign = base64_encode($sign);
        return $sign;
    }

    /**
     +---------------------------------------------------------
     * 微信支付
     +---------------------------------------------------------
     */
    public function weixinGetSign(){
        $order_id = $this->spArgs('order_id');
        $type = $this->spArgs('type');
        if($type !== 'ios' && $type !== 'android'){
            $this->areturn(3);
        }
        $config = $this->config['weixin'][$type];
        if(!$order_id){
            $this->areturn(3);
        }
        $order = spClass('x_order')->spLinker()->find("id = $order_id");
        if(!$order){
            $this->areturn(3);
        }
        // 得到签名分为2部 签名订单参数得到prepayid 根据prepayid得到启动微信页面的签名
        // 第一次签名是md5大写,第二次签名是MD5小写
        
        // 得到请求prepayid 的xml
        $prepayUrl = "https://api.mch.weixin.qq.com/pay/unifiedorder";
        $prepayArr = array(
            'appid'     => $config['APP_ID'],
            'body'      => $order['x_cost']['theme'],
            'mch_id'    => $config['MCH_ID'],
            'nonce_str' => mt_rand(1000 , 9999),
            'notify_url'=> "http://test.a.lovexpp.com/pay-weixinSuccess.html",
            // 'notify_url' => "http://www.lovexpp.com/test-testWx3.html",
            'out_trade_no' => $order['id'], // 订单号
            'spbill_create_ip' => getIp(),
            // 'total_fee' => $order['price']*100, // 微信的单位是 分
            'total_fee' => 1,
            'trade_type'=> 'APP',
            );

        $prepaySign = strtoupper($this->weixinSign($prepayArr , $type));
        $prepayArr['sign'] = $prepaySign;
        $xmlString = toXml($prepayArr);

        // 通过xml得到prepayid
        $prepayRes = curlPost($prepayUrl , $xmlString);

        //打印获得的数据
        $prepay = simplexml_load_string($prepayRes);
        
        // 通过prepayid 得到支付签名
        $result = array(
                'appid' => $config['APP_ID'],
                'noncestr' => mt_rand(1000 , 9999),
                // 'noncestr' => '1000',
                // 'package' => "prepay_id=" . $prepay->prepay_id,
                'package' => "Sign=WXpay", // package 用这样才能兼容ios
                'partnerid' => $config['MCH_ID'],
                'prepayid' => $prepay->prepay_id.'',
                'timestamp' => time().'',
                // 'timestamp' => '1429353068',
            );

        $resultSign = $this->weixinSign($result , $type);
        $result['packageValue'] = $result['package']; // java package是关键字
        unset($result['package']);
        $result['sign'] = $resultSign;
        $this->areturn(1 , $result);
    }

    /**
     * 微信将组合后的参数sign
     * @return [strin] [组合后的参数]
     */
    function weixinSign($arr , $type){
        $sb = '';
        foreach($arr as $key=>$val){
            if(empty($val))
                continue;
            $sb .= $key . '=' . $val . '&';
        }
        $sb .= "key=" . $this->config['weixin'][$type]['API_KEY'];
        // echo $sb;
        // echo "<br/>";
        return md5($sb);
    }


    /**
     * a: porter
     * c: 付款成功,支付宝回调方法
     */
    public function weixinSuccess(){
        $postData = $GLOBALS["HTTP_RAW_POST_DATA"];
        // $postData = (array)simplexml_load_string($postData);
        // 先把 simplexml 对象转换成 json,再将 json 转换成数组。
        $xml = simplexml_load_string($postData, 'SimpleXMLElement', LIBXML_NOCDATA);
        $postData = json_decode(json_encode($xml) , true);

        $wxSign = strtolower($postData['sign']);
        if(!$wxSign) return 'failed';
        unset($postData['sign']);

        // 这里先对微信返回的参数进行sign验证
        //由于现在开发android和ios不是一个配置APP_KEY,所以生成的sign要生成ios,android一样一个,满足一个即可继续操作
        $androidSign = $this->weixinSign($postData , 'android');
        $iosSign = $this->weixinSign($postData , 'ios');
        if($wxSign != $androidSign && $wxSign != $iosSign){
            echo 'failed';
            exit();
        }
        $order_id = $postData['out_trade_no'];
        // 判断是否成功
        // 如果成功,修改订单状态
        $order = spClass('x_order')->find("id = $order_id");
        // 完成支付的  ,订单状态改为已支付
        if(spClass('x_order')->update("id = $order_id" , array('status'=>1))){
            echo 'success';
            exit();
        }
        echo 'failed';
    }
}