PC端应用订阅SDK接入攻略
本文档介绍了联想应用联运sdk接入操作指南,您可在了解文档内容后,自行接入应用联运sdk。
1. 接入前准备
1. 请先与联想商务达成合作意向。
2. 联系联想运营,提供应用和公司信息,并获取商户id、app id、key(公私钥、用于登录和支付校验)、SDK包。
3. 以下为需提供的信息:
1) 商户名称(例:xxx公司)
2) 应用名称
3) 应用图标(建议像素:36*36,png格式
2. 联运SDK接入须知
应用联运支持SDK目前支持版本为windows10及以上版本,具体信息请与我司商务进行咨询。
3. PC端SDK及接入文档下载地址:
下载地址:联想乐云
(密码:ksk3)
4. 简介
4.1. 阅读对象说明
研发工程师、测试工程师、产品经理
4.2. 接入订阅服务流程
1. 联系联想商业化运营,提供应用和公司信息,获取商户id、appid、key(公私钥、用于登录和支付校验)、PC端订阅SDK下载地址
2. 接入PC端订阅SDK (登录+支付)
3. 接入退款API(可选)
4.3. 名词解释
名词 | 解释说明 |
订阅SDK | 指本SDK,由联想提供,用于接入联想的各种基础服务 |
接入方 | 指接入该订阅SDK基础服务的各种三方应用 |
LID | LenovoID,即用户登录联想账号后生成的唯一用户ID |
单点登录登出 | 使用该订阅SDK的不同应用,在同一台设备上会保持相同的登录状态:A应用登录LID账号后,B应用的LID账号也是登录状态的;B应用登出后,A应用也是登出状态 |
自动登录 | 接入方应用登录后,关闭该应用,登录状态会被保留在设备本地,下次应用再启动后,通过调用接口 LYSDK_LidGetLoginStatus 实现自动登录 |
应用私钥 | 商户向订阅服务端发起请求(查询、退款等API接口),进行签名;订阅服务端使用应用公钥验签 |
平台公钥 | 订阅服务端向商户发起通知(支付通知、退款通知),进行签名; 商户使用平台公钥验签 |
5. 应用订阅接入介绍
PC端订阅SDK提供联想账号登录,以及支付功能;支付包括使用联想账号支付、使用非联想账号支付以及设备账号支付,若接入联想账号则使用联想账号支付,否则使用非联想账号支付。
5.1. 支付接入介绍
1. 订阅服务提供的支付能力包括支付、7天无理由退款。
2. 支付的接入,需在应用集成订阅SDK后,调用订阅SDK的支付接口,打开联想通用收银台。
3. 7天无理由退款服务包括应用内无理由退款和联想软件商店内无理由退款两个入口。
a) 应用内无理由退款
i. 退款的接入以CP直接调用服务端退款接口实现,待退款审核通过后通知CP
ii. 满足退款条件的订单,经审核后(周期1-2个工作日),原路退全款至用户账户
iii. 不满足退款条件的订单,接口返回失败,不执行退款流程
b) 联想软件商店内无理由退款
i. 该退款入口不需要CP开发,但需要CP提供退款通知地址,用于用户在联想软件商店内退款成功后,通过该地址进行退款成功的通知,再由CP进行权益变更的操作
5.2. 支付流程介绍
1. CP创建业务订单,确定支付产品编码,调用创单接口
2. 产品编码选择COMMON_CASHIER、COMMON_DK_CASHIER,调起联想通用收银台;
3. 用户在联想通用收银台中扫码支付,支付成功后PC端订阅SDK会同步返回支付结果给应用客户端,且订阅服务也会异步通知CP服务端支付结果。注意:用户权益的变更,需以服务端的通知结果为准。
5.3. 周期扣款接入介绍
1. 订阅服务提供的周期扣款能力是用户在支付时,与支付宝、微信签约代扣协议,按照协议完成后续扣款;
2. 应用内有周期扣款需求的接入方需在支付接口里传入代扣相关字段;
3. 为了保持良好的用户体验,联想侧要求在支付宝/微信的签约页面显示完整的用户信息,若未接入联想账号登录功能的应用,需传入用户id、用户账号等信息。
4. 接入周期扣款后,用户初次签约并支付时,由cp向订阅服务发起支付请求,后续扣款由订阅服务发起,收到三方支付渠道(支付宝、微信)的扣款通知后,订阅服务将扣款成功通知发送给cp服务端;
5. 支持cp主动查询协议信息,可避免因服务不稳定导致的未收到解约通知的问题。
5.4. 退款功能说明
1. 退款功能说明
- 订阅服务支持7天无理由退款能力,退款条件:
(1) 每个应用每个用户只有一次无理由退款权力
(2) 自支付成功时起7日内
- 订阅服务提供cp应用内退款的能力,以调用服务端接口(详见文档章节4.5)实现
(1) 满足退款条件的订单,经我方人工审核后(周期1-2天),原路退全款至用户账户
(2) 不满足退款条件的订单,接口返回失败,不执行退款流程
2. 退款时序
6. PC端订阅SDK接入
6.1. 发行包介绍
发行包内容 | 解释说明 |
订阅SDK动态库 | 联运SDK的主要功能载体,包含LYSDK2.dll,LsfSdk.dll和WebView2Loader.dll,接入方应用发布时,需要带上这三个DLL动态库,并确保这三个文件放在一个目录下 |
订阅SDK测试程序 | 使用联运SDK动态库的测试程序(测试程序.exe),通过运行这个测试程序,可以体验SDK各个接口的功能 |
订阅SDK头文件和静态库 | 给开发使用的,接入方应用发布时,并不需要带上这部分 |
订阅SDK2.0包含LYRelease32和LYRelease64两个目录,分别对应32位版本和64位版本,32位的接入方应用使用LYRelease32目录中的接口文件,64位的接入方应用使用LYRelease64目录中的接口文件,具体如下图所示:
以32位版本为例,具体如下图所示:
LYSDK2.dll是订阅SDK的核心动态库,通过其文件属性中的产品版本来查看订阅SDK的版本号信息,具体如下图所示:
6.2. 接口约定说明
参数约定 | |
char * | 字符串必须使用UTF8编码,便于跨语言接入 |
[in] | 表示这个参数是接入方传入给订阅SDK的参数 |
[out] | 表示这个参数是订阅SDK返回给接入方的参数 |
返回值约定 | |
0 | 成功 |
大于0 | 失败 (不同的整数编码不同的错误) |
6.3. 登录功能相关接口
6.3.1. 数据结构定义
"loginInfo": {
"version":"1.0" , //Json结构的版本号信息,便于后续扩展
"loginstatus":true/false,//bool类型,表示LID账号是否已经登录
"token":"abcd"/"null" //token信息,如果token无效,将返回“null”字符串
}
loginInfo 是Json(不是XML)结构字符串,该结构保存LID账号的状态信息。
注意:
LID登录状态会保存在订阅SDK本地,当接入方登录后,程序关闭,LID依然会保持登录状态,但LID是登录状态,不一定可以拿到token。(比如没有联网,本地缓存的token又失效)。建议在需要拿token进行业务交互,检验到token已失效时,则弹出登录窗口让用户重新登录。
6.3.2. 接口定义
1. 联想LID账号登录信息回调函数指针定义
由接入方实现,通过LYSDK_LidInit接口传入订阅SDK,当发生LID账号登录信息时,会通过该回调函数通知接入方。
typedef void(__stdcall *LYSDK_LOGIN_CALLBACK)(char* loginInfo);
loginInfo [out]:Json字符串,返回登录相关信息
2. 联想LID账号登出信息回调函数指针定义
由接入方实现,通过LYSDK_LidInit接口传入订阅SDK,当发生LID账号登出信息时,会通过该回调函数通知接入方。
typedef void(__stdcall *LYSDK_LOGOUT_CALLBACK)(int errorCode);
errorCode [out]:登出结果
6.3.3. 订阅SDK初始化接口
说明:基于单点登录提高用户体验的考虑,必须在接入方程序启动时调用,联想LID登录登出状态变化,通过异步回调的方式实现。
调用该方法:
Int LYSDK_LidInit(char* appInfo, LYSDK_LOGIN_CALLBACK login_listener, LYSDK_LOGOUT_CALLBACK logout_listener);
appInfo[in]:Json字符串,接入方传入的应用信息,包括mchId,appid,key等
login_listener [in]: 接入方实现的登录通知回调函数
logout_listener [in]:接入方实现的登出通知回调函数
C++示例代码:
void __stdcall OnLoginResultEX( char* loginInfo)
{CString wstrLoginInfo = CA2W(loginInfo, CP_UTF8);MessageBox(0, wstrLoginInfo,L"LYSDK_LOGIN_CALLBACK loginInfo",0);
}
void __stdcall OnLogoutResultEX(int errorCode)
{
if(errorCode==0)MessageBox(0, L"Logout Succeed", L"LYSDK_LOGOUT_CALLBACK", 0);
else
MessageBox(0, L"Logout Failed", L"LYSDK_LOGOUT_CALLBACK", 0);
}CString strParam = L"{\"appid\":\"471561429588736\",\"mchId\":\"471561429588736\",\"key\":\"yJiUHopRvJEaeyb49AbO7kCTOrQ43kWsECm/zue1zM5NUxZb/1K5N18/cLZR8ZFkzqvRYAkflOxft5eABSsu6iyNOoiSmfPhRKGaeu+dMHsEeZWYhUGipc9wFMzne57tZ4Oj+xpaRYaLvzAgMBAAECggEAXPmnmmoirP4NNr011YeT9DbiZ++W58qpyfdTl4YNaoSD9Yg93G08efEtJu5z2hvmbBm6YVy14QTqoV0qPU6rGcJOJxjsGdnNZM7OjSlIpEs2/x7RhduMSvMf+hwWUj5fXDgL5b1M5bmtMGJw/AGkMQO5nPy4MYfh8IMoXKrswYvEQEcAK2KW69ajIsf71cwjjWqptjjYQXDY+xeynSbnUTrA14XhevMWPzYuvoCD28PRX/Jwj+RoDAFr3llP79bGjg70g+E9eCdA6knBHgP2haQ+nEKUkSXJL1Kzzl4qb7Ov1QpIwa22g/qMiSCOzpL69/oqq7nPx5DFCSdg3BVzOQKBgQD5WIUo0BtnBoGpOCxb+6SxdHh6e3QUAmUwRm/Y0xBBdklq+SayLi9ycYU8Kg9viaBW2l/Y/Lrt6YuUIPnJQBJHn0k6JmFD3jc6DTTg1RaNv1HjmUiIyIkfXaNKu26z9iEh7Yvr4gVlhfKu8LHftv7fe4dbCjE1QrUvolz3jE+kbwKBgQDaMnDFijKwORpUjLympmAQNR7cRImqyaa2aGMxwZ+/uBKD8KPP0vsBEsYh5gRCTMdsJmnREBhCsN6cKAIf/SixcRPqbEauH2IW5zkrzKtqLU6H8BOXwixlpWAUQdcjIXDuwLR80DtVNSJudXqGY+pQdBOvUUuvCVpFKRNjJdAKvQKBgHp/n6PGYcACtU6yVzC1d1rrEolx/zwZVScbY7WNM85FU5pnXzhockzyMne1XjH41jn1PON4fkmF1FnovW6+uHxRaANWebCDCnTNqi3O4i6vUIbVdookoyEyupdrb96fy/VEI9q2BtqyrOB/RZPX7m1S3dO/NR+qbyNAzBWd7D6nAoGBAKdk5wtFeJmlVUPkLJ6VKUGF30UQ96Sky1dJQkBb0RieOOYr6SB5NcOfCY3cDwxmJuAboDaZaGNRmZanQuoTp/JpU+QWaSsQPIphnYSyohb05zh2wDE+8ByTAODJmikDcMZZ5J2UitBV0TJ4wiTz5kEOrENl1PBV9oD0gEEiMzbpAoGAcqvZpSbU+snP5Pguq3MuA2zM+mFIH5MrUaaGzTTE4skhAdpdFgwkyhi7jz5l3qJRS2mLaINQ+XXBu+c69DYPZTX4/QAT+E1+5hVDAj8EQLhCC9FGrHwImG0oAUoRMQMeLCDqQ/THpCJXFK8d6kXUNJ/TvicMn03O5beDDwIeE0k=\"}";CStringA strP = CT2A(strParam, CP_UTF8);int nRet = LYSDK_LidInit(strP.GetBuffer(0) ,&OnLoginResultEX, &OnLogoutResultEX);if (nRet!=0){
MessageBox(0, L"LYSDK_LidInit Error",L"Error",0);
}
6.3.4. 订阅SDK退出接口
说明:一般在接入方程序结束前调用。
调用该方法:
int LYSDK_LidClose();
C++示例代码:
int nRet = LYSDK_LidClose();
if (nRet!=0)
{
MessageBox(0, L"LYSDK_LidClose Error",L"Error",0);
}
6.3.5. 获取LID账号相关信息接口
说明:一般在LYSDK_LidInit后直接调用,该接口除了返回LID的登录状态外,还会实现单点登录和自动登录。
调用该方法:
int LYSDK_LidGetLoginStatus(char* loginInfo,int bufLen);
loginInfo [out]:接收loginInfo信息指针,该字符串需接入方分配空间,然后传入
bufLen [in]:接收loginInfo字符串长度,该长度需要大于等于1024字节
C++示例代码:
char szLogInfo[1024] = { 0 };int nRet = LYSDK_LidGetLoginStatus(szLogInfo, sizeof(szLogInfo)/sizeof(char));
if (nRet!=0)
{
MessageBox(0, L"LYSDK_LidGetLoginStatus Error",L"Error",0);
}
6.3.6. LID账户登录接口
说明:在LID未登录状态时调用,该接口是异步实现,弹出登录框后会立即返回接入方,实际的登录结果会通过LYSDK_LidInit中注册的login_listener回调通知。
调用该方法:
int LYSDK_LidLogin(HWND hwndParent=NULL);
hwndParent[in]:接入方传入的接入应用窗口句柄,登录弹窗会把该句柄作为父窗口,以便于显示在这个窗口上面。
C++示例代码:
int nRet = LYSDK_LidLogin(m_hWnd);
if (nRet!=0)
{
MessageBox(0, L"LYSDK_LidLogin Error",L"Error",0);
}
6.3.7. LID账户登出接口
说明:在LID登录状态下,如果需要退出LID登录时调用,该接口是异步实现,调用后立即返回接入方,实际的登出结果会通过LYSDK_LidInit中注册的logout_listener回调通知。
调用该方法:
int LYSDK_LidLogout();
C++示例代码:
int nRet = LYSDK_LidLogout();
if (nRet!=0)
{
MessageBox(0, L"LYSDK_LidLogout Error",L"Error",0);
}
6.4. 支付功能相关接口
说明:客户端通过回调函数接受支付结果,及订单号。
/*
** 支付结果回调
**
* nRetCode[out] PAYCOMPLETED: 7110// 完成支付 PAYCANCEL:7111 // 未支付
* orderNum[out] 订单号
*/
typedef void(__stdcall *LYSDK_PAYSTATUS_CALLBACK)(int nRetCode, char* orderNum);
6.4.1. 联想账号支付接口
说明:接入LID后支付时调用;
调用方法:
extern "C" int __stdcall LYSDK_PayByToken(HWND hwndParent, char* prikey, char* in_param, char* token, char *outbufer, int bufLen, LYSDK_PAYSTATUS_CALLBACK payStatus_callback);
/*
函数功能:lenovoid账号登录 支付
** hwndParent[in]: 父窗口句柄
** prikey[in]: 签名私钥
** in_param [in]: Json字符串,接入方传入的支付参数,参考开发文档( 商户订单号、支付金额等)
** token[in]: lid用户token
** outbufer[out]: 产品编码为COMMON_CASHIER、COMMON_DK_CASHIER时,没有数据返回(json)
** buflen[in]:接收outbufer的长度
** payStatus_callback[in] 回调通知支付结果, 可以为NULL ,为NULL时则不回调
*/
参数说明:
参数 | 类型 | 描述 | 必填 |
普通支付 | |||
appId | Long | 平台分配商户号下创建的appId | Y |
mchId | Long | 平台分配的商户号 | Y |
mchNo | String (128) | 商户订单号参考5.1 说明 | Y |
attach | String (128) | 商品附加信息 | N |
goodsDes | String (128) | 商品描述 | N |
goodsName | String (128) | 商品名称 | Y |
goodsCode | String (128) | 商品编码 | Y |
payAmount | Long | 支付金额,单位为分,大于等于1 | Y |
payNotify | String (256) | 支付通知地址 | Y |
productCode | String(32) | 普通支付:COMMON_CASHIER代扣支付:COMMON_DK_CASHIER | Y |
周期扣费 | |||
deductionFee | long | 代扣金额;未传则以支付金额作为后续扣款金额 | N |
deductionPeriod | int | 代扣周期,单位为自然月 | Y |
firstDeductionDate | String | 首次扣款日期,日期格式yyyy-MM-dd,如2023-05-26 | N |
contractNotify | String (255) | 协议通知地址,签约和解约通知地址 | Y |
productId | String (32) | 产品id,由联想侧提供 | Y |
6.4.2. 非联想账号支付接口
说明:未接入LID,使用三方账号支付时调用;
调用方法:
extern "C" int __stdcall LYSDK_Pay(HWND hwndParent, char* prikey, char* in_param, char *outbufer, int bufLen, LYSDK_PAYSTATUS_CALLBACK payStatus_callback);
/*
函数功能:无账号 支付
** hwndParent[in]: 父窗口句柄
** prikey[in]: 签名私钥
** in_param [in]: Json字符串,接入方传入的支付参数,参考开发文档( 商户订单号、支付金额等)
** outbufer[out]: 产品编码为COMMON_CASHIER、COMMON_DK_CASHIER时,没有数据返回(json)
** buflen[in]:接收outbufer的长度
** payStatus_callback[in] 回调通知支付结果, 可以为NULL ,为NULL时则不回调
*/
参数说明:
参数 | 类型 | 描述 | 必填 |
普通支付 | |||
appId | Long | 平台分配商户号下创建的appId | Y |
mchId | Long | 平台分配的商户号 | Y |
mchNo | String (128) | 商户订单号参考5.1 说明 | Y |
attach | String (128) | 商品附加信息 | N |
goodsDes | String (128) | 商品描述 | N |
goodsName | String (128) | 商品名称 | Y |
goodsCode | String (128) | 商品编码 | Y |
payAmount | Long | 支付金额,单位为分 | Y |
payNotify | String (256) | 支付通知地址 | Y |
productCode | String(32) | 普通支付:COMMON_CASHIER代扣支付:COMMON_DK_CASHIER | Y |
周期扣费 | |||
deductionFee | long | 代扣金额 | N |
deductionPeriod | int | 代扣周期,单位为月 | Y |
firstDeductionDate | String | 首次扣款日期,日期格式yyyy-MM-dd,如 | N |
2023-05-26 | |||
contractNotify | String (255) | 协议通知地址,签约和解约通知地址 | Y |
userId | String (32) | 用户id | Y |
userAccount | String (64) | 用户账号 | Y |
productId | String (32) | 产品id,由联想侧提供 | Y |
6.4.3. 设备账号支付接口
订阅前置条件:应用的用户权益仅在用户的单台设备生效。
若需具体了解此订阅能力,可联系联想商务提供支持。
说明:设备账号订阅,支付时调用。
调用方法:
extern "C" int __stdcall LYSDK_PayByDeviceID(HWND hwndParent, char* prikey,char* in_param, char *outbufer, int bufLen, LYSDK_PAYSTATUS_CALLBACK payStatus_callback);
/*
函数功能:设备账号 支付
** hwndParent[in]: 父窗口句柄
** prikey[in]: 签名私钥
** in_param [in]: Json字符串,接入方传入的支付参数,参考开发文档(设备id 商户订单号、支付金额等)
** outbufer[out]: 产品编码为COMMON_CASHIER、COMMON_DK_CASHIER时,没有数据返回(json)
** buflen[in]:接收outbufer的长度
** payStatus_callback[in] 回调通知支付结果, 可以为NULL ,为NULL时则不回调
*/
参数说明:
参数 | 类型 | 描述 | 必填 |
appId | Long | 平台分配商户号下创建的appId | Y |
mchId | Long | 平台分配的商户号 | Y |
mchNo | String (128) | 商户订单号参考5.1 说明 | Y |
attach | String (128) | 商品附加信息 | N |
goosDes | String(128) | 商品描述 | N |
goodsName | String(128) | 商品名称 | Y |
goodsCode | String(128) | 商品编码 | Y |
deviceId | |||
payAmount | Long | 支付金额,单位为分 | Y |
productCode | String(32) | 普通支付:COMMON_CASHIER代扣支付:COMMON_DK_CASHIER | Y |
6.4.4. 代码示例
std::string strPriKey=” ****”;std::string strin_param=” {\"appId\":11217136061*****,\"mchId\":11217125827*****,\"mchNo\":\"e33bdf96-9a97-12\",\"payAmount\":100,\"goodsName\":\"测试\",\"goodsCode\":\"goodCoe001\",\"productCode\": \"COMMON_CASHIER\" ,
\"goodsDes\":\"goodDes支付\",
\"deviceId\":\"***** \",\"payNotify\":\"https://www.baidu.com/cloud-intermodal-coretify/pay\"
}”;Std::string strToken = “ZAgAAAAAAAGE9MTAxNjA3MTU0NzkmYj0yJmM9MSZkPTE3ODc3MSZlPTY1MDE4N0I5NkJCNDRBRjBEMjBDNDZGMzdCRDgyRkJGMSZoPTE2ODc3NzI0ODUzMjUmaT00MzIwMCZvPWFiMDMxMmZlMmIxNzZlOTA2NGZhZWJlZGViMDBkNjMzJnA9d2F1dGgmcT0wJnVzZXJuYW1lPWxpaHQxMCU0MGxlbm92by5jb20mYW1yPXVua25vd24maWw9Y26Eh0VCDeBtKuetPoew2LIx”;char outbufer[2048]; int bufLen = 2048;LYSDK_Pay(NULL,strPriKey.c_str(), strin_param.c_str(),outbufer, bufLen,NULL);LYSDK_PayByToken (NULL,strPriKey.c_str(), strin_param.c_str(),strToken.c_str(),outbufer, bufLen,NULL);LYSDK_PayByDeviceID(NULL,strPriKey.c_str(), strin_param.c_str(),outbufer, bufLen,NULL);
6.4.5. Demo运行说明
(1) 输入支付接口签名私钥(找联想运营获取)
(2) 在LYRelease32或LYRelease64文件夹内,新增一个payContent.json文件,内容如下:
{"appId":***************,"mchId":***************,"mchNo":"242322251101","payAmount":100,"goodsName":"测试","goodsCode":"test","productCode": "COMMON_CASHIER" ,"goodsDes":"支付","deviceId":"***************","payNotify":"https://www.lenovo.com"
}
7. 服务端接口
7.1. 接口说明
API 采用REST风格设计。所有接口请求地址都是可预期的以及面向资源的。使用规范的HTTP响应代码来表示请求结果的正确或错误信息。所有的API请求都会以规范友好的JSON对象格式返回(包括错误信息)。
- 请求参数格式说明:
请求参数分为2部分,Body和head。Head参数不参与签名,为鉴权所用。Body参数分为基础参数和业务参数。所有基础参数都为必填参数,业务参数根据不同的场景,有所不同。
- http状态码说明:
HTTP状态码 | 描述 |
200 | OK |
401 | 签名或者token无效 |
500 | 错误信息 |
- 接口统一响应数据格式说明
{"code": 10000,"data": "","message": "success"
}
变量名 | 必填 | 类型 | 描述 |
code | Y | String | 返回码,发生错误时code不等于10000 |
data | Y | Object | 返回数据,发生错误时返回null |
message | Y | String | 返回码描述,发生错误时返回错误信息 |
7.2. 支付通知
- 当用户支付完成后,订阅服务端将数据post到支付通知地址。商户返回SUCCESS则表示该订单支付通知,商户成功接收。商户返回其它任何字符都代表接收失败。
- 订阅服务端会再次发送通知。通知触达10次,到达通知次数后,不会触发通知。
Post数据 | |||||
字段名 | 变量名 | 必填 | 类型 | 示例值 | 描述 |
商户ID | mchId | Y | Long | 78993434342 | |
应用ID | appId | Y | Long | 343453453445 | |
签名 | sign | Y | String | 参考签名算法 | |
签名方式 | signType | Y | String | RSA2 | 固定值RSA2 |
版本 | version | Y | String | 1.0 | 固定值1.0 |
编码 | charSet | Y | String | utf-8 | 固定值utf-8 |
随机字符 | nonce | Y | String | dsafsadfasdfasa | 随机字符串 |
商户订单号 | mchNo | Y | String | ||
交易订单号 | tradeNo | Y | Long | 9860494571601920 | 交易订单号 |
银行流水号 | serialsNo | Y | String | 2019090239230923 | 第三方支付渠道的交易流水号 |
支付金额 | payFee | Y | Int | 1 | 支付金额单位(分) |
支付状态 | payStatus | Y | String | 支付状态 1 已支付 | 支付状态 1 已支付 |
支付时间 | payTime | Y | String | 2022-03-23 19:17:56 | yyyy-MM-dd HH:mm:ss |
附加数据 | attach | N | String | Dfasas | 商户私有数据 |
- 商户需返回参数
SUCCESS
通知示例代码:
{"mchNo": "*********1111", "tradeNo": 969549918857856, "serialsNo": "***********2222", "payFee": 3000, "payTime": "2022-10-19 17:23:12", "payStatus": "1", "appId": 12312312, "mchId": 123123123, "sign": "T2IuyxblOnKstHf7EuJZWGBroSUzwN4n6l6yZ1zahsvGfBDn2AxAhifpPUblbMuq2XHsh9Mvg==", "signType": "RSA2", "version": "1.0", "charSet": "UTF-8", "nonce": "m1wo53f6iy"
}
7.3. 查询支付结果接口
- 接口地址:
https://cloud-rest.lenovomm.com/cloud-intermodal-core/api/v1/pay/query/trade
- 请求方式:POST
- 请求头参数说明:Content-Type: application/json
- 请求Body参数说明:
1.基础参数
基础参数 | |||||
字段名 | 变量名 | 必填 | 类型 | 示例值 | 描述 |
商户ID | mchId | Y | Long | 96291345 | 分配的商户号 |
应用ID | appId | Y | Long | 11962913 | 商户号下创建的APPID |
随机字符串 | nonce | Y | String | 5K8264ILTKCH16C | 随机字符串,不长于32位 |
时间戳 | timestamp | Y | String | 1648878162182 | 时间戳(从1970-01-01T00:00:00Z开始的毫秒数) |
版本 | version | Y | String | 1.0 | 版本号 固定值1.0 |
签名 | sign | Y | String | 参考5.4签名算法 | |
签名方式 | signType | Y | String | RSA2 | 签名方式RSA2 |
2. 业务参数说明
业务参数 | |||||
字段名 | 变量名 | 必填 | 类型 | 示例值 | 描述 |
交易订单号 | tradeNo | Y | Long | 524498630711936 |
- 返回参数说明:
字段名 | 变量名 | 必填 | 类型 | 示例值 |
返回码 | code | Y | String | 10000 |
返回消息 | msg | Y | String | SUCCESS |
返回数据体 | data | N | String |
示例:
- 请求参数:
{"mchId": 233799539766016,"appId": 233799539766016,"sign": "ngAcXTBZnuuI944ae8pyMY60CpiRILjTm2uX***SEwHG19+aWotz","signType": "RSA2","timestamp": "1666593772589","nonce": "w190bfrrog1666593772585","version": "1.0","tradeNo": 977319841453440,
}
- 返回参数:
http状态200
{"code": 10000,"message": "Success","data": {"tradeNo": 877319841453440,"serialsNo": "4200001493202206141879749159","payStatus": 1,"payTime": "2022-06-14 11:17:48","payAmount": 1}
}
data 数据说明:
变量名 | 必填 | 类型 | 描述 |
tradeNo | Y | long | 交易订单号 |
serialsNo | N | String | 交易流水号 |
payStatus | Y | Byte | 支付状态:待支付:0,已支付:1 |
payTime | N | String | 支付时间 yyyy-MM-dd HH:mm:ss |
payAmount | Y | BigDecimal | 支付金额单位分 |
错误返回数据:
http状态码:非200
{"code":401,"message":"unauthorizedException","data":null}
{"code":500,"message":"error","data":null}
7.4. 申请退款接口
- 接口地址:
https://cloud-rest.lenovomm.com/cloud-intermodal-core/api/v1/pay/refund
- 请求方式:POST
- 请求头参数说明:Content-Type: application/json
- 请求Body参数说明:
1.基础参数
基础参数 | |||||
字段名 | 变量名 | 必填 | 类型 | 示例值 | 描述 |
商户ID | mchId | Y | Long | 96291345 | 分配的商户号 |
应用ID | appId | Y | Long | 11962913 | 分配的APPID |
随机字符串 | Nonce(32) | Y | String | 5K8264ILTKCH16C | 随机字符串,不长于32位 |
时间戳 | timestamp | Y | String | 1648878162182 | 时间戳(从1970-01-01T00:00:00Z开始的毫秒数) |
版本 | version | Y | String | 1.0 | 版本号 固定值1.0 |
签名 | sign | Y | String | 参考签名算法 | |
签名方式 | signType | Y | String | RSA2 | 签名方式RSA2 |
2. 业务参数说明
业务参数 | |||||
字段名 | 变量名 | 必填 | 类型 | 示例值 | 描述 |
交易号 | tradeNo | Y | Long | Fjkj2345 | 交易订单号 |
退款金额 | refundAmount | Y | Int | 100 | 参考5.2金额说明 |
退款通知地址 | refundNotify | Y | String(256) | http://www.***.com/notify | 异步接收退款成功通知,通知url必须为外网可访问的url。 |
- 返回参数说明:
字段名 | 变量名 | 必填 | 类型 | 示例值 |
返回码 | code | Y | String | 10000 |
返回消息 | msg | Y | String | SUCCESS |
返回数据体 | data | N | String |
示例:
请求参数:
{"mchId":233799539766016,"appId":233799539766016,"sign":"PZP0ZYI0BPXAn2YBD15hG0L9qNNG3Q5uw048bzgKCMv3F8asUbSD7S0pPXxmoKWDigaUNJsHUVFE6hVFkVWDy+SOparIauqa8vMCHTtbhDZe7V/40GcyNd7q4IwnvsmqBOhCV9jZs5J8a9A9K+FqxVlWW2iEgU6UTjrvWEc62GhnzMdsw1AM1yki/Zr0PjmR7kwK1u34AmaGKmTBmReTLl/27usi/gcXw99FcQYIuyIIpDZbpdApAYwLaZvf5qLuPJDg1I7YJmmUiOxdMpKnbmiAUph6LK0nptiCKii+WqX1F+2hQsaLioWGZbXwhDmPEDb4QafJJ0UvfWqWOuCQnA==","signType":"RSA2","timestamp":"1648881113851","nonce":"nonceStr2bb1145d-bbc3-4c","version":"1.0","tradeNo":821614685996160,"refundAmount":1,"refundNotify":"https://www.***.com/api/v1/notify/refund"
}
返回参数:
http状态200
{"code":10000,"message":"success","data":null}
错误返回数据:
http状态码:非200
{"code":401,"message":"unauthorizedException","data":null}
{"code":500,"message":"{ refundAmount.Null.message}","data":null}
7.5. 退款通知
- 当退款单完成退款后,订阅服务端将数据post到退款通知地址。商户返回SUCCESS则表示该订单退款通知,商户成功接收。商户返回其它任何字符都代表接收失败。
- 订阅服务端会再次发送通知。通知触达10次,到达通知次数后,不会触发通知。
Post数据 | |||||
字段名 | 变量名 | 必填 | 类型 | 示例值 | 描述 |
商户ID | mchId | Y | Long | 78993434342 | |
应用ID | appId | Y | Long | 343453453445 | |
签名 | sign | Y | String | 参考签名算法 | |
签名方式 | signType | Y | String | RSA2 | 固定值RSA2 |
版本 | version | Y | String | 1.0 | 固定值1.0 |
编码 | charSet | Y | String | utf-8 | 固定值utf-8 |
随机字符 | nonce | Y | String | dsafsadfasdfasa | 随机字符串 |
商户订单号 | mchNo | Y | String | ||
交易号 | tradeNo | Y | Long | 9860494571601920 | 交易号 |
退款金额 | refundFee | Y | BigDecimal | 1 | 金额单位(分) |
退款状态 | refundStatus | Y | String | 退款状态 2 已完成 | 退款状态 2 已完成 |
退款时间 | refundTime | Y | String | 2022-03-23 19:17:56 | yyyy-MM-dd HH:mm:ss |
返回参数说明:
SUCCESS
通知示例代码:
{"mchNo": "123123123","tradeNo": 964881759168896,"refundFee": 12,"refundTime": "2022-10-17 17:20:37","refundStatus": "2","appId": 132312312,"mchId": 12312312,"sign": "Fh3/fxxPfghQElZyV7dTPvvLHndoAs8PZv0WSEty2hgG6SY04b/B5uNWTd0+pKJGCpauiY0nrB7XznoIIA9JDjrxIEK+Qu+4s4fG9pLWBDiLRLNnS/QegVded+2LbSTZMdIFeCRCEmxTcC00dcRXrJLRAslltpGmvQMTz + P5CopmQPAqr5k + /XELCrMxuCxavXnxfCn0oCjSHLnhQybV7kvwLrFwPCWthnvUflcG+b5yIMGdaRqjZC32v5jXDflpcvcQLWuSafSJn4fVoLXuYsl7ILzMkNfN1IXRRG5KHIsVo2GnibuzcbJIgSlVKpgLbfb56M0w / o4rKio7Mch / Q == ","signType ": "RSA2 ","version ": "1.0 ","charSet ": "UTF - 8 ","nonce ": "xnca609z7z "
}
7.6. 根据token获取lenovoID和用户账号
- 接口地址:
https://cloud-rest.lenovomm.com/cloud-intermodal-core/api/v1/oauth/token
- 请求方式:POST
- 请求头参数说明:
token: "ZAgAAAAAAAGE ",请求头里面必须添加token参数。从SDK提供方法获取token
realm: pcapp.lenovomm.com,固定值
- 请求Body参数说明:
请求参数
基础参数 | |||||
字段名 | 变量名 | 必填 | 类型 | 示例值 | 描述 |
商户ID | mchId | Y | Long | 96291345 | 分配的商户号 |
应用ID | appId | Y | Long | 11962913 | 分配的APPID |
随机字符串 | nonce | Y | String | 5K8264ILTKCH16C | 随机字符串,不长于32位 |
时间戳 | timestamp | Y | String | 1648878162182 | 时间戳(从1970-01-01T00:00:00Z开始的毫秒数) |
版本 | version | Y | String | 1.0 | 版本号(1.0、2.0) 2.0 返回用户信息用户账号信息,具体看响应结果 |
签名 | sign | Y | String | 参考签名算法 | |
签名方式 | signType | Y | String | RSA2 | 签名方式RSA2 |
- 返回参数说明:
字段名 | 变量名 | 必填 | 类型 | 示例值 |
返回码 | code | Y | String | 10000 |
返回消息 | msg | Y | String | SUCCESS |
返回数据体 | data | N | String |
示例:
请求参数:
{ "mchId":233799539766016,"appId":233799539766016, "sign":"viHirVTUoz5M3FsnBNq4BtvHxam+GqkNyFrsbYbY4gXt/cy9oa5AmFrq21QXl2+05ao63zkuKyNE/0/UtSsKb0qeLV5rv8YZWi87EO98lbLAFz6h0R9HP01ZdOKCgUmbB1XxA3mdNBCi9/FSCsFpFQ5QxoFhiXPbXTUIEDqEajd92LaqHZZZdsaxCUQDvbRmik3RtG5jJWfMDaTGx3+NffKWyWFR+lMkI0ZcsbcAlS8zDet72fNJpiOZIN2Yh8+Rtn7rRJ2Ok0zu3349P3QvQ/GYxF8R8VhVJ08sBBSle7pa5e0UhRq9MdtO7vKWCmAiyy8KNHxswuj7NThOOPvT9Q==","signType":"RSA2","timestamp":"1649215075332","nonce":"nonceStr82751c47-ab56-4f","version":"1.0"
}
返回参数:
http状态200
version为1.0时返回结果:
{"code":10000,"message":"Success","data":"10086910024"}
version为2.0时返回结果:
{ "code": 10000, "message": "Success","data": {"lenovoId": "10086910024","account": "s*******@lenovo.com"}
}
错误返回数据:
http状态码:非200
{"code":401,"message":"unauthorizedException","data":null}
{"code":500,"message":"{ refundAmount.Null.message}","data":null}
7.7. 周期扣款—协议查询接口
- 接口地址:
https://cloud-rest.lenovomm.com/cloud-intermodal-core/api/v1/contract/query
- 请求方式:POST
- 请求头参数说明:Content-Type: application/json
- 请求Body参数说明:
1.基础参数
基础参数 | |||||
字段名 | 变量名 | 必填 | 类型 | 示例值 | 描述 |
商户ID | mchId | Y | Long | 96291345 | 分配的商户号 |
应用ID | appId | Y | Long | 11962913 | 商户号下创建的APPID |
随机字符串 | nonce | Y | String | 5K8264ILTKCH16C | 随机字符串,不长于32位 |
时间戳 | timestamp | Y | String | 1648878162182 | 时间戳(从1970-01-01T00:00:00Z开始的毫秒数) |
版本 | version | Y | String | 1.0 | 版本号 固定值1.0 |
签名 | sign | Y | String | 参考5.4签名算法 | |
签名方式 | signType | Y | String | RSA2 | 签名方式RSA2 |
2. 业务参数说明
业务参数 | |||||
字段名 | 变量名 | 必填 | 类型 | 示例值 | 描述 |
协议单号 | contractId | N | Long | 524498630711936 | 不能同时为空 |
商户订单号 | mchNo | N | String | 12312312 |
返回参数说明:
字段名 | 变量名 | 必填 | 类型 | 示例值 |
返回码 | code | Y | String | 10000 |
返回消息 | msg | Y | String | SUCCESS |
返回数据体 | data | N | String |
示例:
请求参数:
{"mchId": 1121712582*****,"appId": 112171361******,"sign": "QkX5k62T5KUwerI7TJZrGT ==","signType": "RSA2","timestamp": "1697106066664","nonce": "sp5xnnh5sa1697106066660","version": "2.0","contractId": 105924711500*****,"mchNo": "6f5cce50-fca3-4f"
}
返回参数:
http状态200
{"code": 10000,"message": "Success","data": {" mchNo": 8773198414*****," contractId": "42000014932022061*****"," status ": 1," time ": "2022-06-14 11:17:48"}
}
data 数据说明:
变量名 | 必填 | 类型 | 描述 |
contractId | Y | long | 协议号 |
mchNo | Y | String | 商户交易号 |
status | Y | Byte | 状态:未签约:0,已签约:1 已解约2 |
time | N | String | 变更时间 yyyy-MM-dd HH:mm:ss |
错误返回数据:
http状态码:非200
{"code":401,"message":"unauthorizedException","data":null}
{"code":500,"message":"error","data":null}
7.8. 每日订单查询接口
- 接口地址:
https://cloud-rest.lenovomm.com/cloud-intermodal-core/api/v1/app/query/trade
- 请求方式:POST
- 请求头参数说明:Content-Type: application/json
- 请求Body参数说明:
1.基础参数
基础参数 | |||||
字段名 | 变量名 | 必填 | 类型 | 示例值 | 描述 |
商户ID | mchId | Y | Long | 96291345 | 分配的商户号 |
应用ID | appId | Y | Long | 11962913 | 商户号下创建的APPID |
随机字符串 | nonce | Y | String | 5K8264ILTKCH16C | 随机字符串,不长于32位 |
时间戳 | timestamp | Y | String | 1648878162182 | 时间戳(从1970-01-01T00:00:00Z开始的毫秒数) |
版本 | version | Y | String | 1.0 | 版本号 固定值1.0 |
签名 | sign | Y | String | 参考5.4签名算法 | |
签名方式 | signType | Y | String | RSA2 | 签名方式RSA2 |
2. 业务参数说明
业务参数 | |||||
字段名 | 变量名 | 必填 | 类型 | 示例值 | 描述 |
日期 | date | Y | String | 2023-08-01 | 可传入最近一个月内的日期进行查询 |
- 返回参数说明:
字段名 | 变量名 | 必填 | 类型 | 示例值 |
返回码 | code | Y | String | 10000 |
返回消息 | msg | Y | String | SUCCESS |
返回数据体 | data | N | String |
示例:
请求参数:
{"mchId": 11217125827*****,"appId": 11217136061*****,"sign": "qseokxdhDkH+jHz0wLluVQyvCvxGSw==","signType": "RSA2","timestamp": "1697106525038","nonce": "0rcscwivez1697106525033","version": "2.0","date": "2023-10-07"
}
- 返回参数:
http状态200
{"code": 10000,"message": "Success","data": {"date": "2023-10-07","fileUrl": "https://pr1-greentea-test.lenovo.com.cn/default/ccd41.xlsx"}
}
data 数据说明:
变量名 | 必填 | 类型 | 描述 |
date | Y | String | 交易日期 yyyy-MM-dd |
fileUrl | Y | String | 文件地址 |
错误返回数据:
http状态码:非200
{"code":401,"message":"unauthorizedException","data":null}
{"code":500,"message":"error","data":null}
7.9. 周期扣款—协议通知
- 用户签约、解约后,订阅服务端将数据post到协议通知地址(3.5 协议通知地址)。商户返回SUCCESS则表示该协议通知,商户成功接收。商户返回其它任何字符都代表接收失败。
- 订阅服务端会再次发送通知。通知触达10次,到达通知次数后,不会触发通知。
Post数据 | |||||
字段名 | 变量名 | 必填 | 类型 | 示例值 | 描述 |
商户ID | mchId | Y | Long | 78993434342 | |
应用ID | appId | Y | Long | 343453453445 | |
签名 | sign | Y | String | 参考签名算法 | |
签名方式 | signType | Y | String | RSA2 | 固定值RSA2 |
版本 | version | Y | String | 1.0 | 固定值1.0 |
编码 | charSet | Y | String | utf-8 | 固定值utf-8 |
随机字符 | nonce | Y | String | dsafsadfasdfasa | 随机字符串 |
商户订单号 | mchNo | Y | String | ||
交易订单号 | tradeNo | Y | Long | 98604945716***** | 协议号 |
协议状态 | status | Y | String | 状态 1 已完成 2 已解约 | |
变更时间 | changeTime | Y | String | 2022-03-23 19:17:56 | yyyy-MM-dd HH:mm:ss |
- 返回参数说明:
SUCCESS
通知示例代码:
{"mchNo": "4fcf9d5e-4891-4e","tradeNo": 1066044865591424,"status": "2","changeTime": "2023-03-02 10:48:56","appId": 233799539766016,"mchId": 233799539766016,"sign": "GP*********=","signType": "RSA2","version": "1.0","charSet": "UTF-8","nonce": "ft2u016vvo"
}
7.10. 错误码定义
以下为接入过程中高频错误码,可供参考。
结果码 | 说明 | 建议 |
500 | “verify signature failure” | 签名验证失败,检查签名信息(密钥、入参) |
500 | “nonce str verify failure” | nonce验证失败,时间戳与nonce每次请求不能重复 |
500 | “unauthorizedException” | 重新获取token |
400 | “系统异常” | 检查“productId”或“userId、userAccount"是否超长 |
500 | “商户订单信息错误” | 检查“productCode” |
500 | “Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported” | 检查参数及代码,确定类型 |
500 | “参数错误” | 检查是否缺失传参 |
8. 其他说明
8.1. 商户订单号
商户支付的订单号由商户自定义生成,仅支持使用字母、数字、中划线-、下划线_、竖线|、星号*这些英文半角字符的组合,请勿使用汉字或全角等特殊字符。订阅服务平台要求商户订单号保持唯一性,同一个应用ID不可重复(建议根据当前系统时间加随机序列来生成订单号)。重新发起一笔支付要使用新订单号,避免重复支付。
8.2. 金额
交易金额默认为人民币交易,接口中参数支付金额单位为【分】,支付金额必须大于 0,参数值不能带小数,暂不支持外币交易。
8.3. 日期时间
标准北京时间,时区为东八区;如果商户的系统时间为非标准北京时间。按照各个接口需要日期时间格式的传入。
8.4. 签名算法
开发者需要自行实现签名,签名过程如下:
1. 筛选并排序
获取所有请求参数,不包括字节类型参数,如文件,字节流,剔除sign字段,剔除值为空的参数,并按照第一个字符的键值ASCII码递增排序(字母升序排序),如果遇到相同字符则按照第二个字符的键值ASCII码递增排序,以此类推。
2. 拼接
将排序后的参数与其对应值,组合成“参数=参数值”的格式,并且把这些参数用&字符连接起来,此时生成的字符串为待签名字符串。
例如:appId=2018071360678029&sign_type=RSA2&version=1.0
3. 签名
使用各自语言对应的SHA256WithRSA(对应signType为RSA2)签名函数利用开发者私钥对待签名字符串进行签名。
4. 把生成的签名赋值给sign参数,拼接到请求参数中.
5. 验签工具:联想验签工具
9. 版本更新日志
9.1. V2.3.3内容变更
变更项 | 接入说明 |
1、PC端订阅SDK收银台样式更新 | 所有CP需接入联想统一支付收银台 |
2、修复部分登录、支付问题 | CP需更新SDK |
3、优化deviceId重复、变更等相关问题 | 针对已接入设备版订阅的应用,CP需重新集成SDK |
10. 常见问题
本模块整理了接入流程“申请参数(appid&key)→接入订阅SDK(登录+支付)→接入退款API→测试→发布应用”各环节的常见问题,开发者可按遇到问题的环节进行查找。
10.1. 申请参数
Q:为什么需要开发者提供退款通知地址?
A:订阅服务支持用户在”联想应用商店-订单中心“进行7天无理由退款,当用户退款完成后,联想服务器会发送退款通知给开发者,开发者需对通知的参数进行处理,变更用户权益,因此需开发者提供一个用于接收退款通知的url
Q:应用内无退款入口,是否还需要提供退款通知地址?
A:需要,用户可在联想应用商店进行退款
Q:退款通知地址是否可以先提供测试环境的,待应用上线时再更改为正式的地址?
A:可以
10.2. 接入订阅SDK
Q:SDK目前支持的语言版本?
A:目前支持C++、C#,其他版本开发中
Q:帐号登录窗口是SDK弹的吗?
A:是的,SDK弹出的登录窗口包含了登录、注册、更改密码等功能
Q:用户必须使用联想帐号登录吗?
A:订阅服务中用户须使用联想帐号登录
Q:开发者是否需要为用户在自己的帐号体系中生成一个新帐号并自动绑定联想的帐号?
A:开发者可生成一个对用户不可见的帐号,或者不生成,直接使用登录SDK提供的唯一ID作为用户的唯一标识
Q:使用token获取lenovoID,开发者是通过应用客户端还是应用服务器去请求联想服务器获取?
A:考虑到通信的安全性,建议开发者尽可能通过应用的服务端去获取
Q:用户登录token是24小时过期吗?24小时过期,用户是否需要频繁登录?
A:为了保护用户帐号安全,token是24小时过期,但对已登录用户没有影响,无需用户频繁登录
Q:用户token如果过期,支付时是否需要用户重新登录?
A:无需用户重新登录,开发者可在调用支付接口前使用客户端提供的“获取最新token接口”获取token
Q:登录的接口中,入参的格式是json字符串吗?
A:是的
Q:登录的接口中,key值使用平台公钥还是应用私钥?
A:应用私钥
10.3. 接入退款API
Q:开发者的应用内是否需要支持用户退款?
A:建议开发者在应用内支持用户退款,若不支持,用户也可在联想应用商店内进行退款
Q:接入订阅服务后,开发者的微信/支付宝支付是否需要屏蔽,改为订阅服务的支付?
A:是的
Q:是否有接口查询支付结果和退款结果?
A:支付结果可通过接入文档中的“查询支付结果接口”查询,退款结果暂无查询接口,开发者可在退款通知中查询退款状态。
10.4. 测试
Q:支付和退款是否有测试环境?
A:无测试环境,开发者可将商品设为一个较低的金额(比如1分钱)进行测试。
10.5. 发布应用
Q:订阅版本的应用如何发布?
A:参与联运的应用首次上架及后续版本更新,开发者需将应用包发送给联想接口人,由联想进行配置上架。
Q:非联运版本的应用如何处理?
A:线上非联运版本的应用支持开发者保留和更新,这样可以满足用户的包体更新,主要依据开发者的诉求来决定是联运和非联运版本并行,还是主推联运版。
原文地址:https://open.lenovomm.com/developer/doc?id=1672841326302597121
联想开放平台地址:联想开放平台
联想开发者专属QQ客服(工作日9:30-18:00):联想开发平台首页右侧悬浮的在线客服聊天入口可直接会话,无需添加好友。也可搜索官方客服QQ号2881414004。
联想应用商店微信公众号:
相关文章:

PC端应用订阅SDK接入攻略
本文档介绍了联想应用联运sdk接入操作指南,您可在了解文档内容后,自行接入应用联运sdk。 1. 接入前准备 1. 请先与联想商务达成合作意向。 2. 联系联想运营,提供应用和公司信息,并获取商户id、app id、key(公私钥、…...

WebService的wsdl详解
webservice服务的wsdl内容详解,以及如何根据其内容编写调用代码 wsdl示例 展示一个webservice的wsdl,及调用这个接口的Axis客户端 wsdl This XML file does not appear to have any style information associated with it. The document tree is shown…...

数据分析实战:从0到1完成数据获取分析到可视化
文章目录 1.数据分析基本流程1.1 数据采集1.2 数据提炼1.3 数据探索分析 2.数据获取的方法和工具2.1 数据解锁器2.2 爬虫浏览器2.3 数据洞察市场 3.完整案例分析:从数据采集到数据可视化3.1 直接按需定制数据集获取数据3.2 获取IP代理,利用python爬取数据…...
【Spring】深入理解 Spring 中的 ImportSelector、Aware 和 Processor 接口
前言 Spring 框架提供了一系列接口和机制,为开发者提供了灵活、可扩展的编程模型。其中,ImportSelector、Aware 接口以及 Processor 系列接口是非常重要的扩展点,本文将深入探讨它们的设计目的、使用方法以及示例应用。 一、ImportSelector…...

【C语言】strstr函数的使用和模拟
前言 今天给大家带来一个字符串函数,strstr()的使用介绍和模拟实现。 模拟实现这个函数,可以帮助我们更深刻地理解这个函数的功能和提高解决字符串相关问题的能力,有兴趣的话就请往下看吧。 strstr函数介绍 函数功能: strstr函…...

五分钟”手撕“异常
目录 一、什么是异常 二、异常的体系和分类 三、异常的处理 1.抛出异常 2.异常的捕获 异常声明throws: try-catch处理 四、finally finally一定会被执行吗? 五、throw和throws区别 六、异常处理的流程 七、自定义异常 一、什么是异常 顾名…...

【vue3+elementuiplus】el-select下拉框会自动触发校验规则
场景:编辑弹框省份字段下拉框必填,触发方式change,有值第一次打开不会触发校验提示,关闭弹框再次打开触发必填校验提示,但是该字段有值 问题的原因是:在关闭弹层事件中,我做了resetfileds&…...

【论文复现】LSTM长短记忆网络
LSTM 前言网络架构总线遗忘门记忆门记忆细胞输出门 模型定义单个LSTM神经元的定义LSTM层内结构的定义 模型训练模型评估代码细节LSTM层单元的首尾的处理配置Tensorflow的GPU版本 前言 LSTM作为经典模型,可以用来做语言模型,实现类似于语言模型的功能&am…...
目标检测YOLO实战应用案例100讲-【自动驾驶】激光雷达
目录 前言 算法原理 测距方法 发射单元 接收单元 扫描单元...
用C语言设计轨道电机的驱动库
一、设计目的 设计能驱动立体轨道电机的抽象驱动程序库。 二、设计要求 命名规范。设计简单,方便使用。体积小。满足电机的移动、停止、初始化、恢复等控制,甚至通过网络控制。 三、设计内容 (一)属性封装 1、定义配置结构体 // 用于配置参数 typed…...

HTML跳动的爱心
目录 写在前面 HTML简介 跳动的爱心 代码分析 运行结果 推荐文章 写在后面 写在前面 哎呀,这是谁的小心心?跳得好快吖! HTML简介 老生常谈啦,咱们还是从HTML开始吧! HTML是超文本标记语言(Hyper…...

汇编原理(二)
寄存器:所有寄存器都是16位(0-15),可以存放两个字节 AX,BX,CX,DX存放一般性数据,称为通用寄存器 AX的逻辑结构。最大存放的数据为2的16次方减1。可分为AH和AL,兼容8位寄存器。 字:1word 2Byte…...

Android Studio开发之路(十三)主题影响Button颜色问题解决及button自定义样式
一、问题描述 在开发过程中发现安卓的默认主题色是紫色,并且会导致button也是紫色,有时直接在xml布局文件中直接设置button的背景色或者设置背景图片不起效果 方案一、如果是app,可以直接设置主题颜色 比如,将主题设置为白色&a…...

eNSP学习——OSPF单区域配置
目录 相关命令 实验背景 实验目的 实验步骤 实验拓扑 实验编址 实验步骤 1、基础配置 2、部署单区域OSPF网络 3、检查OSPF单区域的配置结果 OSPF——开放式最短路径优先 基于链路状态的协议,具有收敛快、路由无环、扩展性好等优点; 相关命令 […...

深度学习中的优化算法二(Pytorch 19)
一 梯度下降 尽管梯度下降(gradient descent)很少直接用于深度学习,但了解它是理解下一节 随机梯度下降算法 的关键。例如,由于学习率过大,优化问题可能会发散,这种现象早已在梯度下降中出现。同样地&…...
R实验 方差分析
实验目的: 掌握单因素方差分析的思想和方法; 掌握多重均值检验方法; 掌握多个总体的方差齐性检验; 掌握Kruskal-Wallis秩和检验的思想和方法; 掌握多重Wilcoxon秩和检验的思想和方法。 实验内容: &…...

AI智能体|手把手教你使用扣子Coze图像流的文生图功能
大家好,我是无界生长。 AI智能体|手把手教你使用扣子Coze图像流的文生图功能本文详细介绍了Coze平台的\x26quot;图像流\x26quot;功能中的\x26quot;文生图\x26quot;节点,包括创建图像流、编排文生图节点、节点参数配置,并通过案例…...

应用程序图标提取
文章目录 [toc]提取过程提取案例——提取7-zip应用程序的图标 提取过程 找到需要提取图标的应用程序的.exe文件 复制.exe文件到桌面,并将复制的.exe文件后缀改为.zip 使用解压工具7-zip解压.zip文件 在解压后的文件夹中,在.rsrc/ICON路径下的.ico文件…...
Excel表格在线解密:轻松解密密码,快速恢复数据
忘记了excel表格密码?教你简单两步走:具体步骤如下。首先,在百度搜索中键入“密码帝官网”。其次,点击“立即开始”,在用户中心上传表格文件即可找回密码。这种方法不用下载软件,操作简单易行,适…...

springboot小结1
什么是springboot Spring Boot是为了简化Spring应用的创建、运行、调试、部署等而出现的,使用它可以做到专注于Spring应用的开发,而无需过多关注XML的配置。 简单来说,它提供了一堆依赖打包Starter,并已经按照使用习惯解决…...

【Axure高保真原型】引导弹窗
今天和大家中分享引导弹窗的原型模板,载入页面后,会显示引导弹窗,适用于引导用户使用页面,点击完成后,会显示下一个引导弹窗,直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...
Vue记事本应用实现教程
文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展:显示创建时间8. 功能扩展:记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...

调用支付宝接口响应40004 SYSTEM_ERROR问题排查
在对接支付宝API的时候,遇到了一些问题,记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...

中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试
作者:Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位:中南大学地球科学与信息物理学院论文标题:BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接:https://arxiv.…...
Linux简单的操作
ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...

DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI
前一阵子在百度 AI 开发者大会上,看到基于小智 AI DIY 玩具的演示,感觉有点意思,想着自己也来试试。 如果只是想烧录现成的固件,乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外,还提供了基于网页版的 ESP LA…...

MySQL 8.0 OCP 英文题库解析(十三)
Oracle 为庆祝 MySQL 30 周年,截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始,将英文题库免费公布出来,并进行解析,帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...
CMake控制VS2022项目文件分组
我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...

网站指纹识别
网站指纹识别 网站的最基本组成:服务器(操作系统)、中间件(web容器)、脚本语言、数据厍 为什么要了解这些?举个例子:发现了一个文件读取漏洞,我们需要读/etc/passwd,如…...
《C++ 模板》
目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板,就像一个模具,里面可以将不同类型的材料做成一个形状,其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式:templa…...