有奖捉虫:办公协同&微信生态&物联网文档专题 HOT

通讯说明

所有接口均使用 HTTPS 通信,数据包格式为 json(HTTP 请求的 content-type 字段必须使用 application/json)。
请求必须传认证信息,需要传认证码和认证算法。
响应要验证认证码。
所有接口参数名使用的字母均为小写。

数据包格式说明

请求包格式

请求格式示例(以 query_order 接口为例):
{??
????"authen_info":?{??
????????"a":?{??
????????????"authen_type":?1,??
????????????"authen_code":?"69E65DA0A32F18D059DBE81CA4D9D702470184966E12A03715584249788BD8DD"??
????????}??
????},??
????"request_content":?"{\\"pay_mch_key\\":?{\\"pay_platform\\":?1,?\\"sub_pay_platform\\":?100,?\\"out_shop_id\\":?\\"sz011biKxOguirmBqiFR\\",?\\"out_sub_mch_id\\":?\\"sz01KzuCUOmw8yjtPite\\",?\\"out_mch_id\\":?\\"sz01lXKA6DKGjNzr2l4B\\"},?\\"trade_type\\":?1,?\\"out_trade_no\\":?\\"sz010002cz11564386781\\",?\\"nonce_str\\":?\\"E94C00688C3F429CA2B0B396BF823548\\",?\\"order_client\\":?{\\"staff_id\\":?\\"1192\\",?\\"machine_no\\":?\\"1111\\",?\\"terminal_type\\":?1,?\\"sdk_version\\":?\\"1.0\\",?\\"device_id\\":?\\"12345\\",?\\"spbill_create_ip\\":?\\"90.0.00.0\\"}}"??
}??
详解: 请求包含两个字段:authen_info 和 request_content。前者表示认证信息,为 json 结构;后者表示请求具体内容,为 json 形式字符串化。
request_content 为具体请求内容的 json 字符串化结构,见各具体接口。
authen_info 结构有嵌套属性 a,字段为认证码:
字段
类型
说明
authen_type
Number(32)
认证算法类型。只支持填1,即为 HMAC-SHA256
authen_code
String(64)
认证码
认证码生成算法:HMAC-SHA256 认证密钥为服务商在云支付录入商户时,在子商户页面上生成的认证密钥。

响应包格式

响应包与请求包类似,包含两个字段:authen_info 和 response_content。前者表示认证信息(响应包仅有认证码方式),为 json 结构;后者表示响应具体内容,为 json 形式字符串化。响应格式示例(以交接班接口为例):
{??
????"authen_info":?{??
????????"a"{??
???????????"authen_type":?1,??
????????????"authen_code"?:?"1CB622818DF1E2D91741A5FE792F1EFDD2557343FBD1275628E832A95CBB0FBC"??
????????}??
????},??
????"response_content":?"{\\"status\\":0,\\"description\\":\\"\\\\u64CD\\\\u4F5C\\\\u6210\\\\u529F\\\\u3002\\",\\"log_id\\":1167366844,\\"internal_status\\":0}"??
}??

其它说明

各种 update 接口中,如选填字段不填写,则该字段不需修改。清空此字段时,需上传此字段的内容为空。
接口调用说明 交易接口中的门店信息,必须和子商户在云支付手机端商户管理系统设置的一致。
订单和退款单号说明 为了保护不同商户的订单号不重复,云支付为每个服务商录入的子商户分配“云支付订单前缀”,在云支付后台的商户详情中可以看到,该商户的订单和退款单必须以云支付子商户号做前缀。

数据包构造示例

下面以刷卡支付为例来介绍整个认证过程:

客户端向服务器发送请求

1. 判定使用场景。 在这个示例中,我们要发出的是刷卡支付请求。因此,需要使用认证算法来计算认证码。
2. 根据接口的输入参数,构造 json 格式字符串。
?
?
3. 将 json 格式字符串转换为字符串,并使用认证算法,认证 key 来计算认证码。
?
?
4. 构造 authen_info 结构。
?
?
5. 构造 json 格式的请求数据包,需要包含 authen_info 和 request_content 字段。
6. 将 json 格式请求转换为字符串,发送给服务器。
?
?

客户端验证服务器应答消息

