winter 1 год назад
Родитель
Сommit
2e02785d8b
11 измененных файлов: 376 добавлений и 27 удалений
  1. +2
    -0
      mallinkAdmin/src/main/resources/db/migration/V202405008.sql
  2. +56
    -16
      mallinkBApi/src/main/java/com/iformall/controller/WxBillController.java
  3. +29
    -0
      mallinkService/src/main/java/com/iformall/domain/po/WxPayAccountBill.java
  4. +33
    -0
      mallinkService/src/main/java/com/iformall/enums/EnumBillPayChannel.java
  5. +14
    -0
      mallinkService/src/main/java/com/iformall/service/payBill/PayBillAdapterService.java
  6. +78
    -0
      mallinkService/src/main/java/com/iformall/service/payBill/PayBillServiceFactory.java
  7. +79
    -0
      mallinkService/src/main/java/com/iformall/service/payBill/impl/JianHangMaServiceImpl.java
  8. +22
    -0
      mallinkService/src/main/java/com/iformall/service/payBill/impl/WxMiniProgramServiceImpl.java
  9. +47
    -0
      mallinkService/src/main/java/com/iformall/service/payBill/impl/entity/JianHangMaRequest.java
  10. +12
    -10
      mallinkService/src/main/java/com/iformall/utils/HttpUtil.java
  11. +4
    -1
      mallinkService/src/main/resources/mapper/WxPayAccountBillMapper.xml

+ 2
- 0
mallinkAdmin/src/main/resources/db/migration/V202405008.sql Просмотреть файл

@@ -0,0 +1,2 @@
ALTER TABLE wx_pay_account_bill ADD COLUMN pay_channel INT(3) COMMENT '支付通道';
ALTER TABLE wx_pay_account_bill ADD COLUMN pay_config VARCHAR(300) COMMENT '支付配置';

+ 56
- 16
mallinkBApi/src/main/java/com/iformall/controller/WxBillController.java Просмотреть файл

@@ -11,11 +11,14 @@ import com.iformall.domain.po.WxBillAction;
import com.iformall.domain.po.WxFlowModel; import com.iformall.domain.po.WxFlowModel;
import com.iformall.domain.po.WxMerchant; import com.iformall.domain.po.WxMerchant;
import com.iformall.domain.po.WxMerchantBUser; import com.iformall.domain.po.WxMerchantBUser;
import com.iformall.domain.po.WxPayAccountBill;
import com.iformall.domain.po.WxUserDataRule; import com.iformall.domain.po.WxUserDataRule;
import com.iformall.domain.po.base.WxBillBaseEntity;
import com.iformall.domain.vo.WxBillAll; import com.iformall.domain.vo.WxBillAll;
import com.iformall.domain.vo.WxBillHotNotify; import com.iformall.domain.vo.WxBillHotNotify;
import com.iformall.enums.EnumBillAllType; import com.iformall.enums.EnumBillAllType;
import com.iformall.enums.EnumBillOweOrNearType; import com.iformall.enums.EnumBillOweOrNearType;
import com.iformall.enums.EnumBillPayChannel;
import com.iformall.enums.EnumBillUpdateType; import com.iformall.enums.EnumBillUpdateType;
import com.iformall.enums.EnumFilterSettle; import com.iformall.enums.EnumFilterSettle;
import com.iformall.enums.EnumFlowKey; import com.iformall.enums.EnumFlowKey;
@@ -27,7 +30,9 @@ import com.iformall.service.WxBillAllService;
import com.iformall.service.WxBillSettleService; import com.iformall.service.WxBillSettleService;
import com.iformall.service.WxFlowService; import com.iformall.service.WxFlowService;
import com.iformall.service.WxMerchantService; import com.iformall.service.WxMerchantService;
import com.iformall.service.WxPayAccountBillService;
import com.iformall.service.helper.WxBillAllHelper; import com.iformall.service.helper.WxBillAllHelper;
import com.iformall.service.payBill.PayBillServiceFactory;
import com.iformall.utils.Constant; import com.iformall.utils.Constant;


