微信小程序支付

/**
 * 购买会员
 * @ApiMethod (POST)
 * @ApiReturn ({ "code": 1,"msg": "登录成功", "time": "1562726766"})
 * @ApiParams (name="type", type="string", required=true, description="会员类型:1=1级会员,2=2级会员")
 * @ApiParams (name="price", type="string", required=true, description="价格")
 */
public function member()
    {
        $user = $this->auth->getUser();
        $type = $this->request->param('type');
        $price = $this->request->param('price');
        if (empty($type) || empty($price)){
            $this->error('缺少参数');
        }
        if ($user['level']==1){
            $this->error('很抱歉!您已经是会员了');
        }
        //2020年12月31号前购买有效期2年
        if (time()< 1609430399){
            $end_time = strtotime(date('Y-m-d 23:59:59',strtotime("+2 year"))) - 86400;//会员结束时间
        }else{
            $end_time = strtotime(date('Y-m-d 23:59:59',strtotime("+1 year"))) - 86400;//会员结束时间
        }

        $member_order1 = date('Y',time()).date('m',time()).date('d',time()).rand(10000,99999);
        $member_order = [
          'member_order'=>$member_order1,
          'user_id' => $user['id'],
          'type'    => $type,
          'price' => $price,
          'create_time'=>time(),
          'end_time'=>$end_time
        ];
        //生成订单
       

       //to do 微信支付
        $user = $this->auth->getUser();
        $openid =  $this->auth->getUser()->openid;
        $appid = '';
        $mch_id = '';
        $key = '';
        $nonce_str = 'omso8gakbdqtxmzjc63pcj0b71v5qy68';
        $body = '会员费';
        $out_trade_no = $member_order1;
        $total_fee = $price*100;
        $spbill_create_ip = get_client_ip();
        $notify_url = 'https://xxx.xxx.com/api/member/back';
        $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']
        ];
        $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;
        $data1 = $this->xmlToArray($data);
        $prepay_id = $data1['prepay_id'];
        $time = time();
        $params_for_paysign = compact('appid','nonce_str','prepay_id','time');
        $paySign = strtoupper(MD5("appId=$appid&nonceStr=$nonce_str&package=prepay_id=$prepay_id&signType=MD5&timeStamp=$time&key=$key"));
        file_put_contents('2.txt',$prepay_id.PHP_EOL.$paySign);
        // 存入订单
        $order =  Db::name('member_order')->insert($member_order);
//        $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 "错误";
        }
        $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=gengyunpeng412018298412018298412"));
        $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 {
            //成功
            $status = Db::name('member_order')->where('member_order',$end_data['out_trade_no'])->value('status');
            if($status != 1){
                Db::name('member_order')->where('member_order',$end_data['out_trade_no'])->update(['status'=>1]);
                Db::name('user')->where('openid',$end_data['openid'])->update(['level'=>1]);
                $userid = Db::name('user')->where('openid',$end_data['openid'])->value('id');
                $money = Db::name('user')->where('openid',$end_data['openid'])->value('money');
                $money_log = [
                    'user_id'=>$userid,
                    'number'=>$end_data['total_fee']/100,
                    'before'=>$money,
                    'after' =>$money,
                    'type'=>$userid.'购买会员',
                    'create_time'=>time(),
                ];
                Db::name('money_log')->insert($money_log);
                $this->benefit($userid,$end_data['total_fee']/100);
            }
            
            Db::commit();
        } catch (\Exception $e) {
//            file_put_contents('4.txt',$end_data['out_trade_no']);
            Db::rollback();
        }
    }

/**

  • 生成签名
  • @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;
}

//数组转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;

    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值