uni-app 微信app支付

解决微信支付:https://ask.dcloud.net.cn/article/34913

重点:第二次签名

两个点:

1、先生成prepareid(预订单),

2、根据prepareid再进行一次签名才可以返回给app!

预支付:要返回值:对应7个值

{
"appid": "wx779a**27b1aaeb10",
"partnerid": "143**41502",
"noncestr": "ZeIlmt3FbV8MzfIo",
"package": "Sign=WXPay",
"prepayid": "wx2017041420152166c4aa07b80812189917",
"timestamp": 1492172122,
"sign": "5b89b644d95779dc304928cdfac68a86"
}

http://demo.dcloud.net.cn/payment/wxpayv3.HBuilder/?total=1

这个签名,要重新根据参数自己生成出来,不能用之前生成的签名

修改后的代码:

	/**
	 * 生成APP第二次签名专用
	 * @param int $wx_type $wx_type  =2用另一个微信商户帐号支付参数  =0所有微信支付都只用一个商户支付帐号参数
	 * @return 签名,本函数不覆盖sign成员变量,如要设置签名需要调用SetSign方法赋值
	 */
    public function signapp($data,$wx_type='') //$prepayid这个参数就是第1步里面获取的预订单id
    {
//   	$data = [];
//      $time = (string)time();
//      $rand = md5(time() . mt_rand(0, 1000));
//      $data['timestamp'] = $time;
//      $data['appid'] = '这是你的appid';
//      $data['partnerid'] = '这是你的商户号';
//      $data['prepayid'] = $prepayid;
//      $data['noncestr'] = $rand;
//      $data['package'] = 'Sign=WXPay';  //介个是固定的

 //       $sign = MakeSignapp2($data,$wx_type);
		//取得支付参数
		$wxconfing=wx_confing();
		if($wx_type==2){//=2用另一个微信商户帐号支付参数  =0所有微信支付都只用一个商户支付帐号参数
			$KEY='hgfuhy88888888888890g45';//商户API密私
		}else{
			$KEY=$wxconfing['KEY'];
		}
			
        //签名步骤一:按字典序排序参数
        ksort($data);
       // $string = $this->ToUrlParamsapp($data);
       
        $buff = "";
        foreach ($data as $k => $v)
        {
            if($k != "sign" && $v != "" && !is_array($v)){
                $buff .= $k . "=" . $v . "&";
            }
        }

        $string = trim($buff, "&");
       
        //签名步骤二:在string后加入KEY
        $string = $string . "&key=".$KEY;  //注意,敲黑板了,这里还要加上在config中配置过的key
        //签名步骤三:MD5加密
        $string = md5($string);
        //签名步骤四:所有字符转为大写
        $result = strtoupper($string);
        
//dump($result);die;
        $data['sign'] = $result;
        
        return $data;  //这个数组就是返回给app的信息
    }


	/**
	 * 获取设置的值
	 */
	public function GetValues()
	{
		return $this->values;
	}
}

