Browse Source

线上退款

zhijiezhao 3 years ago
parent
commit
5dca754d4e

+ 5 - 1
pom.xml

@@ -105,7 +105,11 @@
 	</pluginRepositories>
 	<!-- 依赖项定义 -->
 	<dependencies>
-
+		<dependency>
+			<groupId>commons-httpclient</groupId>
+			<artifactId>commons-httpclient</artifactId>
+			<version>3.1</version>
+		</dependency>
 		<!-- SPRING begin -->
 		<dependency>
 			<groupId>org.springframework</groupId>

+ 7 - 0
src/main/java/com/caimei/modules/order/dao/CmReceiptOrderRelationDao.java

@@ -1,5 +1,6 @@
 package com.caimei.modules.order.dao;
 
+import com.caimei.modules.order.entity.OnlineRefundVo;
 import com.thinkgem.jeesite.common.persistence.CrudDao;
 import com.thinkgem.jeesite.common.persistence.annotation.MyBatisDao;
 import com.caimei.modules.order.entity.CmReceiptOrderRelation;
@@ -31,4 +32,10 @@ public interface CmReceiptOrderRelationDao extends CrudDao<CmReceiptOrderRelatio
     CmReceiptOrderRelation findOrderRelation(Integer orderID);
 
     Date findOnlinePayment(Integer orderID);
+
+    String findPayType(Integer orderId);
+
+    String findUserId(Integer orderId);
+
+    void insertOnlineRefund(OnlineRefundVo onlineRefundVo);
 }

+ 125 - 0
src/main/java/com/caimei/modules/order/entity/AppPayRefundOrderResponseVo.java

@@ -0,0 +1,125 @@
+package com.caimei.modules.order.entity;
+
+import com.google.common.collect.ImmutableSet;
+
+
+import java.io.Serializable;
+import java.util.Set;
+
+public class AppPayRefundOrderResponseVo implements Serializable {
+
+
+    private String rt1_bizType;
+    private String rt2_retCode;
+    private String rt3_retMsg;
+    private String rt4_customerNumber;
+    private String rt5_orderId;
+    private String rt6_refundOrderNum;
+    private String rt7_serialNumber;
+    private String rt8_amount;
+    private String rt9_currency;
+    private String sign;
+
+    /**
+     * 需要加签的属性参数,要求加签的参数空值也签名
+     * 看接口文档
+     */
+    public static final Set<String> NEED_SIGN_PARAMS = ImmutableSet.of("rt1_bizType", "rt2_retCode", "rt4_customerNumber",
+            "rt5_orderId", "rt6_refundOrderNum", "rt7_serialNumber", "rt8_amount", "rt9_currency");
+
+    public AppPayRefundOrderResponseVo() {
+    }
+
+    public AppPayRefundOrderResponseVo(String rt1_bizType, String rt2_retCode, String rt3_retMsg, String rt4_customerNumber, String rt5_orderId, String rt6_refundOrderNum, String rt7_serialNumber, String rt8_amount, String rt9_currency, String sign) {
+        this.rt1_bizType = rt1_bizType;
+        this.rt2_retCode = rt2_retCode;
+        this.rt3_retMsg = rt3_retMsg;
+        this.rt4_customerNumber = rt4_customerNumber;
+        this.rt5_orderId = rt5_orderId;
+        this.rt6_refundOrderNum = rt6_refundOrderNum;
+        this.rt7_serialNumber = rt7_serialNumber;
+        this.rt8_amount = rt8_amount;
+        this.rt9_currency = rt9_currency;
+        this.sign = sign;
+    }
+
+    public String getRt1_bizType() {
+        return rt1_bizType;
+    }
+
+    public void setRt1_bizType(String rt1_bizType) {
+        this.rt1_bizType = rt1_bizType;
+    }
+
+    public String getRt2_retCode() {
+        return rt2_retCode;
+    }
+
+    public void setRt2_retCode(String rt2_retCode) {
+        this.rt2_retCode = rt2_retCode;
+    }
+
+    public String getRt3_retMsg() {
+        return rt3_retMsg;
+    }
+
+    public void setRt3_retMsg(String rt3_retMsg) {
+        this.rt3_retMsg = rt3_retMsg;
+    }
+
+    public String getRt4_customerNumber() {
+        return rt4_customerNumber;
+    }
+
+    public void setRt4_customerNumber(String rt4_customerNumber) {
+        this.rt4_customerNumber = rt4_customerNumber;
+    }
+
+    public String getRt5_orderId() {
+        return rt5_orderId;
+    }
+
+    public void setRt5_orderId(String rt5_orderId) {
+        this.rt5_orderId = rt5_orderId;
+    }
+
+    public String getRt6_refundOrderNum() {
+        return rt6_refundOrderNum;
+    }
+
+    public void setRt6_refundOrderNum(String rt6_refundOrderNum) {
+        this.rt6_refundOrderNum = rt6_refundOrderNum;
+    }
+
+    public String getRt7_serialNumber() {
+        return rt7_serialNumber;
+    }
+
+    public void setRt7_serialNumber(String rt7_serialNumber) {
+        this.rt7_serialNumber = rt7_serialNumber;
+    }
+
+    public String getRt8_amount() {
+        return rt8_amount;
+    }
+
+    public void setRt8_amount(String rt8_amount) {
+        this.rt8_amount = rt8_amount;
+    }
+
+    public String getRt9_currency() {
+        return rt9_currency;
+    }
+
+    public void setRt9_currency(String rt9_currency) {
+        this.rt9_currency = rt9_currency;
+    }
+
+    public String getSign() {
+        return sign;
+    }
+
+    public void setSign(String sign) {
+        this.sign = sign;
+    }
+}

