.NetCore对接各大财务软件凭证API——用友系列(1)

一.前言

今天,我们转战用友系列的第一个产品—T+/Tplus。前两篇文章讲解分享的都是金蝶的产品,因为本身公司牵涉的业务有限,后续有金蝶其他产品的API对接业务时,会继续来分享经验。

T+的API接口,哎,想起来都是心酸泪。关于该接口的对接开发经验,我之前也简单记录了一些,传送门 记录用友T+接口对接的心酸历程。今天我们就来详细解析下这令人头大的财务API接口。

二.API接口详解

2.1接口定义和入参

根据开发者社区API文档的描述我们可以看到,T+版本为12.3以上的API对接,都必须使用V2版本,那v2与v1版本的区别有哪些呢?主要有两点:1. 请求认证方式,增加云企业ID认证方式 ;2.v2版本支持异步请求。OK,因为我们对接的客户财务环境为12.3,那么我们就来处理v2版本的OpenAPI,该版本的API引入了鉴权机制,简单来说就是在请求头增加了授权 Authorization 参数.

2.1.1 Authorization参数以及签名处理

那么 Authorization 参数如何才能生成呢?可以看官网首页的描述是 需要appkey、appsecert、私钥的文件全路径。那这三个参数又如何才能获取呢?必须申请ISV认证,即注册ISV,提交开发申请通过审核后,总部会将这三个参数一并发到注册时预留的邮箱里。

2.1.2 OrgId方式的签名算法处理

这里,我们在上一步已经拿到签名所需的三个必要参数了,官网给了两种请求Head的处理方式,一种使用OrgId,一种使用用户名、密码、账套号,这两种方式我们都会讲到。先看第一种方式OrgId访问。

OrgId的获取方式,官网描述的也有,

即必须开通云企业才能看到

