Sig计算说明



简介:
在调用midas支付API时,出于支付安全性的保证均需计算sig,支付服务器在收到sig后会核对sig 的正确性,通过sig验证的支付请求被认为是合法安全的,才能进行正常的支付流程。

工具:
1. 签名SDK下载
根据业务后台使用的开发语言,选择业务级SDK下对应语言的签名计算包,签名SDK下载计算方法参见《签名生成说明》《签名验证工具》(注:使用此工具须登录)

2. 字符转码
sig签名使用标准的URL Encoding,需要对特殊字符进行转码,具体标准参见《URLEncoding》

3. 示例
C语言示例
需要C SDK包可以联系midas提供
查看 C _SDK_V3.0.1 下tencent_sdk_lib\src\SnsSigCheck.cpp 调用计算签名方法:
string CSnsSigCheck::makeSig(string& method, string& url_path, map<string, string>& params, string& secret)
参数说明:

参数 类型 描述
method string get 或者 post
url_path string 将请求的URI路径(URI不含host,URI示例:/v3/r/mpay/buy_goods_m)。
params map 除“sig”外的所有参数
secret string 在midas申请appid时,生成的appkey,在midas系统中可以查询。
  • 注:该参数后需加&,例:string sAppKey = sAppKey "&";

返回值:

返回内容 类型 描述
签名 string 示例:IC0ErTY2gpTbNq8f1hbh0tSu1CM=

若需要有更加复杂的功能,请直接查看OpenApiV3.cpp源文件,里面提供了多种方法用于应对各种场景。回调发货场景中,应用需要对返回参数中的sig进行校验,看是否正确,可参看C _SDK_V3.0.1\example\test_verifysig.cpp.

示例代码:

#include "http_request.h"
#include "OpenApiV3.h" //生成签名参数具体参数请根据应用的实际情况,根据API的具体参数来填写
map<string, string> mSignParam;
mSignParam["openid"] = sOpenid;
mSignParam["openkey"] = sOpenkey;
mSignParam["appid"] = sAppid;
mSignParam["ts"] = sTs;
mSignParam["payitem"] = sPayitem;
mSignParam["goodsmeta"] = sGoodsmeta;
mSignParam["goodsurl"] = sGoodsurl;
mSignParam["pf"] = sPf;   //"desktop_m_qq-2001-html5-1234";
mSignParam["pfkey"] = sPfkey;  //"pfkey";
mSignParam["zoneid"] = "1";
mSignParam["appmode"] = "1";
mSignParam["app_metadata"] = sAppMetadata;
string sMethod = "GET";
string sUrlPath = "/v3/r/mpay/buy_goods_m";
string sAppKey = sAppKey   "&"; //要加&符号,估计是跟 hmac_sha1 加密的密钥构造方式有关 
//生成签名CSnsSigCheck snsSign;
string sSign = snsSign.makeSig(sMethod, sUrlPath, mSignParam, sAppKey);
//get方式
string sUrl = "http://"+sDomain   sUrlPath+"?openid="+mSignParam["openid"];
sUrl  = "&openkey="   mSignParam["openkey"];
sUrl  = "&appid="   mSignParam["appid"];
sUrl  = "&ts="   mSignParam["ts"];
sUrl  = "&payitem="   mSignParam["payitem"];
sUrl  = "&goodsmeta="   mSignParam["goodsmeta"];
sUrl  = "&goodsurl="   mSignParam["goodsurl"];
sUrl  = "&pf="   mSignParam["pf"];
sUrl  = "&pfkey="   mSignParam["pfkey"];
sUrl  = "&zoneid="   mSignParam["zoneid"];
sUrl  = "&appmode="   mSignParam["appmode"];
sUrl  = "&app_metadata="   mSignParam["app_metadata"];
sUrl  = "&sig="   sSign;
HttpRequest request; //设置cookie值具体参数请根据实际情况,填写正确的登录态信息
string sCookies="session_id=openid; session_type=kp_actoken;
org_loc=" UrlCoder::Encode("/v3/r/mpay/buy_goods_m")";
string respdata="";
string err; //初始化http请求
if(request.Init(sUrl, REQ_GET) != 0)
{
   request.GetErrorInfo(err);
   //OSS_LOG(LP_ERROR,"request init error, info=%s\n", err.c_str()); //打印日志
   sMsg = "系统繁忙!";
   return -1;
} //设置cookierequest.SetCookie(sCookies); //接收返回信息
if(request.GetResponseBody(respdata) != 0)
{
   request.GetErrorInfo(err);
   //OSS_LOG(LP_ERROR,"request get responsebody error, info=%s\n", err.c_str()); //打印日志
   sMsg = "系统繁忙!";
   return -1;
}
sRespdata = respdata;