+ 109 - 0
src/main/java/com/caimei/modules/order/entity/AppPayRefundOrderVo.java

@@ -0,0 +1,109 @@
+package com.caimei.modules.order.entity;
+
+import com.google.common.collect.ImmutableSet;
+
+import java.io.Serializable;
+import java.util.Set;
+
+public class AppPayRefundOrderVo implements Serializable {
+
+
+    private String P1_bizType;
+    private String P2_orderId;
+    private String P3_customerNumber;
+    private String P4_refundOrderId;
+    private String P5_amount;
+    private String P6_callbackUrl;
+    private String P7_desc;
+    private String P8_orderSerialNumber;
+    /**排除签名*/
+    private String acqAddnData;
+    private String sign;
+
+    /**
+     * 需要加签的属性参数,要求加签的参数空值也签名
+     * 看接口文档
+     */
+    public static final Set<String> NEED_SIGN_PARAMS = ImmutableSet.of("P1_bizType", "P2_orderId",
+            "P3_customerNumber", "P4_refundOrderId", "P5_amount", "P6_callbackUrl");
+
+    public String getP1_bizType() {
+        return P1_bizType;
+    }
+
+    public void setP1_bizType(String p1_bizType) {
+        P1_bizType = p1_bizType;
+    }
+
+    public String getP2_orderId() {
+        return P2_orderId;
+    }
+
+    public void setP2_orderId(String p2_orderId) {
+        P2_orderId = p2_orderId;
+    }
+
+    public String getP3_customerNumber() {
+        return P3_customerNumber;
+    }
+
+    public void setP3_customerNumber(String p3_customerNumber) {
+        P3_customerNumber = p3_customerNumber;
+    }
+
+    public String getP4_refundOrderId() {
+        return P4_refundOrderId;
+    }
+
+    public void setP4_refundOrderId(String p4_refundOrderId) {
+        P4_refundOrderId = p4_refundOrderId;
+    }
+
+    public String getP5_amount() {
+        return P5_amount;
+    }
+
+    public void setP5_amount(String p5_amount) {
+        P5_amount = p5_amount;
+    }
+
+    public String getP6_callbackUrl() {
+        return P6_callbackUrl;
+    }
+
+    public void setP6_callbackUrl(String p6_callbackUrl) {
+        P6_callbackUrl = p6_callbackUrl;
+    }
+
+    public String getP7_desc() {
+        return P7_desc;
+    }
+
+    public void setP7_desc(String p7_desc) {
+        P7_desc = p7_desc;
+    }
+
+    public String getP8_orderSerialNumber() {
+        return P8_orderSerialNumber;
+    }
+
+    public void setP8_orderSerialNumber(String p8_orderSerialNumber) {
+        P8_orderSerialNumber = p8_orderSerialNumber;
+    }
+
+    public String getAcqAddnData() {
+        return acqAddnData;
+    }
+
+    public void setAcqAddnData(String acqAddnData) {
+        this.acqAddnData = acqAddnData;
+    }
+
+    public String getSign() {
+        return sign;
+    }
+
+    public void setSign(String sign) {
+        this.sign = sign;
+    }
+}

+ 95 - 0
src/main/java/com/caimei/modules/order/entity/OnlineRefundData.java

@@ -0,0 +1,95 @@
+package com.caimei.modules.order.entity;
+
+import com.google.common.collect.ImmutableSet;
+
+import java.io.Serializable;
+import java.util.Set;
+
+public class OnlineRefundData  implements Serializable {
+    private String rt1_bizType;
+    private String rt2_retCode;
+    private String rt3_retMsg;
+    private String rt4_customerNumber;
+    private String rt5_orderId;
+    private String rt6_refundOrderId;
+    private String rt7_amount;
+    private String rt8_orderStatus;
+    private String sign;
+    public static final Set<String> NEED_SIGN_PARAMS = ImmutableSet.of("rt1_bizType", "rt2_retCode", "rt4_customerNumber",
+            "rt5_orderId", "rt6_refundOrderNum", "rt7_serialNumber", "rt8_amount");
+
+    public OnlineRefundData() {
+    }
+
+    public String getRt1_bizType() {
+        return rt1_bizType;
+    }
+
+    public void setRt1_bizType(String rt1_bizType) {
+        this.rt1_bizType = rt1_bizType;
+    }
+
+    public String getRt2_retCode() {
+        return rt2_retCode;
+    }
+
+    public void setRt2_retCode(String rt2_retCode) {
+        this.rt2_retCode = rt2_retCode;
+    }
+
+    public String getRt3_retMsg() {
+        return rt3_retMsg;
+    }
+
+    public void setRt3_retMsg(String rt3_retMsg) {
+        this.rt3_retMsg = rt3_retMsg;
+    }
+
+    public String getRt4_customerNumber() {
+        return rt4_customerNumber;
+    }
+
+    public void setRt4_customerNumber(String rt4_customerNumber) {
+        this.rt4_customerNumber = rt4_customerNumber;
+    }
+
+    public String getRt5_orderId() {
+        return rt5_orderId;
+    }
+
+    public void setRt5_orderId(String rt5_orderId) {
+        this.rt5_orderId = rt5_orderId;
+    }
+
+    public String getRt6_refundOrderId() {
+        return rt6_refundOrderId;
+    }
+
+    public void setRt6_refundOrderId(String rt6_refundOrderId) {
+        this.rt6_refundOrderId = rt6_refundOrderId;
+    }
+
+    public String getRt7_amount() {
+        return rt7_amount;
+    }
+
+    public void setRt7_amount(String rt7_amount) {
+        this.rt7_amount = rt7_amount;
+    }
+
+    public String getRt8_orderStatus() {
+        return rt8_orderStatus;
+    }
+
+    public void setRt8_orderStatus(String rt8_orderStatus) {
+        this.rt8_orderStatus = rt8_orderStatus;
+    }
+
+    public String getSign() {
+        return sign;
+    }
+
+    public void setSign(String sign) {
+        this.sign = sign;
+    }
+}

