获取prepay_id,再重签参数传给APP发起支付。相信很多同学都会直接把结果返回给APP,因为看到统一订单返回的结果中有sign字段。导致APP无法激活小额支付。实际上,对APP使用的字段数据按照“统一订单签名方式”进行签名后需要得到的签名,就是APP需要的签名。微信支付app支付服务端调用统一下单接口后,服务端需要对返回的订单数据进行二次签名后返回给app。开发文档里说的不是很清楚,因为统一订单的返回数据和二次签名的原始数据有一些重叠。微信支付服务端sdk提供了WxPayResults类,该类确实提供了签名生成方法,即对结果集进行签名。源码如下:以PHP版本为例,与其他语言对比。classWxPayResultsextendsWxPayDataBase{/***生成签名-重写此方法*@paramWxPayConfigInterface$config配置对象*@parambool$needSignType是否添加signtype*@returnSignature,此函数不覆盖sign成员变量,如果你想要设置签名需要调用SetSign方法赋值*/publicfunctionMakeSign($config,$needSignType=false){//签名步骤1:参数按字典顺序排序ksort($this->values);$string=$this->ToUrlParams();//签名步骤2:在字符串$string=$string之后添加KEY。“&键=”。$config->GetKey();//签名步骤3:MD5加密或HMAC-SHA256if(strlen($this->GetSign())<=32){//如果签名小于等于32,使用md5验证$string=md5($字符串);}else{//使用sha256验证$string=hash_hmac("sha256",$string,$config->GetKey());}//签名步骤4:将所有字符转为大写$result=strtoupper($string);返回$结果;}}注意第3步是获取sign判断是用哪种方法生成sign,是否有先有鸡还是先有蛋的短路感。在APP端支付参数列表的sign参数中,有提示“注意:签名方式必须与统一下单接口使用的一致”,所以这里的逻辑是你传入由返回的sign统一的命令,以便在统一的签名方法中。签名后,一定要使用真实的签名来覆盖用于传递签名方法的“签名”。在统一下单接口中,生成签名的过程是$obj->setSign()调用$obj->makeSign(),然后我们可以$obj->getSign()为请求数据添加签名。但是在结果集类中,makeSign直接调用了getSign来决定使用哪个方法生成签名,所以在对结果集进行签名时,需要保证结果集包含同一个订单返回的sign字段数据,所以结果集可以满足“注意:签名方式必须与统一下单接口使用的一致。”所以重写这个类的签名的目的主要是保证二次签名的签名方法和统一订单的签名方法一致,将统一订单的签名作为sign传递给WxPayResults,然后调用makeSign,makeSign可以判断为下单创建一个统一的签名方法,并与其保持一致。统一下单成功接口返回的数据$uniorder=array('appid'=>'wxd930ea5d5a258f4f',//appid'device_info'=>'WEB','mch_id'=>'1900000109',//商户id'nonce_str'=>'g6OZoULWyliPmiPm','prepay_id'=>'wx12143635206473d0a53e80f14278847815','result_code'=>'SUCCESS','return_code'=>'SUCCESS','return_msg'=>'OK','sign'=>'E91035CA434EDF1',//统一订单签名'trade_type'=>'APP',)服务端需要二次签名的数据文件地址:https://pay.weixin.qq.com/wik...package暂补在固定值Sign=WXPaynoncestr中,不需要统一订单返回的nonce_str。也可以自己生成一个32位的时间戳来签名,通过统一订单返回的签名,使结果集签名和统一订单签名一致(或者你知道我知道你对结果集签名的方式是和你下单的方式一样)如果是自己写的,如果不用sdk,我们需要把数据传到$uniorder['appid'],//从统一下单的结果中得到'partnerid'=>$uniorder['mch_id'],//从统一下单的结果中得到'prepayid'=>$uniorder['prepay_id'],//统一下单结果获取'package'=>'Sign=WXPay',//自己写'noncestr'=>WxPayApi::getNonceStr();,//自己写'timestamp'=>time(),//自己写);//可以和统一订单的签名方式保持一致$sign=signMethodConsistWithUniOrder($app_result);$app_result['sign']=$sign;//返回APPreturn$$app_result;如果使用sdk,还必须将统一订单返回的数据中的签名sign传递给WxPayResults类已经确保签名方式一致$uniorder['appid'],//从统一订单的结果中取出'partnerid'=>$uniorder['mch_id'],//从统一订单的结果中取出'prepayid'=>$uniorder['prepay_id'],//从统一订单的结果中获取'sign'=>$uniorder['sign'],//用于使结果集的签名方式与统一订单签名方式一致'package'=>'Sign=WXPay',//自己写'noncestr'=>WxPayApi::getNonceStr();,//自己写'timestamp'=>time(),//自己写);$wxPayResults=newWxPayResults();//构建WxPayResults对象$wxPayResults->FromArray($app_result);//真正返回数据签名覆盖用于统一签名方法的“签名”$app_result['sign']=$wxPayResults->makeSign($wxPayConfig);//这个enupdatetosignaftersecondsignature//返回APPreturn$$app_result;app调用微信支付的方法是IWXAPIapi;PayReqrequest=newPayReq();request.appId="wxd930ea5d5a258f4f";request.partnerId="1900000109";request.prepayId="1101000000140415649af9fc314aa7",;request.packageValue="Sign=WXPay";request.nonceStr="1101000000140429eb40476f8896f4c9";request.timeStamp="1398746574";request.sign="7FFECB600D7157C5AA49810D2D8F28BC2811827B";api.sendReq(request);使用服务端提供的Thedatacaninitiateapaymentrequest
