uni-app 微信app支付
阿新 • • 發佈:2019-01-10
解決微信支付: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