import io.swagger.annotations.Api; import io.swagger.annotations.Api;
@@ -70,6 +75,12 @@ public class WxBillController extends BaseController {
@Autowired @Autowired
private WxBillActionService wxBillActionService; private WxBillActionService wxBillActionService;
@Autowired
private PayBillServiceFactory payBillServiceFactory;
@Autowired
WxPayAccountBillService wxPayAccountBillService;


/** /**
* 账单类型 * 账单类型
@@ -214,25 +225,54 @@ public class WxBillController extends BaseController {
return new ResultData(result); return new ResultData(result);
} }
@ApiOperation("支付")
//必要的参数是这三个,其他根据每个支付方式来传参数
@ApiOperation(value = "支付", notes = "{\"billTypeValue\":\"string\",\"billId\":\"string\",\"payMoney\":\"string\"}")
@PostMapping("payBill") @PostMapping("payBill")
public ResultData payBill(@RequestBody WxBillPayDTO payDto) {
if (null == payDto.getBillTypeValue() || null == payDto.getId() || StringUtils.isBlank(payDto.getAddpay())) {
public ResultData payBill(@RequestBody Map<String, String> paramMap) {
String billTypeValueStr = paramMap.get("billTypeValue");
String billIdStr = paramMap.get("billId");
String payMoney = paramMap.get("payMoney");
if (StringUtils.isBlank(billTypeValueStr) || StringUtils.isBlank(billIdStr) || StringUtils.isBlank(payMoney) ) {
return new ResultData(Result.ERROR,"参数错误"); return new ResultData(Result.ERROR,"参数错误");
} }
// EnumBillAllType btype;
// if (billTypeValue.intValue() == Constant.bill_all_type_manage_fee) {
// btype = EnumBillAllType.RENT_BUSSINESS_MANAGE;
// }else {
// btype = EnumBillAllType.getEnum(billTypeValue);
// if (null == btype) {
// return new ResultData(Result.ERROR,"分类非法");
// }
// }
// wxMerchant.setId(this.getLoginBUser().getMerchantId());
// wxMerchant.updateTenantInfo(getTenantInfo());
// return new ResultData(billAllHelper.getBillList(btype, wxMerchant,pageNum,pageSize));
return null;
Integer billTypeValue = Integer.parseInt(billTypeValueStr);
Long billId = Long.parseLong(billIdStr);
EnumBillAllType btype;
if (billTypeValue.intValue() == Constant.bill_all_type_manage_fee) {
btype = EnumBillAllType.RENT_BUSSINESS_MANAGE;
}else {
btype = EnumBillAllType.getEnum(billTypeValue);
if (null == btype) {
return new ResultData(Result.ERROR,"分类非法");
}
}
WxMerchant wxMerchant = new WxMerchant();
wxMerchant.setId(this.getLoginBUser().getMerchantId());
wxMerchant.updateTenantInfo(getTenantInfo());
WxBillBaseEntity billdetail = billAllHelper.getBillDetail(btype, wxMerchant,billId);
if (null == billdetail) {
return new ResultData(Result.ERROR,"账单支付未查询到");
}
WxPayAccountBill wxPayAccountBill = wxPayAccountBillService.getByTenantInfo(wxMerchant);
if (null == wxPayAccountBill || null == wxPayAccountBill.getPayChannel()) {
return new ResultData(Result.ERROR,"账单支付配置错误,请联系管理员");
}
try {
Object result = payBillServiceFactory.getPayAdapterService(wxPayAccountBill.getPayChannel())
.createPay(wxPayAccountBill,billdetail,Double.parseDouble(payMoney), paramMap);
if (null == result) {
return new ResultData(Result.ERROR,"账单支付错误,请联系管理员");
}
Map retMap = new HashMap();
retMap.put("payChannel", wxPayAccountBill.getPayChannel());
retMap.put("payChannelName", EnumBillPayChannel.getEnum(wxPayAccountBill.getPayChannel()).getMessage());
retMap.put("result", result);
return new ResultData(retMap);
}catch(Exception e) {
logger.error("payBill error.",e);
return new ResultData(Result.ERROR,"账单支付错误:"+e.getMessage());
}
} }


+ 29
- 0
mallinkService/src/main/java/com/iformall/domain/po/WxPayAccountBill.java Просмотреть файл

@@ -1,5 +1,8 @@
package com.iformall.domain.po; package com.iformall.domain.po;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.openservices.shade.org.apache.commons.lang3.StringUtils;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import com.iformall.domain.po.base.TenantEntity; import com.iformall.domain.po.base.TenantEntity;
import lombok.Data; import lombok.Data;
@@ -26,5 +29,31 @@ public class WxPayAccountBill extends TenantEntity {


@io.swagger.annotations.ApiModelProperty(value="手续费费率",name="serviceChargeRate") @io.swagger.annotations.ApiModelProperty(value="手续费费率",name="serviceChargeRate")
private Integer serviceChargeRate; private Integer serviceChargeRate;
@io.swagger.annotations.ApiModelProperty(value="支付渠道 EnumBillPayChannel",name="payChannel")
private Integer payChannel;
@io.swagger.annotations.ApiModelProperty(value="支付配置",name="payConfig")
private String payConfig;
public String getPayConfigString(String key) {
if (StringUtils.isNotBlank(payConfig)) {
JSONObject pc = JSON.parseObject(payConfig);
if (null != pc) {
return pc.getString(key);
}
}
return null;
}
public Integer getPayConfigInteger(String key) {
if (StringUtils.isNotBlank(payConfig)) {
JSONObject pc = JSON.parseObject(payConfig);
if (null != pc) {
return pc.getInteger(key);
}
}
return null;
}


} }

+ 33
- 0
mallinkService/src/main/java/com/iformall/enums/EnumBillPayChannel.java Просмотреть файл

@@ -0,0 +1,33 @@
package com.iformall.enums;

/**
*/
public enum EnumBillPayChannel {
WX_MINI_PROGRAM(1, "微信小程序支付"),
BANK_JIANSHE_MA(2, "建设银行收款码");

public static EnumBillPayChannel getEnum(Integer code) {
for (EnumBillPayChannel value : values()) {
if (value.getCode().equals(code)) {
return value;
}
}
return null;
}

private Integer code;
private String message;

EnumBillPayChannel(Integer code, String message) {
this.code = code;
this.message = message;
}

public Integer getCode() {
return code;
}

public String getMessage() {
return message;
}
}

+ 14
- 0
mallinkService/src/main/java/com/iformall/service/payBill/PayBillAdapterService.java Просмотреть файл

@@ -0,0 +1,14 @@
package com.iformall.service.payBill;

import java.util.Map;

import com.iformall.domain.po.WxPayAccountBill;
import com.iformall.domain.po.base.WxBillBaseEntity;

public interface PayBillAdapterService {

//发起支付,有可能是码,小程序支付,或者其他支付
public Object createPay(WxPayAccountBill wxPayAccountBill,WxBillBaseEntity billdetail,Double money,Map<String,String> params);
//支付通知处理
}

+ 78
- 0
mallinkService/src/main/java/com/iformall/service/payBill/PayBillServiceFactory.java Просмотреть файл

@@ -0,0 +1,78 @@
package com.iformall.service.payBill;

import com.iformall.common.ErrorCode;
import com.iformall.enums.EnumAppPlat;
import com.iformall.enums.EnumBillPayChannel;
import com.iformall.enums.EnumBillPayWay;
import com.iformall.enums.EnumPayVersion;
import com.iformall.enums.EnumPayWay;
import com.iformall.exception.MallinkException;
import com.iformall.service.pay.service.cashout.CashOutAdapterService;
import com.iformall.service.pay.service.cashout.wx.sft.WxCashOutSFTAdapterService;
import com.iformall.service.pay.service.cashout.wx.v2.WxCashOutQYFKAdapterService;
import com.iformall.service.pay.service.fee.ServiceFeeAdapterService;
import com.iformall.service.pay.service.fee.TtServiceFeeService;
import com.iformall.service.pay.service.fee.WxServiceFeeService;
import com.iformall.service.pay.service.pay.CDrivingPayService;
import com.iformall.service.pay.service.pay.CPassivePayService;
import com.iformall.service.pay.service.pay.PayAdapterService;
import com.iformall.service.pay.service.pay.douyin.v2.miniApp.TtMiniAppPayAdapterService;
import com.iformall.service.pay.service.pay.douyin.v3.open.TtOpenPayAdapterService;
import com.iformall.service.pay.service.pay.wx.sft.h5.WxH5PaySFTService;
import com.iformall.service.pay.service.pay.wx.sft.miniApp.appPay.WxMiniAppPaySFTAdapterService;
import com.iformall.service.pay.service.pay.wx.v2.h5.WxH5PayService;
import com.iformall.service.pay.service.pay.wx.v2.miniApp.appPay.WxMiniAppPayAdapterService;
import com.iformall.service.pay.service.pay.wx.v2.miniApp.maPay.WxMiniMaPayAdapterService;
import com.iformall.service.pay.service.pay.wx.v3.miniApp.appPay.WxMiniAppPayV3AdapterService;
import com.iformall.service.pay.service.refund.RefundPayAdapterService;
import com.iformall.service.pay.service.refund.douyin.v2.TtRefundAdapterService;
import com.iformall.service.pay.service.refund.douyin.v3.TtOpenRefundAdapterService;
import com.iformall.service.pay.service.refund.wx.v2.WxRefundAdapterService;
import com.iformall.service.pay.service.refund.wx.v3.WxRefundV3AdapterService;
import com.iformall.service.pay.service.share.PayShareAdapterService;
import com.iformall.service.pay.service.share.douyin.v2.TtPayShareService;
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 org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
* 支付方式工厂
* @author alascor
*/
@Service
public class PayBillServiceFactory {

private Map<String,PayBillAdapterService> serviceMap = null;
@Autowired
JianHangMaServiceImpl jianHangMaService;
@Autowired
WxMiniProgramServiceImpl wxMiniProgramService;

private Map<String,PayBillAdapterService> getServiceMap() {
if (null == serviceMap) {
serviceMap = new ConcurrentHashMap<String,PayBillAdapterService>();
serviceMap.put(EnumBillPayChannel.BANK_JIANSHE_MA.getCode()+"", jianHangMaService);
serviceMap.put(EnumBillPayChannel.WX_MINI_PROGRAM.getCode()+"", wxMiniProgramService);
}
return serviceMap;
}

public PayBillAdapterService getPayAdapterService(Integer type) throws MallinkException{
PayBillAdapterService service = getServiceMap().get(type+"");
if (null == service) {
throw new MallinkException(ErrorCode.SYS_SERVER_ERROR.getCode(),"payChannel["+type+"] 支付service未找到");
}
return service;
}
}

+ 79
- 0
mallinkService/src/main/java/com/iformall/service/payBill/impl/JianHangMaServiceImpl.java Просмотреть файл

@@ -0,0 +1,79 @@
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.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.domain.po.WxPayAccountBill;
import com.iformall.domain.po.base.WxBillBaseEntity;
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 implements PayBillAdapterService {
private static final String url = "https://ibsbjstar.ccb.com.cn/CCBIS/ccbMain?CCB_IBSVersion=V6";
//建行动态二维码接口
@Override
public Object createPay(WxPayAccountBill wxPayAccountBill,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.setORDERID(billdetail.getBillType()+"_"+billdetail.getId());
request.setPAYMENT(money);
try {
request.setREMARK1(URLEncoder.encode(billdetail.getBillTypeName(),"utf-8"));
} catch (UnsupportedEncodingException e) {
log.error("JianHangMaServiceImpl createPay setREMARK1 error.",e);
}
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.toMacString()+"&MAC="+request.getMAC();
String response = HttpUtil.doPost(full_url, null);
log.debug("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.debug("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;
}

}

+ 22
- 0
mallinkService/src/main/java/com/iformall/service/payBill/impl/WxMiniProgramServiceImpl.java Просмотреть файл

@@ -0,0 +1,22 @@
package com.iformall.service.payBill.impl;

import java.util.Map;

import org.springframework.stereotype.Service;

import com.iformall.domain.po.WxPayAccountBill;
import com.iformall.domain.po.base.WxBillBaseEntity;
import com.iformall.service.payBill.PayBillAdapterService;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class WxMiniProgramServiceImpl implements PayBillAdapterService {
@Override
public Object createPay(WxPayAccountBill wxPayAccountBill,WxBillBaseEntity billdetail,Double money,Map<String, String> params) {
return null;
}

}

+ 47
- 0
mallinkService/src/main/java/com/iformall/service/payBill/impl/entity/JianHangMaRequest.java Просмотреть файл

@@ -0,0 +1,47 @@
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 MAC;
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;
}
}

