
简介上海五期医保接口说明文档面向医疗信息系统开发、测试与维护人员是一份围绕 HIS 与上海医保中心系统数据交互的接口对接参考重点覆盖电子凭证解码、医保项目明细上传、门诊挂号收费、住院结算、登记撤销、对账退款等核心业务场景。资源包仅包含 1 个 docx 文档大小 34KB按引言、业务分析、接口描述三章组织可直接作为研发评审、设计参考和联调依据。文档对读卡、解码、挂号请求与确认、收费请求与确认、登记请求、撤销登记、明细上传/撤销、住院结算、对账、退款、账户查询、登记查询等业务做了系统梳理并介绍了标准 JSON 返回报文格式方法部分详细说明了初始化、ShYbV5_S000、ShYbV5_SE01、ShYbV5_SH01 等接口的参数、返回数据项及调用顺序帮助开发者快速理解医保接口调用逻辑与字段含义。已有 1593 人学习下载适合正在进行上海医保五期对接改造或需要撰写接口方案的研发人员参考。1. 上海医保五期接口说明这份文档到底能解决HIS对接里的什么问题如果你所在的公司正在做医院HIS系统而医院又恰好被列为上海医保五期接口的上线范围那你手头大概率已经拿到了这份名为“上海五期医保接口说明.docx”的文档。别被“说明”两个字带偏这其实是一份接口开发规范定义了HIS前台程序如何调用医保中心系统提供的动态链接库方法完成挂号、收费、明细上传、结算、撤销等一整套医保业务。我接手这个对接任务的第一周最大的感受是文档里没有一行业务代码但每一条字段定义、返回码、调用顺序都直接影响你能不能跑通一个结算单。本文我会把这份文档拆开讲讲清楚它的设计逻辑、调用链路、字段含义和最容易翻车的地方帮你省掉自己对着文档反复试错的时间。2. 接口设计拆解JSON报文、16位账户标志与黑匣子调用逻辑2.1 返回报文为什么统一用JSON从串联到解耦文档在 3.1 节明确写了一句所有返回 string 类型的方法统一返回标准 JSON 格式。比如 ShYbV5_S000 返回的报文是{ kh: Z59898D78, xm: test, xb: 1, sfzh: 31000119500417017, lxdh: 13333333333, txdz: 上海市闵行区虹梅路, yzbm: , xzqh: 310000 }这个字段清单就是一个典型的患者实名信息结构卡号、姓名、性别、身份证号、联系电话、通讯地址、邮政编码、行政区域代码。所有键都是拼音缩写没有多余嵌套对HIS方来说解析成本很低用现成的JSON库一行就能转成对象。我在接入时直接用 Newtonsoft.JsonC#的JObject.Parse解析整个项目的报文处理代码几乎没有因为格式问题返工过。这里有个容易被忽略的点为什么中心系统不直接返回一个强类型的类而是统一用 JSON 字符串因为该接口方法所在的动态链接库是被HIS进程直接引用的双方并不是通过 WebService 或 HTTP 通信而是进程内方法调用。用 JSON 字符串做载体可以避免动态链接库升级时因为强类型签名变更导致HIS侧需要重新编译。也就是说中心系统侧升级方法内部逻辑只要方法签名保持string返回HIS侧代码可以不动。这个设计思路值得我们在自己的对外接口里借鉴。2.2 16位账户标志第一眼要读懂的四个典型位文档名词解释里提到医保中心系统通过一个16位账户标志描述参保人员类别每一位数字都有定义具体细节指向《中心系统与定点医疗机构接口规范 5.0》。虽然这份规范不在手头但实际开发中账户标志直接影响医保支付办法的计算结果。我从文档里的医保支付办法能反推出几个关键位职退情况在职还是退休、保健情况是否享受干部保健、特殊人员标识离休、伤残、干保、医保办法普通门诊、大病、家床、工伤。这几个分类直接影响中心系统返回的支付段金额。比如普通门诊是先当年账户、再历年账户、然后自负段而门诊大病则是统筹支付封顶线以下个人自负8%。HIS侧不需要自己实现这套支付段规则但必须把账户标志原样传给后续结算请求并且在前台界面展示给收费员看方便收费员判断病人身份是否与就诊类型匹配。实际接的时候我一般会打印一份账户标志样例把每个位置的值和文档定义的对应关系做成一张配置表放到代码注释里方便后续排查。因为HIS业务人员问“为什么这个病人自负比例不一样”的时候你打开账户标志一看就能回答不用去问医保那边。2.3 调用依赖黑匣子背后的三阶段状态文档在功能分析里有一句话说得比较直白对于主程序而言接口程序比较简单类似一个黑匣子只需按照约定调用相应方法即可。但这不意味着可以随便调用。根据方法描述整个业务可以分成三个阶段第一阶段是前置也就是 Init 初始化必须在每个独立操作前调用比如每个挂号窗口在开始挂号请求前要先初始化。第二阶段是身份获取芯片卡走 S000 读卡电子凭证走 SE01 解码磁条卡直接刷卡拿卡号。第三阶段是业务交易挂号请求 SH01 拿到计算申请序号然后 SH02 确认拿就诊单元号和中心流水号再做明细上传 SN01最后收费并确认。我画过一张简化的状态流转图Init → 身份获取 → 挂号请求 → 挂号确认 → 明细上传 → 收费请求 → 收费确认 → 结算完成。任何一个环节没走完都不能直接跳下一步。特别是挂号请求拿到的计算申请序号其实是在挂号确认、收费请求里反复要用到的凭证。丢失了这个序号等于这笔交易就悬空了只能走撤销或对账流程这一点后面我会专门展开。3. 完整调用链路初始化到收费确认的六个关键方法3.1 初始化与读卡每一个独立操作前都要先Init文档里 Init 方法有两个关键参数操作员编码czybm和操作员姓名czyxm还有交易渠道jyqd默认传 10 表示线下交易20 表示线上交易。这个方法在挂号窗口、收费窗口每次操作前都需要调用但要注意它只需要在每个独立操作前调用一次比如窗口收费员在给当前病人做收费请求前调用之后做收费确认时不需要再调用。我一般会在收费员登录工作站的时候就调用一次 Init把操作员信息保存到会话里而不是每次读卡都重新初始化。因为 Init 传的参数里有操作员姓名如果每次操作前都重新赋值一旦上一笔交易还没结束可能会把操作员上下文冲掉。文档原话是“挂号窗口在进行挂号请求时调用那么在挂号确认时无需调用”这个边界要记牢。读卡方法 ShYbV5_S000 无参数返回的 JSON 里有卡号、姓名、身份证号等。芯片卡插入读卡机后调用这个方法返回的卡号 kh 是 9 位。磁条卡则是直接刷卡获取 28 位卡号不需要调用这个读卡方法读到卡号后走后面的挂号请求。这个区别经常有人在联调时搞混插了芯片卡却不调 S000直接拿读卡机读出来的物理卡号去请求结果报卡号不存在。3.2 电子凭证解码二维码怎么变成身份证与令牌电子凭证也就是我们常说的医保电子凭证是三类卡类型里最特殊的一种。它的流程分两步第一步HIS前置通过支付宝、微信、随申码渠道获取一个二维码值第二步调用 ShYbV5_SE01传参包括二维码值、获取二维码渠道和业务类型。渠道码是固定枚举1 支付宝、2 微信、3 随申码。SE01 返回的 JSON 里有四个字段username姓名、idno证件号码、idtype证件类型、ecToken令牌。这里的关键是ecToken 才是后续挂号请求里 carddata 字段要传的值而不是二维码原始值。我在第一次对接时犯过一个错把二维码明文当成令牌塞进了 SH01 的 carddata结果中心系统直接返回找不到交易。后来看了文档才明白SE01 的作用是把二维码解码成身份证信息和令牌之后所有交易都用令牌来标识患者身份令牌有效期由中心系统控制。所以前端在拿到二维码后要先调 SE01 把令牌解出来再带着令牌走挂号流程。3.3 挂号请求与确认从计算申请序号到就诊单元号挂号请求 ShYbV5_SH01 是整条链路里参数最多的方法。传参包括卡类型、卡号、科室编码、诊疗项目代码、特殊人员标识、医疗类别、大病项目代码、病人类型、工伤认定号还有一组金额字段交易费用总额、医保结算范围总额、诊疗费、门急诊诊疗费自费、非医保结算范围总额、享受社区减免标志。这些金额字段中交易费用总额和医保结算范围总额是两个概念前者是HIS实际收取的总金额后者是医保认可的可结算范围。比如某项自费药品交易费用总额包含它但医保结算范围总额不含。中心系统返回的 JSON 里有一组支付段字段当年账户支付数、历年账户支付数、自负段现金支付数、自负段历年账户支付数、统筹段账户支付数、统筹段现金支付数、统筹支付数、附加段账户支付数、附加段现金支付数、附加支付数外加当年账户余额、历年账户余额和最重要的计算申请序号 jssqxh。挂号确认 ShYbV5_SH02 就简单得多只要把计算申请序号传过去返回就诊单元号和中心流水号。这里有一个常见的理解偏差挂号请求返回的 jssqxh 并不是最终结果的确认凭证它只是一个申请序号表示中心系统已经受理了这笔请求但还没最终落账。只有 SH02 确认成功拿到 jzdyh 和 lsh这笔挂号才算真正有效。3.4 明细上传与收费结算SN01 是整个链路里最沉的一环文档对明细上传的说明很详细核心是在调用明细上传方法之前HIS系统需要提供一个查询病人费用明细的接口接口建议使用 webservice返回 json 格式字符串。输入参数是 djh门诊号或住院号输出是一个明细列表包含序号、处方号、科室编码、科室名称、处方医生号、处方医生姓名、费用类别、明细项目编码、明细项目名称、明细项目单位、单价、数量、金额、交易费用、医保结算范围费用还有医用材料品牌、注册证号、规格、使用日期、报销标志、收费退费标志、减负标志和是否细分明细。其中最复杂的是细分明细循环如果某个明细项设置了“是否细分明细1”那么还要跟一个子循环体里面是上一层的序号、子类明细项目编码、名称、单价、数量、金额、报销标志、收费退费标志等。这个结构用 webservice 返回时需要拼成嵌套 JSON。我的做法是在HIS侧写一个查询服务把主子结构组装成 JSON 数组返回给医保动态链接库。SN01 方法的入参有门诊号/住院号、就诊单元号和结算类型标志。这里有个必须注意的字段jslxbz。门诊结算传 120急诊结算 220家床结算 410急观结算 510住院结算 610。门诊大病前两位是 32也就是 32 开头后面一位区分大病类别1 化疗、2 放疗、3 血透、4 腹透、6 肾移植抗排异、7 同位素治疗、8 介入治疗、9 中医药治疗、A 精神病。这个标志稍微传错医保中心会直接按普通门诊处理自负比例会差很多是医保拒付的高发区。4. 字段字典与业务标志卡类型、医疗类别、结算标志怎么传4.1 卡类型与读卡方式三种卡三种入口文档开篇的名词解释里定义了卡类型枚举芯片卡 1、磁条卡 0、电子凭证 3。这组枚举在实际接入时贯穿所有交易方法的传参。我建议在HIS侧建立一个专门的卡类型管理模块把读卡、解码、刷卡三种入口分别封装成不同的函数但底层统一走同一个交易方法。比如你给一个芯片卡病人做挂号入口函数读卡成功后调用 SH01 时cardtype 永远传 1carddata 传空磁条卡刷卡后 cardtype 传 0carddata 传 28 位卡号电子凭证解码后 cardtype 传 3carddata 传 ecToken。这个映射关系看起来简单但实际联调时最容易错在三处一是把磁条卡的 28 位卡号直接当成 S000 的读卡输入显然 S000 是无参数方法二是电子凭证的 ecToken 长度比较长容易在数据库字段设计时截断导致请求传过去的令牌不完整三是同一台终端可能同时有芯片读卡器和磁条刷卡器需要根据科室的实际设备配置来控制 UI 上显示哪几个入口。4.2 医疗类别与大病项目两个字段决定结算路径医疗类别yllb是一个 3 位字符串文档没有给出完整枚举表但我从实际接口对接经验判断医保中心对医疗类别的取值有明确的字典HIS方一般从中心下发的药品目录或诊疗项目接口里同步。这个字段要和挂号请求里的特殊人员标识personspectag联动普通病人传 0离休传 1伤残传 2干保传 3。大病项目代码dbtype只在门诊大病挂号时填写其他情况可以为空。文档给的示例是大病挂号后一位区分化疗、放疗、血透等这个值要跟结算类型标志里的门诊大病后一位保持一致。比如病人做血透挂号请求里 dbtype 传 4血透到收费结算时 jslxbz 要传 324。两处不一致的后果是中心系统可能把大病费用当成普通门诊来处理。我的项目里专门做了一张“大病类别配置表”把 dbtype 和 jslxbz 的映射关系配好上线前逐条核验。4.3 结算类型标志和特殊人员标识最容易写错的枚举结算类型标志 jslxbz 在文档里有一段比较长的解释我给读者拆成几组方便记忆结算类型标志值说明门诊结算120普通门诊急诊结算220急诊家床结算410家庭病床急观结算510急诊观察住院结算610普通住院门诊大病化疗321前两位 32 加大病代码门诊大病放疗322门诊大病血透324门诊大病腹透324文档中血透与腹透同为 4实际需以中心最新字典为准门诊大病肾移植抗排异326门诊大病同位素治疗327门诊大病介入治疗328门诊大病中医药治疗329门诊大病精神病32AA 为字母注意大小写这张表我是在联调环境中反复比对中心系统返回的支付段金额后才最终确认的。这里给读者一个建议不要盲信任何第二手转述的字典包括我这篇文章。每个项目上线前从医保中心拿一份当期的字段字典表以那个为准。因为文档里写的是“大病项目代码”和“结算类型标志”分开两段描述中间的关联关系并没有写成映射表很容易被忽略。4.4 明细上传字段细分明细循环与退费标志明细上传的输出参数里有一个循环体前面提到的结构到了编码阶段容易出错。我建议在HIS侧先定义两个类明细主表和细分明细子表然后在 webservice 返回值里拼成嵌套数组。主表里的 xh 是序号子循环里的 xh 填的是上一层明细的序号。这个关联关系如果断掉中心系统会无法把子类明细挂载到正确的父级明细下。报销标志 bxbz 的枚举是0 可报销、1 不可报销、2 定额。收费退费标志 sftfbz 是1 收费、2 退费。这两个字段在退费场景里要特别注意退费时上传的明细清单里金额和数量要跟原账单一致但收费退费标志传 2表示这是一笔退费中心系统会冲减原明细。如果退费的明细项和原上传明细没有严格对应比如项目编码或单价不一致中心系统大概率会报错或者产生挂账。5. 避坑与排查对接中最高频的五个翻车现场5.1 电子凭证解码失败错误码没打出来整个流程就断了现象收费员扫描医保电子凭证二维码后SE01 返回的 JSON 里 ecToken 为空或者直接返回一个看不懂的错误字符串。原因SE01 的入参里有一个 officeId 和 officeName这是医保科室编码和名称。这两个字段很多HIS方在联调时没传或者传了空值。中心系统需要根据医保科室编码来确定该科室是否支持电子凭证结算如果这个科室没有在中心系统内登记解码环节就会失败。解决联调前先把院内科室编码和医保科室编码做好对照表在调用 SE01 前把 officeId 和 officeName 填上。另外渠道参数 ecQrChannel 要传对支付宝、微信、随申码生成的二维码格式不同渠道传错解码逻辑在中心侧就直接走另一条路径了。5.2 挂号请求成功但确认失败计算申请序号已经用了现象SH01 返回正常jssqxh 也拿到了但紧接着调 SH02 确认时返回“申请序号不存在”或“交易状态错误”。原因计算申请序号是一次性的。如果同一笔挂号在请求之后因为HIS侧异常又发了一次 SH01那么第一次的 jssqxh 就作废了中心系统只认最新的一笔申请。还有一种情况是SH01 请求发出后迟迟没确认超过中心系统的有效期限制序号过期。解决HIS侧必须保证“请求”和“确认”在短时间内成对出现不要在 SH01 之后插入其他长时间业务操作。从架构上我建议把 SH01 和 SH02 放进同一个事务方法里中间只做必要的金额计算不做网络等待。5.3 明细上传返回明细账单号为空结算流程直接卡死现象SN01 返回 fhm 和 fhxx 看起来正常但 mxzdh明细账单号字段是空字符串。原因SN01 的入参里有一个 djh文档写的是“门诊填写门诊号住院填写住院号”。但这里有个隐含前提这笔就诊必须已经有一个有效的就诊单元号也就是已经挂号确认过。如果 djh 对应的挂号记录在HIS侧还没确认中心系统找不到就诊单元就不会生成明细账单号。解决在调用 SN01 之前校验本地挂号记录是否已经拿到 jzdyh 和 lsh。拿不到就直接报错提示不让用户往下走。另外djh 字段和 jzdyh 字段要配合使用文档说 SN01 的输入参数有 jzdyh就诊单元号如果传了就诊单元号djh 可以用门诊号但两者必须对应同一笔就诊。5.4 医保支付办法与HIS计算金额不一致别急着说“医保算错了”现象中心系统返回的支付段金额中统筹支付数和HIS本地计算的预估金额差了几十甚至上百元。原因文档里写的支付办法是“例如”性质的描述比如普通门诊自负满后按医院级别分别自负10%、15%、20%但实际明细项目还有项目类别、药品目录、诊疗项目目录的限制有些项目医保完全不支付有些项目部分支付这些规则在HIS本地不可能全部精确复刻。中心系统返回的就是最终结果HIS侧展示给患者看的金额应该以中心系统返回为准。解决HIS侧不要试图在本地完整实现医保支付办法规则那是医保中心的职责。HIS只负责把交易费用总额和医保结算范围总额传对把中心返回的支付段金额原样展示。如果差异大到异常优先排查是不是医保结算范围总额字段没传对把自费项目塞进了可结算范围。5.5 退费时把原账单全部撤销重新上传新的明细现象退费操作时HIS侧直接调用了明细撤销方法把整个明细账单撤销然后又重新上传一次新明细结果中心系统提示“明细账单不存在”或者“结算单已存在”。原因明细撤销是有前置条件的只有中心系统尚未对该笔明细做结算确认时才能撤销。如果这笔明细已经通过收费确认完成了结算那么退费应该走退款请求文档里提到的退款请求方法而不是撤销。文档第二章功能分析里退款请求和明细撤销是分开的两个功能说明两个业务场景不同。解决区分两个场景。结算前发现明细录错了走明细撤销重传结算完成后病人要退费走退款请求。退款请求需要在HIS侧同时追回原结算单号、就诊单元号、明细账单号等关联信息。我的做法是设计一张退费关联表退费时把原结算的 jzdyh、lsh、mxzdh 全部带上传避免中心系统找不到原单。6. 上线前的自查用模拟数据把整条链路跑一遍6.1 搭一套中心系统模拟器把动态链接库的返回流程拉通第六阶段的实际操作是在正式接入医保中心环境之前我一般会先搭一套模拟环境。这套模拟器做的事情很简单把动态链接库暴露的方法按文档里的返回报文格式固定返回一组写死的 JSON。比如 ShYbV5_S000 永远返回固定的卡号 Z59898D78SH01 永远返回固定的 jssqxh 和一组支付段金额。这样HIS侧可以在完全不依赖医保中心网络的情况下把整条调用链路上的所有代码逻辑跑通。// C# 伪代码示例模拟读卡方法返回 public string Mock_ShYbV5_S000() { var json new Dictionarystring, string { { kh, Z59898D78 }, { xm, 测试 }, { xb, 1 }, { sfzh, 31000119500417017 }, { lxdh, 13333333333 }, { txdz, 测试地址 }, { yzbm, }, { xzqh, 310000 } }; return JsonConvert.SerializeObject(json); }这段代码很好理解HIS侧把动态链接库的接口抽象成接口比如IYbGateway正式实现是调用医保中心动态链接库模拟实现则直接返回写死的 JSON。这样整套业务代码从挂号、收费、结算到退费都可以在开发机上先跑一遍。我在项目里同时做了异常注入模拟器可以配置成返回指定错误码用来测试HIS侧的异常处理分支。6.2 用中心系统返回字段做金额一致性校验模拟器跑通之后下一步是把模拟返回的字段金额和HIS本地显示金额做对账。核心逻辑是医保结算范围总额 当年账户支付 历年账户支付 自负段现金支付 自负段历年账户支付 统筹段账户支付 统筹段现金支付 统筹支付 附加段账户支付 附加段现金支付 附加支付。这个等式成立说明解析逻辑没有问题。我在项目里做了一个简单的对账页面把这十个字段列出来自动求和和交易费用总额对比超过一分钱就标红。这个方法帮我抓到了不下五个字段解析错位的bug比如把统筹段现金支付和统筹支付两个字段的值搞反了。因为这两个字段在中心返回 JSON 里的位置相邻键名又极其相似解析时稍微手抖就会映射错。6.3 留好计算申请序号和中心流水号排查问题时的后悔药最后一件事也是我建议每个做HIS医保对接的人养成一个习惯所有请求和确认的入参、返回值尤其是计算申请序号、就诊单元号、中心流水号全部落一张日志表。别嫌数据量大一张普通结算单的请求日志撑死几百字节一天门诊量再大一张表半年也就几百万行对现代数据库来说没有压力。从那以后我每次排查医保对账差异第一件事就是查这张日志表把挂号请求的 jssqxh、确认返回的 lsh、明细上传的 mxzdh、结算返回的支付段金额全部拉出来按时间轴排一遍。交易对不上账的时候这几个号就是救命稻草。没有这几个号反推就只能拿着账单去找医保中心的人工通道等好几个工作日才有结果。希望这篇文章能帮你把这套对接流程看得更透也让你少走几趟“测试环境明明通了一上线就翻车”的弯路。本文还有配套的精品资源点击获取