php 微信支付 加密方式

//to do 微信支付
        $user = $this->auth->getUser();
        $openid =  $this->auth->getUser()->openid;  //当前用户openid
        $appid = 'wx********'; //小程序appid
        $mch_id = '15********'; //商户id
        $key = '*****'; //商户号秘钥
        $nonce_str = 'omso8gakbdqtxmzjc63pcj0b71v5qy68'; //随机32(不能高于32)位字符串
        $body = '商品的标题'; //商品的标题
        $out_trade_no = $order_num; //订单号
        $total_fee = $price*100; //金额
        $spbill_create_ip = get_client_ip();//获取用户服务器IP
        $notify_url = 'https:********';//回调地址
        $trade_type = 'JSAPI';//签名类型
        $data = compact('body', 'appid','mch_id', 'nonce_str','out_trade_no','total_fee','spbill_create_ip', 'notify_url','trade_type','openid');//王八的屁股,规定

        $sign = get_sign($data, $key, false);//生成签名
        $info =[
            'appid' =>$appid,
            'mch_id'=>$mch_id,
            'nonce_str'=>$nonce_str,
            'sign'=>$sign,
            'body'=>$body,
            'out_trade_no'=>$out_trade_no,
            'total_fee'=>$total_fee,
            'spbill_create_ip'=>$spbill_create_ip,
            'notify_url'=>$notify_url,
            'trade_type'=>$trade_type,
            'openid'=>$user['openid']
        ];
        // 将数组转化成XML格式 arrayToXml
        $info = $this->arrayToXml($info);
    //    print_r($info);exit;

        $data = $this->curl_post('https://api.mch.weixin.qq.com/pay/unifiedorder',$info);
    //    var_dump($data);exit;
        // XML转成数组
        $data1 = $this->xmlToArray($data);
        // var_dump($data1);exit;
        $prepay_id = $data1['prepay_id'];
        $time = time();
        $params_for_paysign = compact('appid','nonce_str','prepay_id','time');
        // var_dump($params_for_paysign);exit;
        $paySign = strtoupper(MD5("appId=$appid&nonceStr=$nonce_str&package=prepay_id=$prepay_id&signType=MD5&timeStamp=$time&key=$key"));
        // var_dump($paySign);exit;
        file_put_contents('2.txt',$prepay_id.PHP_EOL.$paySign);
//        $paysign = get_sign($params_for_paysign, $key, false);
        return json(['code'=>1,'msg'=>'','data'=>['appId'=>$appid,'nonceStr'=>$nonce_str,'package'=>'prepay_id='.$prepay_id,'signType'=>'MD5','timeStamp'=>$time,'paySign'=>$paySign]]);

回调代码

 /**
     * 回调
     */
    public function back()
    {
        $xml = isset($GLOBALS['HTTP_RAW_POST_DATA']) ? $GLOBALS['HTTP_RAW_POST_DATA'] : file_get_contents("php://input");
        if (empty($xml)) {
            # 如果没有数据,直接返回失败
            return "错误";
        }
        // return $xml;
        $info1 = $this->xmlToArray($xml);
        $appid = $info1['appid'];
        $mch_id = $info1['mch_id'];
        $nonce_str = $info1['nonce_str'];
        $transaction_id = $info1['transaction_id'];
        $sign = strtoupper(md5("appid=$appid&mch_id=$mch_id&nonce_str=$nonce_str&transaction_id=$transaction_id&key=*********"));
        $info2 = [
            'appid'=>$info1['appid'],
            'mch_id'=>$info1['mch_id'],
            'nonce_str'=>$info1['nonce_str'],
            'transaction_id'=>$info1['transaction_id'],
            'sign'=>$sign,
        ];
        $info3 = $this->arrayToXml($info2);
        $xml_data = $this->curl_post('https://api.mch.weixin.qq.com/pay/orderquery',$info3);
        $end_data = $this->xmlToArray($xml_data);
        if ($end_data['return_msg']!="OK"){
            $this->error('签名错误');
        }
        Db::startTrans();
        try {
            //成功
            //成功后的逻辑
            Db::commit();
        } catch (\Exception $e) {
//            file_put_contents('4.txt',$end_data['out_trade_no']);
            Db::rollback();
        }
    }

common.php 中用到的方法

