| @@ -10,7 +10,7 @@ import com.iformall.enums.EnumBillPayWay; | |||
| public interface PayBillAdapterService { | |||
| //发起支付,有可能是码,小程序支付,或者其他支付 | |||
| public Object createPay(WxPayAccountBill wxPayAccountBill,WxMerchantBUser buser,WxBillBaseEntity billdetail,Double money,Map<String,String> params); | |||
| public Object createPay(WxPayAccountBill wxPayAccountBill,WxMerchantBUser buser,WxBillBaseEntity billdetail,Double money,Map<String,String> params) throws Exception; | |||
| //支付通知处理 | |||
| public void paidCallBack(String tenantId,EnumBillPayWay payWay,Map paramMap); | |||
| @@ -35,8 +35,8 @@ import com.iformall.service.pay.service.share.douyin.v3.TtOpenShareService; | |||
| import com.iformall.service.pay.service.share.wx.sft.WxPayShareSFTService; | |||
| import com.iformall.service.pay.service.share.wx.v2.WxPayShareService; | |||
| import com.iformall.service.pay.service.share.wx.v3.WxPayShareV3Service; | |||
| import com.iformall.service.payBill.impl.JianHangMaServiceImpl; | |||
| import com.iformall.service.payBill.impl.WxMiniProgramServiceImpl; | |||
| import com.iformall.service.payBill.impl.jianhang.JianHangMaServiceImpl; | |||
| import com.iformall.service.payBill.impl.wx.WxMiniProgramServiceImpl; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.stereotype.Service; | |||
| @@ -1,99 +0,0 @@ | |||
| package com.iformall.service.payBill.impl; | |||
| import java.io.UnsupportedEncodingException; | |||
| import java.net.URLDecoder; | |||
| import java.net.URLEncoder; | |||
| import java.util.Date; | |||
| import java.util.HashMap; | |||
| import java.util.Map; | |||
| import org.apache.commons.codec.digest.DigestUtils; | |||
| import org.springframework.stereotype.Service; | |||
| import com.alibaba.fastjson.JSON; | |||
| import com.alibaba.fastjson.JSONObject; | |||
| import com.aliyun.openservices.shade.org.apache.commons.lang3.StringUtils; | |||
| import com.iformall.common.IdWorker; | |||
| import com.iformall.domain.po.WxMerchantBUser; | |||
| import com.iformall.domain.po.WxPayAccountBill; | |||
| import com.iformall.domain.po.base.WxBillBaseEntity; | |||
| import com.iformall.enums.EnumBillAllType; | |||
| import com.iformall.enums.EnumBillPayWay; | |||
| import com.iformall.service.payBill.PayBillAdapterService; | |||
| import com.iformall.service.payBill.impl.entity.JianHangMaRequest; | |||
| import com.iformall.utils.DateUtils; | |||
| import com.iformall.utils.HttpUtil; | |||
| import lombok.extern.slf4j.Slf4j; | |||
| @Slf4j | |||
| @Service | |||
| public class JianHangMaServiceImpl extends PayBillBaseService implements PayBillAdapterService { | |||
| private static final String url = "https://ibsbjstar.ccb.com.cn/CCBIS/ccbMain?CCB_IBSVersion=V6"; | |||
| //建行动态二维码接口 | |||
| @Override | |||
| public Object createPay(WxPayAccountBill wxPayAccountBill,WxMerchantBUser buser,WxBillBaseEntity billdetail,Double money,Map<String, String> params) { | |||
| JianHangMaRequest request = new JianHangMaRequest(); | |||
| request.setMERCHANTID(wxPayAccountBill.getPayConfigString("MERCHANTID")); | |||
| request.setPOSID(wxPayAccountBill.getPayConfigString("POSID")); | |||
| request.setBRANCHID(wxPayAccountBill.getPayConfigString("BRANCHID")); | |||
| request.setPUB(wxPayAccountBill.getPayConfigString("PUB_30"));//柜台公钥后30位 | |||
| final IdWorker idWorker = IdWorker.get(); | |||
| request.setORDERID(billdetail.getBillType()+"_"+idWorker.nextId()); | |||
| request.setPAYMENT(money); | |||
| //request.setREMARK1(URLEncoder.encode(billdetail.getBillTypeName(),"utf-8")); | |||
| request.setREMARK1(billdetail.getBillType()+"_"+billdetail.getId()); | |||
| request.setREMARK2(String.valueOf(buser.getId())); | |||
| request.setTIMEOUT(DateUtils.date2String(DateUtils.getSecondsTimeAfter(10*60, new Date()), DateUtils.DATE_PATTERN_ALL_NOSPACE)); | |||
| try { | |||
| request.setMAC(DigestUtils.md5Hex(request.toMacString().getBytes("UTF-8"))); | |||
| } catch (UnsupportedEncodingException e) { | |||
| log.error("JianHangMaServiceImpl createPay setMAC error.",e); | |||
| return null; | |||
| } | |||
| String full_url = url + "&"+request.toMustString()+"&MAC="+request.getMAC(); | |||
| log.info("full_url:"+full_url); | |||
| String response = HttpUtil.doPost(full_url, null); | |||
| log.info("url:"+full_url+">>>>reponse:"+response); | |||
| if (StringUtils.isBlank(response)) { | |||
| return null; | |||
| } | |||
| JSONObject rb = JSON.parseObject(response); | |||
| if ("true".equals(rb.getString("SUCCESS"))) { | |||
| String payurl = rb.getString("PAYURL"); | |||
| String qrresponse = HttpUtil.doPost(payurl, null); | |||
| log.info("url:"+payurl+">>>>qrreponse:"+qrresponse); | |||
| if (StringUtils.isBlank(qrresponse)) { | |||
| return null; | |||
| } | |||
| JSONObject qb = JSON.parseObject(qrresponse); | |||
| if ("true".equals(qb.getString("SUCCESS"))) { | |||
| String qrurl = qb.getString("QRURL"); | |||
| try { | |||
| return URLDecoder.decode(qrurl, "utf-8"); | |||
| } catch (UnsupportedEncodingException e) { | |||
| log.error("JianHangMaServiceImpl createPay decode error.",e); | |||
| return null; | |||
| } | |||
| } | |||
| } | |||
| return null; | |||
| } | |||
| @Override | |||
| public void paidCallBack(String tenantId,EnumBillPayWay payWay, Map paramMap) { | |||
| String success = (String) paramMap.get("SUCCESS"); | |||
| if ("Y".equals(success.toUpperCase())) { | |||
| String money = (String) paramMap.get("PAYMENT"); | |||
| String remark1 = (String) paramMap.get("REMARK1"); | |||
| String[] remark1_args = remark1.split("_"); | |||
| Integer billType = Integer.parseInt(remark1_args[0]); | |||
| Long billId = Long.parseLong(remark1_args[1]); | |||
| Long merchantBUserId = Long.parseLong((String)paramMap.get("REMARK2")); | |||
| String orderId = (String) paramMap.get("ORDERID"); | |||
| this.updateBillPaid(tenantId, merchantBUserId, EnumBillAllType.getEnum(billType), billId, | |||
| money, payWay, "商户单号"+orderId); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,55 +0,0 @@ | |||
| package com.iformall.service.payBill.impl.entity; | |||
| import org.apache.commons.lang3.StringUtils; | |||
| import lombok.Data; | |||
| @Data | |||
| public class JianHangMaRequest { | |||
| //商户代码 CHAR(15) 由建行统一分配 | |||
| private String MERCHANTID; | |||
| //商户柜台代码 CHAR(9) 由建行统一分配 | |||
| private String POSID; | |||
| //分行代码 CHAR(9) 由建行统一指定 | |||
| private String BRANCHID; | |||
| //定单号 CHAR(30) 由商户提供,最长30位 | |||
| private String ORDERID; | |||
| //付款金额 NUMBER(16,2) | |||
| private Double PAYMENT; | |||
| //币种 CHAR(2) 缺省为01-人民币 | |||
| private String CURCODE = "01"; | |||
| //备注1 CHAR(30) 商户自定义备注信息使用,可在对账单中显示 中文需使用escape编码 | |||
| private String REMARK1; | |||
| //备注2 CHAR(30) 商户自定义备注信息使用,可在对账单中显示 中文需使用escape编码 | |||
| private String REMARK2; | |||
| //交易码 CHAR(6) 由建行统一分配为530550 | |||
| private String TXCODE = "530550"; | |||
| /** | |||
| * 返回类型 CHAR(6) | |||
| * 0或空:返回二维码页面,只支持建行龙支付; | |||
| 1:返回JSON格式【二维码信息串】,只支持建行龙支付; | |||
| 2:返回聚合扫码二维码页面; | |||
| 3:返回聚合扫码JSON 格式【二维码信息串】 | |||
| 聚合扫码只能上送2或3 4:返回聚合银联二维码信息串 | |||
| */ | |||
| private String RETURNTYPE = "3"; | |||
| //订单超时时间 CHAR(14) YYYYMMDDHHMMSS 如:20120214143005 | |||
| private String TIMEOUT; | |||
| //MAC校验域 CHAR(32) 采用标准MD5算法,由商户实现 | |||
| private String PUB; | |||
| //MAC校验域 CHAR(32) 采用标准MD5算法,由商户实现 | |||
| private String MAC; | |||
| public String toMustString() { | |||
| return "MERCHANTID="+this.MERCHANTID+"&POSID="+this.POSID+"&BRANCHID="+this.BRANCHID+"&ORDERID="+this.ORDERID | |||
| +"&PAYMENT="+this.PAYMENT+"&CURCODE="+this.CURCODE+"&REMARK1="+this.REMARK1+"&REMARK2="+StringUtils.trimToEmpty(this.REMARK2) | |||
| +"&TXCODE="+this.TXCODE+"&RETURNTYPE="+this.RETURNTYPE+"&TIMEOUT="+this.TIMEOUT; | |||
| } | |||
| public String toMacString() { | |||
| return "MERCHANTID="+this.MERCHANTID+"&POSID="+this.POSID+"&BRANCHID="+this.BRANCHID+"&ORDERID="+this.ORDERID | |||
| +"&PAYMENT="+this.PAYMENT+"&CURCODE="+this.CURCODE+"&REMARK1="+this.REMARK1+"&REMARK2="+StringUtils.trimToEmpty(this.REMARK2) | |||
| +"&TXCODE="+this.TXCODE+"&RETURNTYPE="+this.RETURNTYPE+"&TIMEOUT="+this.TIMEOUT+"&PUB="+this.PUB; | |||
| } | |||
| } | |||
| @@ -0,0 +1,55 @@ | |||
| package com.iformall.service.payBill.impl.jianhang; | |||
| import java.io.UnsupportedEncodingException; | |||
| import java.net.URLDecoder; | |||
| import java.net.URLEncoder; | |||
| import java.util.Date; | |||
| import java.util.HashMap; | |||
| import java.util.Map; | |||
| import org.apache.commons.codec.digest.DigestUtils; | |||
| import org.springframework.stereotype.Service; | |||
| import com.alibaba.fastjson.JSON; | |||
| import com.alibaba.fastjson.JSONObject; | |||
| import com.aliyun.openservices.shade.org.apache.commons.lang3.StringUtils; | |||
| import com.iformall.common.IdWorker; | |||
| import com.iformall.domain.po.WxMerchantBUser; | |||
| import com.iformall.domain.po.WxPayAccountBill; | |||
| import com.iformall.domain.po.base.WxBillBaseEntity; | |||
| import com.iformall.enums.EnumBillAllType; | |||
| import com.iformall.enums.EnumBillPayWay; | |||
| import com.iformall.service.payBill.PayBillAdapterService; | |||
| import com.iformall.service.payBill.impl.PayBillBaseService; | |||
| import com.iformall.utils.DateUtils; | |||
| import com.iformall.utils.HttpUtil; | |||
| import lombok.extern.slf4j.Slf4j; | |||
| @Slf4j | |||
| @Service | |||
| public class JianHangMaServiceImpl extends PayBillBaseService implements PayBillAdapterService { | |||
| private static final String url = "https://ibsbjstar.ccb.com.cn/CCBIS/ccbMain?CCB_IBSVersion=V6"; | |||
| //建行动态二维码接口 | |||
| @Override | |||
| public Object createPay(WxPayAccountBill wxPayAccountBill,WxMerchantBUser buser,WxBillBaseEntity billdetail,Double money,Map<String, String> params) throws Exception { | |||
| return QrDemo.getMa(wxPayAccountBill, buser, billdetail, money); | |||
| } | |||
| @Override | |||
| public void paidCallBack(String tenantId,EnumBillPayWay payWay, Map paramMap) { | |||
| String success = (String) paramMap.get("SUCCESS"); | |||
| if ("Y".equals(success.toUpperCase())) { | |||
| String money = (String) paramMap.get("PAYMENT"); | |||
| String remark1 = (String) paramMap.get("REMARK1"); | |||
| String[] remark1_args = remark1.split("_"); | |||
| Integer billType = Integer.parseInt(remark1_args[0]); | |||
| Long billId = Long.parseLong(remark1_args[1]); | |||
| Long merchantBUserId = Long.parseLong((String)paramMap.get("REMARK2")); | |||
| String orderId = (String) paramMap.get("ORDERID"); | |||
| this.updateBillPaid(tenantId, merchantBUserId, EnumBillAllType.getEnum(billType), billId, | |||
| money, payWay, "商户单号"+orderId); | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,92 @@ | |||
| package com.iformall.service.payBill.impl.jianhang; | |||
| import java.io.*; | |||
| import java.security.*; | |||
| public class MD5 | |||
| { | |||
| public static String md5Str(String str) | |||
| { | |||
| if (str == null)return ""; | |||
| return md5Str(str, 0); | |||
| } | |||
| /** | |||
| * ������ϢժҪ�� | |||
| * @param data ����ժҪ�����ݡ� | |||
| * @param offset ����ƫ�Ƶ�ַ�� | |||
| * @param length ���ݳ��ȡ� | |||
| * @return ժҪ�����(16�ֽ�) | |||
| */ | |||
| public static String md5Str(String str, int offset) | |||
| { | |||
| try | |||
| { | |||
| MessageDigest md5 = MessageDigest.getInstance("MD5"); | |||
| byte[] b = str.getBytes("UTF8"); | |||
| md5.update(b, offset, b.length); | |||
| return byteArrayToHexString(md5.digest()); | |||
| } | |||
| catch (NoSuchAlgorithmException ex) | |||
| { | |||
| ex.printStackTrace(); | |||
| return null; | |||
| } | |||
| catch (UnsupportedEncodingException ex) | |||
| { | |||
| ex.printStackTrace(); | |||
| return null; | |||
| } | |||
| } | |||
| /** | |||
| * | |||
| * @param b byte[] | |||
| * @return String | |||
| */ | |||
| public static String byteArrayToHexString(byte[] b) | |||
| { | |||
| String result = ""; | |||
| for (int i = 0; i < b.length; i++) | |||
| { | |||
| result += byteToHexString(b[i]); | |||
| } | |||
| return result; | |||
| } | |||
| private static String[] hexDigits = | |||
| { | |||
| "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", | |||
| "c", "d", "e", "f"}; | |||
| /** | |||
| * ���ֽ�ת��Ϊ��Ӧ��16�������� | |||
| * @param b byte | |||
| * @return String | |||
| */ | |||
| public static String byteToHexString(byte b) | |||
| { | |||
| int n = b; | |||
| if (n < 0) | |||
| { | |||
| n = 256 + n; | |||
| } | |||
| int d1 = n / 16; | |||
| int d2 = n % 16; | |||
| return hexDigits[d1] + hexDigits[d2]; | |||
| } | |||
| public static void main(String[] args) | |||
| { | |||
| System.out.println(byteToHexString((byte)-99)); | |||
| String str = | |||
| "eeeeeeeeeeeeeewrw213123122222222222222222222222213123213213213erwer"; | |||
| String ened = MD5.md5Str(str); | |||
| System.out.println(ened.length()); | |||
| System.out.println(ened); | |||
| } | |||
| } | |||
| @@ -0,0 +1,88 @@ | |||
| package com.iformall.service.payBill.impl.jianhang; | |||
| import java.net.URLDecoder; | |||
| import java.util.Date; | |||
| import java.util.HashMap; | |||
| import java.util.Map; | |||
| import com.google.gson.Gson; | |||
| import com.iformall.common.IdWorker; | |||
| import com.iformall.domain.po.WxMerchantBUser; | |||
| import com.iformall.domain.po.WxPayAccountBill; | |||
| import com.iformall.domain.po.base.WxBillBaseEntity; | |||
| import com.iformall.utils.DateUtils; | |||
| import com.iformall.utils.HttpUtil; | |||
| import lombok.extern.slf4j.Slf4j; | |||
| @Slf4j | |||
| public class QrDemo { | |||
| private static final String bankURL="https://ibsbjstar.ccb.com.cn/CCBIS/ccbMain"; | |||
| public static String getMa(WxPayAccountBill wxPayAccountBill,WxMerchantBUser buser,WxBillBaseEntity billdetail,Double money) throws Exception { | |||
| String MERCHANTID = wxPayAccountBill.getPayConfigString("MERCHANTID"); | |||
| String POSID = wxPayAccountBill.getPayConfigString("POSID"); | |||
| String BRANCHID = wxPayAccountBill.getPayConfigString("BRANCHID"); | |||
| final IdWorker idWorker = IdWorker.get(); | |||
| String ORDERID = billdetail.getBillType()+"_"+idWorker.nextId(); | |||
| String PAYMENT= money.toString(); | |||
| String CURCODE="01"; | |||
| String TXCODE = "530550"; | |||
| String REMARK1 = billdetail.getBillType()+"_"+billdetail.getId(); | |||
| String REMARK2 = String.valueOf(buser.getId()); | |||
| String RETURNTYPE="3"; | |||
| String TIMEOUT = DateUtils.date2String(DateUtils.getSecondsTimeAfter(10*60, new Date()), DateUtils.DATE_PATTERN_ALL_NOSPACE); | |||
| String PUB32TR2= wxPayAccountBill.getPayConfigString("PUB_30"); | |||
| StringBuffer tmp = new StringBuffer(); //��ǩ�ֶ� | |||
| tmp.append("MERCHANTID="); | |||
| tmp.append(MERCHANTID); | |||
| tmp.append("&POSID="); | |||
| tmp.append(POSID); | |||
| tmp.append("&BRANCHID="); | |||
| tmp.append(BRANCHID); | |||
| tmp.append("&ORDERID="); | |||
| tmp.append(ORDERID); | |||
| tmp.append("&PAYMENT="); | |||
| tmp.append(PAYMENT); | |||
| tmp.append("&CURCODE="); | |||
| tmp.append(CURCODE); | |||
| tmp.append("&TXCODE="); | |||
| tmp.append(TXCODE); | |||
| tmp.append("&REMARK1="); | |||
| tmp.append(REMARK1); | |||
| tmp.append("&REMARK2="); | |||
| tmp.append(REMARK2); | |||
| tmp.append("&RETURNTYPE="); | |||
| tmp.append(RETURNTYPE); | |||
| tmp.append("&TIMEOUT="); | |||
| tmp.append(TIMEOUT); | |||
| tmp.append("&PUB="); | |||
| tmp.append(PUB32TR2); | |||
| Map map = new HashMap(); | |||
| map.put("CCB_IBSVersion","V6"); //������ | |||
| map.put("MERCHANTID",MERCHANTID); | |||
| map.put("BRANCHID",BRANCHID); | |||
| map.put("POSID",POSID); | |||
| map.put("ORDERID",ORDERID); | |||
| map.put("PAYMENT",PAYMENT); | |||
| map.put("CURCODE",CURCODE); | |||
| map.put("TXCODE",TXCODE); | |||
| map.put("REMARK1",REMARK1); | |||
| map.put("REMARK2",REMARK2); | |||
| map.put("RETURNTYPE",RETURNTYPE); | |||
| map.put("TIMEOUT",TIMEOUT); | |||
| map.put("MAC",MD5.md5Str(tmp.toString())); | |||
| String ret = HttpUtil.doPost(bankURL, map); //�����ά���������Ӵ� | |||
| Gson gson = new Gson(); | |||
| QrURLDemo qrurl = (QrURLDemo) gson.fromJson(ret, QrURLDemo.class); | |||
| log.info("jianhang payUrl:"+qrurl.getPAYURL()); | |||
| //ret = HttpUtil.httpGet(qrurl.getPAYURL(), "UTF-8"); //��ȡ��ά�봮 | |||
| ret = HttpUtil.doGet(qrurl.getPAYURL()); | |||
| return URLDecoder.decode(ret, "utf-8"); | |||
| } | |||
| } | |||
| @@ -0,0 +1,19 @@ | |||
| package com.iformall.service.payBill.impl.jianhang; | |||
| public class QrURLDemo { | |||
| private String SUCCESS; | |||
| private String PAYURL; | |||
| public String getSUCCESS() { | |||
| return SUCCESS; | |||
| } | |||
| public void setSUCCESS(String success) { | |||
| SUCCESS = success; | |||
| } | |||
| public String getPAYURL() { | |||
| return PAYURL; | |||
| } | |||
| public void setPAYURL(String payurl) { | |||
| PAYURL = payurl; | |||
| } | |||
| } | |||
| @@ -1,4 +1,4 @@ | |||
| package com.iformall.service.payBill.impl; | |||
| package com.iformall.service.payBill.impl.wx; | |||
| import java.math.BigDecimal; | |||
| import java.math.RoundingMode; | |||
| @@ -29,6 +29,7 @@ import com.iformall.service.WxPayAccountService; | |||
| import com.iformall.service.pay.service.pay.entity.PayAdapterResult; | |||
| import com.iformall.service.pay.service.pay.wx.v2.miniApp.appPay.WxMiniAppPayAdapterService; | |||
| import com.iformall.service.payBill.PayBillAdapterService; | |||
| import com.iformall.service.payBill.impl.PayBillBaseService; | |||
| import com.iformall.utils.DateUtils; | |||
| import lombok.extern.slf4j.Slf4j; | |||
| @@ -45,7 +46,7 @@ public class WxMiniProgramServiceImpl extends PayBillBaseService implements PayB | |||
| WxPayAccountService wxPayAccountService; | |||
| @Override | |||
| public Object createPay(WxPayAccountBill wxPayAccountBill,WxMerchantBUser buser,WxBillBaseEntity billdetail,Double money,Map<String, String> params) { | |||
| public Object createPay(WxPayAccountBill wxPayAccountBill,WxMerchantBUser buser,WxBillBaseEntity billdetail,Double money,Map<String, String> params) throws Exception{ | |||
| String openId = params.get("openId"); | |||
| if (StringUtils.isBlank(openId)) { | |||
| throw new MallinkException(ErrorCode.APP_ID_NOT_FOUND.getCode(),"参数openId为空"); | |||