1. 将响应包从 string 转换为 json 格式消息。
2. 取出 json 格式消息中的 authen_info 和 response_content 字段信息。
3. 使用认证算法和认证 key 对 response_content 计算认证码。
4. 将计算得到的认证码和 authen_info 中的 authen_code 进行比较;正确情况下,两者应该一致。

代码示例(C++)

构造请求字符串(以刷卡支付为例):
std::string?MicroPay_request_str()??
{??
????/*?1.构造业务请求参数?*/??
????Json::Value?pay_mch_key;??????//?构造?pay_mch_key??
????pay_mch_key["pay_platform"]???=?1;??
????pay_mch_key["out_mch_id"]?????=?"sz013NzuonO6CMJd0rCB";??
????pay_mch_key["out_sub_mch_id"]?=?"sz01ELTR281OFpmdAp6J";??
????pay_mch_key["out_shop_id"]????=?"sz01qyoPJmd3j1hWmul4";??
????Json::Value?pay_content;??????//?构造?pay_content??
????pay_content["out_trade_no"]???=?"sz0100lmnx20171228151031";??
????pay_content["author_code"]????=?"134680423163089456";??
????pay_content["total_fee"]??????=?1;??
????pay_content["fee_type"]???????=?"CNY";??
????pay_content["attach"]?????????=?"attach";??
????Json::Value?order_client;????????//?构造?order_client??
????order_client["machine_no"]???????=?"32-62-A8-14-B3-C0";??
????order_client["sdk_version"]??????=?"1.0";??
????order_client["device_id"]????????=?1;??
????order_client["spbill_create_ip"]?=?"192.168.100.75";??
????order_client["staff_id"]?????????=?"1003";??
???order_client["terminal_type"]????=?2;??
????Json::Value?request_content;?????//?构造?request_content??
????request_content["pay_mch_key"]???=?pay_mch_key;??
????request_content["pay_content"]???=?pay_content;??
????request_content["order_client"]??=?order_client;??
????request_content["nonce_str"]?????=?"416492026bc84091bcaf7e74ea90ceba";??
????Json::FastWriter?w;??
????std::string?request_content_str?=?w.write(request_content);??
????/*?2.?根据上面的业务请求参数计算认证码?*/??
????Json::Value?authen;??
????std::string?hmac;??
???calc_HMAC_SHA256(authen_key,?request_content_str,?&hmac);?//计算认证码??
????authen["authen_code"]?=?hmac;??
????authen["authen_type"]?=?1;?//hmac_sha256?为1??
????Json::Value?authen_info;??
????authen_info["a"]?=?authen;??//认证码??
????/*?3.?拼装最终请求参数?*/??
????Json::Value?request;???????//构造最终发给服务器的请求??
????request["request_content"]?=?request_content_str;??
????request["authen_info"]?????=?authen_info;??
????std::string?request_str?=?w.write(request);??
????return?request_str;??
}??
计算认证码:
/*?
返回是否成功,成功时认证码存放于?hmac?指向的?string?
*/??
bool?calc_HMAC_SHA256(const?std::string?&key,?const?std::string?&input,?std::string?*hmac)??
{??
????unsigned?char?md[SHA256_DIGEST_LENGTH]?=?{0};//32?bytes??
????char?format_md[65]?=?{0};??
????unsigned?int?md_len?=?sizeof(md);??
????HMAC_CTX?ctx;??
????HMAC_CTX_init(&ctx);??
????if?(!HMAC_Init_ex(&ctx,?key.data(),?(int)key.length(),?EVP_sha256(),?NULL)??||??
????????!HMAC_Update(&ctx,?(const?unsigned?char?*)input.data(),?input.length())?||??
????????!HMAC_Final(&ctx,?md,?&md_len))?{??
????????HMAC_CTX_cleanup(&ctx);??
????????return?false;??
????}??
????HMAC_CTX_cleanup(&ctx);??
????for?(int?i?=?0;?i?<?32;?i++)?{??
????????snprintf(&format_md[i?*?2],?3,?"%02x",?md[i]);?//二进制转为十六进制大写??
????}??
????hmac->assign(format_md);??
????//?转大写??
????transform(hmac->begin(),?hmac->end(),?hmac->begin(),?::toupper);??
????return?true;??
}??
?


http://www.vxiaotou.com