具体例子:

    /**
     * 获取预支付信息
     *
     * @param array  $params 订单信息
     * @param string $params['body'] 商品简单描述
     * @param string $params['out_trade_no'] 商户订单号, 要保证唯一性
     * @param string $params['total_fee'] 标价金额, 请注意, 单位为分!!!!!
     * @param int $type =0所有微信支付都只用一个商户支付帐号参数,=1用另一个微信商户帐号支付参数
     * @param int $wx_type 0=微信其它支付 =1是微信小程序(支付需要用小程appid、secret)  
     * @return array 预支付信息
     */
    public static function getAppParams($params,$type='')
    {
        // 1.校检参数
        $that = new self();
		//dump("00");
		//dump($params);die;
        $that->checkParams($params);
        // 2.组装参数
        //dump($params);
        //dump($params['openid']);die;
        $input = $that->getPostData($params);
         //dump($input);die;
         if($type==2){//=1用另一个微信商户帐号支付参数
         	$wx_type=2;
         }
         
        // 3.获取预支付信息
        $result = \WxPayApi::unifiedOrderApp($input,'',$wx_type);//=2用另一个微信商户帐号支付参数
        //$result=json_encode($result2,true);
        //dump($result);die;

        // 4.返回支付参数
        return $result;
    }
	/**
	 * 
	 * APP支付统一下单,WxPayUnifiedOrder中out_trade_no、body、total_fee、trade_type必填
	 * appid、mchid、spbill_create_ip、nonce_str不需要填入
	 * @param WxPayUnifiedOrder $inputObj
	 * @param int $timeOut
	 * @param int $wx_type 0=微信其它支付 =1是微信小程序(支付需要用小程appid、secret) =2用另一个微信商户帐号支付参数
	 * @throws WxPayException
	 * @return 成功时返回,其他抛异常
	 */
	public static function unifiedOrderApp($inputObj, $timeOut = 6,$wx_type='')
	{
		
		//初始化,取得微信支付参数
		$wxconfing=wx_confing();
		
		$url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
		
		//检测必填参数
		if(!$inputObj->IsOut_trade_noSet()) {
			throw new WxPayException("缺少统一支付接口必填参数out_trade_no!");
		}else if(!$inputObj->IsBodySet()){
			throw new WxPayException("缺少统一支付接口必填参数body!");
		}else if(!$inputObj->IsTotal_feeSet()) {
			throw new WxPayException("缺少统一支付接口必填参数total_fee!");
		}else if(!$inputObj->IsTrade_typeSet()) {
			throw new WxPayException("缺少统一支付接口必填参数trade_type!");
		}
		
		//关联参数
		if($inputObj->GetTrade_type() == "JSAPI" && !$inputObj->IsOpenidSet()){
			throw new WxPayException("统一支付接口中,缺少必填参数openid!trade_type为JSAPI时,openid为必填参数!");
		}
		if($inputObj->GetTrade_type() == "NATIVE" && !$inputObj->IsProduct_idSet()){
			throw new WxPayException("统一支付接口中,缺少必填参数product_id!trade_type为JSAPI时,product_id为必填参数!");
		}
		
		$NOTIFY_URL=$wxconfing['NOTIFY_URL'];//异步通知url
		if($wx_type==2){
			$APPID='wxd49cae4321347238';//appID
			$MCHID='1522613141';//商户号
		}else{
			$APPID=$wxconfing['wx_appid'];//appID
			$MCHID=$wxconfing['MCHID'];//商户号
		}
	    	
		//dump($APPID);die;
		//异步通知url未设置,则使用配置文件中的url
		if(!$inputObj->IsNotify_urlSet()){
			$inputObj->SetNotify_url($NOTIFY_URL);//异步通知url
		}
		
		$inputObj->SetAppid($APPID);//公众账号ID
		$inputObj->SetMch_id($MCHID);//商户号
		$inputObj->SetSpbill_create_ip(get_client_ip());//终端ip	  
		//$inputObj->SetSpbill_create_ip("1.1.1.1");  	    
		$inputObj->SetNonce_str(self::getNonceStr());//随机字符串
		//签名

		$inputObj->SetSignApp($wx_type);

		$xml = $inputObj->ToXml();
		
		$startTimeStamp = self::getMillisecond();//请求开始时间
		$response = self::postXmlCurl($xml, $url, false, $timeOut);

	//xml转数组
	libxml_disable_entity_loader(true);
	$result= json_decode(json_encode(simplexml_load_string($response, 'SimpleXMLElement', LIBXML_NOCDATA)), true);  

//dump($result['sign']);die;
		// 统一下单接口返回正常的prepay_id,再按签名规范重新生成签名后,将数据传输给APP。
		// 参与签名的字段名为appId,partnerId,prepayId,nonceStr,timeStamp,package。注意:package的值格式为Sign=WXPay
		//$Sign=$result['sign'];
		$time_stamp = time();
		$pack	= 'Sign=WXPay';//介个是固定的
		//$pack	= 'Sign='.$Sign;
		//输出参数列表
		$prePayParams =array();
		$prePayParams['appid']		=$result['appid'];
		$prePayParams['noncestr']	=$result['nonce_str'];
		$prePayParams['package']	=$pack;
		$prePayParams['partnerid']	=$result['mch_id'];
		$prePayParams['prepayid']	=$result['prepay_id'];
		$prePayParams['timestamp']	=$time_stamp;
		//dump($prePayParams);
		//第二次签名:
		$sign =  WxPayDataBase::signapp($prePayParams,2);//=2用另一个微信商户帐号支付参数  =0所有微信支付都只用一个商户支付帐号参数
		$prePayParams['sign']	=$sign;
		//echo json_encode($prePayParams);
		$result3 = WxPayResults::InitFromArray($prePayParams,true)->GetValues();
		self::reportCostTime($url, $startTimeStamp, $result3);//上报请求花费时间
		
		return $result3;
	}

转载:https://ask.dcloud.net.cn/article/34913

猜你喜欢

转载自blog.csdn.net/haibo0668/article/details/85758292