PHP语言示例
在下载的sdk包中找到SnsSigCheck.php,调用计算签名方法:SnsSigCheck::makeSig( $method, $url_path, $params, $secret);
参数说明:

参数 类型 描述
method string get 或者 post
url_path string 将请求的URI路径(URI不含host,URI示例:/v3/r/mpay/buy_goods_m)。
params map 除“sig”外的所有参数
secret string 在midas申请appid时,生成的appkey,在midas系统中可以查询。
  • 注:PHP中该参数后需加&,例:$secret = $this->appkey . '&';

返回值:

返回内容 类型 描述
签名 string 示例:IC0ErTY2gpTbNq8f1hbh0tSu1CM=

以下代码举例在调试get_balance_m方法时计算sig签名的步骤:

include 'SnsSigCheck.php';
//设置对get_balance_m接口计算sig
$url_path='/v3/r/mpay/get_balance_m';

$appKey='EaZX46HqpjqNyKyhJlAZReqqLx4JPhbR';
$openID='oGanswb13uLoR9ujCzCIdmjBMbUA';
$openKey="11_2jgzvMqBK4GT6NJVDwR7ArrkRx5hnOpxUXRlOhLm11YyK4SXEf9tI14Fz
K4uJCFT8yX9SWM2xgxf2vUwfmrOWJsreGndvlB_M9xBV6c353g";
$appid="1450001088";
$ts=time();
$pf="qq_m_qq-1001-android-1001-qq";
$pfKey="pfkey";
$zoneid="1";
$accounttype="common";

//设置get_balance_m接口使用的参数,参数都需要参与sig的计算'''
$params['openid']=$openID;
$params['openkey']=$openKey;
//用手机QQ登录时,获取到的paytoken内容,非手Q登录态不需要该参数
$params['appid']=$appid;
$params['ts']=$ts;
//pf从msdk获取pf接口获取
$params['pf']=$pf;
//pfkey从msdk的获取pfkey接口获取
$params['pfkey']=$pfKey;
//分区ID,在分区配置里可自助配置管理
$params['zoneid']=$zoneid;

//构造密钥,请注意需要加&
$secret=$appKey.'&';
//调用SnsSigCheckModel::makeSig接口计算签名
$sig = SnsSigCheck::makeSig('GET', $url_path, $params, $secret) ;

//调用测试环境环境的支付API
$url='http://https://sandbox.api.unipay.qq.com/v3/r/mpay/get_balance_m';
$furl=$url.'?openid='.$openID.'&openkey='.$openKey.'&appid='.$appid.'&ts=
'.$ts.'&pf='.$pf.'&pfkey='.$pfKey.'&zoneid='.$zoneid.'&sig='.$sig;

echo $furl;
//用curl方式发起http请求,带上cookie
$ch = curl_init ($furl);

// 设置获取数据返回
curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, true );
// 在启用 CURLOPT_RETURNTRANSFER 时候将获取数据返回
curl_setopt ( $ch, CURLOPT_BINARYTRANSFER, true );

//设置cookie,(手Q登录态)
//手Q登录使用:openid , kp_actoken
//微信登录使用:hy_gameid, wc_actoken
$session_id= 'hy_gameid';
$session_type= 'wc_actoken';