+ 85 - 0
src/main/java/com/caimei/modules/order/entity/OnlineRefundVo.java

@@ -0,0 +1,85 @@
+package com.caimei.modules.order.entity;
+
+import java.io.Serializable;
+
+public class OnlineRefundVo implements Serializable {
+    private static final long serialVersionUID = 1L;
+    private String id;
+    private String userId;
+    //发起退款商户唯一订单请求号
+    private String orderRequestNo;
+    private String orderId;
+    private String amount;
+    //退款方式 1线上支付原路退回 ,2线上余额退现金
+    private String refundType;
+    private String delFlag;
+
+    public OnlineRefundVo() {
+    }
+
+    public OnlineRefundVo(String id, String userId, String orderRequestNo, String orderId, String amount, String balanceRefundOrderId, String refundType, String delFlag) {
+        this.id = id;
+        this.userId = userId;
+        this.orderRequestNo = orderRequestNo;
+        this.orderId = orderId;
+        this.amount = amount;
+        this.refundType = refundType;
+        this.delFlag = delFlag;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getUserId() {
+        return userId;
+    }
+
+    public void setUserId(String userId) {
+        this.userId = userId;
+    }
+
+    public String getOrderRequestNo() {
+        return orderRequestNo;
+    }
+
+    public void setOrderRequestNo(String orderRequestNo) {
+        this.orderRequestNo = orderRequestNo;
+    }
+
+    public String getOrderId() {
+        return orderId;
+    }
+
+    public void setOrderId(String orderId) {
+        this.orderId = orderId;
+    }
+
+    public String getAmount() {
+        return amount;
+    }
+
+    public void setAmount(String amount) {
+        this.amount = amount;
+    }
+
+    public String getRefundType() {
+        return refundType;
+    }
+
+    public void setRefundType(String refundType) {
+        this.refundType = refundType;
+    }
+
+    public String getDelFlag() {
+        return delFlag;
+    }
+
+    public void setDelFlag(String delFlag) {
+        this.delFlag = delFlag;
+    }
+}

+ 88 - 0
src/main/java/com/caimei/modules/order/entity/OnlineVo.java

@@ -0,0 +1,88 @@
+package com.caimei.modules.order.entity;
+
+import com.google.common.collect.ImmutableSet;
+
+import java.io.Serializable;
+import java.util.Set;
+
+public class OnlineVo implements Serializable {
+    private String P1_bizType;
+    private String P2_orderId;
+    private String P3_customerNumber;
+    private String P4_refundAmount;
+    private String P5_refundOrderId;
+    private String P6_desc;
+    private String P7_serverCallbackUrl;
+    /**排除签名*/
+    private String sign;
+
+    public OnlineVo() {
+    }
+
+    public String getP1_bizType() {
+        return P1_bizType;
+    }
+
+    public void setP1_bizType(String p1_bizType) {
+        P1_bizType = p1_bizType;
+    }
+
+    public String getP2_orderId() {
+        return P2_orderId;
+    }
+
+    public void setP2_orderId(String p2_orderId) {
+        P2_orderId = p2_orderId;
+    }
+
+    public String getP3_customerNumber() {
+        return P3_customerNumber;
+    }
+
+    public void setP3_customerNumber(String p3_customerNumber) {
+        P3_customerNumber = p3_customerNumber;
+    }
+
+    public String getP4_refundAmount() {
+        return P4_refundAmount;
+    }
+
+    public void setP4_refundAmount(String p4_refundAmount) {
+        P4_refundAmount = p4_refundAmount;
+    }
+
+    public String getP5_refundOrderId() {
+        return P5_refundOrderId;
+    }
+
+    public void setP5_refundOrderId(String p5_refundOrderId) {
+        P5_refundOrderId = p5_refundOrderId;
+    }
+
+    public String getP6_desc() {
+        return P6_desc;
+    }
+
+    public void setP6_desc(String p6_desc) {
+        P6_desc = p6_desc;
+    }
+
+    public String getP7_serverCallbackUrl() {
+        return P7_serverCallbackUrl;
+    }
+
+    public void setP7_serverCallbackUrl(String p7_serverCallbackUrl) {
+        P7_serverCallbackUrl = p7_serverCallbackUrl;
+    }
+
+    public String getSign() {
+        return sign;
+    }
+
+    public void setSign(String sign) {
+        this.sign = sign;
+    }
+
+    public static final Set<String> NEED_SIGN_PARAMS = ImmutableSet.of("P1_bizType", "P2_orderId",
+            "P3_customerNumber", "P4_refundAmount", "P5_refundOrderId", "P6_desc","P7_serverCallbackUrl");
+}

+ 108 - 57
src/main/java/com/caimei/modules/order/service/CmReturnedPurchaseService.java

@@ -7,8 +7,7 @@ import com.caimei.modules.coupon.entity.CmCouponOrderRecord;
 import com.caimei.modules.miniprogram.utils.DateUtils;
 import com.caimei.modules.order.dao.*;
 import com.caimei.modules.order.entity.*;
-import com.caimei.modules.order.utils.NewOrderStatus;
-import com.caimei.modules.order.utils.PayUtils;
+import com.caimei.modules.order.utils.*;
 import com.caimei.modules.product.dao.CmPromotionDao;
 import com.caimei.modules.product.dao.CmSecondHandDetailDao;
 import com.caimei.modules.product.entity.CmPromotion;
@@ -33,11 +32,12 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.ui.Model;
-
+import org.apache.commons.httpclient.HttpStatus;
 import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import java.math.BigDecimal;
+import java.text.SimpleDateFormat;
 import java.util.*;
 
 import static com.caimei.modules.miniprogram.utils.UploadPicUtils.saveImageToServer;
@@ -729,70 +729,121 @@ public class CmReturnedPurchaseService extends CrudService<CmReturnedPurchaseDao
      * @param orderId
      */
     private void theOnlineRefund(Integer orderId) throws Exception {
-        //商户标识
-        String merAccount = "aa9aee6a148843a6a9e4ea117df4454b";
-        //私钥,商户密钥
-        String merKey = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAM0qCTZFdi1I59/Jeis+8KVhzSNhsRrKiOlHazIVyxNLzUQvFpWN5PlfVKlnJToorURTStfjAv01HD0Z4ZvMauuHhDT0bptiDln928Ld6SzX889X2nsCxl0Q+WzrkFsnT6gotvGnTeQGUgbBV3SQD3IUOwRwxoWYbrZqxtqHFxqRAgMBAAECgYEAvsHx9MMbAToDVmEXtXP8/lh0Cwy/RgDA0d30voni2pslTNtXbVCUcIUBy8y6oVvG1nt3YEmTsuiZy/nvehPT6GV1Gqj8T6lqWQ8KQKsDGlubvh23tzNM90me2TLZEPdNqC5CPRrwYrjght4BXgzu7s2+5FpeYCob1gVNi+w0Jz0CQQD0dXb9Oez+Ybnxb3rCghGWM6cxi8fsqk6MuKaleg53qfXrkgAVH78faeWzRaeSbVOh5+Z9kX5HUeynfM7E/f4nAkEA1tmnvJp4JQaouO1Trzbnkhowjea5daK/tDE8K0hIMHUjAw+c1QTteGOVGBFBHWPkUwkSCd2HKmk4URkp/snMhwJAO32+qF+Jclq8EqqLmHxo5UHKxX7793d2yD5Dp++tR6fgBiUwyfNA4tc1pEwmPLdIbBVwfUyEC70/N39jHoOlbwI/dX6SPJI9IgKCQp+HJEriWQP5iaCjy7E1JVXHkeP1lop4mzPukJAhTbUn1AGbmncGZmKPetWrFYZ1ReR9EtlJAkEA2kBmARWyOTt8fbikImuHr65M+BDgD+2fkuDb5+tqJljNmSqAIRRwcXj1Je6vkzlDJuSw3wlG6iliFtwe0cq7+w==";
-
-        //维沙商户标识
-        String wsMerAccount = "f8248975517a4feab79cac9d7d453663";
-        //维沙私钥,商户密钥
-        String wsMerKey = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAI4Rb9HBUbjzEsfCOWUsogq8pOoxcSGcL1WFQfqHY1Ul2UwVO5daQtS1pxyM8gKPvvcxNsxz5+wdzb7/cX+SewdF8GbTO2LQIMsOAvtQszsMW8+Hg3J3QFPCHUGh+Q//JXWTFu/GaIlBrpmc7qnB+OMmP315taf5vAmAxC7OzohlAgMBAAECgYBgDiwTn2j46uicxZZ28MmTBt9eNRWvyuE6KoJkuJuR26hjR8vl1rJvDW8y351V3AkbK1xIumlp/PC6ng4IWmrxgu9zuGu+qpb4BdcarS1RMcnpjynCKYO0BnMZBcFrKzWiD6IyZIlLIlJHIDC0mXI/x5V9zG9rL4Tkm4mQPRhzlQJBAPUPledDZXTp2ovvMdL7baI+QVs+tfBqdIdcCgSoEhFh2T/dNVMpBVIjH2D6jTwL94tvWRchMwjXNUSWTRYMH2sCQQCUaOjFeLhSI/gK+f/yXNX/wP6WjXFE9/vuNEaxuaYja2Ia8OwLYoFAYQvKrxLGoHkiI9qKGfqv2h91nF/w/ftvAkBCZA2NkNG8wdpGjO/no9xI1yrnqG6sCns1bLb+GfaDJQoxZiGbPQLHBOLsaBS5Ttiquujc/k6QN5Wj1kBeF7yvAkEAgvWcSfz/8YPJ8q2u3EhtknTUcze29xw5FHbO1y+yWlj8xjdIo7c1xQCd7inVUK70lVq8Etdf7mN1FUx7IOaOQwJAaAl8RFO8zXKy9CdiSsC+2N2qUGLDVOiOJL70Ulh1WxnbLPbwZWCifUu3/UU798dNiZ5Gd06XYinL7lonWpOiEg==";
-
-        //呵呵商户标识
-        String heHeMerAccount = "150a5459416b4046b9153c1cd442e397";
-        //呵呵 私钥,商户密钥
-        String heHeMerKey = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAIggpVq2S1JLH0szxurEgVTz4JTpoyO6/YreVP3xl2bcVj8ekVU+GBwLXNhokxOavgY116XxScinFPa/VoWhaVzyLTbvKz5B6yytuRc3OkSqdDj83jCk+mpmJ5UuCRQ3jesaZAxRpPLzLc99sPtD7xnzEd9UWG8Hlnm6ATmmEQhDAgMBAAECgYBPX+nLGRyWYaNfsFM+tVJMfN/pNMqhnPkWLkoUwPhtS/EmYOaRc+GPCLkcnu2Tstk2udKCuk0xqOs6bZs/1DygxzifYUltWFpqQ2gfmDMoOL4GOflXEHIpoSzSinXz8rjjlQU0wgkbNn6wV6Ao4Jxm5Rzmr9mvTKrAwsnY2eZnYQJBAP+Gj3rrJ7s5778jCramS7yLei2ljkHa/7P0MQsJ+B02/V5CFCh6qKZ2aaAQdk6Z7og5f641TrKX76QetDItSgsCQQCIYVdOdkC3+P6r7WYKXEJ8fdIrf2xyhcCAt9I4q+rcID+ZQ+UqzPoBuib/xpgBZVukDpj9BbIyObyStkvQsNWpAkBd6ADQ5pz6ZKdkMiecym6pAwVKwz4Nm8M/Si2/5dEGQ5BH1Lb9zV4vlvLofURNTKrp61+uES8z2TybryEAE77TAkAD8YSbwTGX4DxE7mVf8VD+1oiIN3QET7fEQQx0FQyCdvA/10W+GhU0jZRpGu30RGEE+mMUFeEUMLUyLNE+ZI6ZAkEA2t0rz4UpljOPms3yfxvzFnShBdshFZOy8kZRG/+OL9entaSOJ0gDmfeFBE9oWXwTj8aVasgbrBV1HjNfyb8WfA==";
-
-        NewOrder order = newOrderService.findByOrderID(orderId);
-        if (order != null && order.getOrganizeID() >= 2) {
-            //维沙订单退款
-            merAccount = wsMerAccount;
-            merKey = wsMerKey;
-        }
-        if (order != null && "2".equals(order.getOrderType())) {
-            //呵呵商城退款
-            merAccount = heHeMerAccount;
-            merKey = heHeMerKey;
-        }
         List<CmReceiptOrderRelation> relationList = cmReceiptOrderRelationDao.findByOrderID(orderId.toString());
         if (null != relationList && relationList.size() > 0) {
             for (CmReceiptOrderRelation orderRelation : relationList) {
-                JSONObject json = new JSONObject();
-                json.put("merAccount", merAccount);
-                //线上收款
+                //cdr表payway为1纯线上收款
                 if ("1".equals(orderRelation.getPayWay())) {
-                    // 当前时间戳
-                    long time = System.currentTimeMillis() / 1000;
-                    json.put("time", time);
-                    //商户退款流水号,由商户自行生成,必须唯一
-                    String merchantRefundNo = orderId + "##" + orderRelation.getId();
-                    json.put("merchantRefundNo", merchantRefundNo);
-                    //退款金额,单位分,必须大于0
-                    int refundAmt = (int) (Double.parseDouble(orderRelation.getAssociateAmount()) * 100);
-                    json.put("refundAmt", refundAmt);
-                    //退款原因
-                    String refundCause = "用户主动退款";
-                    json.put("refundCause", refundCause);
-                    //平台交易订单号
-                    json.put("mbOrderId", orderRelation.getMbOrderId());
-                    String sign = PayUtils.buildSign(json, merKey);
-                    json.put("sign", sign);
-                    String data = PayUtils.buildDataPrivate(json, merKey);
-                    JSONObject result = PayUtils.httpPost("https://platform.mhxxkj.com/paygateway/mbrefund/orderRefund/v1", merAccount, data);
-                    String code = result.getString("code");
-                    logger.info("返回结果-------------------------》"+result.toString());
-                    if (!"000000".equals(code)) {
-                        String msg = result.getString("msg");
-                        logger.info("第三方退款失败>>>>>>>msg:" + msg);
-                        throw new Exception("第三方退款失败!");
+                    //不同产品区分
+                    String payType = cmReceiptOrderRelationDao.findPayType(orderId);
+                    if ("12".equals(payType) || "17".equals(payType)) {
+                        //网银
+                        onlinePay(orderRelation.getOrderRequestNo(), orderRelation.getAssociateAmount(), orderId, "1");
+                    } else {
+                        //扫码
+                        unionRefund(orderRelation.getOrderRequestNo(), orderRelation.getAssociateAmount(), orderId, "1");
                     }
                 }
             }
-            logger.info("第三方退款成功>>>>>>>orderId>>>" + orderId);
         }
     }
 
+    void onlinePay(String orderRequestNo, String money, Integer orderId, String type) throws Exception {
+        AppPayRefundOrderVo orderVo = new AppPayRefundOrderVo();
+        orderVo.setP1_bizType("AppPayRefund");
+        //todo 暂用本商户  E1807062884 网络
+        orderVo.setP3_customerNumber("E1807062884");
+        //退款原单号
+        orderVo.setP2_orderId(orderRequestNo);
+        //自定义退款单号
+        String tk = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
+        orderVo.setP4_refundOrderId("TK" + tk +orderRequestNo);
+        //退款金额
+        orderVo.setP5_amount(money);
+        Map<String, String> map = MyBeanUtils.convertBean(orderVo, new LinkedHashMap());
+        String oriMessage = MyBeanUtils.getSignedByPresetParameter(map, AppPayRefundOrderVo.NEED_SIGN_PARAMS);
+        //网银产品密钥
+        oriMessage += "1iHnZaalUNAVcfcbKdh6n86Z0yUHtM6f";
+        logger.info("签名原文串:" + oriMessage);
+        String sign = Disguiser.disguiseMD5(oriMessage.trim());
+        logger.info("签名串:" + sign);
+        map.put("sign", sign);
+        logger.info("发送参数:" + map);
+        Map<String, Object> resultMap = HttpClientService.getHttpResp(map, "http://pay.trx.helipay.com/trx/app/interface.action");
+        logger.info("响应结果:" + resultMap);
+        if ((Integer) resultMap.get("statusCode") == HttpStatus.SC_OK) {
+            String resultMsg = (String) resultMap.get("response");
+            AppPayRefundOrderResponseVo orderResponseVo = JSONObject.parseObject(resultMsg, AppPayRefundOrderResponseVo.class);
+            String assemblyRespOriSign = MyBeanUtils.getSignedByPresetParameter(orderResponseVo, AppPayRefundOrderResponseVo.NEED_SIGN_PARAMS);
+            //密钥区分
+            assemblyRespOriSign += "CZiCbGrgFYQMldVkQnzbFQeQkn6mp25w";
+            logger.info("组装返回结果签名串:" + assemblyRespOriSign);
+            String responseSign = orderResponseVo.getSign();
+            logger.info("响应签名:" + responseSign);
+            String checkSign = Disguiser.disguiseMD5(assemblyRespOriSign.trim());
+            if (checkSign.equals(responseSign)) {
+                if ("0001".equals(orderResponseVo.getRt2_retCode())) {
+                    logger.info("第三方退款成功>>>>>>>orderId>>>" + orderId);
+                } else {
+                    logger.error("退款失败========================" + orderResponseVo.getRt5_orderId() + "-" + orderResponseVo.getRt3_retMsg());
+                    throw new Exception("第三方退款失败!");
+                }
+            } else {
+                logger.error("退款验签失败");
+                throw new Exception("第三方退款验签失败!");
+            }
+        } else {
+            logger.error("退款请求失败");
+            throw new Exception("第三方退款请求失败!");
+        }
+    }
+
+    void unionRefund(String orderRequestNo,String money,Integer orderId,String type) throws Exception{
+        OnlineVo onlineVo = new OnlineVo();
+        onlineVo.setP1_bizType("OnlineRefund");
+        onlineVo.setP2_orderId(orderRequestNo);
+        onlineVo.setP3_customerNumber("E1807062884");
+        onlineVo.setP4_refundAmount(money);
+        onlineVo.setP5_refundOrderId("TK" +orderRequestNo);
+        //暂时不设置备注和回调
+        //onlineVo.setP6_desc("");
+        //onlineVo.setP7_serverCallbackUrl("");
+        Map<String, String> map = MyBeanUtils.convertBean(onlineVo, new LinkedHashMap());
+        String oriMessage = MyBeanUtils.getSignedByPresetParameter(map, OnlineVo.NEED_SIGN_PARAMS);
+        oriMessage += "CZiCbGrgFYQMldVkQnzbFQeQkn6mp25w";
+        logger.info("签名原文串:" + oriMessage);
+        String sign = Disguiser.disguiseMD5(oriMessage.trim());
+        logger.info("签名串:" + sign);
+        map.put("sign", sign);
+        logger.info("发送参数:" + map);
+        Map<String, Object> resultMap = HttpClientService.getHttpResp(map, "http://pay.trx.helipay.com/trx/online/interface.action");
+        logger.info("响应结果:" + resultMap);
+        if ((Integer) resultMap.get("statusCode") == HttpStatus.SC_OK) {
+            String resultMsg = (String) resultMap.get("response");
+            OnlineRefundData onlineRefund = JSONObject.parseObject(resultMsg, OnlineRefundData.class);
+            String assemblyRespOriSign = MyBeanUtils.getSignedByPresetParameter(onlineRefund, OnlineRefundData.NEED_SIGN_PARAMS);
+            //密钥区分
+            assemblyRespOriSign += "CZiCbGrgFYQMldVkQnzbFQeQkn6mp25w";
+            logger.info("组装返回结果签名串:" + assemblyRespOriSign);
+            String responseSign = onlineRefund.getSign();
+            logger.info("响应签名:" + responseSign);
+            String checkSign = Disguiser.disguiseMD5(assemblyRespOriSign.trim());
+            if (checkSign.equals(responseSign)) {
+                if ("0000".equals(onlineRefund.getRt2_retCode())) {
+                    logger.info("第三方退款成功>>>>>>>orderId>>>" + orderId);
+                } else {
+                    logger.error("退款失败========================" + onlineRefund.getRt5_orderId() + "-" + onlineRefund.getRt3_retMsg());
+                    throw new Exception("第三方退款失败!");
+                }
+            } else {
+                logger.error("退款验签失败");
+                throw new Exception("第三方退款验签失败!");
+            }
+        } else {
+            logger.error("退款请求失败");
+            throw new Exception("第三方退款请求失败!");
+        }
+    }
 
     @Transactional(readOnly = false)
     public void revokeApply(CmReturnedPurchase cmReturnedPurchase, HttpServletRequest request) {

+ 77 - 0
src/main/java/com/caimei/modules/order/utils/Disguiser.java

@@ -0,0 +1,77 @@
+package com.caimei.modules.order.utils;
+
+import com.caimei.modules.order.utils.ConvertUtils;
+
+import java.io.UnsupportedEncodingException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+
+/**
+ * 
+ * @ClassName: Disguiser
+ * @Description: 哈希算法的工具类,提供SHA MD5 HMAC等算法
+ *
+ */
+public class Disguiser {
+
+	public static final String ENCODE = "UTF-8";
+	private static final String KEY = "8data998mnwepxugnk03-2zirb";
+
+	public static String disguiseMD5(String message) {
+
+		if (null == message) {
+			return null;
+		}
+		return disguiseMD5(message, ENCODE);
+	}
+	
+	public static String disguise(String message){
+    	return disguise(message+KEY,ENCODE);
+    	
+    }
+	public static String disguise(String message,String encoding){
+    	message = message.trim();
+        byte value[];
+        try{
+            value = message.getBytes(encoding);
+        }
+        catch(UnsupportedEncodingException e){
+            value = message.getBytes();
+        }
+        MessageDigest md = null;
+        try{
+            md = MessageDigest.getInstance("SHA");
+        }catch(NoSuchAlgorithmException e){
+        	e.printStackTrace();
+            return null;
+        }
+        return ConvertUtils.toHex(md.digest(value));
+    }
+
+	public static String disguiseMD5(String message, String encoding) {
+
+		if (null == message || null == encoding) {
+
+			return null;
+		}
+
+		message = message.trim();
+		byte value[];
+		try {
+			value = message.getBytes(encoding);
+		} catch (UnsupportedEncodingException e) {
+			value = message.getBytes();
+		}
+		MessageDigest md = null;
+		try {
+			md = MessageDigest.getInstance("MD5");
+		} catch (NoSuchAlgorithmException e) {
+			e.printStackTrace();
+			return null;
+		}
+		return ConvertUtils.toHex(md.digest(value));
+	}
+
+
+}

+ 127 - 0
src/main/java/com/caimei/modules/order/utils/HttpClientService.java

@@ -0,0 +1,127 @@
+package com.caimei.modules.order.utils;
+
+import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.HttpStatus;
+import org.apache.commons.httpclient.NameValuePair;
+import org.apache.commons.httpclient.methods.PostMethod;
+import org.apache.commons.httpclient.params.HttpMethodParams;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import java.io.BufferedReader;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.*;
+
+public class HttpClientService {
+
+    private static final Log LOG = LogFactory.getLog(HttpClientService.class);
+
+    public static Map<String, Object> getHttpResp(Map<String, String> reqMap, String httpUrl) {
+        HttpClient client = new HttpClient();
+        PostMethod method = new PostMethod(httpUrl);
+        method.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, "UTF-8");
+        method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler());
+        method.getParams().setParameter(HttpMethodParams.SO_TIMEOUT, new Integer(300000));
+        String response = "";
+
+
+        Map<String, Object> mp = new HashMap<String, Object>();
+
+        try {
+            NameValuePair[] nvps = getNameValuePair(reqMap);
+            method.setRequestBody(nvps);
+            int rescode = client.executeMethod(method);
+            mp.put("statusCode", rescode);
+
+            LOG.info("http rescode:" + rescode);
+            if (rescode == HttpStatus.SC_OK) {
+                BufferedReader reader = new BufferedReader(new InputStreamReader(method.getResponseBodyAsStream(), "UTF-8"));
+                String curline = "";
+                while ((curline = reader.readLine()) != null) {
+                    response += curline;
+                }
+                LOG.info("http response:" + response);
+                mp.put("response", response);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            method.releaseConnection();
+        }
+        return mp;
+    }
+
+    /**
+     *
+     * HTTP协议POST请求方法
+     */
+    public static String httpMethodPost(String url, String params, String gb) {
+        if (null == gb || "".equals(gb)) {
+            gb = "UTF-8";
+        }
+        StringBuffer sb = new StringBuffer();
+        URL urls;
+        HttpURLConnection uc = null;
+        BufferedReader in = null;
+        DataOutputStream out = null;
+        try {
+            urls = new URL(url);
+            uc = (HttpURLConnection) urls.openConnection();
+            uc.setRequestMethod("POST");
+            uc.setDoOutput(true);
+            uc.setDoInput(true);
+            uc.setUseCaches(false);
+            uc.setRequestProperty("Connection", "keep-alive");
+            uc.setRequestProperty("Keep-Alive", "timeout=1, max=100");
+            uc.setRequestProperty("Content-Length", params.length() + "");
+            uc.setRequestProperty("Content-Type","application/json");
+            uc.setConnectTimeout(7000);
+            uc.setReadTimeout(10000);
+            uc.connect();
+            out = new DataOutputStream(uc.getOutputStream());
+            out.write(params.getBytes(gb));
+            out.flush();
+            out.close();
+            in = new BufferedReader(new InputStreamReader(uc.getInputStream(),
+                    gb));
+            String readLine = "";
+            while ((readLine = in.readLine()) != null) {
+                sb.append(readLine);
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        } finally {
+            try {
+                if (out != null){
+                    out.close();
+                }
+                if (in != null){
+                    in.close();
+                }
+                if (uc != null) {
+                    uc.disconnect();
+                }
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+        return sb.toString();
+    }
+
+    public static NameValuePair[] getNameValuePair(Map<String, String> bean) {
+        List<NameValuePair> x = new ArrayList<NameValuePair>();
+        for (Iterator<String> iterator = bean.keySet().iterator(); iterator.hasNext(); ) {
+            String type = (String) iterator.next();
+            x.add(new NameValuePair(type, String.valueOf(bean.get(type))));
+        }
+        Object[] y = x.toArray();
+        NameValuePair[] n = new NameValuePair[y.length];
+        System.arraycopy(y, 0, n, 0, y.length);
+        return n;
+    }
+}

+ 110 - 0
src/main/java/com/caimei/modules/order/utils/MyBeanUtils.java

@@ -0,0 +1,110 @@
+package com.caimei.modules.order.utils;
+
+
+import org.apache.commons.beanutils.BeanUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.beans.IntrospectionException;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ *
+ */
+public class MyBeanUtils extends BeanUtils{
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(MyBeanUtils.class);
+
+    private MyBeanUtils(){ }
+
+    public static Map convertBean(Object bean, Map retMap)
+            throws IntrospectionException, IllegalAccessException, InvocationTargetException {
+        Class clazz = bean.getClass();
+        Field[] fields = clazz.getDeclaredFields();
+        for (Field f : fields) {
+            f.setAccessible(true);
+        }
+        for (Field f : fields) {
+            String key = f.toString().substring(f.toString().lastIndexOf(".") + 1);
+            if (StringUtils.equalsIgnoreCase("NEED_SIGN_PARAMS", key)) {
+                continue;
+            }
+            Object value = f.get(bean);
+            if (value == null)
+                value = "";
+            retMap.put(key, value);
+        }
+        return retMap;
+    }
+
+    public static String getSigned(Map<String, String> map, String[] excludes){
+        StringBuffer sb = new StringBuffer();
+        Set<String> excludeSet = new HashSet<String>();
+        excludeSet.add("sign");
+        if(excludes != null){
+            for(String exclude : excludes){
+                excludeSet.add(exclude);
+            }
+        }
+        for(String key : map.keySet()){
+            if(!excludeSet.contains(key)){
+                String value = map.get(key);
+                value = (value == null ? "" : value);
+                sb.append("&");
+                sb.append(value);
+            }
+        }
+        sb.append("&");
+        return sb.toString();
+    }
+
+    public static String getSigned(Object bean, String[] excludes) throws IllegalAccessException, IntrospectionException, InvocationTargetException {
+        Map map  = convertBean(bean, new LinkedHashMap());
+        String signedStr = getSigned(map, excludes);
+        return signedStr;
+    }
+
+    /**
+     * new style
+     *
+     * @param bean
+     * @param needSignParams
+     */
+    public static String getSignedByPresetParameter(Object bean, Set<String> needSignParams) throws IllegalAccessException,
+            IntrospectionException, InvocationTargetException {
+        Map map = convertBean(bean, new LinkedHashMap<>());
+        return getSignedByPresetParameter(map, needSignParams);
+    }
+
+    /**
+     * new style
+     *
+     * @param map
+     * @param needSignParams
+     * @return
+     */
+    public static String getSignedByPresetParameter(Map<String, String> map, Set<String> needSignParams) {
+        StringBuffer sb = new StringBuffer();
+        if (needSignParams == null || needSignParams.isEmpty()) {
+            throw new RuntimeException("needSignParams is required");
+        }
+        for (String key : map.keySet()) {
+            if (needSignParams.contains(key)) {
+                // do sign
+                String value = map.get(key);
+                value = (value == null ? "" : value);
+                sb.append("&");
+                sb.append(value);
+            }
+        }
+        sb.append("&");
+        return sb.toString();
+    }
+
+}

+ 13 - 0
src/main/resources/mappings/modules/order/CmReceiptOrderRelationMapper.xml

@@ -71,6 +71,10 @@
 			#{delFlag}
 		)
 	</insert>
+	<insert id="insertOnlineRefund">
+		INSERT INTO cm_online_refund (userId, orderRequestNo, orderId, amount, refundType)
+		VALUES (#{userId}, #{orderRequestNo}, #{orderId}, #{amount}, #{balanceRefundOrderId}, #{refundType})
+	</insert>
 
 	<update id="update">
 		UPDATE cm_receipt_order_relation SET
@@ -202,4 +206,13 @@
 		LIMIT
 		  1
 	</select>
+    <select id="findPayType" resultType="java.lang.String">
+		SELECT payType
+		FROM cm_discern_receipt cdr
+		LEFT JOIN cm_receipt_order_relation cror ON cdr.id = cror.receiptID
+		WHERE cror.orderID = #{orderId}
+	</select>
+	<select id="findUserId" resultType="java.lang.String">
+		select userId from cm_order where orderId=#{orderId}
+	</select>
 </mapper>