一、背景
目前公司支付平台集成了支付宝app、微信app、支付宝小程序、微信小程序、支付宝H5(扫码-主扫)、微信H5(扫码-主扫)、云闪付、建设钱包付等多种支付方式,今天给大家分享支付宝当面付的支付流程。
二、代码
目前我们当面付是把支付宝和微信集成在一个Controller里面的,今天先拆分下,分享支付宝当面付,下面是主要的代码。
@RequestMapping("/createOrder")
public String creatOrder(@Valid FaceToFaceCreateOrderVo faceToFaceCreateOrderVo, HttpServletRequest request,
BindingResult bindingResult) throws IOException, AlipayApiException {
if (bindingResult.hasErrors()) {
List<FieldError> fieldErrors = bindingResult.getFieldErrors();
for (Iterator<FieldError> iterator = fieldErrors.iterator(); iterator.hasNext(); ) {
FieldError fieldError = (FieldError) iterator.next();
return ResponseUtils.validError(fieldError.getDefaultMessage());
}
}
log.info("当面付业务入参:{}",JSONObject.toJSONString(faceToFaceCreateOrderVo));
//检查当面付服务控制开关 ON: 服务开启 OFF:服务暂停
String faceToFaceServFlg = tyPubSysParamCacheClient.getParamValue("F2F_SERV_FLG","ON");
if("OFF".equals(faceToFaceServFlg.toUpperCase())){
throw new PayVerifyException("PYE530", errCode.getShowMsg("PYE530"));
}
faceToFaceCreateOrderVo.setMedicalJson(faceToFaceCreateOrderVo.getMedicalJson().replaceAll(" ","+"));
ZfMerMerchInfoDO merch;//商户信息
ZfMerIntfCtrlDO merIntfCtrl;//商户接入控制信息
String key;//数据加密KEY AES KEY:amFkZXN1dW1qYWRlc3V1bQ==
String platEncKey;//平台数据加密秘钥
String merRsaPubKey;//签名KEY公钥
String ip = Ip.getIpAddr(WebUtils.getRequest());//IP地址
boolean isAgentComy = faceToFaceCreateOrderVo.getMerchFlag().equals(PayOrderConstant.MerchFlag.AGENCY);
if (!VERSION.equals(faceToFaceCreateOrderVo.getVersion())) {
throw new PayVerifyException("PYB601", errCode.getShowMsg("PYB601"));//PYB601:接口版本不一致
}
// 校验商户信息
merch = payOrderVerifyService.merchantVerify(faceToFaceCreateOrderVo.getMerchId());
platEncKey = tyPubSysParamCacheClient.getParamValue("AES_KEY","");
// 代理商模式
if (isAgentComy) {
// 代理商校验
payOrderVerifyService.agentComyVerify(faceToFaceCreateOrderVo.getAgentComyId(), merch.getMerId());
// 校验代理商接入控制信息
merIntfCtrl = payOrderVerifyService.merIntfCtrVerify(faceToFaceCreateOrderVo.getAgentComyId(), faceToFaceCreateOrderVo.getPayService());
merRsaPubKey = merIntfCtrl.getMerPubKey();
} else {
// 非外部商户需要绑定代理商
if (!merch.getMerType().equals(PayCodeConstants.ZF_MER_MERCH_INFO_MER_TYPE.外部商户.getDictValue()))
throw new PayVerifyException("PYP708", errCode.getShowMsg("PYP708"));//PYP708:非外部商户必须通过代理商进行支付
// 校验商户接入控制信息
merIntfCtrl = payOrderVerifyService.merIntfCtrVerify(merch.getMerId(), faceToFaceCreateOrderVo.getPayService());
merRsaPubKey = merIntfCtrl.getMerPubKey();
}
// 验签
if (StringUtils.isEmpty(merRsaPubKey)) {
throw new PayVerifyException("PYP718", errCode.getShowMsg("PYP718"));//PYP718:接入控制签名KEY为空
}
if (!PaySignUtil.payAttestation(faceToFaceCreateOrderVo, merRsaPubKey, faceToFaceCreateOrderVo.getSign())) {
throw new PayVerifyException("PYB625", errCode.getShowMsg("PYB625"));//PYB625:验证签名失败
}
//创建订单
key = merIntfCtrl.getDataEncryKey();//数据加密密钥
MedicalInfoVo medicalInfoVo = new MedicalInfoVo();//请求医疗扩展字段
try {// AES解密医疗扩展信息
if (StringUtils.isNotBlank(faceToFaceCreateOrderVo.getMedicalJson())) {
String str = AES.decrypt(faceToFaceCreateOrderVo.getMedicalJson(), key);
medicalInfoVo = JSONObject.parseObject(str, MedicalInfoVo.class);
log.info("#######解析后的medicalJson:" + JSON.toJSONString(medicalInfoVo));
} else {
log.info("#######当面付医疗扩展信息为空");
throw new PayVerifyException("PYB604", errCode.getShowMsg("PYP604"));
}
} catch (Exception e) {
log.info("医疗订单扩展信息解析失败", e);
throw new PayVerifyException("PYB605", errCode.getShowMsg("PYB605"));
}
/* 支付授权码检查 */
String f2fPayWay = this.getF2fPayWay(faceToFaceCreateOrderVo.getAuthCode());
if (null == f2fPayWay) {
log.info("当面付支付授权码:{}不合法", faceToFaceCreateOrderVo.getAuthCode());
throw new PayVerifyException("PYB653", "当面付支付授权码不合法");
}
String orderPayWay = "";
String chnPayId = "";
String amtPayType = "";
if ("wechatCashPay".equals(f2fPayWay) || "wechatSiPay".equals(f2fPayWay)) {
//微信
orderPayWay = PayCodeConstants.ZF_ORDER_INFO_PAY_WAY.微信当面付.getDictValue();
chnPayId = "WXACC";
} else if ("alipay".equals(f2fPayWay)) {
//支付宝
orderPayWay = PayCodeConstants.ZF_ORDER_INFO_PAY_WAY.支付宝当面付.getDictValue();
chnPayId = "ALIPAY";
} else if ("ehcCardPay".equals(f2fPayWay)) {
//电子健康卡二维码支付
chnPayId = "ALIPAY";
orderPayWay = PayCodeConstants.ZF_ORDER_INFO_PAY_WAY.支付宝免密支付.getDictValue();
} else {
//支付授权码不合法
log.info("当面付支付授权码:[{}]不合法", faceToFaceCreateOrderVo.getAuthCode());
throw new PayVerifyException("PYB653", errCode.getShowMsg("PYB653"));
}
/* 判断金额支付方式:自费 or 医保 */
String _payFlag = medicalInfoVo.getPayFlag();
if (PayCodeConstants.ZF_ORDER_INFO_PAY_TYPE.自费.getDictValue().equals(_payFlag)) {
if (medicalInfoVo.getSelfPayAmt().compareTo(BigDecimal.ZERO) > 0) {
amtPayType = PayCodeConstants.ZF_ORDER_INFO_PAY_TYPE.自费.getDictValue();
} else {
log.info("当面付自费支付金额:[{}]不合法", medicalInfoVo.getSelfPayAmt().toString());
throw new PayVerifyException("PYB610", errCode.getShowMsg("PYB610"));
}
} else if (PayCodeConstants.ZF_ORDER_INFO_PAY_TYPE.医保.getDictValue().equals(_payFlag)
|| PayCodeConstants.ZF_ORDER_INFO_PAY_TYPE.自费医保.getDictValue().equals(_payFlag)) {
//医保支付先删掉,主要是分享自费的
} else {
log.info("当面付支付方式:[{}]不合法", medicalInfoVo.getPayFlag().toString());
throw new PayVerifyException("PYB611", errCode.getShowMsg("PYB611"));
}
BigDecimal _totalPayAmt = BigDecimal.ZERO;
BigDecimal _selfPayAmt = BigDecimal.ZERO;
BigDecimal _siPayAmt = BigDecimal.ZERO;
if (null != medicalInfoVo.getSelfPayAmt()) {
_selfPayAmt = medicalInfoVo.getSelfPayAmt();
}
if (null != medicalInfoVo.getSiPayAmt()) {
_siPayAmt = medicalInfoVo.getSiPayAmt();
}
_totalPayAmt = _selfPayAmt.add(_siPayAmt);
if (faceToFaceCreateOrderVo.getAmount().compareTo(_totalPayAmt) != 0) {
throw new PayVerifyException("PYB611", "支付金额不合法,订单金额与实际支付金额不等");
}
/* 创建订单 */
//根据自己的业务需要创建自己的订单记录
//createOrder
//根据自己的业务需要,创建渠道支付记录
//createChnOrder
//金额为分
BigDecimal _orderAmount = faceToFaceCreateOrderVo.getAmount().multiply(new BigDecimal("100.00"));
/**
* 00:支付成功
* 01:支付失败
* 02:支付处理中(比如密码验证中)
*/
String orderF2fPayStatus = "01";
/**
* 医保0元挂号费用的渠道报备接口返回医保结构体内容
*/
String siZeroRegPayUploadResponse = "";
/* 渠道用户是否关注 */
boolean isSubscribe = false;
//当面付渠道下单并支付
if ("wechatCashPay".equals(f2fPayWay)) {
//微信自费
WeChatF2fPayVO payVo = new WeChatF2fPayVO();
payVo.setAuth_code(faceToFaceCreateOrderVo.getAuthCode());
payVo.setOrderId(platOrderId);
payVo.setBody(faceToFaceCreateOrderVo.getOrderDesc());
payVo.setTimeStart(DateUtils.getCurrentDateTimeNumber());
payVo.setTimeEnd(DateUtils.format(DateUtils.addDateMinute(new Date(), 5), "yyyyMMddHHmmss"));//有效期5分钟
payVo.setTotalFee(_orderAmount.setScale(0, BigDecimal.ROUND_HALF_UP).toString());
log.info(">>>>>>>>>>>>>>微信当面付入参:"+JSON.toJSONString(payVo));
WeChatF2FRes weChatF2FRes = weChatPayService.weChatF2fPay(payVo);
log.info(">>>>>>>>>>>>>>微信当面付出参:"+JSON.toJSONString(weChatF2FRes));
if (WeChatPayConstants.SUCCESS.equalsIgnoreCase(weChatF2FRes.getResult_code())) {
// 支付成功
zfOrderInfoDO.setPayWaySeqno(weChatF2FRes.getTransaction_id());// 支付渠道流水号
zfOrderInfoDO.setOrderStatus(PayCodeConstants.ZF_ORDER_INFO_ORDER_STATUS.已支付.getDictValue());
zfOrderInfoDO.setOrderPayStatus(PayCodeConstants.ZF_ORDER_INFO_ORDER_PAY_STATUS.已支付.getDictValue());
zfOrderInfoDO.setOrderPaySuccTime(new Date());
zfOrderInfoDO.setOrderLastUpdTime(new Date());
zfOrderInfoDO.setAcctDay(DateUtils.format(nowDate, "yyyyMMdd"));
if (!StringUtils.isEmpty(weChatF2FRes.getOpenid())) {
/*新增渠道用户信息------*/
String payAppid = weChatF2FRes.getAppid();
String payChnUserId = weChatF2FRes.getOpenid();
zfOrderInfoDO.setPayAppid(payAppid);
zfOrderInfoDO.setPayUserId(payChnUserId);
isSubscribe = "N".equalsIgnoreCase(weChatF2FRes.getIs_subscribe()) ? false:true;
}
zfOrderChnPayDO.setPayWaySeqno(weChatF2FRes.getTransaction_id());// 支付渠道流水号
zfOrderChnPayDO.setOrderPayStatus(PayCodeConstants.ZF_ORDER_INFO_ORDER_PAY_STATUS.已支付.getDictValue());
zfOrderChnPayDO.setOrderPaySuccTime(new Date());
extOrderService.updateOrder(zfOrderInfoDO, zfOrderChnPayDO);
orderF2fPayStatus = F2F_PAY_RESULT_SUCCESS;
} else if ("USERPAYING".equals(weChatF2FRes.getErr_code())) {
orderF2fPayStatus = F2F_PAY_RESULT_PROCESS;
log.info("微信当面付用户正在支付中,处理信息:{},{}", weChatF2FRes.getErr_code(), weChatF2FRes.getErr_code_des());
} else {
// 支付失败
orderF2fPayStatus = F2F_PAY_RESULT_FAIL;
log.error("微信当面付支付失败,出错信息:{},{}", weChatF2FRes.getErr_code(), weChatF2FRes.getErr_code_des());
if("SYSTEMERROR".equals(weChatF2FRes.getErr_code() )){
return ResponseUtils.error("PYP605","支付失败请稍后重试。");
}else{
return ResponseUtils.error("PYP605", StringUtils.isEmpty(weChatF2FRes.getErr_code_des()) ? errCode.getShowMsg("PYP605"):weChatF2FRes.getErr_code_des());
}
}
} else if ("wechatSiPay".equals(f2fPayWay)) {
//微信医保当面付的逻辑先去掉,只分享自费的
} else if ("alipay".equals(f2fPayWay)) {
// 支付宝
// 如果订单金额>0调用支付宝渠道支付
if (faceToFaceCreateOrderVo.getAmount().compareTo(BigDecimal.ZERO) == 1) {
ZfAlipayTradePayReq zfAlipayTradePayReq = new ZfAlipayTradePayReq();
String requestContent = medicalInfoVo.getRequestContent();// 医保结构体
String medicalRequestExt = medicalInfoVo.getRequestContent();// 扩展医保结构体
if (PayCodeConstants.ZF_PUBLIC_ORDER_TYPE.预约挂号.getDictValue().equals(faceToFaceCreateOrderVo.getOrderType())
&& (PayCodeConstants.ZF_ORDER_INFO_PAY_TYPE.医保.getDictValue().equals(_payFlag) || PayCodeConstants.ZF_ORDER_INFO_PAY_TYPE.自费医保.getDictValue().equals(_payFlag))) {
requestContent = zfAlipayService.convertReqContentReg(medicalInfoVo.getRequestContent());// 挂号医保透传体格式化
} else if (PayCodeConstants.ZF_PUBLIC_ORDER_TYPE.门诊缴费.getDictValue().equals(faceToFaceCreateOrderVo.getOrderType())
&& (PayCodeConstants.ZF_ORDER_INFO_PAY_TYPE.医保.getDictValue().equals(_payFlag) || PayCodeConstants.ZF_ORDER_INFO_PAY_TYPE.自费医保.getDictValue().equals(_payFlag))) {
requestContent = zfAlipayService.convertReqContentVis(medicalInfoVo.getRequestContent());// 诊间医保透传体格式化
} else {
requestContent = "";
log.info("支付宝当面付订单类型为:{}", faceToFaceCreateOrderVo.getOrderType());
}
if (PayCodeConstants.ZF_ORDER_INFO_PAY_TYPE.医保.getDictValue().equals(_payFlag)
|| PayCodeConstants.ZF_ORDER_INFO_PAY_TYPE.自费医保.getDictValue().equals(_payFlag)) {
medicalRequestExt = zfAlipayService.convertMedicalRequestExt(medicalRequestExt, zfOrderInfoDO.getPlatOrderId());// 扩展医保透传体格式化
} else {
medicalRequestExt = "";
log.info("支付宝当面付订单支付方式:{}", medicalInfoVo.getPayFlag());
}
// (必填) 支付宝的条形码
String authCode = faceToFaceCreateOrderVo.getAuthCode();
// (必填)卖家支付宝账号ID,如果该字段为空,则默认为与支付宝签约的商户的PID,也就是appid对应的PID
String sellerId = Configs.getPid();
// (必填) 商户订单号
String outTradeNo = platOrderId;
// (必填) 订单标题
String subject = faceToFaceCreateOrderVo.getOrderDesc();
// (必填) 订单总金额,单位为元,不能超过1亿元
String totalAmount = ArithUtils.format(faceToFaceCreateOrderVo.getAmount());
// (可选)订单不可打折金额
String undiscountableAmount = totalAmount;
// (可选)订单描述,可以对交易或商品进行一个详细地描述,比如填写"购买商品2件共15.00元"
String body = subject;
// (可选) 商户操作员编号,添加此参数可以为商户操作员做销售统计
String operatorId = null;
// (必填 ) 商户门店编号
String storeId = faceToFaceCreateOrderVo.getMerchId();
// (必填) 业务扩展参数
ExtendParams extendParams = new ExtendParams();
if (PayCodeConstants.ZF_ORDER_INFO_PAY_TYPE.自费.getDictValue().equals(_payFlag)) {
String providerId = "2088431608833299";
extendParams.setSysServiceProviderId(providerId);
} else if (PayCodeConstants.ZF_ORDER_INFO_PAY_TYPE.医保.getDictValue().equals(_payFlag)
|| PayCodeConstants.ZF_ORDER_INFO_PAY_TYPE.自费医保.getDictValue().equals(_payFlag)) {
String providerId = "2088431608833299";
extendParams.setSysServiceProviderId(providerId);
extendParams.setMedicalCardInstId(MEDICALCARDINSTID);
extendParams.setMedicalRequestContent(requestContent);
extendParams.setMedicalRequestExt(medicalRequestExt);
extendParams.setIsInsurancePay(ISINSURANCE);
} else {
log.info("当面付支付方式不合法{}", medicalInfoVo.getPayFlag().toString());
throw new PayVerifyException("PYB611", errCode.getShowMsg("PYB611"));
}
// (可选)支付超时,线下扫码交易定义为5分钟
String timeoutExpress = "5m";
// (可选)商品明细列表,需填写购买商品详细信息,
List<GoodsDetail> goodsDetailList = new ArrayList<GoodsDetail>();
zfAlipayTradePayReq.setAuthCode(authCode);
zfAlipayTradePayReq.setBody(body);
zfAlipayTradePayReq.setExtendParams(extendParams);
zfAlipayTradePayReq.setGoodsDetailList(goodsDetailList);
zfAlipayTradePayReq.setOperatorId(operatorId);
zfAlipayTradePayReq.setOutTradeNo(outTradeNo);
zfAlipayTradePayReq.setSellerId(sellerId);
zfAlipayTradePayReq.setStoreId(storeId);
zfAlipayTradePayReq.setSubject(subject);
zfAlipayTradePayReq.setTimeoutExpress(timeoutExpress);
zfAlipayTradePayReq.setTotalAmount(totalAmount);
zfAlipayTradePayReq.setUndiscountableAmount(undiscountableAmount);
zfAlipayTradePayReq.setScene("bar_code");
log.info("》》》》支付宝当面付下单请求参数:{}" + JSON.toJSONString(zfAlipayTradePayReq));
AlipayF2FPayResult result = zfAlipayService.tradePay(zfAlipayTradePayReq);
log.info("》》》》支付宝当面付下单请求出参:{}" + JSON.toJSONString(result));
if ("10000".equals(result.getResponse().getCode()) && TradeStatus.SUCCESS == result.getTradeStatus()) {
log.info("支付宝当面付下单支付成功!");
log.info(result.getResponse().getBody());
// 修改订单记录表/渠道订单记录表中的订单状态为:已支付
try {
zfOrderInfoDO.setPayWaySeqno(result.getResponse().getTradeNo());
zfOrderInfoDO.setOrderStatus(PayCodeConstants.ZF_ORDER_INFO_ORDER_STATUS.已支付.getDictValue());
zfOrderInfoDO.setOrderPayStatus(PayCodeConstants.ZF_ORDER_INFO_ORDER_PAY_STATUS.已支付.getDictValue());
zfOrderInfoDO.setOrderPaySuccTime(DateUtils.getCurrentDateTime());
zfOrderInfoDO.setOrderLastUpdTime(DateUtils.getCurrentDateTime());
zfOrderInfoDO.setAcctDay(DateUtils.format(DateUtils.getCurrentDateTime(), "yyyyMMdd"));
zfOrderInfoDO.setFinishTime(DateUtils.getCurrentDateTime());
if (!StringUtils.isEmpty(result.getResponse().getBuyerUserId())) {
//更新渠道用户标识
String payAppid = tyPubSysParamCacheClient.getParamValue("ALIPAY_APPID","");
String payUserId = result.getResponse().getBuyerUserId();
zfOrderInfoDO.setPayAppid(payAppid);
zfOrderInfoDO.setPayUserId(payUserId);
}
updateOrderPaySuccess(zfOrderInfoDO, result.getResponse().getTradeNo());
} catch (Exception e) {
log.error("支付宝当面付更新订单失败,msg:{}", e.getMessage());
return ResponseUtils.error("PYA204", errCode.getShowMsg("PYA204"));
}
orderF2fPayStatus = F2F_PAY_RESULT_SUCCESS;
//支付渠道用户信息推送至MQ
if (!StringUtils.isEmpty(zfOrderInfoDO.getPayUserId())) {
//转为消息队列推送
mqMsgService.payNotifyUserInfo(zfOrderInfoDO);
}
} else if ("10003".equals(result.getResponse().getCode())
|| TradeStatus.UNKNOWN == result.getTradeStatus()) {
orderF2fPayStatus = F2F_PAY_RESULT_PROCESS;
log.info("支付宝当面付用户正在支付中,处理信息:{},{}", result.getResponse().getCode(), result.getResponse().getMsg());
} else {
log.error("支付宝当面付支付失败!");
log.error(result.getResponse().getBody());
orderF2fPayStatus = F2F_PAY_RESULT_FAIL;
return ResponseUtils.error("PYP605", StringUtils.isEmpty(result.getResponse().getSubMsg()) ? errCode.getShowMsg("PYP605"):result.getResponse().getSubMsg());
}
}
} else {
//电子健康卡扫码支付,先去掉
}
那通过什么方式来区分是微信当面付还是医保当面付呢?这里是通过扫码墩扫描的条码来区分的。
public String getF2fPayWay(String authCode) {
if (StringUtils.isBlank(authCode)) return null;
if (authCode.length() == 18 &&
(authCode.startsWith("10") || authCode.startsWith("11") || authCode.startsWith("12") || authCode.startsWith("13") || authCode.startsWith("14") || authCode.startsWith("15"))) {
//微信当面付自费支付
return "wechatCashPay";
} else if (authCode.startsWith("28")) {
//支付宝
return "alipay";
} else if ((authCode.startsWith("36") || authCode.startsWith("37")) && authCode.length() == 18) {
//微信医保
return "wechatSiPay";
} else {
String[] qrCodeArray = authCode.split(":");
if (qrCodeArray[0].matches("[A-Za-z0-9]{64}")) {
//电子健康卡付款二维码
return "ehcCardPay";
}
return null;
}
}
此时返回给收银台的结果并不是已经支付成功的状态,需要收银台主动查询渠道订单查询接口,然后同步更新我们平台的订单,最后将支付结果返回给收银台。下面是订单查询接口的逻辑。
@RequestMapping("/resultQuery")
public String resultQuery(@Valid FaceToFaceQueryOrderVo faceToFaceQueryOrderVo, BindingResult bindingResult) {
ZfMerMerchInfoDO merch;//商户信息
ZfMerIntfCtrlDO merIntfCtrl;//商户接入控制信息
String key;//数据加密KEY AES KEY:amFkZXN1dW1qYWRlc3V1bQ==
String merRsaPubKey;//签名KEY公钥
boolean isAgentComy = faceToFaceQueryOrderVo.getMerchFlag().equals(PayOrderConstant.MerchFlag.AGENCY);
if (!VERSION.equals(faceToFaceQueryOrderVo.getVersion())) {
throw new PayVerifyException("PYB601", errCode.getShowMsg("PYB601"));//PYB601:接口版本不一致
}
// 校验商户信息
merch = payOrderVerifyService.merchantVerify(faceToFaceQueryOrderVo.getMerchId());
// 代理商模式
if (isAgentComy) {
// 代理商校验
payOrderVerifyService.agentComyVerify(faceToFaceQueryOrderVo.getAgentComyId(), merch.getMerId());
// 校验代理商接入控制信息
merIntfCtrl = payOrderVerifyService.merIntfCtrVerify(faceToFaceQueryOrderVo.getAgentComyId(), null);
key = merIntfCtrl.getDataEncryKey();
merRsaPubKey = merIntfCtrl.getMerPubKey();
} else {
// 非外部商户需要绑定代理商
if (!merch.getMerType().equals(PayCodeConstants.ZF_MER_MERCH_INFO_MER_TYPE.外部商户.getDictValue())) {
throw new PayVerifyException("PYP708", errCode.getShowMsg("PYP708"));// PYP708:非外部商户必须通过代理商进行支付
}
// 校验商户接入控制信息
merIntfCtrl = payOrderVerifyService.merIntfCtrVerify(merch.getMerId(), null);
key = merIntfCtrl.getDataEncryKey();
merRsaPubKey = merIntfCtrl.getMerPubKey();
}
// 验签
if (StringUtils.isEmpty(merRsaPubKey)) {
throw new PayVerifyException("PYP718", errCode.getShowMsg("PYP718"));//PYP718:接入控制签名KEY为空
}
if (!PaySignUtil.payAttestation(faceToFaceQueryOrderVo, merRsaPubKey, faceToFaceQueryOrderVo.getSign())) {
throw new PayVerifyException("PYB625", errCode.getShowMsg("PYB625"));//PYB625:验证签名失败
}
ZfOrderInfoQuery query = new ZfOrderInfoQuery();
query.setMerOrderId(faceToFaceQueryOrderVo.getMerchOrderId());
query.setMerId(faceToFaceQueryOrderVo.getMerchId());
List<ZfOrderInfoDO> listByPoList = zfOrderInfoService.listByPo(query);
if (listByPoList == null || listByPoList.size() == 0) {
return ResponseUtils.error("PYO201", errCode.getShowMsg("PYO201"));//PYO201:订单不存在
}
ZfOrderInfoDO zfOrderInfoDO = listByPoList.get(0);
String outTradeNo = zfOrderInfoDO.getPlatOrderId();
if (PayCodeConstants.ZF_ORDER_INFO_ORDER_PAY_STATUS.待支付.getDictValue().equals(zfOrderInfoDO.getOrderPayStatus())
&& (PayCodeConstants.ZF_ORDER_INFO_PAY_WAY.支付宝当面付.getDictValue().equals(zfOrderInfoDO.getPayWay())
|| PayCodeConstants.ZF_ORDER_INFO_PAY_WAY.支付宝免密支付.getDictValue().equals(zfOrderInfoDO.getPayWay()))) {
ZfAlipayTradeQueryReq zfAlipayTradeQueryReq = new ZfAlipayTradeQueryReq();
zfAlipayTradeQueryReq.setOutTradeNo(outTradeNo);
log.info(">>>>>>>>>>>>>当面付订单查询入参:"+JSON.toJSONString(zfAlipayTradeQueryReq));
AlipayF2FQueryResult result = zfAlipayService.tradeQuery(zfAlipayTradeQueryReq);
log.info(">>>>>>>>>>>>>当面付订单查询返回参数:"+JSON.toJSONString(zfAlipayTradeQueryReq));
log.info("查询返回该订单[" + outTradeNo + "]" + result.getTradeStatus() + "--" + result.getResponse().getBody());
if(result.isTradeSuccess()) {
log.info("支付宝当面付查询返回该订单支付成功!!!");
//修改订单记录表/渠道订单记录表中的订单状态为:已支付
try {
zfOrderInfoDO.setPayWaySeqno(result.getResponse().getTradeNo());
zfOrderInfoDO.setOrderStatus(PayCodeConstants.ZF_ORDER_INFO_ORDER_STATUS.已支付.getDictValue());
zfOrderInfoDO.setOrderPayStatus(PayCodeConstants.ZF_ORDER_INFO_ORDER_PAY_STATUS.已支付.getDictValue());
zfOrderInfoDO.setOrderPaySuccTime(DateUtils.getCurrentDateTime());
zfOrderInfoDO.setOrderLastUpdTime(DateUtils.getCurrentDateTime());
zfOrderInfoDO.setAcctDay(DateUtils.format(DateUtils.getCurrentDateTime(), "yyyyMMdd"));
zfOrderInfoDO.setFinishTime(DateUtils.getCurrentDateTime());
if (!StringUtils.isEmpty(result.getResponse().getBuyerUserId())) {
//更新渠道用户标识
String payAppid = tyPubSysParamCacheClient.getParamValue("ALIPAY_APPID","");
String payUserId = result.getResponse().getBuyerUserId();
zfOrderInfoDO.setPayAppid(payAppid);
zfOrderInfoDO.setPayUserId(payUserId);
}
updateOrderPaySuccess(zfOrderInfoDO,result.getResponse().getTradeNo());
} catch (Exception e) {
log.error("支付宝当面付更新订单失败,msg:{}", e.getMessage());
return ResponseUtils.error("PYA204", errCode.getShowMsg("PYA204"));
}
// 调用见证宝充值
if(PayCodeConstants.ZF_ORDER_INFO_PAY_TYPE.自费.getDictValue().equals(zfOrderInfoDO.getPayType())||PayCodeConstants.ZF_ORDER_INFO_PAY_TYPE.自费医保.getDictValue().equals(zfOrderInfoDO.getPayType())) {
rechargeJzb(zfOrderInfoDO);
}
//支付渠道用户信息推送至MQ
if (!StringUtils.isEmpty(zfOrderInfoDO.getPayUserId())) {
//转为消息队列推送
mqMsgService.payNotifyUserInfo(zfOrderInfoDO);
}
}else {
log.info("支付宝当面付查询返回,处理信息:{}", result.getResponse().getBody());
List<ZfOrderInfoDO> alipayOrder = zfOrderInfoService.listByPo(query);
ZfOrderInfoDO vo = alipayOrder.get(0);
JSONObject alipayDate = new JSONObject();
alipayDate.put("version", VERSION);// 通讯协议版本号
alipayDate.put("agentComyId", vo.getAgentComyId());// 代理商编号
alipayDate.put("merchId", vo.getMerId());// 商户编号
alipayDate.put("merchOrderId", vo.getMerOrderId());// 商户订单号
alipayDate.put("tradeNo", vo.getPlatOrderId());// 支付平台订单号
alipayDate.put("orderType", vo.getOrderType());// 订单类型
alipayDate.put("amount", ArithUtils.format(vo.getOrderAmt()));// 订单金额
alipayDate.put("orderStatus", PayCodeConstants.ZF_ORDER_INFO_ORDER_PAY_STATUS.待支付.getDictValue());// 订单状态
alipayDate.put("tradeTime", DateUtils.format(vo.getAddTime(), "yyyyMMddHHmmss"));// 交易时间
String prikey = tyPubSysParamCacheClient.getParamValue(PayConstant.RSA_PUB_PAI_KEY.PRI_KEY, null);
if (prikey == null) {
return ResponseUtils.error("PYD302", errCode.getShowMsg("PYD302"));//PYD302:未配置参数-加密KEY
}
return ResponseUtils.succDataObjectWithSign(alipayDate, prikey);
}
}
if (PayCodeConstants.ZF_ORDER_INFO_ORDER_PAY_STATUS.待支付.getDictValue().equals(zfOrderInfoDO.getOrderPayStatus())
&& PayCodeConstants.ZF_ORDER_INFO_PAY_WAY.微信当面付.getDictValue().equals(zfOrderInfoDO.getPayWay())
&& PayCodeConstants.ZF_ORDER_INFO_PAY_TYPE.自费.getDictValue().equals(zfOrderInfoDO.getPayType())) {
OrderQueryVO orderQueryVO = new OrderQueryVO();
orderQueryVO.setOrderId(outTradeNo);
orderQueryVO.setOrderSource("2");
log.info(">>>>>>>>>>>>>微信当面付订单查询入参:"+JSON.toJSONString(orderQueryVO));
ZiFeiQueryOrderRes result = weChatOrderQueyService.ziFeiOrderQuery(orderQueryVO);
log.info(">>>>>>>>>>>>>微信当面付订单查询返回参数:"+JSON.toJSONString(result));
boolean isSubscribe = false;
if (result.getTrade_state().equals("SUCCESS")) {
log.info("微信当面付自费查询返回该订单支付成功!!!");
//修改订单记录表/渠道订单记录表中的订单状态为:已支付
try {
zfOrderInfoDO.setPayWaySeqno(result.getTransaction_id());
zfOrderInfoDO.setOrderStatus(PayCodeConstants.ZF_ORDER_INFO_ORDER_STATUS.已支付.getDictValue());
zfOrderInfoDO.setOrderPayStatus(PayCodeConstants.ZF_ORDER_INFO_ORDER_PAY_STATUS.已支付.getDictValue());
zfOrderInfoDO.setOrderPaySuccTime(DateUtils.getCurrentDateTime());
zfOrderInfoDO.setOrderLastUpdTime(DateUtils.getCurrentDateTime());
zfOrderInfoDO.setAcctDay(DateUtils.format(DateUtils.getCurrentDateTime(), "yyyyMMdd"));
zfOrderInfoDO.setFinishTime(DateUtils.getCurrentDateTime());
if (!StringUtils.isEmpty(result.getOpenid())) {
/*新增渠道用户信息------*/
String payAppid = result.getAppid();
String payChnUserId = result.getOpenid();
zfOrderInfoDO.setPayAppid(payAppid);
zfOrderInfoDO.setPayUserId(payChnUserId);
isSubscribe = "N".equalsIgnoreCase(result.getIs_subscribe()) ? false:true;
}
updateOrderPaySuccess(zfOrderInfoDO, result.getTransaction_id());
} catch (Exception e) {
log.error("微信当面付自费更新订单失败,msg:{}", e.getMessage());
return ResponseUtils.error("PYA204", errCode.getShowMsg("PYA204"));
}
}else if("USERPAYING".equals(result.getTrade_state())){
//例如针对用户正在输入密码中的情况下
log.info("微信当面付自费查询,处理信息:{},{}", result.getTrade_state(), result.getTrade_state_desc());
List<ZfOrderInfoDO> wechatSelfOrder = zfOrderInfoService.listByPo(query);
ZfOrderInfoDO vo = wechatSelfOrder.get(0);
JSONObject wechatSelfDate = new JSONObject();
wechatSelfDate.put("version", VERSION);// 通讯协议版本号
wechatSelfDate.put("agentComyId", vo.getAgentComyId());// 代理商编号
wechatSelfDate.put("merchId", vo.getMerId());// 商户编号
wechatSelfDate.put("merchOrderId", vo.getMerOrderId());// 商户订单号
wechatSelfDate.put("tradeNo", vo.getPlatOrderId());// 支付平台订单号
wechatSelfDate.put("orderType", vo.getOrderType());// 订单类型
wechatSelfDate.put("amount", ArithUtils.format(vo.getOrderAmt()));// 订单金额
wechatSelfDate.put("orderStatus", PayCodeConstants.ZF_ORDER_INFO_ORDER_PAY_STATUS.待支付.getDictValue());// 订单状态
wechatSelfDate.put("tradeTime", DateUtils.format(vo.getAddTime(), "yyyyMMddHHmmss"));// 交易时间
String prikey = tyPubSysParamCacheClient.getParamValue(PayConstant.RSA_PUB_PAI_KEY.PRI_KEY, null);
if (prikey == null) {
return ResponseUtils.error("PYD302", errCode.getShowMsg("PYD302"));//PYD302:未配置参数-加密KEY
}
return ResponseUtils.succDataObjectWithSign(wechatSelfDate, prikey);
}else{
//例如针对用户输入密码超时的情况下
log.info("微信当面付自费查询,处理信息:{},{}", result.getTrade_state(), result.getTrade_state_desc());
List<ZfOrderInfoDO> wechatOvertimeOrder = zfOrderInfoService.listByPo(query);
ZfOrderInfoDO vo = wechatOvertimeOrder.get(0);
JSONObject wechatOvertimeDate = new JSONObject();
wechatOvertimeDate.put("version", VERSION);// 通讯协议版本号
wechatOvertimeDate.put("agentComyId", vo.getAgentComyId());// 代理商编号
wechatOvertimeDate.put("merchId", vo.getMerId());// 商户编号
wechatOvertimeDate.put("merchOrderId", vo.getMerOrderId());// 商户订单号
wechatOvertimeDate.put("tradeNo", vo.getPlatOrderId());// 支付平台订单号
wechatOvertimeDate.put("orderType", vo.getOrderType());// 订单类型
wechatOvertimeDate.put("amount", ArithUtils.format(vo.getOrderAmt()));// 订单金额
wechatOvertimeDate.put("orderStatus", vo.getOrderStatus());// 订单状态
wechatOvertimeDate.put("tradeTime", DateUtils.format(vo.getAddTime(), "yyyyMMddHHmmss"));// 交易时间
String prikey = tyPubSysParamCacheClient.getParamValue(PayConstant.RSA_PUB_PAI_KEY.PRI_KEY, null);
if (prikey == null) {
return ResponseUtils.error("PYD302", errCode.getShowMsg("PYD302"));//PYD302:未配置参数-加密KEY
}
return ResponseUtils.succDataObjectWithSign(wechatOvertimeDate, prikey);
}
}
if (PayCodeConstants.ZF_ORDER_INFO_ORDER_PAY_STATUS.待支付.getDictValue().equals(zfOrderInfoDO.getOrderPayStatus())
&& PayCodeConstants.ZF_ORDER_INFO_PAY_WAY.微信当面付.getDictValue().equals(zfOrderInfoDO.getPayWay())
&& (PayCodeConstants.ZF_ORDER_INFO_PAY_TYPE.医保.getDictValue().equals(zfOrderInfoDO.getPayType())
|| PayCodeConstants.ZF_ORDER_INFO_PAY_TYPE.自费医保.getDictValue().equals(zfOrderInfoDO.getPayType()))) {
OrderQueryVO orderQueryVO = new OrderQueryVO();
orderQueryVO.setOrderId(outTradeNo);
orderQueryVO.setOrderSource("2");
YiBaoQueryOrderRes result = weChatOrderQueyService.yiBaoOrderQuery(orderQueryVO);
if (!"SUCCESS".equals(result.getResult_code())) {
//查询交易失败-交易订单不存在
JSONObject wechatMedDate = new JSONObject();
wechatMedDate.put("version", VERSION);// 通讯协议版本号
wechatMedDate.put("agentComyId", zfOrderInfoDO.getAgentComyId());// 代理商编号
wechatMedDate.put("merchId", zfOrderInfoDO.getMerId());// 商户编号
wechatMedDate.put("merchOrderId", zfOrderInfoDO.getMerOrderId());// 商户订单号
wechatMedDate.put("tradeNo", zfOrderInfoDO.getPlatOrderId());// 支付平台订单号
wechatMedDate.put("orderType", zfOrderInfoDO.getOrderType());// 订单类型
wechatMedDate.put("amount", ArithUtils.format(zfOrderInfoDO.getOrderAmt()));// 订单金额
wechatMedDate.put("orderStatus", PayCodeConstants.ZF_ORDER_INFO_ORDER_PAY_STATUS.待支付.getDictValue());// 订单状态
wechatMedDate.put("tradeTime", DateUtils.format(zfOrderInfoDO.getAddTime(), "yyyyMMddHHmmss"));// 交易时间
String prikey = tyPubSysParamCacheClient.getParamValue(PayConstant.RSA_PUB_PAI_KEY.PRI_KEY, null);
if (prikey == null) {
return ResponseUtils.error("PYD302", errCode.getShowMsg("PYD302"));// PYD302:未配置参数-加密KEY
}
return ResponseUtils.succDataObjectWithSign(wechatMedDate, prikey);
}
if (result.getMed_trade_state().equals("SUCCESS")) {
log.info("微信当面付医保查询返回该订单支付成功!!!");
//修改订单记录表/渠道订单记录表中的订单状态为:已支付
if (StringUtils.isNotEmpty(result.getInsurance_order_id())) {
zfOrderInfoDO.setSiSonOrderId(result.getInsurance_order_id());//医保子单号
}
if (StringUtils.isNotEmpty(result.getCash_order_id())) {//自费子订单
zfOrderInfoDO.setSelfSonOrderId(result.getCash_order_id());
}
String medTransId = result.getMed_trans_id();//微信交易单号
String stlBizSeq = result.getBill_no();// 医保单据号
String siPaySuccStruct = result.getResponse_content();//人社返回的结算成功结构体
//医保支付金额
String siPayAmt = result.getInsurance_fee();
BigDecimal _siPayAmt = StringUtils.isEmpty(siPayAmt)?BigDecimal.ZERO : new BigDecimal(siPayAmt);
_siPayAmt = _siPayAmt.divide(new BigDecimal("100.00"));//分转化为元
//自费支付金额
String selfPayAmt = result.getCash_fee();
BigDecimal _selfPayAmt = StringUtils.isEmpty(selfPayAmt)?BigDecimal.ZERO : new BigDecimal(selfPayAmt);
_selfPayAmt = _selfPayAmt.divide(new BigDecimal("100.00"));//分转化为元
if(zfOrderInfoDO.getPayType().equals(PayCodeConstants.ZF_ORDER_INFO_PAY_TYPE.医保.getDictValue())
&& _selfPayAmt.compareTo(BigDecimal.ZERO)==1 ){
zfOrderInfoDO.setPayType(PayCodeConstants.ZF_ORDER_INFO_PAY_TYPE.自费医保.getDictValue());
zfOrderInfoDO.setMerStlAmt(_selfPayAmt);
}
zfOrderInfoDO.setPayWaySeqno(medTransId);
zfOrderInfoDO.setSelfPayAmt(zfOrderInfoDO.getOrderAmt().subtract(_siPayAmt));
zfOrderInfoDO.setMerStlAmt(_selfPayAmt);
zfOrderInfoDO.setSiSelfAmt(_siPayAmt);
zfOrderInfoDO.setSiPayAmt(_siPayAmt);
zfOrderInfoDO.setStlBizSeqno(stlBizSeq);
zfOrderInfoDO.setSiPaySuccStruct(siPaySuccStruct);
try {
zfOrderInfoDO.setPayWaySeqno(medTransId);
zfOrderInfoDO.setOrderStatus(PayCodeConstants.ZF_ORDER_INFO_ORDER_STATUS.已支付.getDictValue());
zfOrderInfoDO.setOrderPayStatus(PayCodeConstants.ZF_ORDER_INFO_ORDER_PAY_STATUS.已支付.getDictValue());
zfOrderInfoDO.setOrderPaySuccTime(DateUtils.getCurrentDateTime());
zfOrderInfoDO.setOrderLastUpdTime(DateUtils.getCurrentDateTime());
zfOrderInfoDO.setAcctDay(DateUtils.format(DateUtils.getCurrentDateTime(), "yyyyMMdd"));
zfOrderInfoDO.setFinishTime(DateUtils.getCurrentDateTime());
updateOrderPaySuccess(zfOrderInfoDO,medTransId);
} catch (Exception e) {
log.error("微信当面付医保更新订单失败,msg:{}", e.getMessage());
return ResponseUtils.error("PYA204", "微信当面付医保更新订单失败");
}
// 调用见证宝充值
if(PayCodeConstants.ZF_ORDER_INFO_PAY_TYPE.自费医保.getDictValue().equals(zfOrderInfoDO.getPayType())) {
rechargeJzb(zfOrderInfoDO);
}
} else {
log.info("微信当面付医保查询,处理信息:{},{},{}", result.getErr_code_des(), result.getReturn_code(),
result.getReturn_msg());
List<ZfOrderInfoDO> wechatMedOrder = zfOrderInfoService.listByPo(query);
ZfOrderInfoDO vo = wechatMedOrder.get(0);
JSONObject wechatMedDate = new JSONObject();
wechatMedDate.put("version", VERSION);// 通讯协议版本号
wechatMedDate.put("agentComyId", vo.getAgentComyId());// 代理商编号
wechatMedDate.put("merchId", vo.getMerId());// 商户编号
wechatMedDate.put("merchOrderId", vo.getMerOrderId());// 商户订单号
wechatMedDate.put("tradeNo", vo.getPlatOrderId());// 支付平台订单号
wechatMedDate.put("orderType", vo.getOrderType());// 订单类型
wechatMedDate.put("amount", ArithUtils.format(vo.getOrderAmt()));// 订单金额
wechatMedDate.put("orderStatus", PayCodeConstants.ZF_ORDER_INFO_ORDER_PAY_STATUS.待支付.getDictValue());// 订单状态
wechatMedDate.put("tradeTime", DateUtils.format(vo.getAddTime(), "yyyyMMddHHmmss"));// 交易时间
String prikey = tyPubSysParamCacheClient.getParamValue(PayConstant.RSA_PUB_PAI_KEY.PRI_KEY, null);
if (prikey == null) {
return ResponseUtils.error("PYD302", errCode.getShowMsg("PYD302"));// PYD302:未配置参数-加密KEY
}
return ResponseUtils.succDataObjectWithSign(wechatMedDate, prikey);
}
}
/* 确认已支付的订单有没有撤下记录(TRADE_CANCEL_FLAG == 1) */
List<ZfOrderInfoDO> orderByPoList = zfOrderInfoService.listByPo(query);
ZfOrderInfoDO vo = orderByPoList.get(0);
if (PayCodeConstants.ZF_ORDER_INFO_TRADE_CANCEL_FLAG.已撤销.getDictValue().equals(vo.getTradeCancelFlag())) {
/* 订单有撤销记录需要调渠道交易结果查询-确认渠道结果 */
boolean orderChnIsPayed = true; //渠道订单状态是否已支付
if (PayCodeConstants.ZF_ORDER_INFO_PAY_WAY.支付宝当面付.getDictValue().equals(zfOrderInfoDO.getPayWay())
|| PayCodeConstants.ZF_ORDER_INFO_PAY_WAY.支付宝免密支付.getDictValue().equals(zfOrderInfoDO.getPayWay())) {
ZfAlipayTradeQueryReq zfAlipayTradeQueryReq = new ZfAlipayTradeQueryReq();
zfAlipayTradeQueryReq.setOutTradeNo(outTradeNo);
AlipayF2FQueryResult result = zfAlipayService.tradeQuery(zfAlipayTradeQueryReq);
log.info("订单[" + outTradeNo + "]支付宝渠道支付结果返回:" + result.getTradeStatus() + "--" + result.getResponse().getBody());
if(!result.isTradeSuccess()) {
/* 渠道不是已支付状态 */
log.info("->>订单:{}平台与支付宝交易渠道支付状态不符!需要返回支付渠道实际支付状态");
orderChnIsPayed = false;
}
} else if (PayCodeConstants.ZF_ORDER_INFO_PAY_WAY.微信当面付.getDictValue().equals(zfOrderInfoDO.getPayWay())
&& PayCodeConstants.ZF_ORDER_INFO_PAY_TYPE.自费.getDictValue().equals(zfOrderInfoDO.getPayType())) {
OrderQueryVO orderQueryVO = new OrderQueryVO();
orderQueryVO.setOrderId(outTradeNo);
orderQueryVO.setOrderSource("2");
ZiFeiQueryOrderRes result = weChatOrderQueyService.ziFeiOrderQuery(orderQueryVO);
log.info("订单[{}]微信支付渠道支付结果返回:{}", outTradeNo, JSON.toJSONString(result));
if (!"SUCCESS".equalsIgnoreCase(result.getTrade_state())) {
/* 渠道不是已支付状态 */
log.info("->>订单:{}平台与微信交易渠道支付状态不符!需要返回支付渠道实际支付状态");
orderChnIsPayed = false;
}
} else if (PayCodeConstants.ZF_ORDER_INFO_PAY_WAY.微信当面付.getDictValue().equals(zfOrderInfoDO.getPayWay())
&& (PayCodeConstants.ZF_ORDER_INFO_PAY_TYPE.医保.getDictValue().equals(zfOrderInfoDO.getPayType())
|| PayCodeConstants.ZF_ORDER_INFO_PAY_TYPE.自费医保.getDictValue().equals(zfOrderInfoDO.getPayType()))) {
OrderQueryVO orderQueryVO = new OrderQueryVO();
orderQueryVO.setOrderId(outTradeNo);
orderQueryVO.setOrderSource("2");
YiBaoQueryOrderRes result = weChatOrderQueyService.yiBaoOrderQuery(orderQueryVO);
log.info("订单[{}]微信医保支付渠道支付结果返回:{}", outTradeNo, JSON.toJSONString(result));
if (!"SUCCESS".equalsIgnoreCase(result.getMed_trade_state())) {
/* 渠道医保不是已支付状态 */
log.info("->>订单:{}平台与微信医保交易渠道支付状态不符!需要返回支付渠道实际支付状态");
orderChnIsPayed = false;
}
}
if (!orderChnIsPayed) {
//支付渠道订单状态为:已关闭
JSONObject res = new JSONObject();
res.put("version", VERSION);// 通讯协议版本号
res.put("agentComyId", vo.getAgentComyId());// 代理商编号
res.put("merchId", vo.getMerId());// 商户编号
res.put("merchOrderId", vo.getMerOrderId());// 商户订单号
res.put("tradeNo", vo.getPlatOrderId());// 支付平台订单号
res.put("orderType", vo.getOrderType());// 订单类型
res.put("amount", ArithUtils.format(vo.getOrderAmt()));// 订单金额
res.put("orderStatus", PayCodeConstants.ZF_ORDER_INFO_ORDER_STATUS.关闭作废.getDictValue());// 订单状态
res.put("tradeTime", DateUtils.format(vo.getAddTime(), "yyyyMMddHHmmss"));// 交易时间
String prikey = tyPubSysParamCacheClient.getParamValue(PayConstant.RSA_PUB_PAI_KEY.PRI_KEY, null);
if (prikey == null) {
return ResponseUtils.error("PYD302", errCode.getShowMsg("PYD302"));//PYD302:未配置参数-加密KEY
}
return ResponseUtils.succDataObjectWithSign(res, prikey);
}
}
JSONObject data = new JSONObject();
data.put("version", VERSION);// 通讯协议版本号
data.put("agentComyId", vo.getAgentComyId());// 代理商编号
data.put("merchId", vo.getMerId());// 商户编号
data.put("merchOrderId", vo.getMerOrderId());// 商户订单号
data.put("tradeNo", vo.getPlatOrderId());// 支付平台订单号
data.put("orderType", vo.getOrderType());// 订单类型
data.put("amount", ArithUtils.format(vo.getOrderAmt()));// 订单金额
data.put("orderStatus", vo.getOrderStatus());// 订单状态
data.put("payTime", DateUtils.format(vo.getOrderPaySuccTime(), "yyyyMMddHHmmss"));// 支付时间
data.put("settleTime", vo.getAcctDay());// 是否是账务日期
data.put("merchHoldInf", vo.getMerHoldInf());// 商户保留信息
data.put("payWay", vo.getPayWay());//支付方式
data.put("tradeTime", DateUtils.format(vo.getAddTime(), "yyyyMMddHHmmss"));// 交易时间
String medicalJsonStr = "";// 医疗订单扩展信息
// 如果订单类型为11:预约挂号,12:门诊缴费,则返回医疗扩展字段
JSONObject medicalJson = new JSONObject();
medicalJson.put("payFlag", vo.getPayType());// 支付类型
medicalJson.put("selfPayAmt",ArithUtils.format(vo.getSelfPayAmt() == null ? new BigDecimal(0) : vo.getSelfPayAmt())); // 自费支付金额
medicalJson.put("sIPayAmt", ArithUtils.format(vo.getSiPayAmt() == null ? new BigDecimal(0) : vo.getSiPayAmt())); // 医保支付金额
medicalJson.put("sISelfPayAmt",ArithUtils.format(vo.getSiSelfAmt() == null ? new BigDecimal(0) : vo.getSiSelfAmt())); // 医保个帐支付金额
medicalJson.put("transBody", vo.getSiPaySuccStruct() == null ? null : vo.getSiPaySuccStruct()); // 医保支付成功结构体
if (Arrays.asList(PayCodeConstants.ZF_PUBLIC_ORDER_TYPE.预约挂号.getDictValue(),
PayCodeConstants.ZF_PUBLIC_ORDER_TYPE.门诊缴费.getDictValue()).contains(vo.getOrderType())) {
medicalJsonStr = medicalJson.toJSONString();
data.put("medicalJson", medicalJsonStr);
// 对返回医疗扩展字段进行AES加密处理
try {
data.put("medicalJson", AES.crypt(medicalJsonStr, key));
} catch (Exception e) {
log.error("加密medicalJson异常", e);
return ResponseUtils.error("PYB605", errCode.getShowMsg("PYB605"));// 医疗订单扩展信息解析失败
}
}
//返回报文加签名
String platRsaPirKey = tyPubSysParamCacheClient.getParamValue(PayConstant.RSA_PUB_PAI_KEY.PRI_KEY, null);
if (platRsaPirKey == null) {
return ResponseUtils.error("PYD302", errCode.getShowMsg("PYD302"));//PYD302:未配置参数-加密KEY
}
return ResponseUtils.succDataObjectWithSign(data, platRsaPirKey);
}
当订单在支付的过程出现异常,收银台可以主动发起撤销订单的操作;谁叫我们对接了一个比价垃圾的社康系统呢!动不动社康在支付的过程就会出现异常,所以这个接口主要是给社康在支付过程中出现异常时调用的。当然,在支付的过程中,出现网络超时或者用户支付时输入密码超时,也会使用到这个接口来处理。
@RequestMapping("/cancelOrder")
public String cancelOrder(@Valid FaceToFaceCancelOrderVo faceToFaceCancelOrderVo, BindingResult bindingResult) {
ZfMerMerchInfoDO merch;//商户信息
ZfMerIntfCtrlDO merIntfCtrl;//商户接入控制信息
String merRsaPubKey;//签名KEY公钥
boolean isAgentComy = faceToFaceCancelOrderVo.getMerchFlag().equals(PayOrderConstant.MerchFlag.AGENCY);
if (!VERSION.equals(faceToFaceCancelOrderVo.getVersion())) {
throw new PayVerifyException("PYB601", errCode.getShowMsg("PYB601"));// PYB601:接口版本不一致
}
// 校验商户信息
merch = payOrderVerifyService.merchantVerify(faceToFaceCancelOrderVo.getMerchId());
// 代理商模式
if (isAgentComy) {
// 代理商校验
payOrderVerifyService.agentComyVerify(faceToFaceCancelOrderVo.getAgentComyId(), merch.getMerId());
// 校验代理商接入控制信息
merIntfCtrl = payOrderVerifyService.merIntfCtrVerify(faceToFaceCancelOrderVo.getAgentComyId(), null);
merRsaPubKey = merIntfCtrl.getMerPubKey();
} else {
// 非外部商户需要绑定代理商
if (!merch.getMerType().equals(PayCodeConstants.ZF_MER_MERCH_INFO_MER_TYPE.外部商户.getDictValue())) {
throw new PayVerifyException("PYP708", errCode.getShowMsg("PYP708"));//PYP708:非外部商户必须通过代理商进行支付
}
// 校验商户接入控制信息
merIntfCtrl = payOrderVerifyService.merIntfCtrVerify(merch.getMerId(), null);
merRsaPubKey = merIntfCtrl.getMerPubKey();
}
// 验签
if (StringUtils.isEmpty(merRsaPubKey)) {
throw new PayVerifyException("PYP718", errCode.getShowMsg("PYP718"));//PYP718:接入控制签名KEY为空
}
if (!PaySignUtil.payAttestation(faceToFaceCancelOrderVo, merRsaPubKey, faceToFaceCancelOrderVo.getSign())) {
throw new PayVerifyException("PYB625", errCode.getShowMsg("PYB625"));//PYB625:验证签名失败
}
//查询该订单是否存在
ZfOrderInfoQuery query = new ZfOrderInfoQuery();
query.setMerOrderId(faceToFaceCancelOrderVo.getMerchOrderId());
query.setMerId(faceToFaceCancelOrderVo.getMerchId());
List<ZfOrderInfoDO> zfOrderInfoList = zfOrderInfoService.listByPo(query);
if (zfOrderInfoList == null || zfOrderInfoList.size() == 0) {
return ResponseUtils.error("PYO201", errCode.getShowMsg("PYO201"));//PYO201:订单不存在
}
ZfOrderInfoDO zfOrderInfoDO = zfOrderInfoList.get(0);
String outTradeNo = zfOrderInfoDO.getPlatOrderId();
String oderStatus = zfOrderInfoDO.getOrderStatus();//订单状态
BigDecimal refAmt = zfOrderInfoDO.getOrderAmt();//退款金额
BigDecimal waitStlAmt = merch.getWaitStlAmt(); //商户待结算金额
ZfOrderRefundDO zfOrderRefundDO = new ZfOrderRefundDO();
// 订单状态校验
if (oderStatus.equals(PayCodeConstants.ZF_ORDER_INFO_ORDER_STATUS.全额退款.getDictValue())
|| oderStatus.equals(PayCodeConstants.ZF_ORDER_INFO_ORDER_STATUS.部分退款.getDictValue())
|| oderStatus.equals(PayCodeConstants.ZF_ORDER_INFO_ORDER_STATUS.关闭作废.getDictValue())) {
log.info("订单支付状态:{},此类订单状态,不允许退款", oderStatus);
return ResponseUtils.error("PYO216", errCode.getShowMsg("PYO216"));// 订单状态不支持退款
}
// 新增退款表-待处理
try {
zfOrderRefundDO = creatRefDo(zfOrderRefundDO, zfOrderInfoDO, faceToFaceCancelOrderVo);
zfOrderRefundService.insertSelective(zfOrderRefundDO);
} catch (Exception e) {
log.error("新增退款订单申请失败!,msg:{}", e.getMessage());
return ResponseUtils.error("PYA203", errCode.getShowMsg("PYA203"));
}
// 调用渠道退费
try {
//同步退费--实时退
ZfOrderChnRefundDO zfOrderChnRefundDO = extChnRefundService.callChnRef(zfOrderRefundDO, zfOrderInfoDO,merch);
//判断退款是否成功 未成功重试三次
String incRetFlag = zfOrderChnRefundDO.getIncRetFlag();//接口调用标志
String refdRetFlag =zfOrderChnRefundDO.getRefdRetFlag();//退款结果
int i = 2;
String refundCount = tyPubSysParamCacheClient.getParamValue("REFUND_COUNT","5");
if(PayCodeConstants.ZF_CHN_TRAN_ERR_REFUND_INC_RET_FLAG.调用成功.getDictValue().equals(incRetFlag)
&& PayCodeConstants.ZF_CHN_TRAN_ERR_REFUND_REFD_RET_FLAG.未退款.getDictValue().equals(refdRetFlag)){
while (PayCodeConstants.ZF_CHN_TRAN_ERR_REFUND_REFD_RET_FLAG.未退款.getDictValue().equals(zfOrderChnRefundDO.getRefdRetFlag())
&& i< Integer.parseInt(refundCount)){
log.info("---------当面付订单渠道未退款尝试第:{} 次调用退款",i);
zfOrderChnRefundDO = extChnRefundService.callChnRef(zfOrderRefundDO, zfOrderInfoDO,merch);
incRetFlag = zfOrderChnRefundDO.getIncRetFlag();
refdRetFlag =zfOrderChnRefundDO.getRefdRetFlag();
i++;
}
}
/* 标记当前订单撤销标识:为已撤销交易 */
try {
zfOrderInfoDO.setTradeCancelFlag(PayCodeConstants.ZF_ORDER_INFO_TRADE_CANCEL_FLAG.已撤销.getDictValue());
zfOrderInfoService.updateSelective(zfOrderInfoDO);
} catch (Exception e) {
return ResponseUtils.error("PYA204", errCode.getShowMsg("PYA204"));
}
} catch (Exception e) {
log.error("调用渠道退费失败 msg:{}", e.getMessage());
return ResponseUtils.error("PYE529", errCode.getShowMsg("PYE529"));
}
}
if (PayCodeConstants.ZF_ORDER_INFO_ORDER_PAY_STATUS.待支付.getDictValue().equals(zfOrderInfoDO.getOrderPayStatus())
&& (PayCodeConstants.ZF_ORDER_INFO_PAY_WAY.支付宝当面付.getDictValue().equals(zfOrderInfoDO.getPayWay())
|| PayCodeConstants.ZF_ORDER_INFO_PAY_WAY.支付宝免密支付.getDictValue().equals(zfOrderInfoDO.getPayWay()))) {
/* 标记订单撤销标识:为已撤销交易 */
try {
this.TagOrderTradeCancelFlag(zfOrderInfoDO.getPlatOrderId());
} catch (Exception e) {
return ResponseUtils.error("PYA204", errCode.getShowMsg("PYA204"));
}
ZfAlipayTradeCancelReq zfAlipayTradeCancelReq = new ZfAlipayTradeCancelReq();
zfAlipayTradeCancelReq.setOutTradeNo(outTradeNo);
log.info(">>>>>>>>>>>>>>>支付宝当面撤销入参:"+JSON.toJSONString(zfAlipayTradeCancelReq));
AlipayF2FCancelResult result = zfAlipayService.tradeCancel(zfAlipayTradeCancelReq);
log.info(">>>>>>>>>>>>>>>支付宝当面撤销返回参数:"+JSON.toJSONString(result));
if(result.isSuccess()) {
log.info("支付宝当面付撤销成功");
}else {
log.info("支付宝当面付撤销返回信息:{},{}",result.getSubCode(),result.getErrorMsg());
List<ZfOrderInfoDO> aliCancelOrder = zfOrderInfoService.listByPo(query);
ZfOrderInfoDO vo = aliCancelOrder.get(0);
JSONObject aliCancelData = new JSONObject();
aliCancelData.put("version", VERSION);// 通讯协议版本号
aliCancelData.put("agentComyId", vo.getAgentComyId());// 代理商编号
aliCancelData.put("merchId", vo.getMerId());// 商户编号
aliCancelData.put("merchOrderId", vo.getMerOrderId());// 商户订单号
aliCancelData.put("cancelResult", "0");// 撤销结果 0:关闭订单 1:订单退款
aliCancelData.put("merchCancelId", zfOrderRefundDO.getMerRefdSeqno());//原商户撤销申请号
aliCancelData.put("tradeTime", DateUtils.format(vo.getAddTime(), "yyyyMMddHHmmss"));// 交易时间
//返回报文加签名
String platRsaPirKey = tyPubSysParamCacheClient.getParamValue(PayConstant.RSA_PUB_PAI_KEY.PRI_KEY, null);
if (platRsaPirKey == null) {
return ResponseUtils.error("PYD302", errCode.getShowMsg("PYD302"));//PYD302:未配置参数-加密KEY
}
return ResponseUtils.succDataObjectWithSign(aliCancelData, platRsaPirKey);
}
}
if (PayCodeConstants.ZF_ORDER_INFO_ORDER_PAY_STATUS.待支付.getDictValue().equals(zfOrderInfoDO.getOrderPayStatus())
&& PayCodeConstants.ZF_ORDER_INFO_PAY_WAY.微信当面付.getDictValue().equals(zfOrderInfoDO.getPayWay())
&& PayCodeConstants.ZF_ORDER_INFO_PAY_TYPE.自费.getDictValue().equals(zfOrderInfoDO.getPayType())) {
/* 标记订单撤销标识:为已撤销交易 */
try {
this.TagOrderTradeCancelFlag(zfOrderInfoDO.getPlatOrderId());
} catch (Exception e) {
return ResponseUtils.error("PYA204", errCode.getShowMsg("PYA204"));
}
WeChatF2FReverseVO weChatF2FReverseVO = new WeChatF2FReverseVO();
weChatF2FReverseVO.setPlatOrderId(zfOrderInfoDO.getPlatOrderId());
log.info(">>>>>>>>>>>>>>>微信当面撤销入参:"+JSON.toJSONString(weChatF2FReverseVO));
WeChatF2FReverseRes result = wechatRefService.wechatF2FReverse(weChatF2FReverseVO);
log.info(">>>>>>>>>>>>>>>微信当面撤销返回参数:"+JSON.toJSONString(result));
if(result.getReturn_code().equals("SUCCESS")) {
if("N".equals(result.getRecall())){
log.info("微信当面付自费撤销订单成功!");
}else{
String reCall="";
int i= 0;
String refundCount = tyPubSysParamCacheClient.getParamValue("MAX_CANCEL_RETRY","3");
//需要重新撤销
if(!"SUCCESS".equals(result.getResult_code()) || "Y".equals(result.getRecall())){
while (!reCall.equals("N")&& i<Integer.parseInt(refundCount)){
//Utils.sleep(5);
result = wechatRefService.wechatF2FReverse(weChatF2FReverseVO);
log.info(">>>>>>>重新发起微信撤销 次数:{},返回参数:{}",i,JSONObject.toJSONString(result));
if("SUCCESS".equals(result.getResult_code())){
reCall= result.getRecall();
}else{
reCall ="";
}
i++;
}
}
if ("N".equals(result.getRecall())) {
log.info("微信当面付自费撤销订单成功!");
/* 标记订单撤销标识:为已撤销交易 */
try {
this.TagOrderTradeCancelFlag(zfOrderInfoDO.getPlatOrderId());
} catch (Exception e) {
return ResponseUtils.error("PYA204", errCode.getShowMsg("PYA204"));
}
}
}
}else {
log.info("微信当面付自费关闭订单返回信息:{},{}",result.getReturn_code(),result.getReturn_msg());
List<ZfOrderInfoDO> wechatCancelOrder = zfOrderInfoService.listByPo(query);
ZfOrderInfoDO vo = wechatCancelOrder.get(0);
JSONObject wechatCancelData = new JSONObject();
wechatCancelData.put("version", VERSION);// 通讯协议版本号
wechatCancelData.put("agentComyId", vo.getAgentComyId());// 代理商编号
wechatCancelData.put("merchId", vo.getMerId());// 商户编号
wechatCancelData.put("merchOrderId", vo.getMerOrderId());// 商户订单号
wechatCancelData.put("cancelResult", "0");// 撤销结果 0:关闭订单 1:订单退款
wechatCancelData.put("merchCancelId", zfOrderRefundDO.getMerRefdSeqno());//原商户撤销申请号
wechatCancelData.put("tradeTime", DateUtils.format(vo.getAddTime(), "yyyyMMddHHmmss"));// 交易时间
//返回报文加签名
String platRsaPirKey = tyPubSysParamCacheClient.getParamValue(PayConstant.RSA_PUB_PAI_KEY.PRI_KEY, null);
if (platRsaPirKey == null) {
return ResponseUtils.error("PYD302", errCode.getShowMsg("PYD302"));//PYD302:未配置参数-加密KEY
}
return ResponseUtils.succDataObjectWithSign(wechatCancelData, platRsaPirKey);
}
}
if (PayCodeConstants.ZF_ORDER_INFO_ORDER_PAY_STATUS.待支付.getDictValue().equals(zfOrderInfoDO.getOrderPayStatus())
&& PayCodeConstants.ZF_ORDER_INFO_PAY_WAY.微信当面付.getDictValue().equals(zfOrderInfoDO.getPayWay())
&& (PayCodeConstants.ZF_ORDER_INFO_PAY_TYPE.医保.getDictValue().equals(zfOrderInfoDO.getPayType())
|| PayCodeConstants.ZF_ORDER_INFO_PAY_TYPE.自费医保.getDictValue().equals(zfOrderInfoDO.getPayType()))) {
/* 标记订单撤销标识:为已撤销交易 */
try {
this.TagOrderTradeCancelFlag(zfOrderInfoDO.getPlatOrderId());
} catch (Exception e) {
return ResponseUtils.error("PYA204", errCode.getShowMsg("PYA204"));
}
/* step1:首先查询渠道医保医保是否结算成功 */
OrderQueryVO orderQueryVO = new OrderQueryVO();
orderQueryVO.setOrderId(outTradeNo);
orderQueryVO.setOrderSource("2");
YiBaoQueryOrderRes result = weChatOrderQueyService.yiBaoOrderQuery(orderQueryVO);
if (!"SUCCESS".equals(result.getResult_code())) {
//查询交易失败-交易订单不存在
JSONObject wechatCancelMedData = new JSONObject();
wechatCancelMedData.put("version", VERSION);// 通讯协议版本号
wechatCancelMedData.put("agentComyId", zfOrderInfoDO.getAgentComyId());// 代理商编号
wechatCancelMedData.put("merchId", zfOrderInfoDO.getMerId());// 商户编号
wechatCancelMedData.put("merchOrderId", zfOrderInfoDO.getMerOrderId());// 商户订单号
wechatCancelMedData.put("cancelResult", "0");// 撤销结果 0:关闭订单 1:订单退款
wechatCancelMedData.put("merchCancelId", zfOrderRefundDO.getMerRefdSeqno());//原商户撤销申请号
wechatCancelMedData.put("tradeTime", DateUtils.format(zfOrderInfoDO.getAddTime(), "yyyyMMddHHmmss"));// 交易时间
//返回报文加签名
String platRsaPirKey = tyPubSysParamCacheClient.getParamValue(PayConstant.RSA_PUB_PAI_KEY.PRI_KEY, null);
if (platRsaPirKey == null) {
return ResponseUtils.error("PYD302", errCode.getShowMsg("PYD302"));//PYD302:未配置参数-加密KEY
}
return ResponseUtils.succDataObjectWithSign(wechatCancelMedData, platRsaPirKey);
}
if (result.getMed_trade_state().equals("SUCCESS")) {
log.info("微信当面付医保查询返回该订单支付成功!!!");
/* 平台未支付,渠道医保已扣费的情况 */
/* 渠道医保结算成功需要调用退费接口 */
log.info("===================>微信服务商医保渠道退款:");
Map<String, String> siParam = this.yBPayService.parsSIPayStruct(zfOrderInfoDO.getSiPayStruct());
log.info("解析医保支付透传体返回:{}", siParam.toString());
YiBaoRefVO yiBaoRefVO = new YiBaoRefVO();
yiBaoRefVO.setOrderId(zfOrderRefundDO.getPlatOrderId());
yiBaoRefVO.setRefundId(zfOrderRefundDO.getRefdSeqno());
yiBaoRefVO.setCancelSerialNo(siParam.get("akc190"));//门诊流水号
yiBaoRefVO.setOrderSource("2");
yiBaoRefVO.setCancelBillNo(siParam.get("bke384"));
yiBaoRefVO.setRequestContent(zfOrderInfoDO.getSiPayStruct());
log.info("##################微信服务商渠道退款入参:{}", JSONObject.toJSONString(yiBaoRefVO));
YiBaoRefundRes yiBaoRefundRes = wechatRefService.yiBaoRef(yiBaoRefVO);
log.info("##################微信服务商渠道退款出参:{}", JSONObject.toJSONString(yiBaoRefundRes));
if (yiBaoRefundRes.getReturn_code().equals(WeChatPayConstants.SUCCESS)
&& yiBaoRefundRes.getResult_code().equals(WeChatPayConstants.SUCCESS)) {
//渠道退款成功,修改渠道表和退款记录表
log.info("微信医保渠道退费成功!渠道退费交易单号:{},医保支付金额:{}", yiBaoRefundRes.getMed_refund_id(), yiBaoRefundRes.getInsurance_refund_fee());
} else {
log.info("微信医保渠道退费失败,稍后转人工服务");
}
}
/* step2:关闭订单,终止交易 */
CloseOrderVO closeOrderVO = new CloseOrderVO();
closeOrderVO.setOrderId(zfOrderInfoDO.getPlatOrderId());
closeOrderVO.setOrderSource("2");
BaseRes closeRes = weChatCloseOrderService.closeYiBaoOrder(closeOrderVO);
if(closeRes.getResult_code().equals("SUCCESS")) {
log.info("微信当面付医保关闭订单成功!");
}else {
log.info("微信当面付医保关闭订单返回信息:{},{}",result.getReturn_code(),result.getReturn_msg());
List<ZfOrderInfoDO> wechatCancelMedOrder = zfOrderInfoService.listByPo(query);
ZfOrderInfoDO vo = wechatCancelMedOrder.get(0);
JSONObject wechatCancelMedData = new JSONObject();
wechatCancelMedData.put("version", VERSION);// 通讯协议版本号
wechatCancelMedData.put("agentComyId", vo.getAgentComyId());// 代理商编号
wechatCancelMedData.put("merchId", vo.getMerId());// 商户编号
wechatCancelMedData.put("merchOrderId", vo.getMerOrderId());// 商户订单号
wechatCancelMedData.put("cancelResult", "0");// 撤销结果 0:关闭订单 1:订单退款
wechatCancelMedData.put("merchCancelId", zfOrderRefundDO.getMerRefdSeqno());//原商户撤销申请号
wechatCancelMedData.put("tradeTime", DateUtils.format(vo.getAddTime(), "yyyyMMddHHmmss"));// 交易时间
//返回报文加签名
String platRsaPirKey = tyPubSysParamCacheClient.getParamValue(PayConstant.RSA_PUB_PAI_KEY.PRI_KEY, null);
if (platRsaPirKey == null) {
return ResponseUtils.error("PYD302", errCode.getShowMsg("PYD302"));//PYD302:未配置参数-加密KEY
}
return ResponseUtils.succDataObjectWithSign(wechatCancelMedData, platRsaPirKey);
}
}
//返回报文信息
List<ZfOrderInfoDO> orderInfoList = zfOrderInfoService.listByPo(query);
ZfOrderInfoDO vo = orderInfoList.get(0);
String cancelResult = null;//撤销结果 0:关闭订单 1:订单退款
if (vo.getOrderStatus().equals(PayCodeConstants.ZF_ORDER_INFO_ORDER_STATUS.全额退款.getDictValue())
||vo.getOrderStatus().equals((PayCodeConstants.ZF_ORDER_INFO_ORDER_STATUS.部分退款.getDictValue()))) {
cancelResult = "1";
} else {
cancelResult = "0";
}
JSONObject data = new JSONObject();
data.put("version", VERSION);// 通讯协议版本号
data.put("agentComyId", vo.getAgentComyId());// 代理商编号
data.put("merchId", vo.getMerId());// 商户编号
data.put("merchOrderId", vo.getMerOrderId());// 商户订单号
data.put("merchCancelId", zfOrderRefundDO.getMerRefdSeqno());//原商户撤销申请号
data.put("cancelResult", cancelResult);// 撤销结果 0:关闭订单 1:订单退款
data.put("tradeTime", DateUtils.format(vo.getAddTime(), "yyyyMMddHHmmss"));// 交易时间
//返回报文加签名
String platRsaPirKey = tyPubSysParamCacheClient.getParamValue(PayConstant.RSA_PUB_PAI_KEY.PRI_KEY, null);
if (platRsaPirKey == null) {
return ResponseUtils.error("PYD302", errCode.getShowMsg("PYD302"));//PYD302:未配置参数-加密KEY
}
return ResponseUtils.succDataObjectWithSign(data, platRsaPirKey);
}