这样,我们第一种使用OrgId认证方式的所需参数就已全部准备完毕了,接着往下看,首先需要对appKey、orgid、appsecret、私钥全路径做一个签名1的算法加密,这个算法官网给我们提供的也有,这里仅提供C#版本的签名算法1.接着做一个Base64位的加密即可得到Authorization参数。

          if (!APIConfig.AuthorizeParameters.ContainsKey("appkey")|| !APIConfig.AuthorizeParameters.ContainsKey("orgid")|| !APIConfig.AuthorizeParameters.ContainsKey("appsecret")|| !APIConfig.AuthorizeParameters.ContainsKey("secerturl")){throw new Exception("鉴权参数不完整");}var request = new AccessTokenRequest();Dictionary<string, object> parm = new Dictionary<string, object>();string appkey = APIConfig.AuthorizeParameters["appkey"];string orgid = APIConfig.AuthorizeParameters["orgid"];string appsecret = APIConfig.AuthorizeParameters["appsecret"];string secetrurl = APIConfig.AuthorizeParameters["secerturl"];parm.Add("appkey", appkey);parm.Add("orgid", orgid);parm.Add("appsecret", appsecret);JsonSerializer jsonSerializer = new JsonSerializer();string datas = jsonSerializer.Serialize(parm);try{var signClass = new TokenManage();string signvalue = signClass.CreateSignedToken(datas, secetrurl);string authStr = @"{""appKey"":""" + appkey + @""",""authInfo"":""" + signvalue + @""",""orgId"":" + orgid + @"}";string encode = Convert.ToBase64String(UTF8Encoding.UTF8.GetBytes(authStr));Dictionary<string, string> parms = new Dictionary<string, string>();parms.Add("Authorization", encode);request.SetHeaderParameters(parms);var response = Excute(request);return response;}catch (Exception ex){throw new Exception(ex.Message);}

当你处理完第一步,调试接口正常返回

{"result":true,"access_token":"03e74889-1457-48cd-970a-ba3742ffcdea","sid":""}

先不要高兴的太早了,我们还要根据这一步获取到的Token做业务调用。如图所示

官网也给的有测试的Demo供我们调用调试,这比较方便我们对问题作出反馈。 T+OpenAPI测试工具-包含v2版本-C#.zip. 然后大坑就来了…demo中的jose-jwt.dll是 .NET Framework的版本,但是我们的开发环境是.netCore2.2,很遗憾的是该dll在.netCore环境下不支持.详细的解决过程很心酸,就不再多叙述,我在之前的文章里已详细描述,这里我们只说最后的结果就是解决了不支持的问题。

2.1.3 用户名密码方式的签名算法处理

这种方式的登录相比第一种使用OrgId认证的方式有什么好处呢?我在实际的开发中得到了验证,OrgId方式的认证在对那些没有开通云企业的客户来说这种方式是行不通的,所以相比较来说,还是用户名密码的认证比较通用,只要客户能提供给我们一个正常可登录财务系统的用户名和密码,我们就可以使用该方式来进行接口的开发对接。下面具体来说一下,如何正确得到该方式的Authoirzation参数。

这是第一步得到Token的方法,可以看到签名方式和加密方式不变,变得是签名方式的参数不同,orgId为空,在PostBody里要传入用户名、密码和账套号。

账套号为中括号里的,比如上图的021809… 不要传名称!不要传名称!不要传名称!接着获取到Token后,我们就可以调用业务接口了,这里还是使用用户名密码的方式来调用。

增加了上一步获取到的Token,详细代码如下

            var signClass = new TokenManage();var request = new GetTokenByPwdRequest();string appkey = APIConfig.AuthorizeParameters["appkey"];string appsecret = APIConfig.AuthorizeParameters["appsecret"];string secetrurl = APIConfig.AuthorizeParameters["secerturl"];string userName = APIConfig.AuthorizeParameters["userName"];string password = APIConfig.AuthorizeParameters["password"];string EncodePassword = signClass.GetMd5(password);string accNum = APIConfig.AuthorizeParameters["accNum"];Dictionary<string, object> parm = new Dictionary<string, object>();parm.Add("appkey", appkey);parm.Add("orgid", "");parm.Add("appsecret", appsecret);JsonSerializer jsonSerializer = new JsonSerializer();string datas = jsonSerializer.Serialize(parm);try{string signvalue = signClass.CreateSignedToken(datas, secetrurl);string authStr = @"{""appKey"":""" + appkey + @""",""authInfo"":""" + signvalue + @""",""orgId"":""""}";string encode = Convert.ToBase64String(UTF8Encoding.UTF8.GetBytes(authStr));Dictionary<string, string> parms = new Dictionary<string, string>();parms.Add("Authorization", encode);request.SetHeaderParameters(parms);Dictionary<string, object> postParms = new Dictionary<string, object>();var args = new PwdEntity() { userName = userName, password = EncodePassword, accNum = accNum };var argsJson = jsonSerializer.Serialize(args);postParms.Add("_args", argsJson);request.SetPostParameters(postParms);var response = Excute(request);return response;}catch (Exception ex){throw new Exception(ex.Message);}

两种方式都处理完毕了,我们就可以愉快的使用API来做业务的处理啦。

2.2 业务接口调用

2.2.1 会计科目查询


URL的话,v2版本的调用,我们只需将v1改为v2即可,若想一次性获取到所有的会计科目,查询条件传空值即可,即如下:

{ dto:{ }
}
        public QueryAccountResponse QueryAccountRequest(){var request = new QueryAccountRequest();var parmsDic = new Dictionary<string, object>();var parms = new QuertyEntity() { dto = new BasicDto { } };parmsDic.Add("_args", JsonConvert.SerializeObject(parms));request.SetPostParameters(parmsDic);return _Client.Excute(request);}

该方法可返回所有会计科目用作基础档案或者前端页面展示使用。

2.2.2 凭证相关操作

凭证创建请求实体:

