Commit 79cf6afe by yuanchao

20240329建行支付

parent 3061ca3d
package com.qianhe.system.controller; package com.qianhe.system.controller;
import com.alibaba.fastjson.JSON;
import com.qianhe.system.domain.CCBNotifyInfo;
import com.qianhe.system.domain.WaterOrderLog;
import com.qianhe.system.mapper.WaterOrderLogMapper;
import com.qianhe.system.mapper.WaterOrderMapper;
import com.qianhe.system.vo.WaterOrderVo;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import sun.security.rsa.RSASignature;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
/** /**
* @author yc * @author yc
...@@ -15,5 +28,37 @@ import org.springframework.web.bind.annotation.RestController; ...@@ -15,5 +28,37 @@ import org.springframework.web.bind.annotation.RestController;
@Slf4j @Slf4j
@RequestMapping("/ccbback") @RequestMapping("/ccbback")
public class CCBBackController { public class CCBBackController {
private String pubKey = "";
@Autowired
private WaterOrderLogMapper orderLogMapper;
@Autowired
private WaterOrderMapper orderMapper;
@PostMapping("/jh/notify")
public String pay(CCBNotifyInfo notifyInfo) {
log.info("建行回调通知参数[{}]", JSON.toJSONString(notifyInfo));
String src = "POSID=" + notifyInfo.getPOSID() + "&BRANCHID=" + notifyInfo.getBRANCHID() + "&ORDERID=" + notifyInfo.getORDERID() +
"&PAYMENT=" + notifyInfo.getPAYMENT() + "&CURCODE=" + notifyInfo.getCURCODE() + "&REMARK1=" + notifyInfo.getREMARK1() + "&REMARK2=" + notifyInfo.getREMARK2() + "&ACC_TYPE=" + notifyInfo.getACC_TYPE() +
"&SUCCESS=" + notifyInfo.getSUCCESS() + "&TYPE=" + notifyInfo.getTYPE() + "&REFERER=" + notifyInfo.getREFERER() + "&CLIENTIP=" + notifyInfo.getCLIENTIP();
if (notifyInfo.getSUCCESS().equals("Y")) {
// 这里需要调用建行龙支付提供的查询订单接口以保证订单确实支付成功
/* SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX");
Date date = sdf.parse(successTime);*/
WaterOrderLog orderLog = new WaterOrderLog();
orderLog.setPayNum(notifyInfo.getORDERID());
//orderLog.setPayTime(date);
orderLog.setPayMoney(new BigDecimal(notifyInfo.getPAYMENT()));
int iLog = orderLogMapper.insertWaterOrderLog(orderLog);
WaterOrderVo orderVo = new WaterOrderVo();
orderVo.setOrderNum(notifyInfo.getORDERID());
int orderI = orderMapper.updateByOrderNum(orderVo);
log.info("验签通过");
return "SUCCESS";
} else {
// 验签失败
log.info("验签失败");
return "FAIL";
}
}
} }
\ No newline at end of file
...@@ -10,9 +10,7 @@ import org.apache.http.client.methods.HttpPost; ...@@ -10,9 +10,7 @@ import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils; import org.apache.http.util.EntityUtils;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException; import java.io.IOException;
import java.util.HashMap; import java.util.HashMap;
...@@ -37,61 +35,61 @@ public class CCBPayController { ...@@ -37,61 +35,61 @@ public class CCBPayController {
/** /**
* 预支付订单生成入口 * 预支付订单生成入口
*/ */
@GetMapping("/pay") @PostMapping("/pay")
public AjaxResult bankPay(WaterGoods goods) throws IOException { public AjaxResult bankPay(@RequestBody WaterGoods goods) throws IOException {
//建行提供
String MERCHANTID = "105000149005386"; String MERCHANTID = "105000149005386";
//建行提供
String POSID = "081113098"; String POSID = "081113098";
//建行提供
String BRANCHID = "370000000"; String BRANCHID = "370000000";
String ORDERID = "1234665"; String ORDERID = goods.getOrderNo();
String PAYMENT = "0.01"; String PAYMENT = goods.getTotalPrice();
String CURCODE = "01"; String CURCODE = "01";
String TXCODE = "530590"; String TXCODE = "530590";
String REMARK1 = ""; String REMARK1 = "";
String REMARK2 = ""; String REMARK2 = "";
String TYPE = "1"; String TYPE = "1";
//公钥后30位
String PUB = "c2660ff6f7c5d64570352f21020111"; String PUB = "c2660ff6f7c5d64570352f21020111";
String GATEWAY = "0"; String GATEWAY = "0";
String CLIENTIP = "127.0.0.1"; String CLIENTIP = "127.0.0.1";
String REGINFO = ""; String REGINFO = "";
String PROINFO = "test"; String PROINFO = goods.getTitle();
String REFERER = ""; String REFERER = "";
String TRADE_TYPE = "MINIPRO"; String TRADE_TYPE = "MINIPRO";
//订水微信小程序appId
String SUB_APPID = "wx3c0181d9800dfbf2"; String SUB_APPID = "wx3c0181d9800dfbf2";
String SUB_OPENID = "orQvH66uR0zvOhHx1sxq49qEln9s"; //所属用户微信openId
String SUB_OPENID = goods.getOpenId();
String macStr = "MERCHANTID=105000149005386"; String macStr = "MERCHANTID=105000149005386";
macStr+=POSID; macStr+= "&POSID="+POSID;
macStr+=BRANCHID; macStr+= "&BRANCHID="+BRANCHID;
macStr+=ORDERID; macStr+= "&ORDERID="+ORDERID;
macStr+=PAYMENT; macStr+= "&PAYMENT="+PAYMENT;
macStr+=CURCODE; macStr+= "&CURCODE="+CURCODE;
macStr+=TXCODE; macStr+= "&TXCODE="+TXCODE;
macStr+=REMARK1; macStr+= "&REMARK1="+REMARK1;
macStr+=REMARK2; macStr+= "&REMARK2="+REMARK2;
macStr+=TYPE; macStr+= "&TYPE="+TYPE;
macStr+=PUB; macStr+= "&PUB="+PUB;
macStr+=GATEWAY; macStr+= "&GATEWAY="+GATEWAY;
macStr+=CLIENTIP; macStr+= "&CLIENTIP="+CLIENTIP;
macStr+=REGINFO; macStr+= "&REGINFO="+REGINFO;
macStr+=PROINFO; macStr+= "&PROINFO="+PROINFO;
macStr+=REFERER; macStr+= "&REFERER="+REFERER;
macStr+=TRADE_TYPE; macStr+= "&TRADE_TYPE="+TRADE_TYPE;
macStr+=SUB_APPID; macStr+= "&SUB_APPID="+SUB_APPID;
macStr+=SUB_OPENID; macStr+= "&SUB_OPENID="+SUB_OPENID;
//参与MAC计算所需参数具体看开发文档
String macStrMd5 = MD5.EncodeByMD5(macStr); String macStrMd5 = MD5.EncodeByMD5(macStr);
String url = "https://ibsbjstar.ccb.com.cn/CCBIS/ccbMain?CCB_IBSVersion=V6"; String url = "https://ibsbjstar.ccb.com.cn/CCBIS/ccbMain?CCB_IBSVersion=V6";
url += "&MERCHANTID="+MERCHANTID; url += "&MERCHANTID="+MERCHANTID;
url += "&POSID="+POSID; url += "&POSID="+POSID;
url += "&BRANCHID="+BRANCHID; url += "&BRANCHID="+BRANCHID;
...@@ -113,11 +111,8 @@ public class CCBPayController { ...@@ -113,11 +111,8 @@ public class CCBPayController {
url += "&MAC="+macStrMd5; url += "&MAC="+macStrMd5;
System.out.println("mac===="+macStr);
System.out.println("md5加密mac===="+macStrMd5);
System.out.println("请求url==="+url);
CloseableHttpClient httpclient = HttpClients.createDefault(); CloseableHttpClient httpclient = HttpClients.createDefault();
//发起第一次支付请求,获取PAYURL
HttpPost httppost = new HttpPost(url); HttpPost httppost = new HttpPost(url);
CloseableHttpResponse response = httpclient.execute(httppost); CloseableHttpResponse response = httpclient.execute(httppost);
...@@ -153,7 +148,6 @@ public class CCBPayController { ...@@ -153,7 +148,6 @@ public class CCBPayController {
String packageS = (String) map.get("package"); String packageS = (String) map.get("package");
String signType = (String) map.get("signType"); String signType = (String) map.get("signType");
String paySign = (String) map.get("paySign"); String paySign = (String) map.get("paySign");
// 小程序id // 小程序id
resultMap.put("appId", appId); resultMap.put("appId", appId);
// 时间戳 // 时间戳
...@@ -167,11 +161,9 @@ public class CCBPayController { ...@@ -167,11 +161,9 @@ public class CCBPayController {
// 签名 // 签名
resultMap.put("paySign", paySign); resultMap.put("paySign", paySign);
} }
} finally { } finally {
response.close(); response.close();
} }
return success(resultMap); return success(resultMap);
} }
} }
\ No newline at end of file
package com.qianhe.system.domain;
import com.alibaba.fastjson.annotation.JSONField;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
/**
* @author yc
* @version 1.0
* @className CCBNotifyInfo
* @date 2024/3/29 14:16
* @description 建行回调实体类
*/
@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class CCBNotifyInfo {
private String POSID;
/**
* 分行代码
*/
@JSONField(name="BRANCHID")
private String BRANCHID;
/**
* 订单号(最长30位)
*/
@JSONField(name="ORDERID")
private String ORDERID;
/**
* 付款金额
*/
@JSONField(name="PAYMENT")
private String PAYMENT;
/**
* 币种
* 缺省为 01-人民币
*/
@JSONField(name="CURCODE")
private String CURCODE;
/**
* 备注信息1
* 一般作为商户自定义备注信
* 息使用,可在对账单中显示
*/
@JSONField(name="REMARK1")
private String REMARK1;
/**
* 备注信息2
* 一般作为商户自定义备注信
* 息使用,可在对账单中显示
*/
@JSONField(name="REMARK2")
private String REMARK2;
/**
* 账户类型
* 服务器通知中有此字段返回且参与验签
* AL:代表支付宝支付
* WX:代表微信支付
* 其他:代表建行支付或跨行付
*/
@JSONField(name="ACC_TYPE")
private String ACC_TYPE;
/**
* 成功-Y,失败-N
*/
@JSONField(name="SUCCESS")
private String SUCCESS;
/**
* 接口类型
* 分行业务人员在 P2 员工渠道后台设置防钓鱼的开关。
* 1- 防钓鱼接口
*/
@JSONField(name="TYPE")
private String TYPE;
/**
* Referer信息
* 分行业务人员在P2员工渠道后台设置防钓鱼开关。
* 1.开关关闭时,无此字段返回且不参与验签。
* 2.开关打开时,有此字段返回且参与验签。
*/
@JSONField(name="REFERER")
private String REFERER;
/**
* 客户端IP
* 客户在商户系统中的IP,即客户登陆(访问)商户系统时使用的IP)
* 分行业务人员在P2员工渠道后台设置防钓鱼开关。
* 1.开关关闭时,无此字段返回且不参与验签。
* 2.开关打开时,有此字段返回且参与验签。
*/
@JSONField(name="CLIENTIP")
private String CLIENTIP;
/**
* 系统记账日期
* 商户登陆商户后台设置返回记账日期的开关
* 1.开关关闭时,无此字段返回且不参与验签。
* 2.开关打开时,有此字段返回且参与验签。参数值格式为YYYYMMDD(如20100907)。
*/
@JSONField(name="ACCDATE")
private String ACCDATE;
/**
* 分期期数
* 从商户传送的信息中获得;
* 当分期期数为空或无此字段上送时,无此字段返回且不参与验签,否则有此字段返回且参与验签。
*/
@JSONField(name="INSTALLNUM")
private String INSTALLNUM;
/**
* 错误信息
* 该值默认返回为空,商户无需处理,仅需参与验签即可。当有分期期数返回时,则有ERRMSG字段返回且参与验签,否则无此字段返回且不参与验签。
*/
@JSONField(name="ERRMSG")
private String ERRMSG;
/**
* 支付账户信息
* 分行业务人员在P2员工渠道后台设置防钓鱼开关和返回账户信息的开关。
* 1.开关关闭时,无此字段返回且不参与验签。
* 2.开关打开但支付失败时,无此字段返回且不参与验签。
* 3.开关打开且支付成功时,有此字段返回且参与验签。参数值格式如下:“姓名|账号加密后的密文”。
* 解密方法请参考“商户通知验签包“文件夹下的《USERMSG》压缩包
*/
@JSONField(name="USRMSG")
private String USRMSG;
/**
* 客户加密信息
* 分行业务人员在P2员工渠道后台设置防钓鱼开关和客户信息加密返回的开关。
* 1.开关关闭时,无此字段返回且不参与验签
* 2.开关打开时,有此字段返回且参数验签。参数值格式如下:“证件号密文|手机号密文”。该字段不可解密。
*/
@JSONField(name="USRINFO")
private String USRINFO;
/**
* 实付金额
* 优惠之后的实际支付金额。
* 目前只针对白名单商户返回,无此字段返回且不参与验签,有此字段返回且参与验签。
*/
@JSONField(name="DISCOUNT")
private String DISCOUNT;
/**
* 返回客户的积分使用情况,格式如下:
* {“APnt_Hpn_Num”:”积分发生数量”,”APntCmpt_Amt”:”积分抵扣金额”}
* 当综合积分字段为空或无此字段上送时,无此字段返回且不参与验签,否则有此字段返回且参与验签。
*/
@JSONField(name="ZHJF")
private String ZHJF;
/**
* 客户识别号
* 提交建行的参数RETURN_FIELD打开对应开关才返回该字段。
* 客户识别码, 微信、支付宝、龙支付时返回。
* 有该字段返回时(无论返回值是空还是其他),需参与验签,否则无需参与验签。
*/
@JSONField(name="OPENID")
private String OPENID;
/**
* 用户子标识
* 提交建行的参数RETURN_FIELD打开对应开关才返回该字段。
* 微信支付专有字段。
* 子商户appid下用户唯一标识,如需返回则请求时需要传sub_appid。
* 有该字段返回时(无论返回值是空还是其他),需参与验签,否则无需参与验签。
*/
@JSONField(name="SUB_OPENID")
private String SUB_OPENID;
/**
* 支付详细信息
* 支付详细信息。当RETURN_FIELD字段第四位上送1时返回。
* 字段说明见下方[支付详细信息字段说明]
* 格式如下:
* {“TYPE“:"ALIPAY",“PAY_CHANNEL“:"BANKCARD",“DEBIT_CREDIT_TYPE“:"DEBIT_CARD",“THIRD_TRADE_NO“:"2018010521001004890523646975"}
* 为防止特殊字符,建行会将该参数值用utf-8编码进行urlencode,因此商户需先decode之后才能拿到明文。
* 编码之后为:
* %7B%22TYPE%22%3A%22ALIPAY%22%2C%22PAY_CHANNEL%22%3A%22BANKCARD%22%2C%22DEBIT_CREDIT_TYPE%22%3A%22DEBIT_CARD%22%2C%22THIRD_TRADE_NO%22%3A%222018010521001004890523646975%22%7D
* 有该字段返回时(无论返回值是空还是其他),需参与验签,否则无需参与验签,参与签名的是encode之后的参数值。
*/
@JSONField(name="PAYMENT_DETAILS")
private String PAYMENT_DETAILS;
/**
* 数字签名
*/
@JSONField(name="SIGN")
private String SIGN;
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment