资讯专栏INFORMATION COLUMN

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

Miracle_lihb / 3877人阅读

摘要:微信支付支付在服务端调用统一下单接口后,服务端需要将返回的订单数据进行二次签名后才能返回给端。微信支付服务端提供了类,类中也的确提供了生成签名方法,即对结果集签名,源码如下以版为例,其他语言自行对照。

获取到 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",
)
服务端需要二签的数据

文档地址:https://pay.weixin.qq.com/wik...

package 暂填写固定值Sign=WXPay

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

timestamp 自己生成即可

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

如果自己写,二不用 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;

// 返回给 APP 端
return $$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 = 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);

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

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/29953.html

相关文章

  • 一次痛苦又甜蜜的微信支付踩坑之旅

    摘要:这是我第一次接触微信支付,发现网上还是有很多同学在求助,了怎么办是什么情况为了帮助更多的小伙伴脱离苦海,我决定写下这次的踩坑之旅,给更多的人帮助。 凡是和钱打交道的事,没有一样是容易的。这是我第一次接触微信支付,发现网上还是有很多同学在求助,XXX了怎么办?XXX是什么情况?为了帮助更多的小伙伴脱离苦海,我决定写下这次的踩坑之旅,给更多的人帮助。 介绍 微信支付方式分为刷卡支付、公众号...

    vpants 评论0 收藏0
  • 一次痛苦又甜蜜的微信支付踩坑之旅

    摘要:这是我第一次接触微信支付,发现网上还是有很多同学在求助,了怎么办是什么情况为了帮助更多的小伙伴脱离苦海,我决定写下这次的踩坑之旅,给更多的人帮助。 凡是和钱打交道的事,没有一样是容易的。这是我第一次接触微信支付,发现网上还是有很多同学在求助,XXX了怎么办?XXX是什么情况?为了帮助更多的小伙伴脱离苦海,我决定写下这次的踩坑之旅,给更多的人帮助。 介绍 微信支付方式分为刷卡支付、公众号...

    DrizzleX 评论0 收藏0
  • 微信支付服务端开发总结

    摘要:前言最近应公司业务需求,把微信支付完成了,当然已经顺利上线。第三步查询订单该接口提供所有微信支付订单的查询,商户可以通过该接口主动查询订单状态,完成下一步的业务逻辑。 前言 最近应公司业务需求,把微信支付完成了,当然已经顺利上线。但是开发的过程是也是踩了很多坑,下面我就先说说开发流程,以及在开发中遇到的大大小小的坑。 开发流程 首先,看一下微信开方平台关于支付的一个时序图,如下: sh...

    马忠志 评论0 收藏0
  • 支付开发填坑记之微信支付

    摘要:前者集成在中,后者主要是为微信用户提供了另一种支付方式需要在微信的内置浏览器中打开页面,再调起微信支付。步骤商户后台收到用户支付单,调用微信支付统一下单接口。拿到所有参数后,就可以在页面中发起微信支付的请求了。 微信支付,支持的支付方式比较多:有扫码支付,刷卡支付,APP支付和公众号支付。其中,APP和网站上最常用的就是APP支付和公众号支付。前者集成在APP中,后者主要是为微信用户提...

    zhunjiee 评论0 收藏0
  • 小程序微信支付开发流程记录

    摘要:附微信支付流程微信支付流程和小程序的支付流程基本一致,需要注意两点需要在微信商户平台配置支付目录,只有跳转到了支付目录的地址,才能发起微信支付。 我所在公司需要开发一款商城小程序,里面需要用到微信支付,我负责里面的下单功能,从小程序端到后台的支付流程都是我自己开发的,由于我们组没有人有开发微信支付的经验,很多东西都还不怎么明白,但是没办法,只能我自己琢磨,写完之后总感觉有bug,但是不...

    whjin 评论0 收藏0

发表评论

0条评论

Miracle_lihb

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<