1. 程式人生 > >uni-app 微信app支付

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