//cookie中设置查询余额api的url
$org_loc='/v3/r/mpay/get_balance_m';
$cookie="session_id=$session_id;session_type=$session_type;org_loc=$org_loc";
curl_setopt ($ch, CURLOPT_COOKIE , $cookie );
$output = curl_exec ( $ch );

Java语言示例
在下载的sdk包中找到SnsSigCheck.java,调用计算签名方法:
public static String makeSig(String method, String url_path, HashMap<String, String> params, String secret) throws OpensnsException
参数说明:

参数 类型 描述
method string get 或者 post
url_path string 将请求的URI路径(URI不含host,URI示例:/v3/r/mpay/buy_goods_m)。
params map 除“sig”外的所有参数
secret string 在midas申请appid时,生成的appkey,在midas系统中可以查询。
  • 注:该参数后需加&,例:string sAppKey = sAppKey "&";

返回值:

返回内容 类型 描述
签名 string 示例:IC0ErTY2gpTbNq8f1hbh0tSu1CM=

计算签名示例代码:

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
// http 请求方法
String method = "GET";
// http 请求URI,用于计算签名,实际调用地址为/v3/r/mpay/buy_goods_m
String uri = "/v3/mpay/buy_goods_m";// 申请的appkey, 参数后需要加&
String appkey = "56abfbcd12fe46f5ad85ad9f12345678"   "&";
// http下订单请求参数:部分参数是从request中获取,有些是固定的(有可能需要申请),具体以文档为准
Map<String, String> params = new HashMap<String, String>();具体参数请根据应用的实际情况,根据API的要求正确填写
params.put("openid", "1234567");
params.put("openkey", "ATUSgxY2caiipUxcGo5iHfgi");
params.put("appid", "1450001304");
params.put("ts", Long.toString(System.currentTimeMillis() / 1000));
params.put("goodsmeta", "NBA积分*NBA积分购买物品");
params.put("goodsurl", "http://3gimg.qq.com/wap30/infoapp/touch/nba3/images/nba.png");
params.put("payitem", "g1*1*1");
params.put("pf", "desktop_m_qq-2001-html5-2011");
params.put("pfkey", "pfkey");
params.put("zoneid", "1");
// 可选参数,根据情况添加
params.put("app_metadata", "1234567");
params.put("userip", "xxx.xxx.xxx.xxx"); 
// 计算签名   SnsSigCheck为官方提供sdk中自带,demo不提供
String sig = SnsSigCheck.makeSig(method, uri, params, appkey);
params.put("sig", sig);
 InputStream is = null;
 try{
   // 组装URL
   String url = "http://10.130.2.233/v3/r/mpay/buy_goods_m?"   toParams(params, "&");   // 组装Cookie
   具体参数请根据实际情况,填写正确的登录态信息
   Map<String, String> cookies = new HashMap<String, String>();
   cookies.put("openid", "4575754545");
   cookies.put("openkey", "@df45DFSss");
   cookies.put("org_loc", "/v3/mpay/buy_goods_m");
   cookies.put("appip", "xxx.xxx.xxx.xxx");

   String cookie = toParams(cookies, ";");   // 发起http连接
   URL u = new URL(url);
   HttpURLConnection conn = (HttpURLConnection) u.openConnection();
   conn.setRequestMethod(method);
   conn.addRequestProperty("Cookie", cookie);
   conn.setConnectTimeout(3000);
   conn.setReadTimeout(3000);
   conn.connect();
   is = conn.getInputStream();
   String content = toString(is);
   System.out.println(content);

} catch (Exception e) {
    throw new RuntimeException(e);
} finally {
    closeQuietly(is);
}

回调发货场景中,应用需要对返回参数中的sig进行校验,请调用签名校验方法:

public static boolean verifySig(String method, String url_path, HashMap<String, 
String> params, String secret, String sig) throws OpensnsException

以上信息是否解决您的问题?

Copyright © 1998 - 2021 Tencent. All Rights Reserved.

腾讯公司 版权所有

返回顶部