OneCodePay.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403
  1. using Newtonsoft.Json;
  2. using Newtonsoft.Json.Linq;
  3. using PTMedicalInsurance.Common.SMLib;
  4. using PTMedicalInsurance.Entity;
  5. using PTMedicalInsurance.Helper;
  6. using PTMedicalInsurance.Variables;
  7. using Sunny.UI.Win32;
  8. using System;
  9. using System.Collections.Generic;
  10. using System.ComponentModel;
  11. using System.ComponentModel.DataAnnotations;
  12. using System.Data.Linq;
  13. using System.Data.Linq.Mapping;
  14. using System.Windows.Forms;
  15. namespace HeNanMI.Business
  16. {
  17. public class OneCodePay
  18. {
  19. public string url;
  20. InvokeHelper invoker = new InvokeHelper();
  21. public OneCodePay() { }
  22. public int GetCertAndSendToHis(decimal cashPay, out string msg)
  23. {
  24. msg = "";
  25. if (string.IsNullOrEmpty(Global.pat.ecToken))
  26. {
  27. msg = "一码付介质必须是电子凭证或人脸支付,其他介质暂不支持!";
  28. return -1;
  29. }
  30. if (!Global.pat.isOneCodePayEnabled)
  31. {
  32. msg = "未在界面勾选启用一码付!";
  33. return -1;
  34. }
  35. //先查询状态
  36. if (QuerySignedPayStatus(out msg) != 0)
  37. {
  38. return -1;
  39. }
  40. JObject jo = JObject.Parse(msg);
  41. string stasFlag = JsonHelper.getDestValue(jo, "stasFlag");
  42. string abnRea = JsonHelper.getDestValue(jo, "abnRea");
  43. //解析状态
  44. switch (stasFlag)
  45. {
  46. case "0":
  47. msg = "未签约不可用!" + abnRea;
  48. return -1;
  49. case "1":
  50. //msg = "已签约且可用";
  51. //return 0;
  52. break;
  53. case "2":
  54. msg = "已签约不可用" + abnRea;
  55. return -1;
  56. default:
  57. msg = "返回stasFlag值不正确!";
  58. return -1;
  59. }
  60. //获取凭证
  61. if (GetPayCert(cashPay, out msg) != 0)
  62. {
  63. return -1;
  64. }
  65. else
  66. {
  67. jo = JObject.Parse(msg);
  68. string payCert = JsonHelper.getDestValue(jo, "payCert");
  69. string payChnlName = JsonHelper.getDestValue(jo, "payChnlName");
  70. msg = BuildOneCodePaySuccessResult(payChnlName,payCert);
  71. Global.writeLog($"BuildOneCodePaySuccessResult:{msg}");
  72. return 0;
  73. }
  74. }
  75. /// <summary>
  76. /// 构建一码付结算成功的返回结果(含支付信息)
  77. /// </summary>
  78. /// <param name="payChannel">支付渠道,如 "ALIPAY" 或 "WECHAT"</param>
  79. /// <param name="authCode">用户授权码(付款码)</param>
  80. /// <returns>JSON 格式的 Iris 返回值字符串</returns>
  81. private string BuildOneCodePaySuccessResult(string payChannel, string authCode)
  82. {
  83. if (string.IsNullOrWhiteSpace(payChannel))
  84. MessageBox.Show($"支付渠道不能为空{nameof(payChannel)}");
  85. if (string.IsNullOrWhiteSpace(authCode))
  86. MessageBox.Show($"授权码不能为空{nameof(authCode)}");
  87. string paywCode = "";
  88. if (payChannel == "支付宝")
  89. {
  90. paywCode = "ALIPAY"; //ALIPAY,WECHAT
  91. }
  92. if (payChannel == "微信")
  93. {
  94. paywCode = "WECHAT"; //ALIPAY,WECHAT
  95. }
  96. var payInfo = new JObject
  97. {
  98. ["paywCode"] = paywCode,
  99. ["authcode"] = authCode
  100. };
  101. var result = JsonHelper.setIrisReturnValue(
  102. 0,
  103. "结算成功",
  104. new JObject { ["payInfo"] = payInfo }
  105. );
  106. return result.ToString(Formatting.None); // 紧凑格式,符合接口规范
  107. }
  108. ///查询一码付状态
  109. public int QuerySignedPayStatus(out string msg)
  110. {
  111. var request = new QuerySignedPayStatusRequest
  112. {
  113. token = Global.pat.ecToken, // 电子凭证令牌(模拟值)
  114. orgCodg = Global.inf.hospitalNO, // 定点医药机构代码(示例医保编码)
  115. orgName = Global.inf.hospitalName, // 机构名称(中文支持)
  116. opterId = Global.user.ID, // 经办人员编号
  117. opterName = Global.user.name, // 经办人姓名
  118. devId = Global.curEvt.mac, // 设备唯一标识(如 MAC 地址或 UUID)
  119. devIP = Global.curEvt.ip // 设备 IP 地址
  120. };
  121. string jsonStr = JsonConvert.SerializeObject(request, Formatting.None, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });//紧凑格式
  122. JObject joRtn = invoker.invokeOneCodePayService("QuerySignedPayStatus", jsonStr);
  123. if (JsonHelper.parseOneCodePayRtnValue(joRtn, out msg) != 0)
  124. {
  125. return -1;
  126. }
  127. else
  128. {
  129. msg = OneCodePayEncryptUtil.decrypt(JsonHelper.getDestValue(joRtn, "data.encData"), Global.inf.OneCodePay.apiSecretKey);
  130. Global.writeLog("QuerySignedPayStatus(明文)",jsonStr,msg);
  131. return 0;
  132. }
  133. }
  134. //获取一码付凭证
  135. public int GetPayCert(decimal cashPay,out string msg)
  136. {
  137. var request = new GetPayCertRequest
  138. {
  139. token = Global.pat.ecToken, // 电子凭证令牌(模拟值)
  140. ownPaySetlAmt = cashPay.ToString("0.00"), //现金支付金额
  141. orgCodg = Global.inf.hospitalNO, // 定点医药机构代码(示例医保编码)
  142. orgName = Global.inf.hospitalName, // 机构名称(中文支持)
  143. opterId = Global.user.ID, // 经办人员编号
  144. opterName = Global.user.name, // 经办人姓名
  145. devId = Global.curEvt.mac, // 设备唯一标识(如 MAC 地址或 UUID)
  146. devIP = Global.curEvt.ip, // 设备 IP 地址
  147. fixmedinsTrnsSn = Global.pat.recordID //医疗机构交易流水号
  148. };
  149. string jsonStr = JsonConvert.SerializeObject(request, Formatting.None, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });//紧凑格式
  150. JObject joRtn = invoker.invokeOneCodePayService("GetPayCert", jsonStr);
  151. if (JsonHelper.parseOneCodePayRtnValue(joRtn, out msg) != 0)
  152. {
  153. return -1;
  154. }
  155. else
  156. {
  157. msg = OneCodePayEncryptUtil.decrypt(JsonHelper.getDestValue(joRtn, "data.encData"), Global.inf.OneCodePay.apiSecretKey);
  158. Global.writeLog("GetPayCert(明文)", jsonStr, msg);
  159. return 0;
  160. }
  161. }
  162. //按照HIS约定返回给前端,前端根据返回结果调用
  163. }
  164. /// <summary>
  165. /// 查询用户一码付状态 - 请求参数
  166. /// </summary>
  167. public class QuerySignedPayStatusRequest:EntityBase
  168. {
  169. /// <summary>
  170. /// 电子凭证令牌
  171. /// </summary>
  172. [Column(Name = "token", DbType = "VARCHAR2(40)", CanBeNull = false)]
  173. [StringLength(40)]
  174. [DisplayName("电子凭证令牌")]
  175. public string token { get; set; }
  176. /// <summary>
  177. /// 定点医药机构代码
  178. /// </summary>
  179. [Column(Name = "orgCodg", DbType = "VARCHAR2(40)", CanBeNull = false)]
  180. [StringLength(40)]
  181. [DisplayName("定点医药机构代码")]
  182. public string orgCodg { get; set; }
  183. /// <summary>
  184. /// 定点医药机构名称
  185. /// </summary>
  186. [Column(Name = "orgName", DbType = "VARCHAR2(40)", CanBeNull = false)]
  187. [StringLength(40)]
  188. [DisplayName("定点医药机构名称")]
  189. public string orgName { get; set; }
  190. /// <summary>
  191. /// 经办人员编号
  192. /// </summary>
  193. [Column(Name = "opterId", DbType = "VARCHAR2(40)", CanBeNull = false)]
  194. [StringLength(40)]
  195. [DisplayName("经办人员编号")]
  196. public string opterId { get; set; }
  197. /// <summary>
  198. /// 经办人员姓名
  199. /// </summary>
  200. [Column(Name = "opterName", DbType = "VARCHAR2(40)", CanBeNull = false)]
  201. [StringLength(40)]
  202. [DisplayName("经办人员姓名")]
  203. public string opterName { get; set; }
  204. /// <summary>
  205. /// 设备唯一标识
  206. /// </summary>
  207. [Column(Name = "devId", DbType = "VARCHAR2(40)", CanBeNull = false)]
  208. [StringLength(40)]
  209. [DisplayName("设备唯一标识")]
  210. public string devId { get; set; }
  211. /// <summary>
  212. /// 设备网络IP
  213. /// </summary>
  214. [Column(Name = "devIP", DbType = "VARCHAR2(40)", CanBeNull = false)]
  215. [StringLength(40)]
  216. [DisplayName("设备网络IP")]
  217. public string devIP { get; set; }
  218. }
  219. /// <summary>
  220. /// 查询用户一码付状态 - 响应结果
  221. /// </summary>
  222. public class QuerySignedPayStatusResponse : EntityBase
  223. {
  224. /// <summary>
  225. /// 状态标识
  226. /// 0-未签约不可用,1-已签约且可用,2-已签约不可用
  227. /// </summary>
  228. [Column(Name = "stasFlag", DbType = "VARCHAR2(3)", CanBeNull = false)]
  229. [StringLength(3)]
  230. [DisplayName("状态标识")]
  231. public string stasFlag { get; set; }
  232. /// <summary>
  233. /// 不可用原因
  234. /// 状态异常原因描述,可用于定点医药机构侧识别及展示
  235. /// </summary>
  236. [Column(Name = "abnRea", DbType = "VARCHAR2(200)", CanBeNull = true)]
  237. [StringLength(200)]
  238. [DisplayName("不可用原因")]
  239. public string abnRea { get; set; }
  240. /// <summary>
  241. /// 支付渠道用户账号名
  242. /// 支付渠道自定义,可用于定点医药机构侧识别及展示
  243. /// </summary>
  244. [Column(Name = "payChnlUserName", DbType = "VARCHAR2(40)", CanBeNull = true)]
  245. [StringLength(40)]
  246. [DisplayName("支付渠道用户账号名")]
  247. public string payChnlUserName { get; set; }
  248. /// <summary>
  249. /// 支付渠道名称
  250. /// 可用于定点医药机构侧识别支付渠道
  251. /// </summary>
  252. [Column(Name = "payChnlName", DbType = "VARCHAR2(40)", CanBeNull = true)]
  253. [StringLength(40)]
  254. [DisplayName("支付渠道名称")]
  255. public string payChnlName { get; set; }
  256. }
  257. /// <summary>
  258. /// 获取一码付付款凭据请求
  259. /// </summary>
  260. public class GetPayCertRequest : EntityBase
  261. {
  262. /// <summary>
  263. /// 电子凭证令牌
  264. /// </summary>
  265. [Column(Name = "token", DbType = "VARCHAR2(40)", CanBeNull = false)]
  266. [StringLength(40)]
  267. [DisplayName("电子凭证令牌")]
  268. public string token { get; set; }
  269. /// <summary>
  270. /// 现金支付金额
  271. /// </summary>
  272. [Column(Name = "ownPaySetlAmt", DbType = "VARCHAR2(20)", CanBeNull = false)]
  273. [StringLength(20)]
  274. [DisplayName("现金支付金额")]
  275. public string ownPaySetlAmt { get; set; }
  276. /// <summary>
  277. /// 定点医药机构代码
  278. /// </summary>
  279. [Column(Name = "orgCodg", DbType = "VARCHAR2(40)", CanBeNull = false)]
  280. [StringLength(40)]
  281. [DisplayName("定点医药机构代码")]
  282. public string orgCodg { get; set; }
  283. /// <summary>
  284. /// 定点医药机构名称
  285. /// </summary>
  286. [Column(Name = "orgName", DbType = "VARCHAR2(200)", CanBeNull = false)]
  287. [StringLength(200)]
  288. [DisplayName("定点医药机构名称")]
  289. public string orgName { get; set; }
  290. /// <summary>
  291. /// 经办人员编号
  292. /// </summary>
  293. [Column(Name = "opterId", DbType = "VARCHAR2(40)", CanBeNull = false)]
  294. [StringLength(40)]
  295. [DisplayName("经办人员编号")]
  296. public string opterId { get; set; }
  297. /// <summary>
  298. /// 经办人员姓名
  299. /// </summary>
  300. [Column(Name = "opterName", DbType = "VARCHAR2(40)", CanBeNull = false)]
  301. [StringLength(40)]
  302. [DisplayName("经办人员姓名")]
  303. public string opterName { get; set; }
  304. /// <summary>
  305. /// 设备唯一标识
  306. /// </summary>
  307. [Column(Name = "devid", DbType = "VARCHAR2(40)", CanBeNull = false)]
  308. [StringLength(40)]
  309. [DisplayName("设备唯一标识")]
  310. public string devId { get; set; }
  311. /// <summary>
  312. /// 设备网络IP
  313. /// </summary>
  314. [Column(Name = "devIP", DbType = "VARCHAR2(40)", CanBeNull = false)]
  315. [StringLength(40)]
  316. [DisplayName("设备网络IP")]
  317. public string devIP { get; set; }
  318. /// <summary>
  319. /// 定点医药机构交易流水号
  320. /// </summary>
  321. [Column(Name = "fixmedinsTrnsSn", DbType = "VARCHAR2(200)", CanBeNull = false)]
  322. [StringLength(200)]
  323. [DisplayName("定点医药机构交易流水号")]
  324. public string fixmedinsTrnsSn { get; set; }
  325. }
  326. /// <summary>
  327. /// 获取一码付付款凭据响应
  328. /// </summary>
  329. public class GetPayCertResponse:EntityBase
  330. {
  331. /// <summary>
  332. /// 付款凭据
  333. /// </summary>
  334. [Column(Name = "payCert", DbType = "VARCHAR2(2000)", CanBeNull = false)]
  335. [StringLength(2000)]
  336. [DisplayName("付款凭据")]
  337. public string payCert { get; set; }
  338. /// <summary>
  339. /// 支付渠道用户账号名
  340. /// </summary>
  341. [Column(Name = "payChnlUserName", DbType = "VARCHAR2(400)", CanBeNull = true)]
  342. [StringLength(400)]
  343. [DisplayName("支付渠道用户账号名")]
  344. public string payChnlUserName { get; set; }
  345. /// <summary>
  346. /// 支付渠道名称
  347. /// </summary>
  348. [Column(Name = "payChnlName", DbType = "VARCHAR2(400)", CanBeNull = true)]
  349. [StringLength(400)]
  350. [DisplayName("支付渠道名称")]
  351. public string payChnlName { get; set; }
  352. }
  353. }