取现-斗拱平台
专用API
服务商:
上海汇付支付有限公司
【更新时间: 2024.01.22】
商户主动发起将收款资金取现到绑定的银行卡;
商户开通结算的前提:渠道商端已开通取现相关权限,渠道商端权限开通仅支持在运营控台开通
取现配置:支持配置D0(取现当日到账)、D1(取现次日到账)、T1(取现次工作日到账)
咨询
去服务商官网采购>
|
服务星级:6星
浏览次数
16
采购人数
1
试用次数
0
SLA: N/A
响应: N/A
适用于个人&企业
收藏
×
完成
取消
×
书签名称
确定
|
- API详情
- 使用指南
- 常见 FAQ
- 关于我们
- 相关推荐
什么是斗拱平台的取现?
斗拱开放平台的取现服务是为商户和服务商提供的一项资金流转服务,允许商户主动发起操作,将收款资金从商户账户转移到绑定的银行卡中。这项服务支持多种取现配置,包括D0(当日到账)、D1(次日到账)和T1(次工作日到账),以满足不同商户对资金流动性的需求。商户开通结算的前提是渠道商端已开通取现相关权限,且权限开通仅支持在运营控台开通。取现服务不仅提高了资金的流转效率,还为商户提供了灵活的资金管理方式。
什么是斗拱平台的取现?
斗拱平台的取现有哪些核心功能?
1. 多模式取现配置:取现服务支持D0、D1和T1三种取现模式,商户可以根据自身的业务需求和资金流转需求,选择合适的到账时间,实现资金的快速流转或计划性管理。
2. 灵活的资金管理:商户可以通过取现服务,灵活管理自己的资金流,无论是日常经营的资金需求,还是应对突发事件的资金调配,都能得到有效的支持。
3. 安全的交易保障:取现服务提供了严格的安全措施,包括密钥获取和公共参数获取等,确保每一笔取现交易的安全性和可靠性。
4. 详细的交易记录:商户可以通过取现服务查询每一笔取现交易的详细记录,包括取现金额、到账时间等,帮助商户进行财务核算和资金流分析。
5. 便捷的操作流程:取现服务的操作流程简洁明了,商户可以在商户控台轻松完成取现操作,无需复杂的步骤,提高了操作的便捷性。
6. 实时的技术支持:服务商控台提供了取现配置操作指引,商户在遇到问题时可以快速获得技术支持,确保取现服务的顺畅进行。
斗拱平台的取现的核心优势是什么?
1. 提高资金流动性:取现服务使得商户能够根据需要快速将资金从商户账户转移到银行卡,极大地提高了资金的流动性和使用效率。
2. 灵活的到账时间选择:商户可以根据自己的业务需求选择当日到账、次日到账或次工作日到账,这种灵活性使得资金管理更加贴合商户的实际运营情况。
3. 增强资金安全性:通过严格的安全措施和密钥管理,取现服务确保了资金转移的安全性,降低了资金流转过程中的风险。
4. 优化财务核算:详细的交易记录和查询功能使得商户能够轻松进行财务核算,提高了财务管理的效率和准确性。
5. 提升操作便捷性:简洁的操作流程和商户控台的便捷性使得商户可以快速完成取现操作,无需复杂的步骤,节省了商户的时间和人力资源。
6. 强大的技术支持:服务商控台提供的详细操作指引和技术支持,使得商户在遇到问题时能够得到及时的帮助,确保了取现服务的顺利进行。
斗拱平台的取现有哪些使用限制?
1. 取现业务类型:支持D0、D1和T1部分及全部勾选。
2. 取现手续费配置:配置D0、D1、T1取现手续费及取现手续费率。
3. 取现手续费扣款方式:开通时配置取现手续费只支持统一选择内扣或外扣,变更时,支持单个取现类型分别设置内扣或外扣。
4. 取现手续费计算:取现手续费=手续费固定金额+取现费率%*取现金额。
5. 接口取现目前仅支持基本户提现。
在哪些场景会用到斗拱平台的取现?
1. 商户日常资金流转
在日常经营活动中,商户经常需要将通过各种支付渠道收取的资金汇总并转入指定的银行卡,以用于支付货款、发放工资、支付租金等日常运营开支。斗拱开放平台的取现服务提供了灵活的到账时间选择,商户可以根据自己的资金需求,选择当日到账、次日到账或次工作日到账,确保资金能够及时到位。便捷的操作流程使得商户在忙碌的经营中也能快速完成资金的转移,大大提高了资金流转的效率。一家零售连锁店在每天营业结束后,需要将当天的收入汇总并转入公司账户,以便第二天支付供应商货款,取现服务的高效性确保了资金的及时流转,支持了企业的日常运营。
2. 应急资金调配
在商业运营中,商户可能会遇到突发事件,如供应链中断、紧急设备维修或市场机会出现等,这些情况都可能需要商户迅速调配资金以应对。取现服务的即时性和灵活性使得商户可以在最短时间内将资金转移到需要的地方。一家工厂突然接到一个大订单,需要立即购买额外的原材料,通过取现服务,工厂可以将资金快速转移到供应商账户,确保订单能够及时完成,抓住市场机会。
3. 财务核算和资金流分析
商户需要定期进行财务核算和资金流分析,以评估业务表现和优化资金管理。斗拱开放平台的取现服务提供了详细的交易记录查询功能,商户可以轻松获取每一笔取现交易的详细信息,包括交易时间、金额和到账时间等。这些数据对于财务团队来说至关重要,它们可以用来核对账目、分析现金流趋势和预测未来的资金需求。一家电子商务公司在每个季度末需要进行财务审计,通过取现服务提供的详细记录,财务团队可以准确地追踪资金流向,确保财务报告的准确性。
4. 资金规划和管理
对于需要进行长期资金规划的商户来说,选择合适的取现模式是实现资金计划性管理的关键。斗拱开放平台的取现服务允许商户根据业务周期和资金需求,选择最合适的取现时间,从而更好地规划资金使用。一家酒店可能在旅游旺季需要更多的流动资金来应对客流量的增加,通过选择D0或D1取现模式,酒店可以确保在需要时有足够的现金储备,以支持日常运营和应对突发事件。
5. 提高资金使用效率
资金使用效率的提升对于任何企业来说都是至关重要的。斗拱开放平台的取现服务通过提供快速的资金转移,帮助商户减少了资金在途时间,加快了资金周转。这意味着商户可以更快地回收资金,并将这些资金重新投入到业务中,以产生更多的收入。一家批发商在完成销售后,需要快速将资金回笼以支付给供应商和补充库存,取现服务的高效率使得资金能够迅速回流,支持了业务的连续性。
6. 增强资金安全性
在资金流转过程中,安全性是商户最为关心的问题之一。斗拱开放平台的取现服务提供了严格的安全措施,包括密钥管理和交易加密,确保了资金转移的安全性。这降低了资金在流转过程中的风险,保护了商户的资金安全。一家在线支付服务提供商需要处理大量的客户交易,通过使用取现服务,公司可以确保每一笔交易都是安全的,从而保护了公司和客户的资金不受网络攻击和欺诈行为的影响。
v2版接口加签验签
最近更新时间:2024.9.1
适用范围
所有以下出口接口: https://api.huifu.com/v2/
公私钥
查看联调公私参数获取说明;
參數形式
- 接口都是以POST方法请求一个完整的JSON对象(不是JSON字符串)
- body.data 是完整的业务参数
- body.data是JSON对象,不是JSON字符串
- body.data内层复杂对象类型请参考API文档(大部分是字符串类型)
- 详细样例,请参考具体文档或者下面的例子
- body.data提出了完整的业务参数,第一层是基本类型(String、Int),没有复杂类型JSON
- body.data第一层所有提交的参数参与签名
如果出现楼层,则以JSON字符串形式传递。例如下面的terminal_device_info
{
"sys_id":"test",
"product_id":"HSK",
“data”: {
"devs_id": "TYXJL0623715525894234",
"auth_code": "134558771750600000",
"terminal_device_info": "{\"devs_id\":\"TYXJL0623715525894234\"}"
},
“sign”:”签名”
}复制代码复制失败复制成功
如何加签
只需对body.data中的内容进行加签。
- body.data中的数据,去掉换行、空格等格式字符后,按照参数字典顺序排序生成字符串(参数名ASCII码到大排序(字典序);参数名区分大小写;)以上文为排序后
{
"auth_code": "134558771750600000",
"devs_id": "TYXJL0623715525894234",
"terminal_device_info": "{\"devs_id\":\"TYXJL0623715525894234\"}"
}复制代码复制失败复制成功
注:如果是JSON字符串,不需要进行排序,例如terminal_device_info的值不需要排序
- 对第一步生成的字符串结合您的私钥进行加签;注:如果你有自己的私钥可以用自己的。如果没有看到联调公私钥参数获取后续说明
- 首先将json对象按照参数字典顺序(参数名ASCII码到大排序,参数名区分大小写)排序生成字符串,然后进行加签和验签。
JSON数据排序代码示例
java代码示例
import java.util.TreeMap;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
JSON.toJSONString(JSONObject.parseObject(inputDataJSON, TreeMap.class))复制代码复制失败复制成功
python代码示例
# json 数据排序示例
def sort_dict(params):
"""
排序json 对象,按ASCII顺序排序。多层结构只排序第一层
:param params:
:return:
"""
keys = sorted(params.keys())
result = {}
for key in keys:
value = params.get(key)
if type(value).__name__ == 'dict':
result[key] = value
elif type(value).__name__ == 'list' and len(value) != 0:
result[key] = params.get(key)
elif params.get(key) is not None:
result[key] = params.get(key)
return result复制代码复制失败复制成功
PHP代码示例
/** @param array $data 原数据( 排序后的json字符串; 数组参数排序后转json字符串(数据的中文和斜杠均不转码):**/
ksort($post_data);
json_encode($post_data, JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE); )复制代码复制失败复制成功
C#代码示例
//排序
public static string sort4JsonString(string sourceJson)
{
var dic = JsonConvert.DeserializeObject<SortedDictionary<string, object>>(sourceJson);
SortedDictionary<string, object> keyValues = new SortedDictionary<string, object>(dic);
var result = keyValues.OrderBy(m => m.Key);//升序 把Key换成Value 就是对Value进行排序
//var result = keyValues.OrderByDescending(m => m.Key);//降序
//简化为如下代码
Dictionary<string, object> resultDic = result.ToDictionary(x => x.Key, x => x.Value);
return JsonConvert.SerializeObject(resultDic);
}复制代码复制失败复制成功
- 概要如下
java代码示例
/**
* RSA私钥签名:签名方式SHA256WithRSA
* @param data 待签名字符串
* @param privateKeyBase64 私钥(Base64编码)
* @return 签名byte[]
* @throws Exception
*/
public static String sign(String data, String privateKeyBase64) {
// Base64 --> Key
try {
byte[] bytes = Base64.getDecoder().decode(privateKeyBase64);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(bytes);
KeyFactory keyFactory;
keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
// Sign
Signature signature = Signature.getInstance("SHA256WithRSA");
signature.initSign(privateKey);
signature.update(data.getBytes("UTF-8"));
return Base64.getEncoder().encodeToString(signature.sign());
} catch (Exception e) {
return null;
}
}复制代码复制失败复制成功
python代码示例
# 私钥加签
def rsa_sign(private_key, message, charset='utf-8'):
try:
private_key = add_start_end(private_key, "-----BEGIN PRIVATE KEY-----\n", "\n-----END PRIVATE KEY-----")
msg = message.encode(charset)
private_key = RSA.importKey(private_key)
# message做“哈希”处理,RSA签名这么要求的
hash_obj = SHA256.new(msg)
signature = pkcs1_15.new(private_key).sign(hash_obj)
return True, base64.b64encode(signature).decode(charset)
except Exception as ex:
return False, str(ex)复制代码复制失败复制成功
PHP代码示例
/**
* 私钥加签(对数据源排序),可用于 V2 版本接口数据加签
*
* @param array $data 原数据( 排序后的json字符串; 数组参数排序后转json字符串(数据的中文和斜杠均不转码):
ksort($post_data); json_encode($post_data, JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE); )
*
* @param string $rsaPrivateKey 私钥
* @param int $alg 默认 OPENSSL_ALGO_SHA256
*
* @return string 签名串
*/
function sha_with_rsa_sign($data, $rsaPrivateKey, $alg=OPENSSL_ALGO_SHA256){
$key = "-----BEGIN PRIVATE KEY-----\n".wordwrap($rsaPrivateKey, 64, "\n", true)."\n-----END PRIVATE KEY-----";
$signature= '';
try {
openssl_sign($data, $signature, $key, $alg);
} catch (\Exception $e) {
echo $e->getMessage();
}
return base64_encode($signature);
}复制代码复制失败复制成功
C#代码示例
//私钥加签
public static string sign(string signaturePrivateKey, string signatureData, string hashAlgorithm = "SHA256", string encoding = "UTF-8")
{
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
// var privateJavaKey = signaturePrivateKey;
// var privateCSharpKey = RSAPrivateKeyJava2DotNet(privateJavaKey);
// rsa.FromXmlString(privateCSharpKey);
rsa.FromPrivateKeyJavaString(signaturePrivateKey);
byte[] signatureBytes = rsa.SignData(Encoding.GetEncoding(encoding).GetBytes(signatureData), hashAlgorithm);
return Convert.ToBase64String(signatureBytes);
}复制代码复制失败复制成功
提示:您可以通过斗拱CLI工具提供的verify_sign命令验证生成的签文是否正确;参见CLI工具介绍
如何签
仅对数据中的内容进行验签
- 数据中的数据,同步返参参数字典顺序排序生成字符串,自动返参不需要排序。
以上文为例整理后
{
"auth_code": "134558771750600000",
"devs_id": "TYXJL0623715525894234",
"terminal_device_info": "{\"devs_id\":\"TYXJL0623715525894234\"}"
}复制代码复制失败复制成功
注:如果是JSON字符串,不需要进行排序,例如terminal_device_info不需要排序;
- 对第一步生成的字符串结合斗拱平台进行验签
- 經驗訂閱如下
java代码示例
/**
* 使用汇付RSA公钥验签
* @param data 待签名字符串
* @param publicKeyBase64 公钥(Base64编码)
* @return 验签结果
* @throws Exception
*/
public static boolean verify(String data, String publicKeyBase64, String sign) {
// Base64 --> Key
try {
byte[] bytes = Base64.getDecoder().decode(publicKeyBase64);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(bytes);
KeyFactory keyFactory;
keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(keySpec);
// verify
Signature signature = Signature.getInstance("SHA256WithRSA");
signature.initVerify(publicKey);
signature.update(data.getBytes("UTF-8"));
return signature.verify(Base64.getDecoder().decode(sign));
} catch (Exception e) {
logger.error("Exception", e);
return false;
}
}复制代码复制失败复制成功
python代码示例
# 使用汇付公钥验签
def rsa_design(signature, message, my_rsa_public):
try:
my_rsa_public = fill_public_key_marker(my_rsa_public)
message = message.encode("utf-8")
public_key = RSA.importKey(my_rsa_public)
# message做“哈希”处理,RSA签名这么要求的
hash_obj = SHA256.new(message)
pkcs1_15.new(public_key).verify(hash_obj, base64.b64decode(signature))
return True, ''
except (ValueError, TypeError) as ex:
return False, str(ex)复制代码复制失败复制成功
PHP代码示例
/**
* 汇付公钥验签(对数据源排序),可用于 V2 版本接口返回数据验签
*
* @param string $signature 签文
* @param array $data 原数据(array)
* @param string $rsaPublicKey 公钥
* @param int $alg 默认 OPENSSL_ALGO_SHA256
*
* @return false|int 验证结果:成功/失败
*/
function verifySign_sort($signature, $data, $rsaPublicKey, $alg=OPENSSL_ALGO_SHA256){
$key = "-----BEGIN PUBLIC KEY-----\n".wordwrap($rsaPublicKey, 64, "\n", true)."\n-----END PUBLIC KEY-----";
ksort($data);
return openssl_verify(json_encode($data, JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE), base64_decode($signature), $key, $alg);
}复制代码复制失败复制成功
C#代码示例
//使用汇付公钥验签
public static bool verfySign(string publicKey, string signature, string content, string hashAlgorithm = "SHA256", string encoding = "UTF-8")
{
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
//导入公钥,准备验证签名
rsa.FromPublicKeyJavaString(publicKey);
//返回数据验证结果
byte[] Data = Encoding.GetEncoding(encoding).GetBytes(content);
byte[] rgbSignature = Convert.FromBase64String(signature);
return rsa.VerifyData(Data, hashAlgorithm, rgbSignature);
}
汇付天下成立于2006年7月,是国内领先的数字化支付企业,旨在为企业收款、数据集成和资金管理提供平台服务。汇付一路在技术实践、商业模式、解决方案等领域开创行业先河,在业内率先开启全方位的数字化转型,首创支付PaaS“斗拱平台”,践行 Payment&Beyond 发展战略,与各方共建数字生态。
秉持“一切以客户为中心”的发展宗旨,汇付面向品牌连锁、集团企业、互联网平台、跨境国际、数字经济、小微商户等行业场景,携手数百家知名SaaS/软件公司、商业银行以及数十万渠道服务商等合作伙伴,提供全渠道收款和数据管理、智能对账、供应链资金结算、数电发票、数字权益、跨云IaaS集成等一站式数字化解决方案,助力上万家行业客户与千万中小微商户实现降本、提效、增长的转型目标。
v2版接口加签验签
最近更新时间:2024.9.1
适用范围
所有以下出口接口: https://api.huifu.com/v2/
公私钥
查看联调公私参数获取说明;
參數形式
- 接口都是以POST方法请求一个完整的JSON对象(不是JSON字符串)
- body.data 是完整的业务参数
- body.data是JSON对象,不是JSON字符串
- body.data内层复杂对象类型请参考API文档(大部分是字符串类型)
- 详细样例,请参考具体文档或者下面的例子
- body.data提出了完整的业务参数,第一层是基本类型(String、Int),没有复杂类型JSON
- body.data第一层所有提交的参数参与签名
如果出现楼层,则以JSON字符串形式传递。例如下面的terminal_device_info
{
"sys_id":"test",
"product_id":"HSK",
“data”: {
"devs_id": "TYXJL0623715525894234",
"auth_code": "134558771750600000",
"terminal_device_info": "{\"devs_id\":\"TYXJL0623715525894234\"}"
},
“sign”:”签名”
}复制代码复制失败复制成功
如何加签
只需对body.data中的内容进行加签。
- body.data中的数据,去掉换行、空格等格式字符后,按照参数字典顺序排序生成字符串(参数名ASCII码到大排序(字典序);参数名区分大小写;)以上文为排序后
{
"auth_code": "134558771750600000",
"devs_id": "TYXJL0623715525894234",
"terminal_device_info": "{\"devs_id\":\"TYXJL0623715525894234\"}"
}复制代码复制失败复制成功
注:如果是JSON字符串,不需要进行排序,例如terminal_device_info的值不需要排序
- 对第一步生成的字符串结合您的私钥进行加签;注:如果你有自己的私钥可以用自己的。如果没有看到联调公私钥参数获取后续说明
- 首先将json对象按照参数字典顺序(参数名ASCII码到大排序,参数名区分大小写)排序生成字符串,然后进行加签和验签。
JSON数据排序代码示例
java代码示例
import java.util.TreeMap;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
JSON.toJSONString(JSONObject.parseObject(inputDataJSON, TreeMap.class))复制代码复制失败复制成功
python代码示例
# json 数据排序示例
def sort_dict(params):
"""
排序json 对象,按ASCII顺序排序。多层结构只排序第一层
:param params:
:return:
"""
keys = sorted(params.keys())
result = {}
for key in keys:
value = params.get(key)
if type(value).__name__ == 'dict':
result[key] = value
elif type(value).__name__ == 'list' and len(value) != 0:
result[key] = params.get(key)
elif params.get(key) is not None:
result[key] = params.get(key)
return result复制代码复制失败复制成功
PHP代码示例
/** @param array $data 原数据( 排序后的json字符串; 数组参数排序后转json字符串(数据的中文和斜杠均不转码):**/
ksort($post_data);
json_encode($post_data, JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE); )复制代码复制失败复制成功
C#代码示例
//排序
public static string sort4JsonString(string sourceJson)
{
var dic = JsonConvert.DeserializeObject<SortedDictionary<string, object>>(sourceJson);
SortedDictionary<string, object> keyValues = new SortedDictionary<string, object>(dic);
var result = keyValues.OrderBy(m => m.Key);//升序 把Key换成Value 就是对Value进行排序
//var result = keyValues.OrderByDescending(m => m.Key);//降序
//简化为如下代码
Dictionary<string, object> resultDic = result.ToDictionary(x => x.Key, x => x.Value);
return JsonConvert.SerializeObject(resultDic);
}复制代码复制失败复制成功
- 概要如下
java代码示例
/**
* RSA私钥签名:签名方式SHA256WithRSA
* @param data 待签名字符串
* @param privateKeyBase64 私钥(Base64编码)
* @return 签名byte[]
* @throws Exception
*/
public static String sign(String data, String privateKeyBase64) {
// Base64 --> Key
try {
byte[] bytes = Base64.getDecoder().decode(privateKeyBase64);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(bytes);
KeyFactory keyFactory;
keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
// Sign
Signature signature = Signature.getInstance("SHA256WithRSA");
signature.initSign(privateKey);
signature.update(data.getBytes("UTF-8"));
return Base64.getEncoder().encodeToString(signature.sign());
} catch (Exception e) {
return null;
}
}复制代码复制失败复制成功
python代码示例
# 私钥加签
def rsa_sign(private_key, message, charset='utf-8'):
try:
private_key = add_start_end(private_key, "-----BEGIN PRIVATE KEY-----\n", "\n-----END PRIVATE KEY-----")
msg = message.encode(charset)
private_key = RSA.importKey(private_key)
# message做“哈希”处理,RSA签名这么要求的
hash_obj = SHA256.new(msg)
signature = pkcs1_15.new(private_key).sign(hash_obj)
return True, base64.b64encode(signature).decode(charset)
except Exception as ex:
return False, str(ex)复制代码复制失败复制成功
PHP代码示例
/**
* 私钥加签(对数据源排序),可用于 V2 版本接口数据加签
*
* @param array $data 原数据( 排序后的json字符串; 数组参数排序后转json字符串(数据的中文和斜杠均不转码):
ksort($post_data); json_encode($post_data, JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE); )
*
* @param string $rsaPrivateKey 私钥
* @param int $alg 默认 OPENSSL_ALGO_SHA256
*
* @return string 签名串
*/
function sha_with_rsa_sign($data, $rsaPrivateKey, $alg=OPENSSL_ALGO_SHA256){
$key = "-----BEGIN PRIVATE KEY-----\n".wordwrap($rsaPrivateKey, 64, "\n", true)."\n-----END PRIVATE KEY-----";
$signature= '';
try {
openssl_sign($data, $signature, $key, $alg);
} catch (\Exception $e) {
echo $e->getMessage();
}
return base64_encode($signature);
}复制代码复制失败复制成功
C#代码示例
//私钥加签
public static string sign(string signaturePrivateKey, string signatureData, string hashAlgorithm = "SHA256", string encoding = "UTF-8")
{
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
// var privateJavaKey = signaturePrivateKey;
// var privateCSharpKey = RSAPrivateKeyJava2DotNet(privateJavaKey);
// rsa.FromXmlString(privateCSharpKey);
rsa.FromPrivateKeyJavaString(signaturePrivateKey);
byte[] signatureBytes = rsa.SignData(Encoding.GetEncoding(encoding).GetBytes(signatureData), hashAlgorithm);
return Convert.ToBase64String(signatureBytes);
}复制代码复制失败复制成功
提示:您可以通过斗拱CLI工具提供的verify_sign命令验证生成的签文是否正确;参见CLI工具介绍
如何签
仅对数据中的内容进行验签
- 数据中的数据,同步返参参数字典顺序排序生成字符串,自动返参不需要排序。
以上文为例整理后
{
"auth_code": "134558771750600000",
"devs_id": "TYXJL0623715525894234",
"terminal_device_info": "{\"devs_id\":\"TYXJL0623715525894234\"}"
}复制代码复制失败复制成功
注:如果是JSON字符串,不需要进行排序,例如terminal_device_info不需要排序;
- 对第一步生成的字符串结合斗拱平台进行验签
- 經驗訂閱如下
java代码示例
/**
* 使用汇付RSA公钥验签
* @param data 待签名字符串
* @param publicKeyBase64 公钥(Base64编码)
* @return 验签结果
* @throws Exception
*/
public static boolean verify(String data, String publicKeyBase64, String sign) {
// Base64 --> Key
try {
byte[] bytes = Base64.getDecoder().decode(publicKeyBase64);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(bytes);
KeyFactory keyFactory;
keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(keySpec);
// verify
Signature signature = Signature.getInstance("SHA256WithRSA");
signature.initVerify(publicKey);
signature.update(data.getBytes("UTF-8"));
return signature.verify(Base64.getDecoder().decode(sign));
} catch (Exception e) {
logger.error("Exception", e);
return false;
}
}复制代码复制失败复制成功
python代码示例
# 使用汇付公钥验签
def rsa_design(signature, message, my_rsa_public):
try:
my_rsa_public = fill_public_key_marker(my_rsa_public)
message = message.encode("utf-8")
public_key = RSA.importKey(my_rsa_public)
# message做“哈希”处理,RSA签名这么要求的
hash_obj = SHA256.new(message)
pkcs1_15.new(public_key).verify(hash_obj, base64.b64decode(signature))
return True, ''
except (ValueError, TypeError) as ex:
return False, str(ex)复制代码复制失败复制成功
PHP代码示例
/**
* 汇付公钥验签(对数据源排序),可用于 V2 版本接口返回数据验签
*
* @param string $signature 签文
* @param array $data 原数据(array)
* @param string $rsaPublicKey 公钥
* @param int $alg 默认 OPENSSL_ALGO_SHA256
*
* @return false|int 验证结果:成功/失败
*/
function verifySign_sort($signature, $data, $rsaPublicKey, $alg=OPENSSL_ALGO_SHA256){
$key = "-----BEGIN PUBLIC KEY-----\n".wordwrap($rsaPublicKey, 64, "\n", true)."\n-----END PUBLIC KEY-----";
ksort($data);
return openssl_verify(json_encode($data, JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE), base64_decode($signature), $key, $alg);
}复制代码复制失败复制成功
C#代码示例
//使用汇付公钥验签
public static bool verfySign(string publicKey, string signature, string content, string hashAlgorithm = "SHA256", string encoding = "UTF-8")
{
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
//导入公钥,准备验证签名
rsa.FromPublicKeyJavaString(publicKey);
//返回数据验证结果
byte[] Data = Encoding.GetEncoding(encoding).GetBytes(content);
byte[] rgbSignature = Convert.FromBase64String(signature);
return rsa.VerifyData(Data, hashAlgorithm, rgbSignature);
}
汇付天下成立于2006年7月,是国内领先的数字化支付企业,旨在为企业收款、数据集成和资金管理提供平台服务。汇付一路在技术实践、商业模式、解决方案等领域开创行业先河,在业内率先开启全方位的数字化转型,首创支付PaaS“斗拱平台”,践行 Payment&Beyond 发展战略,与各方共建数字生态。
秉持“一切以客户为中心”的发展宗旨,汇付面向品牌连锁、集团企业、互联网平台、跨境国际、数字经济、小微商户等行业场景,携手数百家知名SaaS/软件公司、商业银行以及数十万渠道服务商等合作伙伴,提供全渠道收款和数据管理、智能对账、供应链资金结算、数电发票、数字权益、跨云IaaS集成等一站式数字化解决方案,助力上万家行业客户与千万中小微商户实现降本、提效、增长的转型目标。