+ 12
- 10
mallinkService/src/main/java/com/iformall/utils/HttpUtil.java Просмотреть файл

@@ -121,16 +121,18 @@ public class HttpUtil {
HttpPost request = new HttpPost(); HttpPost request = new HttpPost();
request.setURI(new URI(url)); request.setURI(new URI(url));


//设置参数
List<NameValuePair> nvps = new ArrayList<NameValuePair>();
for (Iterator iter = params.keySet().iterator(); iter.hasNext();) {
String name = (String) iter.next();
String value = String.valueOf(params.get(name));
nvps.add(new BasicNameValuePair(name, value));

//System.out.println(name +"-"+value);
if (null != params) {
//设置参数
List<NameValuePair> nvps = new ArrayList<NameValuePair>();
for (Iterator iter = params.keySet().iterator(); iter.hasNext();) {
String name = (String) iter.next();
String value = String.valueOf(params.get(name));
nvps.add(new BasicNameValuePair(name, value));
//System.out.println(name +"-"+value);
}
request.setEntity(new UrlEncodedFormEntity(nvps,HTTP.UTF_8));
} }
request.setEntity(new UrlEncodedFormEntity(nvps,HTTP.UTF_8));


HttpResponse response = client.execute(request); HttpResponse response = client.execute(request);
int code = response.getStatusLine().getStatusCode(); int code = response.getStatusLine().getStatusCode();
@@ -156,7 +158,7 @@ public class HttpUtil {
} }
} }
catch(Exception e){ catch(Exception e){
logger.error(e.getMessage());
logger.error(e.getMessage(),e);
return null; return null;
} }