<?php
// 微信特殊字符转化
function filterEmoji($str)
{
    $str = preg_replace_callback(
        '/./u',
        function (array $match) {
            return strlen($match[0]) >= 4 ? '' : $match[0];
        },
        $str);

    return $str;
}
//解密
function decryptData( $appid, $sessionKey, $encryptedData, $iv, &$data )
{
    $OK = 0;
    $IllegalAesKey = -41001;
    $IllegalIv = -41002;
    $IllegalBuffer = -41003;
    $DecodeBase64Error = -41004;

    if (strlen($sessionKey) != 24) {
        return $IllegalAesKey;
    }

    $aesKey=base64_decode($sessionKey);


    if (strlen($iv) != 24) {
        return $IllegalIv;
    }
    $aesIV=base64_decode($iv);

    $aesCipher=base64_decode($encryptedData);
//var_dump($aesKey,$aesIV,$aesCipher);

    $result=openssl_decrypt( $aesCipher, "AES-128-CBC", $aesKey, 1, $aesIV);

    $dataObj=json_decode( $result );

    if( $dataObj  == NULL )
    {
        return $IllegalBuffer;
    }
    if( $dataObj->watermark->appid != $appid )
    {
        return $IllegalBuffer;
    }
    $data = $result;
    return $OK;
}

/**
 * 生成签名
 * @param WxPayConfigInterface $config  配置对象
 * @param String    $key    商户秘钥
 * @param bool $needSignType  是否需要补signtype
 * @return 签名,本函数不覆盖sign成员变量,如要设置签名需要调用SetSign方法赋值
 */
function get_sign($config, $key, $needSignType = true)
{   $sign_type = 'MD5';
    if($needSignType) {
        $sign_type = GetSignType();
    }
    //签名步骤一:按字典序排序参数
    ksort($config);
    $string = ToUrlParams($config);
    //签名步骤二:在string后加入KEY
    $string = $string . "&key=".$key;

    //签名步骤三:MD5加密或者HMAC-SHA256
    if($sign_type == "MD5"){
        $string = md5($string);
    } else if($sign_type == "HMAC-SHA256") {
        $string = hash_hmac("sha256", $string, $key);
    } else {
        throw new Exception("签名类型不支持!");
    }

    //签名步骤四:所有字符转为大写
    $result = strtoupper($string);
    return $result;
}

/**
 * 获取客户端IP地址
 * @param integer $type 返回类型 0 返回IP地址 1 返回IPV4地址数字
 * @param boolean $adv 是否进行高级模式获取(有可能被伪装)
 * @return mixed
 */
function get_client_ip($type = 0,$adv=false) {
    $type       =  $type ? 1 : 0;
    static $ip  =   NULL;
    if ($ip !== NULL) return $ip[$type];
    if($adv){
        if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
            $arr    =   explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
            $pos    =   array_search('unknown',$arr);
            if(false !== $pos) unset($arr[$pos]);
            $ip     =   trim($arr[0]);
        }elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
            $ip     =   $_SERVER['HTTP_CLIENT_IP'];
        }elseif (isset($_SERVER['REMOTE_ADDR'])) {
            $ip     =   $_SERVER['REMOTE_ADDR'];
        }
    }elseif (isset($_SERVER['REMOTE_ADDR'])) {
        $ip     =   $_SERVER['REMOTE_ADDR'];
    }
    // IP地址合法验证
    $long = sprintf("%u",ip2long($ip));
    $ip   = $long ? array($ip, $long) : array('0.0.0.0', 0);
    return $ip[$type];
}

/**
 * 格式化参数格式化成url参数
 * @param $config  array  待排序的参数数组
 */
function ToUrlParams($config)
{
    $buff = "";
    foreach ($config as $k => $v)
    {
        if($k != "sign" && $v != "" && !is_array($v)){
            $buff .= $k . "=" . $v . "&";
        }
    }

    $buff = trim($buff, "&");
    return $buff;
}

/**
 *
 * 产生随机字符串,不长于32位
 * @param int $length
 * @return 产生的随机字符串
 */
function get_nonce_str($length = 32)
{
    $chars = "abcdefghijklmnopqrstuvwxyz0123456789";
    $str ="";
    for ( $i = 0; $i < $length; $i++ )  {
        $str .= substr($chars, mt_rand(0, strlen($chars)-1), 1);
    }
    return $str;
}

//订单号
    function build_order_no()
    {
        return date('ymd').substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
    }

    //数组转xml
    function arrayToXml($arr) {
        $xml = "<xml>";
        foreach ($arr as $key => $val){
            $xml.="<$key>$val</$key>";
        }
        if (!is_numeric($val)){
            $xml.="<$key>$val</$key>";
        }
        else
            $xml.="<$key><![CDATA[$val]]></$key>";
//        }
        $xml.="</xml>";
        return $xml;
    }

//Xml转数组
    function xmlToArray($xml) {
        $arr = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
        return $arr;
    }

    /**
     * 发送post请求
     */
    public function curl_post($url , $data=array()){

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        // POST数据
        curl_setopt($ch, CURLOPT_POST, 1);
        // 把post的变量加上
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        $output = curl_exec($ch);
        curl_close($ch);
        return $output;

    }




common中的方法不一定都能用上,缺啥拿啥,然后就成功了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值