{"dto": {"ExternalCode": "1", //外部编码-唯一码,长度小于50"DocType": {"Code": "记" // 凭证类别编码},"AttachedVoucherNum": "2",// 附单据数"Memo": "无", // 备注 长度小于50"VoucherDate": "2014-09-30",// 凭证日期"Entrys": [{"Summary": "提现", // 凭证摘要 "Account": {"Code": "1001" // 科目档案},"Currency": {"Code": "RMB" // 币别},"AmountCr": "100" //贷方金额},{"Summary": "提现","Account": {"Code": "1002"},"Currency": {"Code": "RMB"},"AmountDr": "100", // 借方金额"AuxInfos": [{ // 辅助核算信息"AuxAccDepartment": { // 部门核算"Code": "001"},"AuxAccInventory": { // 存货核算"Code": "001"},"AuxAccProject": { // 项目核算"Code": "001"},"AuxAccPerson": { // 人员核算"Code": "001"},"AuxAccCustomer": { //往来单位核算"Code": "001"}}]}]}
}

URL: TPlus/api/v1/doc/Create || TPlus/api/v2/doc/Create

构造好对应的凭证实体即可正常传输凭证了。

凭证查询:官网给的示例是传入一个dtos的数组,但是在实际的开发过程中,真正传入一个起始期间,一个截止时间时,并没有正确的返回对应的数据,所以我到现在也没搞明白这个起始和截止时间该咋用,如果有知道的小伙伴,还请帮忙解答。

三.结束语

其实,真正对于T+的业务调用并没有花费很多时间,因为前面的坑已经踩完了,后面基本上也没啥了,就是我很纳闷的是,每个接口的返回值格式是不固定的,这个就很令人费解啊。咱也搞不懂到底为啥这样定义。倒是前面处理签名算法和dll不兼容的问题前前后后大约搞了一个星期才完整解决,这个很是让人头大。

曾经在T+的开发群了看到这样一句话,每个开发都是一个实施。也确实是这样一种情况,你对接的每个API接口,不可能总会有人给你解答问题,这时候你只能靠自己去摸索,去猜,当然了大部分的开发文档还是很规范的。其实做对接的做多了,你会遇到不同形式的API接口,每家厂商都有自己独特的开发标准,我们能做的就是遵循这套标准,不然如何对接,如何正确处理我们的工作。

最后的最后,希望我们做API对接或者说是做开发的,要保持一颗良好的心态去面对问题,要相信问题总是会被解决的,只是时间早晚。而且要找对方法,比如社区,或者对应的交流群等等,会有很多大佬帮你解答疑惑,祝你在开发的道路上勇往直前的。

我是程序猿贝塔,一个分享自己对接过财务系统API经历和生活感悟的程序员。

.NetCore对接各大财务软件凭证API——用友系列(1)相关推荐

  1. .NetCore对接各大财务软件凭证API——用友系列(3)

    一. 前言 由于前段时间项目比较集中,所以停更了好久,终于来到我们用友的系列产品3-U8Cloud2.7了. 一,2.7和2.5的api方式有什么区别? 1.2.7版本以后可以直接使用u8c登入地址直 ...

  2. .NetCore对接各大财务软件凭证API——金蝶系列(1)

    .NetCore对接各大财务软件凭证API--金蝶系列(1) 哈喽,又和大家见面了,虽然看文章的小伙伴不多,但是我相信总有一天,自己写的这些文章或多或少会对其他人有些帮助,让他们在相关的业务开发下能少 ...

  3. NetCore对接各大财务软件凭证API——前言

    @ .NetCore对接各大财务软件凭证API--前言 前言:作为一名程序员,难免少不了和其他系统做对接,那么API接口是最常见的一种对接方式了.当然,得益于公司的业务方向就是解决各大餐饮业财务手工做 ...

  4. oracle财务软件凭证打印,金算盘财务软件后台数据库为Oracle

    金算盘财务软件后台数据库为Oracle,OA系统中虽然提供了金算盘财务软件的接口,但由于版本较低,无法直接采集金算盘财务软件的备份数据.我们发现,在已试验的金算盘财务软件的凭证表中,科目字段中既有科目 ...

  5. 金蝶k3财务接口_记录用友T+接口对接的心酸历程

    前言:公司的业务主要是对接财务系统做单据传输或者凭证处理的,难免少不了和各大财务软件做数据对接,其中当然是必须通过接口来传递数据了.于是乎,用友T+的版本来了,对接的工作自然是我来做,可没想到就是这样 ...

  6. 购买财务软件需要注意的4个方面

    如今,伴随着信息化的普及,会计工作在这个时代的大背景下,也不再是传统的手工记账,而是转向了管理软件,那么新的问题来了,如何购买财务软件呢?市场上的财务软件琳琅满目,各式各样,只有适合自己企业的财务软件 ...

  7. ERP售前史话:本土财务软件前世今生

    15年的用友与10年的金蝶背后,是中国本土财务软件厂商整体缺钙的缩影. 文/本刊记者 辛云勇 表面上,用友金蝶们又回到了当年的起点.不过,这种戏剧性的回归背后,却是整个本土财务软件其实盛名难符的真实写 ...

  8. 【远程办公】外网远程访问公司内网用友畅捷通T财务软件

    文章目录 前言 1.本地访问简介 2. cpolar内网穿透 3. 公网远程访问 4. 固定公网地址 转发自cpolar极点云的文章:外网远程访问公司内网用友畅捷通T财务软件 – 远程办公 前言 用友 ...

  9. 在家远程使用公司用友ERP财务软件 【远程办公】

    文章目录 前言 1.本地访问简介 2. cpolar内网穿透 3. 公网远程访问 4. 固定公网地址 转发自cpolar极点云的文章:外网远程访问公司内网用友畅捷通T财务软件 – 远程办公 前言 用友 ...

  10. 智点财务软件记账凭证的录入

    目前的财务软件市场中,有大家熟知的大众会计软件,像智点等,也有新兴起的小众软件.越来越多的会计软件在充斥着这个市场,所以,难免企业在选择记账软件的时候,就显得非常的谨慎而又困难,因为有些软件的稳定性和 ...

最新文章

  1. python怎么建立画板_Python基于opencv实现的简单画板功能示例
  2. gcc: error: CreateProcess: No such file or directory解决方案
  3. 在SAP WebIDE里开发一个最简单的react component
  4. 异步api_如何设计无服务器异步API
  5. arry-718 Maximum Length of Repeated Subarray
  6. Android之智能问答机器人
  7. openfire php注册,openfire php 初始配置
  8. Spring boot与Quartz实现任务定时提醒
  9. 签约!睿铂与泰瑞数创共同助力实景三维中国建设
  10. 淘宝Web服务器Tengine正式开源
  11. 蚂蚁金服CTO程立:金融级分布式交易的技术路径
  12. 【数字信号】基于matlab CEEMD数字信号分解【含Matlab源码 1383】
  13. linux终端怎么复制粘贴某一行_如何在Linux终端中复制和粘贴文本、文件和文件夹...
  14. [树 乱搞] BZOJ 4238 电压
  15. 【信息学奥赛】1005:地球人口承载力估计(C++)
  16. 知乎页面颜色个性化修改
  17. macOS手动启动 Simulator(ios模拟器)
  18. 六、Dubbo协议模块原理源码解析
  19. [Android Studio]开发APP应用出现软件程序打开闪退的排错
  20. Unity优化翻译官方文档(六) ------ CPU Usage Profiler

热门文章

  1. 计算机网络(谢希仁版)知识点汇总
  2. 企业图纸无纸化,企业图纸安全使用和传输解决方案
  3. SPI总线-物理层 协议层
  4. 杰理AC692X系列---关于692x及693x的打开在线调EQ功能(4)
  5. 用c语言找最大素数,C语言实现寻找大素数
  6. 将数字转为中文金额的大写方式(C++版)
  7. 统计学中p值计算公式_统计学中的P值应该怎么计算
  8. Python爬虫系列(五)360图库美女图片下载
  9. 【干货分享】Color Fonts是什么?多彩字体详解
  10. Vue音乐播放器入门Demo及Vue环境搭建运行