+ 4
- 1
mallinkService/src/main/resources/mapper/WxPayAccountBillMapper.xml Просмотреть файл

@@ -10,10 +10,13 @@
<result column="social_credit_code" jdbcType="VARCHAR" property="socialCreditCode"/> <result column="social_credit_code" jdbcType="VARCHAR" property="socialCreditCode"/>
<result column="bank_name" jdbcType="VARCHAR" property="bankName"/> <result column="bank_name" jdbcType="VARCHAR" property="bankName"/>
<result column="service_charge_rate" property="serviceChargeRate"/> <result column="service_charge_rate" property="serviceChargeRate"/>
<result column="pay_channel" property="payChannel"/>
<result column="pay_config" property="payConfig"/>
</resultMap> </resultMap>


<sql id="allColumns"> <sql id="allColumns">
`id`,`tenant_id`,`parent_tenant_id`,`bank_account_name`,`bank_card_id`,`social_credit_code`,`bank_name`,`service_charge_rate`
`id`,`tenant_id`,`parent_tenant_id`,`bank_account_name`,`bank_card_id`,`social_credit_code`,`bank_name`,
`service_charge_rate`,`pay_channel`,`pay_config`
</sql> </sql>


<sql id="dynamicWhereConditions"> <sql id="dynamicWhereConditions">


Загрузка…
Отмена
Сохранить