getPrepayId php,获取到 prepay_id 后将参数再次签名传输给 APP 发起支付

获取到 prepay_id 后将参数再次签名传输给 APP 发起支付。

相信有不少同学因为看到统一下单返回的结果中有 sign 字段,会直接将结果返回给 APP 端,结果 APP 端没办法调起微支付。其实需要对 APP 端用到的字段数据按 “统一下单的签名方式” 签名后得到的 sign,才是 APP 端需要的 sign。

微信支付 App支付 在服务端调用统一下单接口后,服务端需要将返回的订单数据进行二次签名后才能返回给 App 端。开发文档中说的并不是很明确,因为统一下单的返回数据和二签的原数据上存在一些重叠。

微信支付服务端 sdk 提供了 WxPayResults 类,类中也的确提供了生成签名方法,即对结果集签名,源码如下:

以 PHP 版为例,其他语言自行对照。

class WxPayResults extends WxPayDataBase

{

/**

* 生成签名 - 重写该方法

* @param WxPayConfigInterface $config 配置对象

* @param bool $needSignType 是否需要补signtype

* @return 签名,本函数不覆盖sign成员变量,如要设置签名需要调用SetSign方法赋值

*/

public function MakeSign($config, $needSignType = false)

{

//签名步骤一:按字典序排序参数

ksort($this->values);

$string = $this->ToUrlParams();

//签名步骤二:在string后加入KEY

$string = $string . "&key=" . $config->GetKey();

//签名步骤三:MD5加密或者HMAC-SHA256

if (strlen($this->GetSign()) <= 32) {

//如果签名小于等于32个,则使用md5验证

$string = md5($string);

} else {

//是用sha256校验

$string = hash_hmac("sha256", $string, $config->GetKey());

}

//签名步骤四:所有字符转为大写

$result = strtoupper($string);

return $result;

}

}

注意步骤三,是需要获取 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' => 'E91035CA24EDF115374BD2B4C4F9B419',//统一下单的签名

'trade_type' => 'APP',

)

服务端需要二签的数据

bVbm8j2?w=931&h=448

package 暂填写固定值Sign=WXPay

noncestr 并不一定要统一下单返回的 nonce_str,自己生成 32位 的也可以

timestamp 自己生成即可

sign 传递统一下单返回的签名,以使得结果集签名和统一下单签名方式一致(或者你清楚的知道你对结果集签名的方式同下单的一致)

如果自己写,二不用 sdk 的话,我们需要对

// 传递的数据

$app_result = array (

'appid' => $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;

// 返回给 APP 端

return $$app_result;

如果用 sdk 的务必要将 统一下单返回的数据里的签名 sign 也传递给 WxPayResults 类,已使得保证签名方式一致

// 传递的数据

// 传递的数据

$app_result = array (

'appid' => $uniorder['appid'],//从统一下单的结果中取

'partnerid' => $uniorder['mch_id'],//从统一下单的结果中取

'prepayid' => $uniorder['prepay_id'],//从统一下单的结果中取

'sign' => $uniorder['sign'],//用来使结果集签名方式与统一下单签名方式一致

'package' => 'Sign=WXPay',//自己写

'noncestr' => WxPayApi::getNonceStr();,//自己写

'timestamp ' => time(),//自己写

);

$wxPayResults = new WxPayResults();

// 构建 WxPayResults 对象

$wxPayResults->FromArray($app_result);

// 真正的返回数据的签名 覆盖用来统一签名方式的“签名”

$app_result['sign'] = $wxPayResults->makeSign($wxPayConfig);//然后更新成二签后的sign

// 返回给 APP 端

return $$app_result;

App 端调用微信支付的方式为

IWXAPI api;

PayReq request = new PayReq();

request.appId = "wxd930ea5d5a258f4f";

request.partnerId = "1900000109";

request.prepayId= "1101000000140415649af9fc314aa427",;

request.packageValue = "Sign=WXPay";

request.nonceStr= "1101000000140429eb40476f8896f4c9";

request.timeStamp= "1398746574";

request.sign= "7FFECB600D7157C5AA49810D2D8F28BC2811827B";

api.sendReq(request);

使用服务端提供的数据发起支付请求即可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值