Browse Source

Merge branch 'master' of dq/kmall-pt into master

黄亚琴 6 years ago
parent
commit
f6571b1ace
55 changed files with 5750 additions and 112 deletions
  1. 63 5
      kmall-admin/src/main/java/com/kmall/admin/controller/OrderController.java
  2. 17 0
      kmall-admin/src/main/java/com/kmall/admin/dao/PinganPayOrderDao.java
  3. 16 0
      kmall-admin/src/main/java/com/kmall/admin/dao/PinganResponseDao.java
  4. 3 0
      kmall-admin/src/main/java/com/kmall/admin/service/OrderService.java
  5. 75 0
      kmall-admin/src/main/java/com/kmall/admin/service/PinganPayOrderService.java
  6. 72 0
      kmall-admin/src/main/java/com/kmall/admin/service/PinganResponseService.java
  7. 43 0
      kmall-admin/src/main/java/com/kmall/admin/service/impl/OrderServiceImpl.java
  8. 64 0
      kmall-admin/src/main/java/com/kmall/admin/service/impl/PinganPayOrderServiceImpl.java
  9. 59 0
      kmall-admin/src/main/java/com/kmall/admin/service/impl/PinganResponseServiceImpl.java
  10. 8 4
      kmall-admin/src/main/resources/conf/pingan-pay.properties
  11. 315 0
      kmall-admin/src/main/resources/mybatis/mapper/pingan/PinganPayOrderDao.xml
  12. 131 0
      kmall-admin/src/main/resources/mybatis/mapper/pingan/PinganResponseDao.xml
  13. 2 0
      kmall-admin/src/main/resources/spring/spring-pingan-pay.xml
  14. 4 3
      kmall-admin/src/main/webapp/js/shop/orderrefund.js
  15. 133 1
      kmall-api/kmall-api.iml
  16. 302 0
      kmall-api/src/main/java/com/kmall/api/api/pingan/ApiPayPinganController.java
  17. 149 0
      kmall-api/src/main/java/com/kmall/api/api/pingan/mpconfig/ApiPinganMpconfigController.java
  18. 2 0
      kmall-api/src/main/java/com/kmall/api/dao/ApiOrderMapper.java
  19. 18 0
      kmall-api/src/main/java/com/kmall/api/dao/ApiPinganPayOrderMapper.java
  20. 17 0
      kmall-api/src/main/java/com/kmall/api/dao/ApiPinganResponseMapper.java
  21. 9 0
      kmall-api/src/main/java/com/kmall/api/service/ApiOrderService.java
  22. 54 0
      kmall-api/src/main/java/com/kmall/api/service/pingan/ApiPinganPayOrderService.java
  23. 52 0
      kmall-api/src/main/java/com/kmall/api/service/pingan/ApiPinganResponseService.java
  24. 149 60
      kmall-api/src/main/resources/mybatis/mapper/ApiOrderMapper.xml
  25. 315 0
      kmall-api/src/main/resources/mybatis/mapper/pingan/ApiPinganPayOrderMapper.xml
  26. 131 0
      kmall-api/src/main/resources/mybatis/mapper/pingan/ApiPinganResponseMapper.xml
  27. 49 12
      kmall-common/src/main/java/com/kmall/common/constant/Dict.java
  28. 30 0
      kmall-common/src/main/java/com/kmall/common/utils/JacksonUtil.java
  29. 328 0
      kmall-common/src/main/java/com/kmall/common/utils/pingan/PinganUtil.java
  30. 595 0
      kmall-common/src/main/java/com/kmall/common/utils/pingan/dto/PinganPayOrderDto.java
  31. 201 0
      kmall-common/src/main/java/com/kmall/common/utils/pingan/dto/PinganResponseDto.java
  32. 9 0
      kmall-common/src/main/java/com/kmall/common/utils/pingan/properties/PinganPayProperties.java
  33. 28 0
      kmall-common/src/main/java/com/kmall/common/utils/pingan/utils/ChildDemo.java
  34. 275 0
      kmall-common/src/main/java/com/kmall/common/utils/pingan/utils/HttpUtil.java
  35. 418 0
      kmall-common/src/main/java/com/kmall/common/utils/pingan/utils/HttpsUtil.java
  36. 36 0
      kmall-common/src/main/java/com/kmall/common/utils/pingan/utils/InterfaceParams.java
  37. 171 0
      kmall-common/src/main/java/com/kmall/common/utils/pingan/utils/MD5.java
  38. 37 0
      kmall-common/src/main/java/com/kmall/common/utils/pingan/utils/ParentDemo.java
  39. 263 0
      kmall-common/src/main/java/com/kmall/common/utils/pingan/utils/TLinx2Util.java
  40. 81 0
      kmall-common/src/main/java/com/kmall/common/utils/pingan/utils/TLinxAESCoder.java
  41. 100 0
      kmall-common/src/main/java/com/kmall/common/utils/pingan/utils/TLinxMapUtil.java
  42. 242 0
      kmall-common/src/main/java/com/kmall/common/utils/pingan/utils/TLinxPluginUtil.java
  43. 211 0
      kmall-common/src/main/java/com/kmall/common/utils/pingan/utils/TLinxRSACoder.java
  44. 34 0
      kmall-common/src/main/java/com/kmall/common/utils/pingan/utils/TLinxSHA1.java
  45. 93 0
      kmall-common/src/main/java/com/kmall/common/utils/pingan/utils/TLinxUtil.java
  46. 1 0
      kmall-common/src/main/java/com/kmall/common/utils/wechat/MD5Util.java
  47. 4 5
      kmall-schedule/src/main/java/com/kmall/schedule/dao/QzOrderMapper.java
  48. 11 0
      kmall-schedule/src/main/java/com/kmall/schedule/quartz/OrderTask.java
  49. 218 8
      kmall-schedule/src/main/java/com/kmall/schedule/service/QzOrderService.java
  50. 68 2
      kmall-schedule/src/main/resources/mybatis/mapper/QzOrderMapper.xml
  51. 3 0
      wx-mall/config/api.js
  52. 23 4
      wx-mall/pages/pay/pay.js
  53. 17 7
      wx-mall/pages/pay/pay.wxml
  54. 1 1
      wx-mall/pages/payResult/payResult.wxml
  55. BIN
      wx-mall/static/images/pinganpay.png

+ 63 - 5
kmall-admin/src/main/java/com/kmall/admin/controller/OrderController.java

@@ -9,6 +9,8 @@ import com.kmall.admin.utils.ParamUtils;
 import com.kmall.common.constant.Dict;
 import com.kmall.common.entity.SysUserEntity;
 import com.kmall.common.utils.*;
+import com.kmall.common.utils.pingan.PinganUtil;
+import com.kmall.common.utils.pingan.dto.PinganResponseDto;
 import com.kmall.common.utils.print.ticket.item.Ticket;
 import com.kmall.common.utils.wechat.WechatMicropayApiResult;
 import com.kmall.common.utils.wechat.WechatRefundApiResult;
@@ -16,6 +18,7 @@ import com.kmall.common.utils.wechat.WechatReverseApiResult;
 import com.kmall.common.utils.wechat.WechatUtil;
 import com.kmall.common.utils.wechat.wxglobal.WechatGlobalUtil;
 import com.kmall.common.utils.wechat.wxglobal.dto.WechatGlobalRefundApiResult;
+import net.sf.json.JSONObject;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.shiro.authz.annotation.RequiresPermissions;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -25,6 +28,7 @@ import java.math.BigDecimal;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 
 
 /**
@@ -47,6 +51,8 @@ public class OrderController {
     private StoreService storeService;
     @Autowired
     private OrderWXPayRecordService orderWXPayRecordService;
+    @Autowired
+    private PinganResponseService pinganResponseService;
 
     /**
      * 列表
@@ -289,7 +295,7 @@ public class OrderController {
      */
     @RequiresPermissions(value = {"order:refund"})
     @RequestMapping(value = "refund", method = RequestMethod.POST)
-    public Object refund(Long orderId, BigDecimal refundMoney) {
+    public Object refund(Long orderId, String refundId, BigDecimal refundMoney) {
         OrderEntity orderInfo = orderService.queryObject(orderId);
         if (null == orderInfo) {
             return R.error("订单不存在");
@@ -304,12 +310,17 @@ public class OrderController {
         }
         String refundResult = "";
         if (orderInfo.getOrderStatus() != Integer.parseInt(Dict.orderStatus.item_0.getItem())) {
-            if(orderInfo.getPayFlag().equalsIgnoreCase(Dict.payFlag.item_wxglobalpay.getItem())){
-                refundResult = wxGlobalRefund(orderInfo,totalActualPrice);
-                if(StringUtils.isNotBlank(refundResult)){
+            if (orderInfo.getPayFlag().equalsIgnoreCase(Dict.payFlag.item_wxglobalpay.getItem())) {
+                refundResult = wxGlobalRefund(orderInfo, totalActualPrice);
+                if (StringUtils.isNotBlank(refundResult)) {
                     return R.error(refundResult);
                 }
-            }else{
+            } else if (orderInfo.getPayFlag().equalsIgnoreCase(Dict.payFlag.item_pingan.getItem())) {
+                refundResult = pinganRefund(orderInfo, refundId);
+                if (StringUtils.isNotBlank(refundResult)) {
+                    return R.error(refundResult);
+                }
+            } else{
                 refundResult = wxRefund(orderInfo,totalActualPrice);
                 if(StringUtils.isNotBlank(refundResult)){
                     return R.error(refundResult);
@@ -318,6 +329,53 @@ public class OrderController {
         }
         return R.ok("退款成功");
     }
+
+    /**
+     * 平安申请退款
+     * @param orderInfo
+     * @return
+     */
+    private String pinganRefund(OrderEntity orderInfo, String refundId){
+        Integer refundAmount =  orderInfo.getActualPrice().multiply(new BigDecimal(100)).intValue();
+        PinganResponseDto responseDto = PinganUtil.pinganPayRefund(orderInfo.getMerchOrderSn(), refundId, refundAmount, null);
+
+        if (!Objects.isNull(responseDto)) {
+            responseDto.setOutNo(orderInfo.getMerchOrderSn());
+            responseDto.setCreateTime(new Date());
+            pinganResponseService.save(responseDto);
+
+            if ("0".equals(responseDto.getErrcode())) {
+                JSONObject tradeResult = JSONObject.fromObject(responseDto.getDatajson());
+                if (Dict.pinganRefundStatus.item_1.getItem().equals(tradeResult.getString("status"))) {
+                    orderService.pinganRefund(orderInfo, tradeResult, refundId);
+                } else {
+                    OrderRefundEntity mallOrderRefund = orderRefundService.queryObjectByOrderId(orderInfo.getId());
+                    OrderRefundEntity orderRefund = new OrderRefundEntity();
+                    orderRefund.setRefundType(Integer.parseInt(Dict.RefundType.item_1.getItem()));
+                    orderRefund.setRefundMoney(BigDecimal.valueOf(orderInfo.getActualPrice().doubleValue()));
+                    orderRefund.setRefundStatus(Integer.parseInt(Dict.RefundStatus.item_4.getItem()));
+                    orderRefund.setModTime(new Date());
+                    orderRefund.setOutRefundNo(tradeResult.getString("ord_no"));
+                    if (mallOrderRefund != null) {
+                        orderRefund.setId(mallOrderRefund.getId());
+                        orderRefundService.update(orderRefund);//退款记录
+                    }
+                    OrderExceptionRecordEntity mallOrderExceptionRecord = new OrderExceptionRecordEntity();
+                    mallOrderExceptionRecord.setUserId(Integer.parseInt(orderInfo.getUserId() + ""));
+                    mallOrderExceptionRecord.setOrderSn(orderInfo.getOrderSn());
+                    mallOrderExceptionRecord.setExceptionStatus(Dict.exceptionStatus.item_03.getItem());
+                    mallOrderExceptionRecord.setExceptionContent("退款失败");
+                    mallOrderExceptionRecord.setCreateTime(new Date());
+                    orderExceptionRecordService.save(mallOrderExceptionRecord);
+                    return "发起平安支付退款失败!";
+                }
+            } else {
+                return responseDto.getMsg();
+            }
+        }
+        return "";
+    }
+
     /**
      * 微信申请退款
      * @param orderInfo

+ 17 - 0
kmall-admin/src/main/java/com/kmall/admin/dao/PinganPayOrderDao.java

@@ -0,0 +1,17 @@
+package com.kmall.admin.dao;
+
+import com.kmall.common.dao.BaseDao;
+import com.kmall.common.utils.pingan.dto.PinganPayOrderDto;
+
+/**
+ * Dao
+ *
+ * @author emato
+ * @email admin@qhdswl.com
+ * @date 2018-12-06 15:29:43
+ */
+public interface PinganPayOrderDao extends BaseDao<PinganPayOrderDto> {
+
+    int updateByOutNo(PinganPayOrderDto pinganPayOrder);
+
+}

+ 16 - 0
kmall-admin/src/main/java/com/kmall/admin/dao/PinganResponseDao.java

@@ -0,0 +1,16 @@
+package com.kmall.admin.dao;
+
+
+import com.kmall.common.dao.BaseDao;
+import com.kmall.common.utils.pingan.dto.PinganResponseDto;
+
+/**
+ * Dao
+ *
+ * @author emato
+ * @email admin@qhdswl.com
+ * @date 2018-12-06 15:29:43
+ */
+public interface PinganResponseDao extends BaseDao<PinganResponseDto> {
+
+}

+ 3 - 0
kmall-admin/src/main/java/com/kmall/admin/service/OrderService.java

@@ -7,6 +7,7 @@ import com.kmall.common.entity.SysUserEntity;
 import com.kmall.common.utils.print.ticket.item.Ticket;
 import com.kmall.common.utils.wechat.WechatRefundApiResult;
 import com.kmall.common.utils.wechat.wxglobal.dto.WechatGlobalRefundApiResult;
+import net.sf.json.JSONObject;
 
 import java.util.List;
 import java.util.Map;
@@ -66,6 +67,8 @@ public interface OrderService {
      */
     void globalRefund(OrderEntity order, WechatGlobalRefundApiResult result);
 
+    void pinganRefund(OrderEntity order, JSONObject result, String refundId);
+
     List<OrderRefundEntity> queryRefundList(Map<String, Object> map);
 
     int queryRefundTotal(Map<String, Object> map);

+ 75 - 0
kmall-admin/src/main/java/com/kmall/admin/service/PinganPayOrderService.java

@@ -0,0 +1,75 @@
+package com.kmall.admin.service;
+
+
+import com.kmall.common.utils.pingan.dto.PinganPayOrderDto;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Service接口
+ *
+ * @author emato
+ * @email admin@qhdswl.com
+ * @date 2018-12-06 15:29:43
+ */
+public interface PinganPayOrderService {
+
+    /**
+     * 根据主键查询实体
+     *
+     * @param id 主键
+     * @return 实体
+     */
+    PinganPayOrderDto queryObject(Integer id);
+
+    /**
+     * 分页查询
+     *
+     * @param map 参数
+     * @return list
+     */
+    List<PinganPayOrderDto> queryList(Map<String, Object> map);
+
+    /**
+     * 分页统计总数
+     *
+     * @param map 参数
+     * @return 总数
+     */
+    int queryTotal(Map<String, Object> map);
+
+    /**
+     * 保存实体
+     *
+     * @param pinganPayOrder 实体
+     * @return 保存条数
+     */
+    int save(PinganPayOrderDto pinganPayOrder);
+
+    /**
+     * 根据主键更新实体
+     *
+     * @param pinganPayOrder 实体
+     * @return 更新条数
+     */
+    int update(PinganPayOrderDto pinganPayOrder);
+
+    /**
+     * 根据主键删除
+     *
+     * @param id
+     * @return 删除条数
+     */
+    int delete(Integer id);
+
+    /**
+     * 根据主键批量删除
+     *
+     * @param ids
+     * @return 删除条数
+     */
+    int deleteBatch(Integer[] ids);
+
+    int updateByOutNo(PinganPayOrderDto pinganPayOrder);
+}

+ 72 - 0
kmall-admin/src/main/java/com/kmall/admin/service/PinganResponseService.java

@@ -0,0 +1,72 @@
+package com.kmall.admin.service;
+
+import com.kmall.common.utils.pingan.dto.PinganResponseDto;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Service接口
+ *
+ * @author emato
+ * @email admin@qhdswl.com
+ * @date 2018-12-06 15:29:43
+ */
+public interface PinganResponseService {
+
+    /**
+     * 根据主键查询实体
+     *
+     * @param id 主键
+     * @return 实体
+     */
+    PinganResponseDto queryObject(Integer id);
+
+    /**
+     * 分页查询
+     *
+     * @param map 参数
+     * @return list
+     */
+    List<PinganResponseDto> queryList(Map<String, Object> map);
+
+    /**
+     * 分页统计总数
+     *
+     * @param map 参数
+     * @return 总数
+     */
+    int queryTotal(Map<String, Object> map);
+
+    /**
+     * 保存实体
+     *
+     * @param pinganResponse 实体
+     * @return 保存条数
+     */
+    int save(PinganResponseDto pinganResponse);
+
+    /**
+     * 根据主键更新实体
+     *
+     * @param pinganResponse 实体
+     * @return 更新条数
+     */
+    int update(PinganResponseDto pinganResponse);
+
+    /**
+     * 根据主键删除
+     *
+     * @param id
+     * @return 删除条数
+     */
+    int delete(Integer id);
+
+    /**
+     * 根据主键批量删除
+     *
+     * @param ids
+     * @return 删除条数
+     */
+    int deleteBatch(Integer[] ids);
+}

+ 43 - 0
kmall-admin/src/main/java/com/kmall/admin/service/impl/OrderServiceImpl.java

@@ -290,6 +290,49 @@ public class OrderServiceImpl
         updateStock(order);
     }
 
+    /**
+     * 平安退款逻辑处理
+     * @param order
+     * @param result
+     */
+    @Transactional
+    public void pinganRefund(OrderEntity order, net.sf.json.JSONObject result, String refundId) {
+        boolean needUpdateStock = true;
+        if (order.getOrderStatus() == Integer.parseInt(Dict.orderStatus.item_201.getItem())) {
+            order.setOrderStatus(Integer.parseInt(Dict.orderStatus.item_401.getItem()));
+        }
+        order.setPayStatus(Integer.parseInt(Dict.payStatus.item_3.getItem()));
+        OrderRefundEntity orderRefund = new OrderRefundEntity();
+        orderRefund.setRefundId(refundId);
+        orderRefund.setOutRefundNo(result.getString("ord_no"));
+        orderRefund.setRefundStatus(Integer.parseInt(Dict.RefundStatus.item_5.getItem()));//退款处理中
+        orderRefund.setModTime(new Date());
+        orderRefund.setRefundMoney(BigDecimal.valueOf(result.getInt("trade_amount")).divide(Constant.ONE_HUNDRED));
+
+        OrderRefundEntity mallOrderRefund = orderRefundDao.queryObjectByOrderId(order.getId());
+        if (mallOrderRefund != null) {
+            orderRefund.setRefundType(mallOrderRefund.getRefundType());
+            orderRefund.setId(mallOrderRefund.getId());
+            orderRefundDao.update(orderRefund);
+        } else {//退款记录不存在
+            orderRefund.setOrderId(Integer.parseInt(order.getId() + ""));
+            orderRefund.setUserId(Integer.parseInt(order.getUserId() + ""));
+            orderRefund.setCreateTime(new Date());
+            orderRefundDao.save(orderRefund);//退款记录
+        }
+        orderDao.update(order);//修改为退款中
+        // 判断是否有优惠券
+        UserCouponEntity couponVo = userCouponDao.queryByOrderId(order.getId());
+        if (null != couponVo) {
+            userCouponDao.cancelOrder(couponVo);
+        }
+
+        if (!needUpdateStock) {
+            return;
+        }
+        // 更新库存
+        updateStock(order);
+    }
 
     /**
      * 微信国际退款逻辑处理

+ 64 - 0
kmall-admin/src/main/java/com/kmall/admin/service/impl/PinganPayOrderServiceImpl.java

@@ -0,0 +1,64 @@
+package com.kmall.admin.service.impl;
+
+import com.kmall.admin.dao.PinganPayOrderDao;
+import com.kmall.admin.service.PinganPayOrderService;
+import com.kmall.common.utils.pingan.dto.PinganPayOrderDto;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.Map;
+
+
+/**
+ * Service实现类
+ *
+ * @author emato
+ * @email admin@qhdswl.com
+ * @date 2018-12-06 15:29:43
+ */
+@Service("pinganPayOrderService")
+public class PinganPayOrderServiceImpl implements PinganPayOrderService {
+    @Autowired
+    private PinganPayOrderDao pinganPayOrderDao;
+
+    @Override
+    public PinganPayOrderDto queryObject(Integer id) {
+        return pinganPayOrderDao.queryObject(id);
+    }
+
+    @Override
+    public List<PinganPayOrderDto> queryList(Map<String, Object> map) {
+        return pinganPayOrderDao.queryList(map);
+    }
+
+    @Override
+    public int queryTotal(Map<String, Object> map) {
+        return pinganPayOrderDao.queryTotal(map);
+    }
+
+    @Override
+    public int save(PinganPayOrderDto pinganPayOrder) {
+        return pinganPayOrderDao.save(pinganPayOrder);
+    }
+
+    @Override
+    public int update(PinganPayOrderDto pinganPayOrder) {
+        return pinganPayOrderDao.update(pinganPayOrder);
+    }
+
+    @Override
+    public int delete(Integer id) {
+        return pinganPayOrderDao.delete(id);
+    }
+
+    @Override
+    public int deleteBatch(Integer[]ids) {
+        return pinganPayOrderDao.deleteBatch(ids);
+    }
+
+    @Override
+    public int updateByOutNo(PinganPayOrderDto pinganPayOrder) {
+        return pinganPayOrderDao.updateByOutNo(pinganPayOrder);
+    }
+}

+ 59 - 0
kmall-admin/src/main/java/com/kmall/admin/service/impl/PinganResponseServiceImpl.java

@@ -0,0 +1,59 @@
+package com.kmall.admin.service.impl;
+
+import com.kmall.admin.dao.PinganResponseDao;
+import com.kmall.admin.service.PinganResponseService;
+import com.kmall.common.utils.pingan.dto.PinganResponseDto;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.Map;
+
+
+/**
+ * Service实现类
+ *
+ * @author emato
+ * @email admin@qhdswl.com
+ * @date 2018-12-06 15:29:43
+ */
+@Service("pinganResponseService")
+public class PinganResponseServiceImpl implements PinganResponseService {
+    @Autowired
+    private PinganResponseDao pinganResponseDao;
+
+    @Override
+    public PinganResponseDto queryObject(Integer id) {
+        return pinganResponseDao.queryObject(id);
+    }
+
+    @Override
+    public List<PinganResponseDto> queryList(Map<String, Object> map) {
+        return pinganResponseDao.queryList(map);
+    }
+
+    @Override
+    public int queryTotal(Map<String, Object> map) {
+        return pinganResponseDao.queryTotal(map);
+    }
+
+    @Override
+    public int save(PinganResponseDto pinganResponse) {
+        return pinganResponseDao.save(pinganResponse);
+    }
+
+    @Override
+    public int update(PinganResponseDto pinganResponse) {
+        return pinganResponseDao.update(pinganResponse);
+    }
+
+    @Override
+    public int delete(Integer id) {
+        return pinganResponseDao.delete(id);
+    }
+
+    @Override
+    public int deleteBatch(Integer[]ids) {
+        return pinganResponseDao.deleteBatch(ids);
+    }
+}

+ 8 - 4
kmall-admin/src/main/resources/conf/pingan-pay.properties

@@ -9,8 +9,10 @@ pay.pingan.env = dev
 pingan.dev.payOpenId=6ad8a69d33b5bf188f7c0ab7bae95931
 #平安支付open_key
 pingan.dev.payOpenKey=ac1705d3ace4b6b69044494d0e28310e
-#平安取消交易、退款密钥
-pingan.dev.payPrivateKey=MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDoYLKYSup2POAgmf2iHwGhUQZSeyyxLvslDcFCRekg1D7w+Y8dybhBOyDvlTbuG15jt8vqqH1xlGTI66yz351uxrUL10UL6Uw+kx1091/BCiRo1AY9frOlIeTnVZy/S2LPWjEefI9o0nOBYJkoJZsaFffX6qXVFkCfAGNMohyuU0gNHw3SXXMBiJ2n2E7GfFf/peAmtTg4zFJO+CrikfSTrL0u5Y2dWQp1KQvkfCMrXaECM24fLc6xxwAdiARC6DjMK8F+ZxovEgb0VObpbZ5pnV2XrKEbiDXQ/DbeNTmELHN8k0S3NUY6ozpu1M3JDqZPhBIDgd/gcZknFngCRJ95AgMBAAECggEAXZYkF0WEq93UfgzGozZNl8RkAW/uDeXX65JglOpG+5u/RZmcU+jbthm0KAk2OCr5lrt8+qKk8stK08hmo4KZivWoEH7AJg3tUP46zNKb08jb5QQPB1Ex1H2UDL7kA/6+arfuNFMCBrtLHX3j8NFEZ/sU9/ZelzUBDYhAdaqMVoAbfOX7MIZMRIZRhrZCuQlZI0Wz1oGzOf4WB40HEvgRfkGkdC2C+co9tCK7PRcJCiAnSro175E8NLmYIs+0yUtztUUPSUcVmZ4NfQzM/tD7oyeHREkmBEM6NT62U2PAHyhdFJH23T5Rq80u2Qbzpqv6Fk9aNlBM5uN24umVU7C2oQKBgQD0Hyw7SKOGExbBOOyJFLpeISsiACokPz7rGwgQJfNfGrbnBLuo7VyxRAX9y01FQrsZL0ZqZ09dSnY6KqjmMzUQdtF1mteiF9wC6xHcIN9oXzDtDc0geB/hb3zLRIHs5yrCgNci8FjGL0OwBaNNz0vLa02C8Vm5P6rjlclyjK7ZtQKBgQDzrz0i+mCgklD6+cbEA3Z+0b75s5Lg9cu13eBntZ/+11d2Kf1JCrgrCiRcX1ggOG2ZHmPmi5cs93J6rd+HWInPWJ+j4GUYN5wPS8GxiQun42b3FloT5Zoe4Cj3TmonIHvhFQojYAniKPx3jb3mCLOUyHWjIc5r9zE6Tovth195NQKBgE7k9CqEozRlXuk7OFZk+IYLOiFW5EeqmO7qYYS2fxyxSYMHqI5Dh71SOo128pX7pvPQr3Ubxi5kLilGOCeNTQzxGWhkjmO4SkY3KiJ2DT1x5iH2X+CqccMtgKtAjKy/WLZbZSvJeSczhzCP4eL3p4sqNnanAVQ5G0VJ1zzJ8ogxAoGAA+4inUrOfih9995Jb2Xi5l65pstXphswwukmMmYCg5izh2tb826h08fhGEBNao+ebObJk7FSqd3/0ay2OzeZWWfDg2AeIUrcUH7XS+a68mU/huKsZz+/wZm572srWSAz/0hYloN5BVXF5KO7mVcwlki5ZP0pmCIvgBI+PYF+b7UCgYEA3WpyaYgDSVrE2pcF4+dvqFNIDGcFBGqCyeCaGx4E1WuP0R7y1SFM2miGnbl+te89ZLSzSudoeFq/qS8S3W+M+PuQJlmlFnQ+B/DaEJmKGiiNAqWT9cdohLeYNaJBvk55MdnRJl4dAfkf5PFIf64CWvdDEvhehuV6kub3i8KEvH8=
+#平安退款公钥
+pingan.dev.payPublicKey=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC7q4B8d6EIMUo8AK2sdgxbmdrFyklVW+4+y2KI+jeHgAwA9SwBn3KVIUa1aVrBcZzQh0RhSCy8r+vfh67/KVTU+Oaav0ZH3B/Wem5DkLMrkz8IMm17NsUFhXZCCyC5KXIbzciueHdYTObbV4r4oDazf52708jSIVKDSYkjcTEoiQIDAQAB
+#平安取消交易私钥
+pingan.dev.payPrivateKey=MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALurgHx3oQgxSjwArax2DFuZ2sXKSVVb7j7LYoj6N4eADAD1LAGfcpUhRrVpWsFxnNCHRGFILLyv69+Hrv8pVNT45pq/RkfcH9Z6bkOQsyuTPwgybXs2xQWFdkILILkpchvNyK54d1hM5ttXivigNrN/nbvTyNIhUoNJiSNxMSiJAgMBAAECgYAB3H+XvHACbsq3saIHVdxlhC8hSxJTIGhKgyXlCeZHF8QGtmfLVFOEmyHiZrsZtBDEGLNa66ZV8MC8JNJdgYFv3vZeYpLDgmAPmiKadEiCu4pg/QwpfeHGEDZfaxWfjWfNwyLv6RmXv310hP8WEMC9xv2Cx9DXIAcXg0SlNy4CoQJBAOLsicAop3i7LT+oGw6GoPTaHyTk20yJVXn/VMKXMLIT4371bcANrj1zj2EWjLUPOqYAApWxYDahg4hLIcD1e40CQQDTt16bagAJw/sShVXYcKuuf3vKIG/ZMXgfxddxFkd4aMmpImW6LwqFIV96J5jhYlcVwtXdWtDiuqHgsAgPD6PtAkBRxIfybPPDpjaszGdLeal/8STtx2VaE9ZwClhBcfdDA7Wi5s7wOD3DuOM+ScDT8TPh4vkLdYnExbg+oUv9Wrd1AkEAvC6k/Ob/Ga8FH7U8VKHxN61Azqx+PkNmTnd/w5jV9gTOGnPkj9T4ONUtFFrV3J+YYFNJ3PK38I+LCzfsMdbpEQJAWoJ7g9IMMu6yx4JyCzE15OdOcJDytqZ6gIiXvtkqEGywyxNdEyUOu/+BkAQElTdUCCWuVBllm09K/y95I6zG8A==
 #平安进件open_id
 pingan.dev.pluginOpenId=txafCXQt058248b3230c9081ff90ce80
 #平安进件open_key
@@ -36,8 +38,10 @@ pingan.dev.jumpUrl=
 pingan.prod.payOpenId=6ad8a69d33b5bf188f7c0ab7bae95931
 #平安支付open_key
 pingan.prod.payOpenKey=ac1705d3ace4b6b69044494d0e28310e
-#平安取消交易、退款密钥
-pingan.prod.payPrivateKey=MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDoYLKYSup2POAgmf2iHwGhUQZSeyyxLvslDcFCRekg1D7w+Y8dybhBOyDvlTbuG15jt8vqqH1xlGTI66yz351uxrUL10UL6Uw+kx1091/BCiRo1AY9frOlIeTnVZy/S2LPWjEefI9o0nOBYJkoJZsaFffX6qXVFkCfAGNMohyuU0gNHw3SXXMBiJ2n2E7GfFf/peAmtTg4zFJO+CrikfSTrL0u5Y2dWQp1KQvkfCMrXaECM24fLc6xxwAdiARC6DjMK8F+ZxovEgb0VObpbZ5pnV2XrKEbiDXQ/DbeNTmELHN8k0S3NUY6ozpu1M3JDqZPhBIDgd/gcZknFngCRJ95AgMBAAECggEAXZYkF0WEq93UfgzGozZNl8RkAW/uDeXX65JglOpG+5u/RZmcU+jbthm0KAk2OCr5lrt8+qKk8stK08hmo4KZivWoEH7AJg3tUP46zNKb08jb5QQPB1Ex1H2UDL7kA/6+arfuNFMCBrtLHX3j8NFEZ/sU9/ZelzUBDYhAdaqMVoAbfOX7MIZMRIZRhrZCuQlZI0Wz1oGzOf4WB40HEvgRfkGkdC2C+co9tCK7PRcJCiAnSro175E8NLmYIs+0yUtztUUPSUcVmZ4NfQzM/tD7oyeHREkmBEM6NT62U2PAHyhdFJH23T5Rq80u2Qbzpqv6Fk9aNlBM5uN24umVU7C2oQKBgQD0Hyw7SKOGExbBOOyJFLpeISsiACokPz7rGwgQJfNfGrbnBLuo7VyxRAX9y01FQrsZL0ZqZ09dSnY6KqjmMzUQdtF1mteiF9wC6xHcIN9oXzDtDc0geB/hb3zLRIHs5yrCgNci8FjGL0OwBaNNz0vLa02C8Vm5P6rjlclyjK7ZtQKBgQDzrz0i+mCgklD6+cbEA3Z+0b75s5Lg9cu13eBntZ/+11d2Kf1JCrgrCiRcX1ggOG2ZHmPmi5cs93J6rd+HWInPWJ+j4GUYN5wPS8GxiQun42b3FloT5Zoe4Cj3TmonIHvhFQojYAniKPx3jb3mCLOUyHWjIc5r9zE6Tovth195NQKBgE7k9CqEozRlXuk7OFZk+IYLOiFW5EeqmO7qYYS2fxyxSYMHqI5Dh71SOo128pX7pvPQr3Ubxi5kLilGOCeNTQzxGWhkjmO4SkY3KiJ2DT1x5iH2X+CqccMtgKtAjKy/WLZbZSvJeSczhzCP4eL3p4sqNnanAVQ5G0VJ1zzJ8ogxAoGAA+4inUrOfih9995Jb2Xi5l65pstXphswwukmMmYCg5izh2tb826h08fhGEBNao+ebObJk7FSqd3/0ay2OzeZWWfDg2AeIUrcUH7XS+a68mU/huKsZz+/wZm572srWSAz/0hYloN5BVXF5KO7mVcwlki5ZP0pmCIvgBI+PYF+b7UCgYEA3WpyaYgDSVrE2pcF4+dvqFNIDGcFBGqCyeCaGx4E1WuP0R7y1SFM2miGnbl+te89ZLSzSudoeFq/qS8S3W+M+PuQJlmlFnQ+B/DaEJmKGiiNAqWT9cdohLeYNaJBvk55MdnRJl4dAfkf5PFIf64CWvdDEvhehuV6kub3i8KEvH8=
+#平安退款公钥
+pingan.prod.payPublicKey=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC7q4B8d6EIMUo8AK2sdgxbmdrFyklVW+4+y2KI+jeHgAwA9SwBn3KVIUa1aVrBcZzQh0RhSCy8r+vfh67/KVTU+Oaav0ZH3B/Wem5DkLMrkz8IMm17NsUFhXZCCyC5KXIbzciueHdYTObbV4r4oDazf52708jSIVKDSYkjcTEoiQIDAQAB
+#平安取消交易私钥
+pingan.prod.payPrivateKey=MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALurgHx3oQgxSjwArax2DFuZ2sXKSVVb7j7LYoj6N4eADAD1LAGfcpUhRrVpWsFxnNCHRGFILLyv69+Hrv8pVNT45pq/RkfcH9Z6bkOQsyuTPwgybXs2xQWFdkILILkpchvNyK54d1hM5ttXivigNrN/nbvTyNIhUoNJiSNxMSiJAgMBAAECgYAB3H+XvHACbsq3saIHVdxlhC8hSxJTIGhKgyXlCeZHF8QGtmfLVFOEmyHiZrsZtBDEGLNa66ZV8MC8JNJdgYFv3vZeYpLDgmAPmiKadEiCu4pg/QwpfeHGEDZfaxWfjWfNwyLv6RmXv310hP8WEMC9xv2Cx9DXIAcXg0SlNy4CoQJBAOLsicAop3i7LT+oGw6GoPTaHyTk20yJVXn/VMKXMLIT4371bcANrj1zj2EWjLUPOqYAApWxYDahg4hLIcD1e40CQQDTt16bagAJw/sShVXYcKuuf3vKIG/ZMXgfxddxFkd4aMmpImW6LwqFIV96J5jhYlcVwtXdWtDiuqHgsAgPD6PtAkBRxIfybPPDpjaszGdLeal/8STtx2VaE9ZwClhBcfdDA7Wi5s7wOD3DuOM+ScDT8TPh4vkLdYnExbg+oUv9Wrd1AkEAvC6k/Ob/Ga8FH7U8VKHxN61Azqx+PkNmTnd/w5jV9gTOGnPkj9T4ONUtFFrV3J+YYFNJ3PK38I+LCzfsMdbpEQJAWoJ7g9IMMu6yx4JyCzE15OdOcJDytqZ6gIiXvtkqEGywyxNdEyUOu/+BkAQElTdUCCWuVBllm09K/y95I6zG8A==
 #平安进件open_id
 pingan.prod.pluginOpenId=txafCXQt058248b3230c9081ff90ce80
 #平安进件open_key

+ 315 - 0
kmall-admin/src/main/resources/mybatis/mapper/pingan/PinganPayOrderDao.xml

@@ -0,0 +1,315 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+
+<mapper namespace="com.kmall.admin.dao.PinganPayOrderDao">
+
+    <resultMap type="com.kmall.common.utils.pingan.dto.PinganPayOrderDto" id="pinganPayOrderMap">
+        <result property="id" column="id"/>
+        <result property="outNo" column="out_no"/>
+        <result property="pmtName" column="pmt_name"/>
+        <result property="pmtTag" column="pmt_tag"/>
+        <result property="ordMctId" column="ord_mct_id"/>
+        <result property="ordShopId" column="ord_shop_id"/>
+        <result property="ordCurrency" column="ord_currency"/>
+        <result property="currencySign" column="currency_sign"/>
+        <result property="ordNo" column="ord_no"/>
+        <result property="ordType" column="ord_type"/>
+        <result property="originalAmount" column="original_amount"/>
+        <result property="discountAmount" column="discount_amount"/>
+        <result property="ignoreAmount" column="ignore_amount"/>
+        <result property="tradeAccount" column="trade_account"/>
+        <result property="tradeNo" column="trade_no"/>
+        <result property="tradeAmount" column="trade_amount"/>
+        <result property="tradeQrcode" column="trade_qrcode"/>
+        <result property="amount" column="amount"/>
+        <result property="tradeTime" column="trade_time"/>
+        <result property="tradePayTime" column="trade_pay_time"/>
+        <result property="payTime" column="pay_time"/>
+        <result property="status" column="status"/>
+        <result property="tradeResult" column="trade_result"/>
+        <result property="jsapiPayUrl" column="jsapi_pay_url"/>
+        <result property="randStr" column="rand_str"/>
+        <result property="appid" column="appId"/>
+        <result property="noncestr" column="nonceStr"/>
+        <result property="signtype" column="signType"/>
+        <result property="prepayId" column="prepay_id"/>
+        <result property="paysign" column="paySign"/>
+        <result property="createrSn" column="creater_sn"/>
+        <result property="createTime" column="create_time"/>
+        <result property="moderSn" column="moder_sn"/>
+        <result property="modTime" column="mod_time"/>
+        <result property="tstm" column="tstm"/>
+    </resultMap>
+
+	<select id="queryObject" resultType="com.kmall.common.utils.pingan.dto.PinganPayOrderDto">
+		select
+			`id`,
+			`out_no`,
+			`pmt_name`,
+			`pmt_tag`,
+			`ord_mct_id`,
+			`ord_shop_id`,
+			`ord_currency`,
+			`currency_sign`,
+			`ord_no`,
+			`ord_type`,
+			`original_amount`,
+			`discount_amount`,
+			`ignore_amount`,
+			`trade_account`,
+			`trade_no`,
+			`trade_amount`,
+			`trade_qrcode`,
+			`amount`,
+			`trade_time`,
+			`trade_pay_time`,
+			`pay_time`,
+			`status`,
+			`trade_result`,
+			`jsapi_pay_url`,
+			`rand_str`,
+			`appId`,
+			`nonceStr`,
+			`signType`,
+			`prepay_id`,
+			`paySign`,
+			`creater_sn`,
+			`create_time`,
+			`moder_sn`,
+			`mod_time`,
+			`tstm`
+		from pingan_pay_order
+		where id = #{id}
+	</select>
+
+	<select id="queryList" resultType="com.kmall.common.utils.pingan.dto.PinganPayOrderDto">
+		select
+    		`id`,
+    		`out_no`,
+    		`pmt_name`,
+    		`pmt_tag`,
+    		`ord_mct_id`,
+    		`ord_shop_id`,
+			`ord_currency`,
+			`currency_sign`,
+    		`ord_no`,
+    		`ord_type`,
+    		`original_amount`,
+    		`discount_amount`,
+    		`ignore_amount`,
+    		`trade_account`,
+    		`trade_no`,
+    		`trade_amount`,
+    		`trade_qrcode`,
+    		`amount`,
+			`trade_time`,
+    		`trade_pay_time`,
+    		`pay_time`,
+    		`status`,
+    		`trade_result`,
+    		`jsapi_pay_url`,
+    		`rand_str`,
+    		`appId`,
+    		`nonceStr`,
+    		`signType`,
+    		`prepay_id`,
+    		`paySign`,
+    		`creater_sn`,
+    		`create_time`,
+    		`moder_sn`,
+    		`mod_time`,
+    		`tstm`
+		from pingan_pay_order
+		WHERE 1=1
+		<if test="name != null and name.trim() != ''">
+			AND name LIKE concat('%',#{name},'%')
+		</if>
+        <choose>
+            <when test="sidx != null and sidx.trim() != ''">
+                order by ${sidx} ${order}
+            </when>
+			<otherwise>
+                order by id desc
+			</otherwise>
+        </choose>
+		<if test="offset != null and limit != null">
+			limit #{offset}, #{limit}
+		</if>
+	</select>
+	
+ 	<select id="queryTotal" resultType="int">
+		select count(*) from pingan_pay_order
+		WHERE 1=1
+        <if test="name != null and name.trim() != ''">
+            AND name LIKE concat('%',#{name},'%')
+        </if>
+	</select>
+	 
+	<insert id="save" parameterType="com.kmall.common.utils.pingan.dto.PinganPayOrderDto">
+		insert into pingan_pay_order(
+			`id`,
+			`out_no`,
+			`pmt_name`,
+			`pmt_tag`,
+			`ord_mct_id`,
+			`ord_shop_id`,
+			`ord_currency`,
+			`currency_sign`,
+			`ord_no`,
+			`ord_type`,
+			`original_amount`,
+			`discount_amount`,
+			`ignore_amount`,
+			`trade_account`,
+			`trade_no`,
+			`trade_amount`,
+			`trade_qrcode`,
+			`amount`,
+			`trade_time`,
+			`trade_pay_time`,
+			`pay_time`,
+			`status`,
+			`trade_result`,
+			`jsapi_pay_url`,
+			`rand_str`,
+			`appId`,
+			`nonceStr`,
+			`signType`,
+			`prepay_id`,
+			`paySign`,
+			`creater_sn`,
+			`create_time`,
+			`moder_sn`,
+			`mod_time`,
+			`tstm`)
+		values(
+			#{id},
+			#{outNo},
+			#{pmtName},
+			#{pmtTag},
+			#{ordMctId},
+			#{ordShopId},
+			#{ordCurrency},
+			#{currencySign},
+			#{ordNo},
+			#{ordType},
+			#{originalAmount},
+			#{discountAmount},
+			#{ignoreAmount},
+			#{tradeAccount},
+			#{tradeNo},
+			#{tradeAmount},
+			#{tradeQrcode},
+			#{amount},
+			#{tradeTime},
+			#{tradePayTime},
+			#{payTime},
+			#{status},
+			#{tradeResult},
+			#{jsapiPayUrl},
+			#{randStr},
+			#{appid},
+			#{noncestr},
+			#{signtype},
+			#{prepayId},
+			#{paysign},
+			#{createrSn},
+			#{createTime},
+			#{moderSn},
+			#{modTime},
+			#{tstm})
+	</insert>
+
+	<update id="update" parameterType="com.kmall.common.utils.pingan.dto.PinganPayOrderDto">
+		update pingan_pay_order 
+		<set>
+			<if test="outNo != null">`out_no` = #{outNo}, </if>
+			<if test="pmtName != null">`pmt_name` = #{pmtName}, </if>
+			<if test="pmtTag != null">`pmt_tag` = #{pmtTag}, </if>
+			<if test="ordMctId != null">`ord_mct_id` = #{ordMctId}, </if>
+			<if test="ordShopId != null">`ord_currency` = #{ordShopId}, </if>
+			<if test="ordCurrency != null">`ord_shop_id` = #{ordCurrency}, </if>
+			<if test="currencySign != null">`currency_sign` = #{currencySign}, </if>
+			<if test="ordNo != null">`ord_no` = #{ordNo}, </if>
+			<if test="ordType != null">`ord_type` = #{ordType}, </if>
+			<if test="originalAmount != null">`original_amount` = #{originalAmount}, </if>
+			<if test="discountAmount != null">`discount_amount` = #{discountAmount}, </if>
+			<if test="ignoreAmount != null">`ignore_amount` = #{ignoreAmount}, </if>
+			<if test="tradeAccount != null">`trade_account` = #{tradeAccount}, </if>
+			<if test="tradeNo != null">`trade_no` = #{tradeNo}, </if>
+			<if test="tradeAmount != null">`trade_amount` = #{tradeAmount}, </if>
+			<if test="tradeQrcode != null">`trade_qrcode` = #{tradeQrcode}, </if>
+			<if test="amount != null">`amount` = #{amount}, </if>
+			<if test="tradeTime != null">`trade_time` = #{tradeTime}, </if>
+			<if test="tradePayTime != null">`trade_pay_time` = #{tradePayTime}, </if>
+			<if test="payTime != null">`pay_time` = #{payTime}, </if>
+			<if test="status != null">`status` = #{status}, </if>
+			<if test="tradeResult != null">`trade_result` = #{tradeResult}, </if>
+			<if test="jsapiPayUrl != null">`jsapi_pay_url` = #{jsapiPayUrl}, </if>
+			<if test="randStr != null">`rand_str` = #{randStr}, </if>
+			<if test="appid != null">`appId` = #{appid}, </if>
+			<if test="noncestr != null">`nonceStr` = #{noncestr}, </if>
+			<if test="signtype != null">`signType` = #{signtype}, </if>
+			<if test="prepayId != null">`prepay_id` = #{prepayId}, </if>
+			<if test="paysign != null">`paySign` = #{paysign}, </if>
+			<if test="createrSn != null">`creater_sn` = #{createrSn}, </if>
+			<if test="createTime != null">`create_time` = #{createTime}, </if>
+			<if test="moderSn != null">`moder_sn` = #{moderSn}, </if>
+			<if test="modTime != null">`mod_time` = #{modTime}, </if>
+			<if test="tstm != null">`tstm` = #{tstm}</if>
+		</set>
+		where id = #{id}
+	</update>
+
+	<update id="updateByOutNo" parameterType="com.kmall.common.utils.pingan.dto.PinganPayOrderDto">
+		update pingan_pay_order
+		<set>
+			<if test="pmtName != null">`pmt_name` = #{pmtName}, </if>
+			<if test="pmtTag != null">`pmt_tag` = #{pmtTag}, </if>
+			<if test="ordMctId != null">`ord_mct_id` = #{ordMctId}, </if>
+			<if test="ordShopId != null">`ord_currency` = #{ordShopId}, </if>
+			<if test="ordCurrency != null">`ord_shop_id` = #{ordCurrency}, </if>
+			<if test="currencySign != null">`currency_sign` = #{currencySign}, </if>
+			<if test="ordNo != null">`ord_no` = #{ordNo}, </if>
+			<if test="ordType != null">`ord_type` = #{ordType}, </if>
+			<if test="originalAmount != null">`original_amount` = #{originalAmount}, </if>
+			<if test="discountAmount != null">`discount_amount` = #{discountAmount}, </if>
+			<if test="ignoreAmount != null">`ignore_amount` = #{ignoreAmount}, </if>
+			<if test="tradeAccount != null">`trade_account` = #{tradeAccount}, </if>
+			<if test="tradeNo != null">`trade_no` = #{tradeNo}, </if>
+			<if test="tradeAmount != null">`trade_amount` = #{tradeAmount}, </if>
+			<if test="tradeQrcode != null">`trade_qrcode` = #{tradeQrcode}, </if>
+			<if test="amount != null">`amount` = #{amount}, </if>
+			<if test="tradeTime != null">`trade_time` = #{tradeTime}, </if>
+			<if test="tradePayTime != null">`trade_pay_time` = #{tradePayTime}, </if>
+			<if test="payTime != null">`pay_time` = #{payTime}, </if>
+			<if test="status != null">`status` = #{status}, </if>
+			<if test="tradeResult != null">`trade_result` = #{tradeResult}, </if>
+			<if test="jsapiPayUrl != null">`jsapi_pay_url` = #{jsapiPayUrl}, </if>
+			<if test="randStr != null">`rand_str` = #{randStr}, </if>
+			<if test="appid != null">`appId` = #{appid}, </if>
+			<if test="noncestr != null">`nonceStr` = #{noncestr}, </if>
+			<if test="signtype != null">`signType` = #{signtype}, </if>
+			<if test="prepayId != null">`prepay_id` = #{prepayId}, </if>
+			<if test="paysign != null">`paySign` = #{paysign}, </if>
+			<if test="createrSn != null">`creater_sn` = #{createrSn}, </if>
+			<if test="createTime != null">`create_time` = #{createTime}, </if>
+			<if test="moderSn != null">`moder_sn` = #{moderSn}, </if>
+			<if test="modTime != null">`mod_time` = #{modTime}, </if>
+			<if test="tstm != null">`tstm` = #{tstm}</if>
+		</set>
+		where `out_no` = #{outNo}
+	</update>
+	
+	<delete id="delete">
+		delete from pingan_pay_order where id = #{value}
+	</delete>
+	
+	<delete id="deleteBatch">
+		delete from pingan_pay_order where id in 
+		<foreach item="id" collection="array" open="(" separator="," close=")">
+			#{id}
+		</foreach>
+	</delete>
+
+</mapper>

+ 131 - 0
kmall-admin/src/main/resources/mybatis/mapper/pingan/PinganResponseDao.xml

@@ -0,0 +1,131 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+
+<mapper namespace="com.kmall.admin.dao.PinganResponseDao">
+
+    <resultMap type="com.kmall.common.utils.pingan.dto.PinganResponseDto" id="pinganResponseMap">
+        <result property="id" column="id"/>
+        <result property="outNo" column="out_no"/>
+        <result property="reqInterface" column="req_interface"/>
+        <result property="errcode" column="errcode"/>
+        <result property="msg" column="msg"/>
+        <result property="data" column="data"/>
+        <result property="sign" column="sign"/>
+        <result property="datajson" column="datajson"/>
+		<result property="timestamp" column="timestamp"/>
+        <result property="createTime" column="create_time"/>
+        <result property="tstm" column="tstm"/>
+    </resultMap>
+
+	<select id="queryObject" resultType="com.kmall.common.utils.pingan.dto.PinganResponseDto">
+		select
+			`id`,
+			`out_no`,
+			`req_interface`,
+			`errcode`,
+			`msg`,
+			`data`,
+			`sign`,
+			`datajson`,
+			`timestamp`,
+			`create_time`,
+			`tstm`
+		from pingan_response
+		where id = #{id}
+	</select>
+
+	<select id="queryList" resultType="com.kmall.common.utils.pingan.dto.PinganResponseDto">
+		select
+    		`id`,
+    		`out_no`,
+    		`req_interface`,
+    		`errcode`,
+    		`msg`,
+    		`data`,
+    		`sign`,
+    		`datajson`,
+			`timestamp`,
+    		`create_time`,
+    		`tstm`
+		from pingan_response
+		WHERE 1=1
+		<if test="name != null and name.trim() != ''">
+			AND name LIKE concat('%',#{name},'%')
+		</if>
+        <choose>
+            <when test="sidx != null and sidx.trim() != ''">
+                order by ${sidx} ${order}
+            </when>
+			<otherwise>
+                order by id desc
+			</otherwise>
+        </choose>
+		<if test="offset != null and limit != null">
+			limit #{offset}, #{limit}
+		</if>
+	</select>
+	
+ 	<select id="queryTotal" resultType="int">
+		select count(*) from pingan_response
+		WHERE 1=1
+        <if test="name != null and name.trim() != ''">
+            AND name LIKE concat('%',#{name},'%')
+        </if>
+	</select>
+	 
+	<insert id="save" parameterType="com.kmall.common.utils.pingan.dto.PinganResponseDto">
+		insert into pingan_response(
+			`id`,
+			`out_no`,
+			`req_interface`,
+			`errcode`,
+			`msg`,
+			`data`,
+			`sign`,
+			`datajson`,
+			`timestamp`,
+			`create_time`,
+			`tstm`)
+		values(
+			#{id},
+			#{outNo},
+			#{reqInterface},
+			#{errcode},
+			#{msg},
+			#{data},
+			#{sign},
+			#{datajson},
+			#{timestamp},
+			#{createTime},
+			#{tstm})
+	</insert>
+	 
+	<update id="update" parameterType="com.kmall.common.utils.pingan.dto.PinganResponseDto">
+		update pingan_response 
+		<set>
+			<if test="outNo != null">`out_no` = #{outNo}, </if>
+			<if test="reqInterface != null">`req_interface` = #{reqInterface}, </if>
+			<if test="errcode != null">`errcode` = #{errcode}, </if>
+			<if test="msg != null">`msg` = #{msg}, </if>
+			<if test="data != null">`data` = #{data}, </if>
+			<if test="sign != null">`sign` = #{sign}, </if>
+			<if test="datajson != null">`datajson` = #{datajson}, </if>
+			<if test="timestamp != null">`timestamp` = #{timestamp}, </if>
+			<if test="createTime != null">`create_time` = #{createTime}, </if>
+			<if test="tstm != null">`tstm` = #{tstm}</if>
+		</set>
+		where id = #{id}
+	</update>
+	
+	<delete id="delete">
+		delete from pingan_response where id = #{value}
+	</delete>
+	
+	<delete id="deleteBatch">
+		delete from pingan_response where id in 
+		<foreach item="id" collection="array" open="(" separator="," close=")">
+			#{id}
+		</foreach>
+	</delete>
+
+</mapper>

+ 2 - 0
kmall-admin/src/main/resources/spring/spring-pingan-pay.xml

@@ -17,6 +17,7 @@
     <bean id="pinganPayProdProperties" class="com.kmall.common.utils.pingan.properties.PinganPayProdProperties">
         <property name="payOpenId" value="${pingan.prod.payOpenId}"/>
         <property name="payOpenKey" value="${pingan.prod.payOpenKey}"/>
+        <property name="payPublicKey" value="${pingan.prod.payPublicKey}"/>
         <property name="payPrivateKey" value="${pingan.prod.payPrivateKey}"/>
 
         <property name="pluginOpenId" value="${pingan.prod.pluginOpenId}"/>
@@ -35,6 +36,7 @@
     <bean id="pinganPayDevProperties" class="com.kmall.common.utils.pingan.properties.PinganPayDevProperties">
         <property name="payOpenId" value="${pingan.dev.payOpenId}"/>
         <property name="payOpenKey" value="${pingan.dev.payOpenKey}"/>
+        <property name="payPublicKey" value="${pingan.dev.payPublicKey}"/>
         <property name="payPrivateKey" value="${pingan.dev.payPrivateKey}"/>
 
         <property name="pluginOpenId" value="${pingan.dev.pluginOpenId}"/>

+ 4 - 3
kmall-admin/src/main/webapp/js/shop/orderrefund.js

@@ -65,7 +65,7 @@ $(function () {
                     let htmlStr = '<button class="btn btn-outline btn-info" onclick="vm.lookDetail(' + row.id + ')"><i class="fa fa-info-circle"></i>详情</button>&nbsp;';
                     if (hasPermission('order:refund')) {
                         if (row.refundStatus == 1) {
-                            htmlStr += '<button class="btn btn-outline btn-primary" onclick="vm.refundUpdate(' + row.orderId + ')"><i class="fa fa-check-circle"></i>&nbsp;退款</button>&nbsp;' +
+                            htmlStr += '<button class="btn btn-outline btn-primary" onclick="vm.refundUpdate(' + row.orderId + ', ' + row.id + ')"><i class="fa fa-check-circle"></i>&nbsp;退款</button>&nbsp;' +
                                 '<button class="btn btn-outline btn-danger" onclick="vm.approval(' + row.id + ')"><i class="fa fa-times-circle-o"></i>审核</button>&nbsp;';
                         }
                     }
@@ -202,9 +202,10 @@ var vm = new Vue({
         handleReset: function (name) {
             handleResetForm(this, name);
         },
-        refundUpdate: function (rowId) {
+        refundUpdate: function (orderId, rowId) {
             let params = {};
-            params.orderId = rowId;
+            params.orderId = orderId;
+            params.refundId = rowId;
 
             $.ajax({
                 type: "POST",

+ 133 - 1
kmall-api/kmall-api.iml

@@ -1,8 +1,140 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
+<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" version="4">
   <component name="FacetManager">
     <facet type="Spring" name="Spring">
       <configuration />
     </facet>
   </component>
+  <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
+    <output url="file://$MODULE_DIR$/target/classes" />
+    <output-test url="file://$MODULE_DIR$/target/test-classes" />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
+      <excludeFolder url="file://$MODULE_DIR$/target" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="module" module-name="kmall-common" />
+    <orderEntry type="library" name="Maven: com.qiniu:qiniu-java-sdk:7.2.17" level="project" />
+    <orderEntry type="library" name="Maven: com.squareup.okhttp3:okhttp:3.9.1" level="project" />
+    <orderEntry type="library" name="Maven: com.squareup.okio:okio:1.13.0" level="project" />
+    <orderEntry type="library" name="Maven: com.google.code.gson:gson:2.8.2" level="project" />
+    <orderEntry type="library" name="Maven: com.aliyun.oss:aliyun-sdk-oss:2.5.0" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.httpcomponents:httpclient:4.4.1" level="project" />
+    <orderEntry type="library" name="Maven: org.jdom:jdom:1.1" level="project" />
+    <orderEntry type="library" name="Maven: net.sf.json-lib:json-lib:jdk15:2.4" level="project" />
+    <orderEntry type="library" name="Maven: net.sf.ezmorph:ezmorph:1.0.6" level="project" />
+    <orderEntry type="library" name="Maven: com.qcloud:cos_api:4.4" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.httpcomponents:httpcore:4.4.3" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.httpcomponents:httpmime:4.5.1" level="project" />
+    <orderEntry type="library" name="Maven: org.json:json:20140107" level="project" />
+    <orderEntry type="library" name="Maven: commons-httpclient:commons-httpclient:3.1" level="project" />
+    <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.5.0" level="project" />
+    <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.5.0" level="project" />
+    <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.5.0" level="project" />
+    <orderEntry type="library" name="Maven: dom4j:dom4j:1.6.1" level="project" />
+    <orderEntry type="library" name="Maven: xml-apis:xml-apis:1.0.b2" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.poi:poi:3.15" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.commons:commons-collections4:4.1" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml:3.15" level="project" />
+    <orderEntry type="library" name="Maven: com.github.virtuald:curvesapi:1.04" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml-schemas:3.15" level="project" />
+    <orderEntry type="library" name="Maven: redis.clients:jedis:2.8.2" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.commons:commons-pool2:2.4.2" level="project" />
+    <orderEntry type="library" name="Maven: com.google.guava:guava:17.0" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.3.2" level="project" />
+    <orderEntry type="library" name="Maven: org.jxls:jxls:2.4.7" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.commons:commons-jexl:2.1.1" level="project" />
+    <orderEntry type="library" name="Maven: org.jxls:jxls-poi:1.0.16" level="project" />
+    <orderEntry type="library" name="Maven: org.jxls:jxls-jexcel:1.0.7" level="project" />
+    <orderEntry type="library" name="Maven: net.sourceforge.jexcelapi:jxl:2.6.10" level="project" />
+    <orderEntry type="library" name="Maven: org.jxls:jxls-reader:2.0.5" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.commons:commons-digester3:with-deps:3.2" level="project" />
+    <orderEntry type="library" name="Maven: cglib:cglib:2.2.2" level="project" />
+    <orderEntry type="library" name="Maven: asm:asm:3.3.1" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.xmlbeans:xmlbeans:2.6.0" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-swagger2:2.4.0" level="project" />
+    <orderEntry type="library" name="Maven: io.swagger:swagger-annotations:1.5.6" level="project" />
+    <orderEntry type="library" name="Maven: io.swagger:swagger-models:1.5.6" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-spi:2.4.0" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-core:2.4.0" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-schema:2.4.0" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-swagger-common:2.4.0" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-spring-web:2.4.0" level="project" />
+    <orderEntry type="library" name="Maven: com.fasterxml:classmate:1.3.1" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.plugin:spring-plugin-core:1.2.0.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.plugin:spring-plugin-metadata:1.2.0.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-swagger-ui:2.4.0" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.12" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
+    <orderEntry type="library" scope="PROVIDED" name="Maven: javax.servlet:javax.servlet-api:3.1.0" level="project" />
+    <orderEntry type="library" name="Maven: org.mybatis:mybatis:3.4.1" level="project" />
+    <orderEntry type="library" name="Maven: org.mybatis:mybatis-spring:1.3.0" level="project" />
+    <orderEntry type="library" name="Maven: org.hibernate:hibernate-validator:5.4.1.Final" level="project" />
+    <orderEntry type="library" name="Maven: javax.validation:validation-api:1.1.0.Final" level="project" />
+    <orderEntry type="library" name="Maven: org.jboss.logging:jboss-logging:3.3.0.Final" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-webmvc:4.3.7.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-beans:4.3.7.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-context:4.3.7.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-core:4.3.7.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-expression:4.3.7.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-web:4.3.7.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-jdbc:4.3.7.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-tx:4.3.7.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-context-support:4.3.7.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-aop:4.3.7.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-aspects:4.3.7.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.aspectj:aspectjweaver:1.8.9" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.springframework:spring-test:4.3.7.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.19" level="project" />
+    <orderEntry type="library" name="Maven: org.slf4j:slf4j-log4j12:1.7.19" level="project" />
+    <orderEntry type="library" name="Maven: org.slf4j:jcl-over-slf4j:1.7.19" level="project" />
+    <orderEntry type="library" name="Maven: log4j:log4j:1.2.17" level="project" />
+    <orderEntry type="library" name="Maven: ch.qos.logback:logback-core:1.2.3" level="project" />
+    <orderEntry type="library" name="Maven: ch.qos.logback:logback-classic:1.2.3" level="project" />
+    <orderEntry type="library" name="Maven: org.logback-extensions:logback-ext-spring:0.1.5" level="project" />
+    <orderEntry type="library" name="Maven: com.zaxxer:HikariCP:2.6.3" level="project" />
+    <orderEntry type="library" name="Maven: org.mariadb.jdbc:mariadb-java-client:2.0.2" level="project" />
+    <orderEntry type="library" name="Maven: mysql:mysql-connector-java:5.1.39" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba:druid:1.0.28" level="project" />
+    <orderEntry type="module-library">
+      <library name="Maven: com.alibaba:jconsole:1.8.0">
+        <CLASSES>
+          <root url="jar://C:/Program Files/Java/jdk1.8.0_191/lib/jconsole.jar!/" />
+        </CLASSES>
+        <JAVADOC />
+        <SOURCES />
+      </library>
+    </orderEntry>
+    <orderEntry type="module-library">
+      <library name="Maven: com.alibaba:tools:1.8.0">
+        <CLASSES>
+          <root url="jar://C:/Program Files/Java/jdk1.8.0_191/lib/tools.jar!/" />
+        </CLASSES>
+        <JAVADOC />
+        <SOURCES />
+      </library>
+    </orderEntry>
+    <orderEntry type="library" name="Maven: commons-lang:commons-lang:2.6" level="project" />
+    <orderEntry type="library" name="Maven: commons-fileupload:commons-fileupload:1.3.1" level="project" />
+    <orderEntry type="library" name="Maven: commons-io:commons-io:2.5" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba:fastjson:1.2.30" level="project" />
+    <orderEntry type="library" name="Maven: commons-codec:commons-codec:1.10" level="project" />
+    <orderEntry type="library" name="Maven: commons-configuration:commons-configuration:1.10" level="project" />
+    <orderEntry type="library" name="Maven: commons-logging:commons-logging:1.1.1" level="project" />
+    <orderEntry type="library" name="Maven: commons-beanutils:commons-beanutils:1.9.3" level="project" />
+    <orderEntry type="library" name="Maven: commons-collections:commons-collections:3.2.2" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.shiro:shiro-core:1.3.2" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.shiro:shiro-spring:1.3.2" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.shiro:shiro-web:1.3.2" level="project" />
+    <orderEntry type="library" name="Maven: com.github.axet:kaptcha:0.0.9" level="project" />
+    <orderEntry type="library" name="Maven: com.jhlabs:filters:2.0.235" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.velocity:velocity:1.7" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.velocity:velocity-tools:2.0" level="project" />
+    <orderEntry type="library" name="Maven: commons-digester:commons-digester:1.8" level="project" />
+    <orderEntry type="library" name="Maven: jstl:jstl:1.2" level="project" />
+    <orderEntry type="library" name="Maven: taglibs:standard:1.1.2" level="project" />
+    <orderEntry type="library" name="Maven: org.freemarker:freemarker:2.3.23" level="project" />
+  </component>
 </module>

+ 302 - 0
kmall-api/src/main/java/com/kmall/api/api/pingan/ApiPayPinganController.java

@@ -0,0 +1,302 @@
+package com.kmall.api.api.pingan;
+
+import com.kmall.api.annotation.IgnoreAuth;
+import com.kmall.api.annotation.LoginUser;
+import com.kmall.api.entity.OrderProcessRecordEntity;
+import com.kmall.api.entity.OrderVo;
+import com.kmall.api.entity.UserVo;
+import com.kmall.api.service.*;
+import com.kmall.api.service.pay.wxpay.WxPayPropertiesBuilder;
+import com.kmall.api.service.pingan.ApiPinganPayOrderService;
+import com.kmall.api.service.pingan.ApiPinganResponseService;
+import com.kmall.api.util.ApiBaseAction;
+import com.kmall.api.util.CommonUtil;
+import com.kmall.common.constant.Dict;
+import com.kmall.common.utils.Constant;
+import com.kmall.common.utils.MapUtils;
+import com.kmall.common.utils.RRException;
+import com.kmall.common.utils.StringUtils;
+import com.kmall.common.utils.pingan.PinganUtil;
+import com.kmall.common.utils.pingan.dto.PinganPayOrderDto;
+import com.kmall.common.utils.pingan.dto.PinganResponseDto;
+import com.kmall.common.utils.pingan.properties.PinganPayPropertiesBuilder;
+import com.kmall.common.utils.pingan.utils.InterfaceParams;
+import com.kmall.common.utils.pingan.utils.TLinx2Util;
+import com.kmall.common.utils.pingan.utils.TLinxAESCoder;
+import net.sf.json.JSONObject;
+import org.apache.log4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.math.BigDecimal;
+import java.util.*;
+
+@RestController
+@RequestMapping("api/pay/pingan")
+public class ApiPayPinganController extends ApiBaseAction {
+
+    private Logger logger = Logger.getLogger(ApiPayPinganController.class);
+
+    private static final String SUCCESS_CODE = "0";
+
+    @Autowired
+    private ApiOrderService orderService;
+
+    @Autowired
+    private ApiPayService payService;
+
+    @Autowired
+    private ApiPinganResponseService pinganResponseService;
+
+    @Autowired
+    private ApiPinganPayOrderService pinganPayOrderService;
+
+    @Autowired
+    private ApiOrderProcessRecordService orderProcessRecordService;
+
+    @Autowired
+    private ApiUserService userService;
+
+    @RequestMapping("index")
+    public Object index(@LoginUser UserVo loginUser) {
+        return toResponsSuccess("");
+    }
+
+
+    /**
+     * 平安下单接口
+     * @return
+     */
+    @GetMapping("payorder")
+    public Object payorder(@LoginUser UserVo loginUser, Long[] orderIds,String isMergePay) {
+        loginUser = userService.queryObject(loginUser.getId());
+
+        List<Long> orderIdList=new ArrayList<>();
+        String merchOrderSn = "";
+        for(int i=0;i<orderIds.length;i++){
+            orderIdList.add(orderIds[i]);
+        }
+        BigDecimal actual_price = Constant.ZERO;
+        List<OrderVo> orderVoList = orderService.queryObjectByIdList(orderIdList);
+        List<OrderProcessRecordEntity> processRecordEntityList = new ArrayList<>();
+
+        for (OrderVo orderInfo : orderVoList) {
+            if (orderInfo.getOrder_status() == 101) {
+                return toResponsObject(400, "订单号为"+orderInfo.getOrder_sn()+"的订单超时支付,已取消", "");
+            }
+            if (orderInfo.getPay_status() != 0 && orderInfo.getPay_status() != 1) {
+                return toResponsObject(400, "订单号为"+orderInfo.getOrder_sn()+"的订单已支付,请不要重复操作", "");
+            }
+            merchOrderSn = orderInfo.getMerchOrderSn();
+
+            //如此次是单笔支付,则判断下单时该商户订单是否是拆单订单,如果都满足,则更新商户订单号,生成新的预支付信息
+            if(Dict.isMergePay.item_0.getItem().equalsIgnoreCase(isMergePay)) {
+                if ("2".equalsIgnoreCase(orderInfo.getIsMergePay())) {//多笔订单单笔支付,则商户订单号,生成新的预支付信息
+//                    merchOrderSn = "EMATO" + new SimpleDateFormat("yyyyMMddhhmmss").format(new Date());
+                    merchOrderSn = "EMATO"+ CommonUtil.generateOrderNumber();
+                    orderInfo.setMerchOrderSn(merchOrderSn);
+                } else {
+                    PinganResponseDto payCancel = PinganUtil.pinganPayCancel(null, orderInfo.getMerchOrderSn());
+                    if (payCancel == null) {
+                        logger.info("平安取消订单接口调用失败!");
+                        return toResponsFail("下单失败");
+                    }
+                    payCancel.setOutNo(orderInfo.getMerchOrderSn());
+                    payCancel.setCreateTime(new Date());
+                    pinganResponseService.save(payCancel);
+                    if (!SUCCESS_CODE.equals(payCancel.getErrcode()) && !"8002".equals(payCancel.getErrcode())) {
+                        return toResponsFail(payCancel.getMsg());
+                    }
+                }
+            }
+
+            OrderProcessRecordEntity processRecordEntity = orderProcessRecordService.queryObjectByOrderSn(orderInfo.getOrder_sn());
+            if(processRecordEntity != null){
+                OrderProcessRecordEntity entity = new OrderProcessRecordEntity();
+                entity.setOrderSn(orderInfo.getOrder_sn());
+                entity.setUserId(Integer.valueOf(loginUser.getId().toString()));
+                entity.setPayStartTime(new Date());
+                entity.setId(processRecordEntity.getId());
+                processRecordEntityList.add(entity);
+            }
+            actual_price = actual_price.add(orderInfo.getActual_price());
+        }
+
+        try {
+            String timestamp = new Date().getTime() / 1000 + "";    // 时间
+
+            // 固定参数
+            TreeMap<String, String> postmap = new TreeMap<String, String>();    // 请求参数的map
+
+            postmap.put("open_id", PinganPayPropertiesBuilder.instance().getPayOpenId());
+            postmap.put("timestamp", timestamp);
+
+            TreeMap<String, String> param = new TreeMap<>();
+            param.put("out_no", merchOrderSn);
+            param.put("pmt_tag", "WeixinOL");
+            param.put("original_amount", actual_price.multiply(Constant.ONE_HUNDRED).intValue()+"");//分为单位
+            param.put("trade_amount", actual_price.multiply(Constant.ONE_HUNDRED).intValue()+"");//分为单位
+            param.put("sub_appid", WxPayPropertiesBuilder.instance().getAppId());
+            param.put("sub_openid", loginUser.getWeixin_openid());
+            param.put("trade_type", "JSAPI");
+            // 实名认证
+//            param.put("user_creid", loginUser.getIdNo());
+//            param.put("user_truename", loginUser.getUsername());
+
+            param.put("notify_url", PinganPayPropertiesBuilder.instance().getNotifyUrl());
+
+            //数据加密,加签
+            TLinx2Util.handleEncrypt(param, postmap);
+            TLinx2Util.handleSign(postmap);
+
+            //请求
+            String rspStr = TLinx2Util.handlePost(postmap, InterfaceParams.PAYORDER);
+            System.out.println("返回字符串=" + rspStr);
+
+            //解析数据,处理数据
+            return analysisResponse(rspStr, merchOrderSn, orderVoList);
+
+        } catch (Exception e) {
+            e.printStackTrace();
+            updateFailProcessBatch(processRecordEntityList, "下单失败,error=" + e.getMessage());//更新订单流转信息
+            return toResponsFail("下单失败,error=" + e.getMessage());
+        }
+    }
+
+
+    /**
+     * 更新订单支付失败流转信息
+     * @param processRecordEntityList
+     * @param return_msg
+     */
+    private void updateFailProcessBatch(List<OrderProcessRecordEntity> processRecordEntityList,String return_msg){
+        for (OrderProcessRecordEntity orderProcessRecordEntity : processRecordEntityList) {
+            orderProcessRecordEntity.setIsPaymentSend(Dict.isSend.item_0.getItem());
+            orderProcessRecordEntity.setProcessContent(return_msg);
+        }
+        orderProcessRecordService.updateBatch(processRecordEntityList);
+    }
+
+
+    /**
+     * 解析响应数据
+     * @param rspStr
+     * @return
+     */
+    private Object analysisResponse(String rspStr, String merchOrderSn, List<OrderVo> orderVoList) throws Exception {
+        JSONObject respObject = JSONObject.fromObject(rspStr);
+        logger.info("返回错误码:【" + MapUtils.getString("errcode", respObject) + "】");
+        logger.info("返回错误提示【" + MapUtils.getString("msg", respObject) + "】");
+        logger.info("平安支付下单返回数据:【" + MapUtils.getString("data", respObject) + "】");
+        logger.info("接口签名【" + MapUtils.getString("sign", respObject) + "】");
+
+        if (!respObject.isEmpty()) {
+            PinganResponseDto response = new PinganResponseDto();
+            response.setErrcode(MapUtils.getString("errcode", respObject));
+            response.setMsg(MapUtils.getString("msg", respObject));
+            response.setData(MapUtils.getString("data", respObject));
+            response.setSign(MapUtils.getString("sign", respObject));
+            if (StringUtils.isNotEmpty(MapUtils.getString("timestamp", respObject))) {
+                Long timestamp = Long.parseLong(MapUtils.getString("timestamp", respObject)) * 1000;
+                response.setTimestamp(new Date(timestamp));
+            }
+            response.setReqInterface(InterfaceParams.PAYORDER);
+            response.setCreateTime(new Date());
+            response.setOutNo(merchOrderSn);
+
+            if (SUCCESS_CODE.equals(response.getErrcode())) {
+                // 验签, 判断是否下单成功
+                if (TLinx2Util.verifySign(respObject)) {
+                    String dataJson = TLinxAESCoder.decrypt(response.getData(), PinganPayPropertiesBuilder.instance().getPayOpenKey());
+
+                    // 添加平安支付回执
+                    response.setDatajson(dataJson);
+                    pinganResponseService.save(response);
+
+                    // 参数解密,添加平安支付订单信息
+                    if (dataJson != null) {
+                        JSONObject dataObject = JSONObject.fromObject(dataJson);
+                        PinganPayOrderDto payorder = PinganUtil.buildPayOrderDto(dataObject);
+                        payorder.setCreateTime(new Date());
+                        pinganPayOrderService.save(payorder);
+
+                        String prepay_id = payorder.getTradeNo();
+                        for (OrderVo orderInfo : orderVoList) {
+                            orderInfo.setPay_id(prepay_id);
+                            orderInfo.setPay_status(Integer.parseInt(Dict.payStatus.item_1.getItem())); // 付款中
+                            orderInfo.setOrder_status(Integer.parseInt(Dict.orderStatus.item_100.getItem()));
+                            orderInfo.setPayFlag(Dict.payFlag.item_pingan.getItem());
+                        }
+                        orderService.updateBatch(orderVoList);
+
+                        Map<String, Object> payParam = new HashMap<>();
+                        payParam.put("timeStamp", MapUtils.getString("timeStamp", dataObject));
+                        payParam.put("nonceStr", MapUtils.getString("nonceStr", dataObject));
+                        payParam.put("signType", MapUtils.getString("signType", dataObject));
+                        payParam.put("package", MapUtils.getString("package", dataObject));
+                        payParam.put("paySign", MapUtils.getString("paySign", dataObject));
+                        return toResponsSuccess(payParam);
+                    }
+                }
+            } else {
+                pinganResponseService.save(response);
+                return toResponsFail(response.getMsg());
+            }
+        }
+
+        return toResponsFail("下单失败!");
+    }
+
+
+    /**
+     * 平安订单回调接口
+     *
+     * @return
+     */
+    @IgnoreAuth
+    @RequestMapping(value = "/notify", method = RequestMethod.POST)
+    @ResponseBody
+    public String notify(HttpServletRequest request, HttpServletResponse response) {
+        logger.info("平安订单回调接口>>>>>>pingan notify start");
+        String openId = request.getParameter("open_id");
+        if (StringUtils.isNotEmpty(openId) && openId.equals(PinganPayPropertiesBuilder.instance().getPayOpenId())) {
+            String ordNo = request.getParameter("ord_no");
+            String timestamp = request.getParameter("timestamp");
+            String randStr = request.getParameter("rand_str");
+            String outNo = request.getParameter("out_no");
+            String status = request.getParameter("status");
+            String tradeResult = request.getParameter("trade_result");
+            String payTime = request.getParameter("pay_time");
+            String sign = request.getParameter("sign");
+
+            Map<String, Object> params = new TreeMap<>();
+            params.put("open_id", openId);
+            params.put("ord_no", ordNo);
+            params.put("timestamp", timestamp);
+            params.put("rand_str", randStr);
+            params.put("out_no", outNo);
+            params.put("status", status);
+            params.put("trade_result", tradeResult);
+            params.put("pay_time", payTime);
+            params.put("sign", sign);
+
+            PinganResponseDto responseDto = new PinganResponseDto();
+            responseDto.setOutNo(outNo);
+            responseDto.setReqInterface(InterfaceParams.NOTIFY);
+            responseDto.setDatajson(JSONObject.fromObject(params).toString());
+            responseDto.setCreateTime(new Date());
+            pinganResponseService.save(responseDto);
+
+            JSONObject result = JSONObject.fromObject(tradeResult);
+            payService.notify(result.getString("out_trade_no"), result.getString("total_fee"), result.getString("transaction_id"), result.getString("time_end"));
+            return "notify_success";
+        } else {
+            logger.info("平安订单回调接口openId不匹配");
+        }
+        logger.info("平安订单回调接口>>>>>>pingan notify end");
+        return "notify_fail";
+    }
+
+}

+ 149 - 0
kmall-api/src/main/java/com/kmall/api/api/pingan/mpconfig/ApiPinganMpconfigController.java

@@ -0,0 +1,149 @@
+package com.kmall.api.api.pingan.mpconfig;
+
+import com.kmall.api.annotation.LoginUser;
+import com.kmall.api.entity.UserVo;
+import com.kmall.api.service.pay.wxpay.WxPayPropertiesBuilder;
+import com.kmall.api.util.ApiBaseAction;
+import com.kmall.common.utils.pingan.properties.PinganPayPropertiesBuilder;
+import com.kmall.common.utils.pingan.utils.InterfaceParams;
+import com.kmall.common.utils.pingan.utils.TLinx2Util;
+import com.kmall.common.utils.pingan.utils.TLinxAESCoder;
+import com.kmall.common.utils.pingan.utils.TLinxPluginUtil;
+import net.sf.json.JSONObject;
+import org.apache.commons.lang.RandomStringUtils;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Date;
+import java.util.TreeMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+@RestController
+@RequestMapping("api/pay/pingan/mpconfig")
+public class ApiPinganMpconfigController extends ApiBaseAction {
+
+    @RequestMapping("index")
+    public Object index(@LoginUser UserVo loginUser) {
+        return toResponsSuccess("");
+    }
+
+    /**
+     * Unicode转 汉字字符串
+     * @param str
+     * @return
+     */
+    private static String unicodeToString(String str) {
+        Pattern pattern = Pattern.compile("(\\\\u(\\p{XDigit}{4}))");
+        Matcher matcher = pattern.matcher(str);
+        char ch;
+        while (matcher.find()) {
+            String group = matcher.group(2);
+            ch = (char) Integer.parseInt(group, 16);
+            String group1 = matcher.group(1);
+            str = str.replace(group1, ch + "");
+        }
+        return str;
+    }
+
+    /**
+     * 平安商户支付配置
+     * @return
+     */
+    @GetMapping("add")
+    public Object add() {
+        String timestamp = new Date().getTime() / 1000 + "";    // 时间
+
+        try {
+            // 固定参数
+            TreeMap<String, String> postmap = new TreeMap<String, String>();    // 请求参数的map
+
+            postmap.put("open_id", PinganPayPropertiesBuilder.instance().getPayOpenId());
+            postmap.put("timestamp", timestamp);
+
+            TreeMap<String, String> datamap = new TreeMap<>();
+            datamap.put("pmt_tag", "WeixinOL");
+            datamap.put("sub_appid", WxPayPropertiesBuilder.instance().getAppId());
+
+            //数据加密,加签
+            TLinx2Util.handleEncrypt(datamap, postmap);
+            TLinx2Util.handleSign(postmap);
+
+            //请求
+            String rspStr = TLinx2Util.handlePost(postmap, InterfaceParams.MPCONFIGADD);
+            System.out.println("返回字符串=" + rspStr);
+
+            JSONObject respObject = JSONObject.fromObject(rspStr);
+
+            Object dataStr = respObject.get("data");
+            System.out.println("返回data字符串="+dataStr);
+
+            if (!rspStr.isEmpty() || (dataStr != null)) {
+                if (TLinx2Util.verifySign(respObject)) {    // 验签成功
+                    String respData = TLinxAESCoder.decrypt(dataStr.toString(), PinganPayPropertiesBuilder.instance().getPayOpenKey());
+                    System.out.println("==================响应data内容:" + respData);
+                    return toResponsSuccess("商户支付配置查询成功");
+                } else {
+                    System.out.println("=====验签失败=====");
+                }
+            } else {
+                System.out.println("=====没有返回data数据=====");
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        return toResponsFail("商户支付配置失败");
+    }
+
+    /**
+     * 平安商户支付配置
+     * @return
+     */
+    @GetMapping("query")
+    public Object query() {
+        String timestamp = new Date().getTime() / 1000 + "";    // 时间
+
+        try {
+            // 固定参数
+            TreeMap<String, String> postmap = new TreeMap<String, String>();    // 请求参数的map
+
+            postmap.put("open_id", PinganPayPropertiesBuilder.instance().getPayOpenId());
+            postmap.put("timestamp", timestamp);
+
+            TreeMap<String, String> datamap = new TreeMap<>();
+            datamap.put("pmt_tag", "WeixinOL");
+
+            //数据加密,加签
+            TLinx2Util.handleEncrypt(datamap, postmap);
+            TLinx2Util.handleSign(postmap);
+
+            //请求
+            String rspStr = TLinx2Util.handlePost(postmap, InterfaceParams.MPCONFIGQUERY);
+            System.out.println("返回字符串=" + rspStr);
+
+            JSONObject respObject = JSONObject.fromObject(rspStr);
+
+            Object dataStr = respObject.get("data");
+            System.out.println("返回data字符串="+dataStr);
+
+            if (!rspStr.isEmpty() || (dataStr != null)) {
+                if (TLinx2Util.verifySign(respObject)) {    // 验签成功
+                    String respData = TLinxAESCoder.decrypt(dataStr.toString(), PinganPayPropertiesBuilder.instance().getPayOpenKey());
+                    System.out.println("==================响应data内容:" + respData);
+                    return toResponsSuccess("商户支付配置查询成功");
+                } else {
+                    System.out.println("=====验签失败=====");
+                }
+            } else {
+                System.out.println("=====没有返回data数据=====");
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        return toResponsFail("商户支付配置查询失败");
+    }
+
+}

+ 2 - 0
kmall-api/src/main/java/com/kmall/api/dao/ApiOrderMapper.java

@@ -44,4 +44,6 @@ public interface ApiOrderMapper extends BaseDao<OrderVo> {
     int updateOrderByMerchOrderSn(OrderVo orderVo);
 
     List<OrderVo> queryOrderByMerchOrderSnAndRefundStatus(@Param("merchOrderSn")String merchOrderSn);
+
+    int updateBatch(List<OrderVo> list);
 }

+ 18 - 0
kmall-api/src/main/java/com/kmall/api/dao/ApiPinganPayOrderMapper.java

@@ -0,0 +1,18 @@
+package com.kmall.api.dao;
+
+import com.kmall.common.dao.BaseDao;
+import com.kmall.common.utils.pingan.dto.PinganPayOrderDto;
+import org.springframework.stereotype.Component;
+
+/**
+ * Dao
+ *
+ * @author emato
+ * @email admin@qhdswl.com
+ * @date 2018-12-06 15:29:43
+ */
+@Component
+public interface ApiPinganPayOrderMapper extends BaseDao<PinganPayOrderDto> {
+
+    int updateByOutNo(PinganPayOrderDto pinganPayOrder);
+}

+ 17 - 0
kmall-api/src/main/java/com/kmall/api/dao/ApiPinganResponseMapper.java

@@ -0,0 +1,17 @@
+package com.kmall.api.dao;
+
+import com.kmall.common.dao.BaseDao;
+import com.kmall.common.utils.pingan.dto.PinganResponseDto;
+import org.springframework.stereotype.Component;
+
+/**
+ * Dao
+ *
+ * @author emato
+ * @email admin@qhdswl.com
+ * @date 2018-12-06 15:29:43
+ */
+@Component
+public interface ApiPinganResponseMapper extends BaseDao<PinganResponseDto> {
+
+}

+ 9 - 0
kmall-api/src/main/java/com/kmall/api/service/ApiOrderService.java

@@ -119,10 +119,19 @@ public class ApiOrderService {
         order.setModTime(new Date());
         apiOrderMapper.update(order);
     }
+
     public void updateOrderByMerchOrderSn(OrderVo order) {
         apiOrderMapper.updateOrderByMerchOrderSn(order);
     }
 
+    public void updateBatch(List<OrderVo> list) {
+        for (OrderVo order : list) {
+            order.setIsScan("0");
+            order.setModTime(new Date());
+        }
+        apiOrderMapper.updateBatch(list);
+    }
+
 
     public void delete(Integer id) {
         apiOrderMapper.delete(id);

+ 54 - 0
kmall-api/src/main/java/com/kmall/api/service/pingan/ApiPinganPayOrderService.java

@@ -0,0 +1,54 @@
+package com.kmall.api.service.pingan;
+
+import com.kmall.api.dao.ApiPinganPayOrderMapper;
+import com.kmall.common.utils.pingan.dto.PinganPayOrderDto;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Service实现类
+ *
+ * @author emato
+ * @email admin@qhdswl.com
+ * @date 2018-12-06 15:29:43
+ */
+@Service
+public class ApiPinganPayOrderService{
+    @Autowired
+    private ApiPinganPayOrderMapper apiPinganPayOrderMapper;
+
+    public PinganPayOrderDto queryObject(Integer id) {
+        return apiPinganPayOrderMapper.queryObject(id);
+    }
+
+    public List<PinganPayOrderDto> queryList(Map<String, Object> map) {
+        return apiPinganPayOrderMapper.queryList(map);
+    }
+
+    public int queryTotal(Map<String, Object> map) {
+        return apiPinganPayOrderMapper.queryTotal(map);
+    }
+
+    public int save(PinganPayOrderDto pinganPayOrder) {
+        return apiPinganPayOrderMapper.save(pinganPayOrder);
+    }
+
+    public int update(PinganPayOrderDto pinganPayOrder) {
+        return apiPinganPayOrderMapper.update(pinganPayOrder);
+    }
+
+    public int delete(Integer id) {
+        return apiPinganPayOrderMapper.delete(id);
+    }
+
+    public int deleteBatch(Integer[]ids) {
+        return apiPinganPayOrderMapper.deleteBatch(ids);
+    }
+
+    public int updateByOutNo(PinganPayOrderDto pinganPayOrder) {
+        return apiPinganPayOrderMapper.updateByOutNo(pinganPayOrder);
+    }
+}

+ 52 - 0
kmall-api/src/main/java/com/kmall/api/service/pingan/ApiPinganResponseService.java

@@ -0,0 +1,52 @@
+package com.kmall.api.service.pingan;
+
+import com.kmall.api.dao.ApiPinganResponseMapper;
+import com.kmall.common.utils.pingan.dto.PinganResponseDto;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.Map;
+
+
+/**
+ * Service实现类
+ *
+ * @author emato
+ * @email admin@qhdswl.com
+ * @date 2018-12-06 15:29:43
+ */
+@Service
+public class ApiPinganResponseService {
+
+    @Autowired
+    private ApiPinganResponseMapper apiPinganResponseMapper;
+
+    public PinganResponseDto queryObject(Integer id) {
+        return apiPinganResponseMapper.queryObject(id);
+    }
+
+    public List<PinganResponseDto> queryList(Map<String, Object> map) {
+        return apiPinganResponseMapper.queryList(map);
+    }
+
+    public int queryTotal(Map<String, Object> map) {
+        return apiPinganResponseMapper.queryTotal(map);
+    }
+
+    public int save(PinganResponseDto pinganResponse) {
+        return apiPinganResponseMapper.save(pinganResponse);
+    }
+
+    public int update(PinganResponseDto pinganResponse) {
+        return apiPinganResponseMapper.update(pinganResponse);
+    }
+
+    public int delete(Integer id) {
+        return apiPinganResponseMapper.delete(id);
+    }
+
+    public int deleteBatch(Integer[]ids) {
+        return apiPinganResponseMapper.deleteBatch(ids);
+    }
+}

+ 149 - 60
kmall-api/src/main/resources/mybatis/mapper/ApiOrderMapper.xml

@@ -320,13 +320,13 @@
 			#{coupon_name},
 			#{comment_count},
         <if test="merchSn != null" >
-            #{merchSn,jdbcType=VARCHAR},
+            #{merchSn},
         </if>
         <if test="merchOrderSn != null" >
-            #{merchOrderSn,jdbcType=VARCHAR},
+            #{merchOrderSn},
         </if>
         <if test="isScan != null" >
-            #{isScan,jdbcType=VARCHAR},
+            #{isScan},
         </if>
         <if test="isMergePay != null" >
             #{isMergePay},
@@ -335,31 +335,31 @@
             #{orderBizType,jdbcType=CHAR},
         </if>
         <if test="payTransactionId != null" >
-            #{payTransactionId,jdbcType=VARCHAR},
+            #{payTransactionId},
         </if>
         <if test="payMobile != null" >
-            #{payMobile,jdbcType=VARCHAR},
+            #{payMobile},
         </if>
         <if test="buyerPayCheck != null" >
-            #{buyerPayCheck,jdbcType=VARCHAR},
+            #{buyerPayCheck},
         </if>
         <if test="isOnfflineOrder != null" >
-            #{isOnfflineOrder,jdbcType=VARCHAR},
+            #{isOnfflineOrder},
         </if>
         <if test="payFlag != null" >
-            #{payFlag,jdbcType=VARCHAR},
+            #{payFlag},
         </if>
         <if test="createrSn != null" >
-            #{createrSn,jdbcType=VARCHAR},
+            #{createrSn},
         </if>
         <if test="createTime != null" >
-            #{createTime,jdbcType=TIMESTAMP},
+            #{createTime},
         </if>
         <if test="moderSn != null" >
-            #{moderSn,jdbcType=VARCHAR},
+            #{moderSn},
         </if>
         <if test="modTime != null" >
-            #{modTime,jdbcType=TIMESTAMP}
+            #{modTime}
         </if>
 		)
 	</insert>
@@ -476,19 +476,20 @@
             #{orderInfo.predict_time},
             #{orderInfo.coupon_name},
             #{orderInfo.comment_count},
-            #{orderInfo.merchSn,jdbcType=VARCHAR},
-            #{orderInfo.merchOrderSn,jdbcType=VARCHAR},
-            #{orderInfo.isScan,jdbcType=VARCHAR},
+            #{orderInfo.merchSn},
+            #{orderInfo.merchOrderSn},
+            #{orderInfo.isScan},
             #{orderInfo.isMergePay},
             #{orderInfo.orderBizType,jdbcType=CHAR},
             #{orderInfo.isOnfflineOrder},
-            #{orderInfo.payTransactionId,jdbcType=VARCHAR},
-            #{orderInfo.payMobile,jdbcType=VARCHAR},
-            #{orderInfo.createTime,jdbcType=TIMESTAMP},
-            #{orderInfo.modTime,jdbcType=TIMESTAMP}
+            #{orderInfo.payTransactionId},
+            #{orderInfo.payMobile},
+            #{orderInfo.createTime},
+            #{orderInfo.modTime}
             )
         </foreach>
     </insert>
+
     <update id="update" parameterType="com.kmall.api.entity.OrderVo">
         update mall_order
         <set>
@@ -538,50 +539,86 @@
             <if test="predict_time != null">`predict_time` = #{predict_time},</if>
             <if test="coupon_name != null">`coupon_name` = #{coupon_name},</if>
             <if test="comment_count != null">`comment_count` = #{comment_count},</if>
-
-            <if test="merchSn != null" >
-                merch_sn = #{merchSn,jdbcType=VARCHAR},
-            </if>
-            <if test="merchOrderSn != null" >
-                merch_order_sn = #{merchOrderSn,jdbcType=VARCHAR},
-            </if>
-            <if test="isScan != null" >
-                is_scan = #{isScan,jdbcType=VARCHAR},
-            </if>
-            <if test="isMergePay != null" >
-                is_merge_pay = #{isMergePay},
-            </if>
-            <if test="orderBizType != null" >
-                order_biz_type = #{orderBizType,jdbcType=CHAR},
-            </if>
-            <if test="payTransactionId != null" >
-                pay_transaction_id = #{payTransactionId,jdbcType=VARCHAR},
-            </if>
-            <if test="payMobile != null" >
-                pay_mobile = #{payMobile,jdbcType=VARCHAR},
-            </if>
-            <if test="buyerPayCheck != null" >
-                buyer_pay_check = #{buyerPayCheck,jdbcType=VARCHAR},
-            </if>
-            <if test="payFlag != null" >
-                pay_flag = #{payFlag,jdbcType=VARCHAR},
-            </if>
-            <if test="createrSn != null" >
-                creater_sn = #{createrSn,jdbcType=VARCHAR},
-            </if>
-            <if test="createTime != null" >
-                create_time = #{createTime,jdbcType=TIMESTAMP},
-            </if>
-            <if test="moderSn != null" >
-                moder_sn = #{moderSn,jdbcType=VARCHAR},
-            </if>
-            <if test="modTime != null" >
-                mod_time = #{modTime,jdbcType=TIMESTAMP},
-            </if>
+            <if test="merchSn != null" >merch_sn = #{merchSn},</if>
+            <if test="merchOrderSn != null" >merch_order_sn = #{merchOrderSn},</if>
+            <if test="isScan != null" >is_scan = #{isScan},</if>
+            <if test="isMergePay != null" >is_merge_pay = #{isMergePay},</if>
+            <if test="orderBizType != null" >order_biz_type = #{orderBizType,jdbcType=CHAR},</if>
+            <if test="payTransactionId != null" >pay_transaction_id = #{payTransactionId},</if>
+            <if test="payMobile != null" >pay_mobile = #{payMobile},</if>
+            <if test="buyerPayCheck != null" >buyer_pay_check = #{buyerPayCheck},</if>
+            <if test="payFlag != null" >pay_flag = #{payFlag},</if>
+            <if test="createrSn != null" >creater_sn = #{createrSn},</if>
+            <if test="createTime != null" >create_time = #{createTime},</if>
+            <if test="moderSn != null" >moder_sn = #{moderSn},</if>
+            <if test="modTime != null" >mod_time = #{modTime},</if>
         </set>
         where id = #{id}
     </update>
 
+    <update id="updateBatch" parameterType="java.util.List">
+        <foreach collection="list" item="oderInfo" index="index" open="" close="" separator=";">
+            update mall_order
+            <set>
+                <if test="oderInfo.order_sn != null">`order_sn` = #{oderInfo.order_sn},</if>
+                <if test="oderInfo.user_id != null">`user_id` = #{oderInfo.user_id},</if>
+                <if test="oderInfo.order_status != null">`order_status` = #{oderInfo.order_status},</if>
+                <if test="oderInfo.shipping_status != null">`shipping_status` = #{oderInfo.shipping_status},</if>
+                <if test="oderInfo.shipping_code != null">`shipping_code` = #{oderInfo.shipping_code},</if>
+                <if test="oderInfo.pay_status != null">`pay_status` = #{oderInfo.pay_status},</if>
+                <if test="oderInfo.consignee != null">`consignee` = #{oderInfo.consignee},</if>
+                <if test="oderInfo.country != null">`country` = #{oderInfo.country},</if>
+                <if test="oderInfo.province != null">`province` = #{oderInfo.province},</if>
+                <if test="oderInfo.city != null">`city` = #{oderInfo.city},</if>
+                <if test="oderInfo.district != null">`district` = #{oderInfo.district},</if>
+                <if test="oderInfo.address != null">`address` = #{oderInfo.address},</if>
+                <if test="oderInfo.address_id != null">`address_id` = #{oderInfo.address_id},</if>
+                <if test="oderInfo.mobile != null">`mobile` = #{oderInfo.mobile},</if>
+                <if test="oderInfo.postscript != null">`postscript` = #{oderInfo.postscript},</if>
+                <if test="oderInfo.shipping_id != null">`shipping_id` = #{oderInfo.shipping_id},</if>
+                <if test="oderInfo.shipping_name != null">`shipping_name` = #{oderInfo.shipping_name},</if>
+                <if test="oderInfo.shipping_fee != null">`shipping_fee` = #{oderInfo.shipping_fee},</if>
+                <if test="oderInfo.shipping_no != null">`shipping_no` = #{oderInfo.shipping_no},</if>
+                <if test="oderInfo.pay_id != null">`pay_id` = #{oderInfo.pay_id},</if>
+                <if test="oderInfo.pay_name != null">`pay_name` = #{oderInfo.pay_name},</if>
+                <if test="oderInfo.pay_time != null">`pay_time` = #{oderInfo.pay_time},</if>
+                <if test="oderInfo.actual_price != null">`actual_price` = #{oderInfo.actual_price},</if>
+                <if test="oderInfo.integral != null">`integral` = #{oderInfo.integral},</if>
+                <if test="oderInfo.integral_money != null">`integral_money` = #{oderInfo.integral_money},</if>
+                <if test="oderInfo.order_price != null">`order_price` = #{oderInfo.order_price},</if>
+                <if test="oderInfo.goods_price != null">`goods_price` = #{oderInfo.goods_price},</if>
+                <if test="oderInfo.confirm_time != null">`confirm_time` = #{oderInfo.confirm_time},</if>
+                <if test="oderInfo.freight_price != null">`freight_price` = #{oderInfo.freight_price},</if>
+                <if test="oderInfo.coupon_id != null">`coupon_id` = #{oderInfo.coupon_id},</if>
+                <if test="oderInfo.coupon_price != null">`coupon_price` = #{oderInfo.coupon_price},</if>
+                <if test="oderInfo.full_cut_price != null">`full_cut_price` = #{oderInfo.full_cut_price},</if>
+                <if test="oderInfo.order_type != null">`order_type` = #{oderInfo.order_type},</if>
+                <if test="oderInfo.activity_id != null">`activity_id` = #{oderInfo.activity_id},</if>
+                <if test="oderInfo.store_id != null">`store_id` = #{oderInfo.store_id},</if>
+                <if test="oderInfo.shipping_mobile != null">`shipping_mobile` = #{oderInfo.shipping_mobile},</if>
+                <if test="oderInfo.delivery_date != null">`delivery_date` = #{oderInfo.delivery_date},</if>
+                <if test="oderInfo.delivery_remark != null">`delivery_remark` = #{oderInfo.delivery_remark},</if>
+                <if test="oderInfo.predict_time != null">`predict_time` = #{oderInfo.predict_time},</if>
+                <if test="oderInfo.coupon_name != null">`coupon_name` = #{oderInfo.coupon_name},</if>
+                <if test="oderInfo.comment_count != null">`comment_count` = #{oderInfo.comment_count},</if>
+                <if test="oderInfo.merchSn != null" >merch_sn = #{oderInfo.merchSn},</if>
+                <if test="oderInfo.merchOrderSn != null" >merch_order_sn = #{oderInfo.merchOrderSn},</if>
+                <if test="oderInfo.isScan != null" >is_scan = #{oderInfo.isScan},</if>
+                <if test="oderInfo.isMergePay != null" >is_merge_pay = #{oderInfo.isMergePay},</if>
+                <if test="oderInfo.orderBizType != null" >order_biz_type = #{oderInfo.orderBizType},</if>
+                <if test="oderInfo.payTransactionId != null" >pay_transaction_id = #{oderInfo.payTransactionId},</if>
+                <if test="oderInfo.payMobile != null" >pay_mobile = #{oderInfo.payMobile},</if>
+                <if test="oderInfo.buyerPayCheck != null" >buyer_pay_check = #{oderInfo.buyerPayCheck},</if>
+                <if test="oderInfo.payFlag != null" >pay_flag = #{oderInfo.payFlag},</if>
+                <if test="oderInfo.createrSn != null" >creater_sn = #{oderInfo.createrSn},</if>
+                <if test="oderInfo.createTime != null" >create_time = #{oderInfo.createTime},</if>
+                <if test="oderInfo.moderSn != null" >moder_sn = #{oderInfo.moderSn},</if>
+                <if test="oderInfo.modTime != null" >mod_time = #{oderInfo.modTime},</if>
+            </set>
+            where id = #{oderInfo.id}
+        </foreach>
+    </update>
+
     <update id="riderOrderUpdate" parameterType="com.kmall.api.entity.OrderVo">
         update mall_order
         <set>
@@ -600,7 +637,59 @@
     <update id="updateOrderByMerchOrderSn" parameterType="com.kmall.api.entity.OrderVo">
         update mall_order
         <set>
-            `is_merge_pay` = #{isMergePay}
+            <if test="order_sn != null">`order_sn` = #{order_sn},</if>
+            <if test="user_id != null">`user_id` = #{user_id},</if>
+            <if test="order_status != null">`order_status` = #{order_status},</if>
+            <if test="shipping_status != null">`shipping_status` = #{shipping_status},</if>
+            <if test="shipping_code != null">`shipping_code` = #{shipping_code},</if>
+            <if test="pay_status != null">`pay_status` = #{pay_status},</if>
+            <if test="consignee != null">`consignee` = #{consignee},</if>
+            <if test="country != null">`country` = #{country},</if>
+            <if test="province != null">`province` = #{province},</if>
+            <if test="city != null">`city` = #{city},</if>
+            <if test="district != null">`district` = #{district},</if>
+            <if test="address != null">`address` = #{address},</if>
+            <if test="address_id != null">`address_id` = #{address_id},</if>
+            <if test="mobile != null">`mobile` = #{mobile},</if>
+            <if test="postscript != null">`postscript` = #{postscript},</if>
+            <if test="shipping_id != null">`shipping_id` = #{shipping_id},</if>
+            <if test="shipping_name != null">`shipping_name` = #{shipping_name},</if>
+            <if test="shipping_fee != null">`shipping_fee` = #{shipping_fee},</if>
+            <if test="shipping_no != null">`shipping_no` = #{shipping_no},</if>
+            <if test="pay_id != null">`pay_id` = #{pay_id},</if>
+            <if test="pay_name != null">`pay_name` = #{pay_name},</if>
+            <if test="pay_time != null">`pay_time` = #{pay_time},</if>
+            <if test="actual_price != null">`actual_price` = #{actual_price},</if>
+            <if test="integral != null">`integral` = #{integral},</if>
+            <if test="integral_money != null">`integral_money` = #{integral_money},</if>
+            <if test="order_price != null">`order_price` = #{order_price},</if>
+            <if test="goods_price != null">`goods_price` = #{goods_price},</if>
+            <if test="confirm_time != null">`confirm_time` = #{confirm_time},</if>
+            <if test="freight_price != null">`freight_price` = #{freight_price},</if>
+            <if test="coupon_id != null">`coupon_id` = #{coupon_id},</if>
+            <if test="coupon_price != null">`coupon_price` = #{coupon_price},</if>
+            <if test="full_cut_price != null">`full_cut_price` = #{full_cut_price},</if>
+            <if test="order_type != null">`order_type` = #{order_type},</if>
+            <if test="activity_id != null">`activity_id` = #{activity_id},</if>
+            <if test="store_id != null">`store_id` = #{store_id},</if>
+            <if test="shipping_mobile != null">`shipping_mobile` = #{shipping_mobile},</if>
+            <if test="delivery_date != null">`delivery_date` = #{delivery_date},</if>
+            <if test="delivery_remark != null">`delivery_remark` = #{delivery_remark},</if>
+            <if test="predict_time != null">`predict_time` = #{predict_time},</if>
+            <if test="coupon_name != null">`coupon_name` = #{coupon_name},</if>
+            <if test="comment_count != null">`comment_count` = #{comment_count},</if>
+            <if test="merchSn != null" >merch_sn = #{merchSn},</if>
+            <if test="isScan != null" >is_scan = #{isScan},</if>
+            <if test="isMergePay != null" >is_merge_pay = #{isMergePay},</if>
+            <if test="orderBizType != null" >order_biz_type = #{orderBizType,jdbcType=CHAR},</if>
+            <if test="payTransactionId != null" >pay_transaction_id = #{payTransactionId},</if>
+            <if test="payMobile != null" >pay_mobile = #{payMobile},</if>
+            <if test="buyerPayCheck != null" >buyer_pay_check = #{buyerPayCheck},</if>
+            <if test="payFlag != null" >pay_flag = #{payFlag},</if>
+            <if test="createrSn != null" >creater_sn = #{createrSn},</if>
+            <if test="createTime != null" >create_time = #{createTime},</if>
+            <if test="moderSn != null" >moder_sn = #{moderSn},</if>
+            <if test="modTime != null" >mod_time = #{modTime},</if>
         </set>
         where merch_order_sn = #{merchOrderSn}
     </update>

+ 315 - 0
kmall-api/src/main/resources/mybatis/mapper/pingan/ApiPinganPayOrderMapper.xml

@@ -0,0 +1,315 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+
+<mapper namespace="com.kmall.api.dao.ApiPinganPayOrderMapper">
+
+    <resultMap type="com.kmall.common.utils.pingan.dto.PinganPayOrderDto" id="pinganPayOrderMap">
+        <result property="id" column="id"/>
+        <result property="outNo" column="out_no"/>
+        <result property="pmtName" column="pmt_name"/>
+        <result property="pmtTag" column="pmt_tag"/>
+        <result property="ordMctId" column="ord_mct_id"/>
+        <result property="ordShopId" column="ord_shop_id"/>
+        <result property="ordCurrency" column="ord_currency"/>
+        <result property="currencySign" column="currency_sign"/>
+        <result property="ordNo" column="ord_no"/>
+        <result property="ordType" column="ord_type"/>
+        <result property="originalAmount" column="original_amount"/>
+        <result property="discountAmount" column="discount_amount"/>
+        <result property="ignoreAmount" column="ignore_amount"/>
+        <result property="tradeAccount" column="trade_account"/>
+        <result property="tradeNo" column="trade_no"/>
+        <result property="tradeAmount" column="trade_amount"/>
+        <result property="tradeQrcode" column="trade_qrcode"/>
+        <result property="amount" column="amount"/>
+        <result property="tradeTime" column="trade_time"/>
+        <result property="tradePayTime" column="trade_pay_time"/>
+        <result property="payTime" column="pay_time"/>
+        <result property="status" column="status"/>
+        <result property="tradeResult" column="trade_result"/>
+        <result property="jsapiPayUrl" column="jsapi_pay_url"/>
+        <result property="randStr" column="rand_str"/>
+        <result property="appid" column="appId"/>
+        <result property="noncestr" column="nonceStr"/>
+        <result property="signtype" column="signType"/>
+        <result property="prepayId" column="prepay_id"/>
+        <result property="paysign" column="paySign"/>
+        <result property="createrSn" column="creater_sn"/>
+        <result property="createTime" column="create_time"/>
+        <result property="moderSn" column="moder_sn"/>
+        <result property="modTime" column="mod_time"/>
+        <result property="tstm" column="tstm"/>
+    </resultMap>
+
+	<select id="queryObject" resultType="com.kmall.common.utils.pingan.dto.PinganPayOrderDto">
+		select
+			`id`,
+			`out_no`,
+			`pmt_name`,
+			`pmt_tag`,
+			`ord_mct_id`,
+			`ord_shop_id`,
+			`ord_currency`,
+			`currency_sign`,
+			`ord_no`,
+			`ord_type`,
+			`original_amount`,
+			`discount_amount`,
+			`ignore_amount`,
+			`trade_account`,
+			`trade_no`,
+			`trade_amount`,
+			`trade_qrcode`,
+			`amount`,
+			`trade_time`,
+			`trade_pay_time`,
+			`pay_time`,
+			`status`,
+			`trade_result`,
+			`jsapi_pay_url`,
+			`rand_str`,
+			`appId`,
+			`nonceStr`,
+			`signType`,
+			`prepay_id`,
+			`paySign`,
+			`creater_sn`,
+			`create_time`,
+			`moder_sn`,
+			`mod_time`,
+			`tstm`
+		from pingan_pay_order
+		where id = #{id}
+	</select>
+
+	<select id="queryList" resultType="com.kmall.common.utils.pingan.dto.PinganPayOrderDto">
+		select
+    		`id`,
+    		`out_no`,
+    		`pmt_name`,
+    		`pmt_tag`,
+    		`ord_mct_id`,
+    		`ord_shop_id`,
+			`ord_currency`,
+			`currency_sign`,
+    		`ord_no`,
+    		`ord_type`,
+    		`original_amount`,
+    		`discount_amount`,
+    		`ignore_amount`,
+    		`trade_account`,
+    		`trade_no`,
+    		`trade_amount`,
+    		`trade_qrcode`,
+    		`amount`,
+			`trade_time`,
+    		`trade_pay_time`,
+    		`pay_time`,
+    		`status`,
+    		`trade_result`,
+    		`jsapi_pay_url`,
+    		`rand_str`,
+    		`appId`,
+    		`nonceStr`,
+    		`signType`,
+    		`prepay_id`,
+    		`paySign`,
+    		`creater_sn`,
+    		`create_time`,
+    		`moder_sn`,
+    		`mod_time`,
+    		`tstm`
+		from pingan_pay_order
+		WHERE 1=1
+		<if test="name != null and name.trim() != ''">
+			AND name LIKE concat('%',#{name},'%')
+		</if>
+        <choose>
+            <when test="sidx != null and sidx.trim() != ''">
+                order by ${sidx} ${order}
+            </when>
+			<otherwise>
+                order by id desc
+			</otherwise>
+        </choose>
+		<if test="offset != null and limit != null">
+			limit #{offset}, #{limit}
+		</if>
+	</select>
+	
+ 	<select id="queryTotal" resultType="int">
+		select count(*) from pingan_pay_order
+		WHERE 1=1
+        <if test="name != null and name.trim() != ''">
+            AND name LIKE concat('%',#{name},'%')
+        </if>
+	</select>
+	 
+	<insert id="save" parameterType="com.kmall.common.utils.pingan.dto.PinganPayOrderDto">
+		insert into pingan_pay_order(
+			`id`,
+			`out_no`,
+			`pmt_name`,
+			`pmt_tag`,
+			`ord_mct_id`,
+			`ord_shop_id`,
+			`ord_currency`,
+			`currency_sign`,
+			`ord_no`,
+			`ord_type`,
+			`original_amount`,
+			`discount_amount`,
+			`ignore_amount`,
+			`trade_account`,
+			`trade_no`,
+			`trade_amount`,
+			`trade_qrcode`,
+			`amount`,
+			`trade_time`,
+			`trade_pay_time`,
+			`pay_time`,
+			`status`,
+			`trade_result`,
+			`jsapi_pay_url`,
+			`rand_str`,
+			`appId`,
+			`nonceStr`,
+			`signType`,
+			`prepay_id`,
+			`paySign`,
+			`creater_sn`,
+			`create_time`,
+			`moder_sn`,
+			`mod_time`,
+			`tstm`)
+		values(
+			#{id},
+			#{outNo},
+			#{pmtName},
+			#{pmtTag},
+			#{ordMctId},
+			#{ordShopId},
+			#{ordCurrency},
+			#{currencySign},
+			#{ordNo},
+			#{ordType},
+			#{originalAmount},
+			#{discountAmount},
+			#{ignoreAmount},
+			#{tradeAccount},
+			#{tradeNo},
+			#{tradeAmount},
+			#{tradeQrcode},
+			#{amount},
+			#{tradeTime},
+			#{tradePayTime},
+			#{payTime},
+			#{status},
+			#{tradeResult},
+			#{jsapiPayUrl},
+			#{randStr},
+			#{appid},
+			#{noncestr},
+			#{signtype},
+			#{prepayId},
+			#{paysign},
+			#{createrSn},
+			#{createTime},
+			#{moderSn},
+			#{modTime},
+			#{tstm})
+	</insert>
+
+	<update id="update" parameterType="com.kmall.common.utils.pingan.dto.PinganPayOrderDto">
+		update pingan_pay_order 
+		<set>
+			<if test="outNo != null">`out_no` = #{outNo}, </if>
+			<if test="pmtName != null">`pmt_name` = #{pmtName}, </if>
+			<if test="pmtTag != null">`pmt_tag` = #{pmtTag}, </if>
+			<if test="ordMctId != null">`ord_mct_id` = #{ordMctId}, </if>
+			<if test="ordShopId != null">`ord_currency` = #{ordShopId}, </if>
+			<if test="ordCurrency != null">`ord_shop_id` = #{ordCurrency}, </if>
+			<if test="currencySign != null">`currency_sign` = #{currencySign}, </if>
+			<if test="ordNo != null">`ord_no` = #{ordNo}, </if>
+			<if test="ordType != null">`ord_type` = #{ordType}, </if>
+			<if test="originalAmount != null">`original_amount` = #{originalAmount}, </if>
+			<if test="discountAmount != null">`discount_amount` = #{discountAmount}, </if>
+			<if test="ignoreAmount != null">`ignore_amount` = #{ignoreAmount}, </if>
+			<if test="tradeAccount != null">`trade_account` = #{tradeAccount}, </if>
+			<if test="tradeNo != null">`trade_no` = #{tradeNo}, </if>
+			<if test="tradeAmount != null">`trade_amount` = #{tradeAmount}, </if>
+			<if test="tradeQrcode != null">`trade_qrcode` = #{tradeQrcode}, </if>
+			<if test="amount != null">`amount` = #{amount}, </if>
+			<if test="tradeTime != null">`trade_time` = #{tradeTime}, </if>
+			<if test="tradePayTime != null">`trade_pay_time` = #{tradePayTime}, </if>
+			<if test="payTime != null">`pay_time` = #{payTime}, </if>
+			<if test="status != null">`status` = #{status}, </if>
+			<if test="tradeResult != null">`trade_result` = #{tradeResult}, </if>
+			<if test="jsapiPayUrl != null">`jsapi_pay_url` = #{jsapiPayUrl}, </if>
+			<if test="randStr != null">`rand_str` = #{randStr}, </if>
+			<if test="appid != null">`appId` = #{appid}, </if>
+			<if test="noncestr != null">`nonceStr` = #{noncestr}, </if>
+			<if test="signtype != null">`signType` = #{signtype}, </if>
+			<if test="prepayId != null">`prepay_id` = #{prepayId}, </if>
+			<if test="paysign != null">`paySign` = #{paysign}, </if>
+			<if test="createrSn != null">`creater_sn` = #{createrSn}, </if>
+			<if test="createTime != null">`create_time` = #{createTime}, </if>
+			<if test="moderSn != null">`moder_sn` = #{moderSn}, </if>
+			<if test="modTime != null">`mod_time` = #{modTime}, </if>
+			<if test="tstm != null">`tstm` = #{tstm}</if>
+		</set>
+		where id = #{id}
+	</update>
+
+	<update id="updateByOutNo" parameterType="com.kmall.common.utils.pingan.dto.PinganPayOrderDto">
+		update pingan_pay_order
+		<set>
+			<if test="pmtName != null">`pmt_name` = #{pmtName}, </if>
+			<if test="pmtTag != null">`pmt_tag` = #{pmtTag}, </if>
+			<if test="ordMctId != null">`ord_mct_id` = #{ordMctId}, </if>
+			<if test="ordShopId != null">`ord_currency` = #{ordShopId}, </if>
+			<if test="ordCurrency != null">`ord_shop_id` = #{ordCurrency}, </if>
+			<if test="currencySign != null">`currency_sign` = #{currencySign}, </if>
+			<if test="ordNo != null">`ord_no` = #{ordNo}, </if>
+			<if test="ordType != null">`ord_type` = #{ordType}, </if>
+			<if test="originalAmount != null">`original_amount` = #{originalAmount}, </if>
+			<if test="discountAmount != null">`discount_amount` = #{discountAmount}, </if>
+			<if test="ignoreAmount != null">`ignore_amount` = #{ignoreAmount}, </if>
+			<if test="tradeAccount != null">`trade_account` = #{tradeAccount}, </if>
+			<if test="tradeNo != null">`trade_no` = #{tradeNo}, </if>
+			<if test="tradeAmount != null">`trade_amount` = #{tradeAmount}, </if>
+			<if test="tradeQrcode != null">`trade_qrcode` = #{tradeQrcode}, </if>
+			<if test="amount != null">`amount` = #{amount}, </if>
+			<if test="tradeTime != null">`trade_time` = #{tradeTime}, </if>
+			<if test="tradePayTime != null">`trade_pay_time` = #{tradePayTime}, </if>
+			<if test="payTime != null">`pay_time` = #{payTime}, </if>
+			<if test="status != null">`status` = #{status}, </if>
+			<if test="tradeResult != null">`trade_result` = #{tradeResult}, </if>
+			<if test="jsapiPayUrl != null">`jsapi_pay_url` = #{jsapiPayUrl}, </if>
+			<if test="randStr != null">`rand_str` = #{randStr}, </if>
+			<if test="appid != null">`appId` = #{appid}, </if>
+			<if test="noncestr != null">`nonceStr` = #{noncestr}, </if>
+			<if test="signtype != null">`signType` = #{signtype}, </if>
+			<if test="prepayId != null">`prepay_id` = #{prepayId}, </if>
+			<if test="paysign != null">`paySign` = #{paysign}, </if>
+			<if test="createrSn != null">`creater_sn` = #{createrSn}, </if>
+			<if test="createTime != null">`create_time` = #{createTime}, </if>
+			<if test="moderSn != null">`moder_sn` = #{moderSn}, </if>
+			<if test="modTime != null">`mod_time` = #{modTime}, </if>
+			<if test="tstm != null">`tstm` = #{tstm}</if>
+		</set>
+		where `out_no` = #{outNo}
+	</update>
+	
+	<delete id="delete">
+		delete from pingan_pay_order where id = #{value}
+	</delete>
+	
+	<delete id="deleteBatch">
+		delete from pingan_pay_order where id in 
+		<foreach item="id" collection="array" open="(" separator="," close=")">
+			#{id}
+		</foreach>
+	</delete>
+
+</mapper>

+ 131 - 0
kmall-api/src/main/resources/mybatis/mapper/pingan/ApiPinganResponseMapper.xml

@@ -0,0 +1,131 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+
+<mapper namespace="com.kmall.api.dao.ApiPinganResponseMapper">
+
+    <resultMap type="com.kmall.common.utils.pingan.dto.PinganResponseDto" id="pinganResponseMap">
+        <result property="id" column="id"/>
+        <result property="outNo" column="out_no"/>
+        <result property="reqInterface" column="req_interface"/>
+        <result property="errcode" column="errcode"/>
+        <result property="msg" column="msg"/>
+        <result property="data" column="data"/>
+        <result property="sign" column="sign"/>
+        <result property="datajson" column="datajson"/>
+		<result property="timestamp" column="timestamp"/>
+        <result property="createTime" column="create_time"/>
+        <result property="tstm" column="tstm"/>
+    </resultMap>
+
+	<select id="queryObject" resultType="com.kmall.common.utils.pingan.dto.PinganResponseDto">
+		select
+			`id`,
+			`out_no`,
+			`req_interface`,
+			`errcode`,
+			`msg`,
+			`data`,
+			`sign`,
+			`datajson`,
+			`timestamp`,
+			`create_time`,
+			`tstm`
+		from pingan_response
+		where id = #{id}
+	</select>
+
+	<select id="queryList" resultType="com.kmall.common.utils.pingan.dto.PinganResponseDto">
+		select
+    		`id`,
+    		`out_no`,
+    		`req_interface`,
+    		`errcode`,
+    		`msg`,
+    		`data`,
+    		`sign`,
+    		`datajson`,
+			`timestamp`,
+    		`create_time`,
+    		`tstm`
+		from pingan_response
+		WHERE 1=1
+		<if test="name != null and name.trim() != ''">
+			AND name LIKE concat('%',#{name},'%')
+		</if>
+        <choose>
+            <when test="sidx != null and sidx.trim() != ''">
+                order by ${sidx} ${order}
+            </when>
+			<otherwise>
+                order by id desc
+			</otherwise>
+        </choose>
+		<if test="offset != null and limit != null">
+			limit #{offset}, #{limit}
+		</if>
+	</select>
+	
+ 	<select id="queryTotal" resultType="int">
+		select count(*) from pingan_response
+		WHERE 1=1
+        <if test="name != null and name.trim() != ''">
+            AND name LIKE concat('%',#{name},'%')
+        </if>
+	</select>
+	 
+	<insert id="save" parameterType="com.kmall.common.utils.pingan.dto.PinganResponseDto">
+		insert into pingan_response(
+			`id`,
+			`out_no`,
+			`req_interface`,
+			`errcode`,
+			`msg`,
+			`data`,
+			`sign`,
+			`datajson`,
+			`timestamp`,
+			`create_time`,
+			`tstm`)
+		values(
+			#{id},
+			#{outNo},
+			#{reqInterface},
+			#{errcode},
+			#{msg},
+			#{data},
+			#{sign},
+			#{datajson},
+			#{timestamp},
+			#{createTime},
+			#{tstm})
+	</insert>
+	 
+	<update id="update" parameterType="com.kmall.common.utils.pingan.dto.PinganResponseDto">
+		update pingan_response 
+		<set>
+			<if test="outNo != null">`out_no` = #{outNo}, </if>
+			<if test="reqInterface != null">`req_interface` = #{reqInterface}, </if>
+			<if test="errcode != null">`errcode` = #{errcode}, </if>
+			<if test="msg != null">`msg` = #{msg}, </if>
+			<if test="data != null">`data` = #{data}, </if>
+			<if test="sign != null">`sign` = #{sign}, </if>
+			<if test="datajson != null">`datajson` = #{datajson}, </if>
+			<if test="timestamp != null">`timestamp` = #{timestamp}, </if>
+			<if test="createTime != null">`create_time` = #{createTime}, </if>
+			<if test="tstm != null">`tstm` = #{tstm}</if>
+		</set>
+		where id = #{id}
+	</update>
+	
+	<delete id="delete">
+		delete from pingan_response where id = #{value}
+	</delete>
+	
+	<delete id="deleteBatch">
+		delete from pingan_response where id in 
+		<foreach item="id" collection="array" open="(" separator="," close=")">
+			#{id}
+		</foreach>
+	</delete>
+
+</mapper>

+ 49 - 12
kmall-common/src/main/java/com/kmall/common/constant/Dict.java

@@ -109,6 +109,7 @@ public class Dict {
             this.itemName = itemName;
         }
     }
+
     /**
      * 平安返回核验结果,0:未知,1:一致,2:不一致
      */
@@ -173,6 +174,7 @@ public class Dict {
             this.itemName = itemName;
         }
     }
+
     /**
      * 通知状态,0:待发送,1:发送中,2:成功,3:失败
      */
@@ -206,6 +208,7 @@ public class Dict {
             this.itemName = itemName;
         }
     }
+
     /**
      * 是否停止通知,0:否,1:是
      */
@@ -302,6 +305,7 @@ public class Dict {
             this.itemName = itemName;
         }
     }
+
     /**
      * 物流状态:0-暂无轨迹信息 2-在途中,3-签收,4-问题件
      */
@@ -348,7 +352,7 @@ public class Dict {
         item_201("201", "订单已付款"),
         item_300("300", "订单已发货"),
         item_301("301", "用户确认收货"),
-//        item_400("400", "维权申请中"),
+        //        item_400("400", "维权申请中"),
         item_401("401", "没有发货,退款"),
         item_402("402", "已收货,退款退货"),
         item_500("500", "订单已关闭"),
@@ -486,7 +490,7 @@ public class Dict {
     }
 
     /**
-     *  退款状态 1 申请中 2 退款成功 3 已拒绝  4 微信退款失败 5 微信退款处理中
+     * 退款状态 1 申请中 2 退款成功 3 已拒绝  4 微信退款失败 5 微信退款处理中
      */
     public enum RefundStatus {
         item_1("1", "申请中"),
@@ -521,7 +525,7 @@ public class Dict {
     }
 
     /**
-     *  商品分类级别 L1:一级分类 L2:二级分类
+     * 商品分类级别 L1:一级分类 L2:二级分类
      */
     public enum Level {
         item_L1("L1", "一级分类"),
@@ -553,7 +557,7 @@ public class Dict {
     }
 
     /**
-     *  是否合并支付 0:单笔支付 1:合并支付
+     * 是否合并支付 0:单笔支付 1:合并支付
      */
     public enum isMergePay {
         item_0("0", "单笔支付"),
@@ -585,7 +589,7 @@ public class Dict {
     }
 
     /**
-     *  是否线下订单:0:线上购买 1:线下购买
+     * 是否线下订单:0:线上购买 1:线下购买
      */
     public enum isOnfflineOrder {
         item_0("0", "线上购买"),
@@ -617,7 +621,7 @@ public class Dict {
     }
 
     /**
-     *  角色类型:1:操作员;2:店员;3:商户管理员
+     * 角色类型:1:操作员;2:店员;3:商户管理员
      */
     public enum roleType {
         item_1("1", "操作员"),
@@ -648,6 +652,7 @@ public class Dict {
             this.itemName = itemName;
         }
     }
+
     public enum isDelete {
         item_0("0", "未删除"),
         item_1("1", "已删除");
@@ -676,6 +681,7 @@ public class Dict {
             this.itemName = itemName;
         }
     }
+
     public enum isOnSale {
         item_0("0", "下架"),
         item_1("1", "上架");
@@ -707,12 +713,12 @@ public class Dict {
 
     /**
      * SUCCESS—支付成功
-     REFUND—转入退款
-     NOTPAY—未支付
-     CLOSED—已关闭
-     REVOKED—已撤销(刷卡支付)
-     USERPAYING--用户支付中
-     PAYERROR--支付失败(其他原因,如银行返回失败)
+     * REFUND—转入退款
+     * NOTPAY—未支付
+     * CLOSED—已关闭
+     * REVOKED—已撤销(刷卡支付)
+     * USERPAYING--用户支付中
+     * PAYERROR--支付失败(其他原因,如银行返回失败)
      */
     public enum tradeState {
         item_SUCCESS("SUCCESS", "支付成功"),
@@ -747,6 +753,7 @@ public class Dict {
             this.itemName = itemName;
         }
     }
+
     public enum pinganPayStatus {
         item_1("1", "交易成功"),
         item_2("2", "待支付"),
@@ -778,4 +785,34 @@ public class Dict {
         }
     }
 
+    public enum pinganRefundStatus {
+        item_1("1", "退款成功"),
+        item_2("2", "退款处理中"),
+        item_3("3", "退款异常"),
+        item_4("4", "退款关闭");
+
+        private String item;
+        private String itemName;
+
+        pinganRefundStatus(String item, String itemName) {
+            this.item = item;
+            this.itemName = itemName;
+        }
+
+        public String getItem() {
+            return item;
+        }
+
+        public void setItem(String item) {
+            this.item = item;
+        }
+
+        public String getItemName() {
+            return itemName;
+        }
+
+        public void setItemName(String itemName) {
+            this.itemName = itemName;
+        }
+    }
 }

+ 30 - 0
kmall-common/src/main/java/com/kmall/common/utils/JacksonUtil.java

@@ -0,0 +1,30 @@
+package com.kmall.common.utils;
+
+import java.io.IOException;
+import java.io.StringWriter;
+
+import com.fasterxml.jackson.core.JsonFactory;
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+/**
+ * bean转json格式或者json转bean格式, 项目中我们通常使用这个工具类进行json---java互相转化
+ */
+public class JacksonUtil {
+    private static ObjectMapper mapper = new ObjectMapper();
+
+    public static String bean2Json(Object obj) throws IOException {
+        StringWriter sw = new StringWriter();
+        JsonGenerator gen = new JsonFactory().createJsonGenerator(sw);
+        mapper.writeValue(gen, obj);
+        gen.close();
+        return sw.toString();
+    }
+
+    public static <T> T json2Bean(String jsonStr, Class<T> objClass)
+            throws JsonParseException, JsonMappingException, IOException {
+        return mapper.readValue(jsonStr, objClass);
+    }
+}

+ 328 - 0
kmall-common/src/main/java/com/kmall/common/utils/pingan/PinganUtil.java

@@ -0,0 +1,328 @@
+package com.kmall.common.utils.pingan;
+
+import com.kmall.common.utils.DateUtils;
+import com.kmall.common.utils.MapUtils;
+import com.kmall.common.utils.StringUtils;
+import com.kmall.common.utils.pingan.dto.PinganPayOrderDto;
+import com.kmall.common.utils.pingan.dto.PinganResponseDto;
+import com.kmall.common.utils.pingan.properties.PinganPayPropertiesBuilder;
+import com.kmall.common.utils.pingan.utils.InterfaceParams;
+import com.kmall.common.utils.pingan.utils.TLinx2Util;
+import com.kmall.common.utils.pingan.utils.TLinxAESCoder;
+import com.kmall.common.utils.pingan.utils.TLinxSHA1;
+import com.kmall.common.utils.wechat.WechatRefundQueryResult;
+import net.sf.json.JSONObject;
+import org.apache.log4j.Logger;
+
+import java.util.Date;
+import java.util.TreeMap;
+
+public class PinganUtil {
+
+    private static final String SUCCESS_CODE = "0";
+    private static Logger logger = Logger.getLogger(PinganUtil.class);
+
+    /**
+     * 构建平安支付订单信息
+     */
+    public static PinganPayOrderDto buildPayOrderDto(JSONObject dataObject) {
+        PinganPayOrderDto payorder = new PinganPayOrderDto();
+        payorder.setOutNo(MapUtils.getString("out_no", dataObject).equals("null") ? null : MapUtils.getString("out_no", dataObject));
+        payorder.setPmtName(MapUtils.getString("pmt_name", dataObject).equals("null") ? null : MapUtils.getString("pmt_name", dataObject));
+        payorder.setPmtTag(MapUtils.getString("pmt_tag", dataObject).equals("null") ? null : MapUtils.getString("pmt_tag", dataObject));
+        payorder.setOrdMctId(MapUtils.getInteger("ord_mct_id", dataObject));
+        payorder.setOrdShopId(MapUtils.getInteger("ord_shop_id", dataObject));
+        payorder.setOrdCurrency(MapUtils.getString("ord_currency", dataObject).equals("null") ? null : MapUtils.getString("ord_currency", dataObject));
+        payorder.setCurrencySign(MapUtils.getString("currency_sign", dataObject).equals("null") ? null : MapUtils.getString("currency_sign", dataObject));
+        payorder.setOrdNo(MapUtils.getString("ord_no", dataObject).equals("null") ? null : MapUtils.getString("ord_no", dataObject));
+        payorder.setOrdType(MapUtils.getInteger("ord_type", dataObject));
+        payorder.setOriginalAmount(MapUtils.getInteger("original_amount", dataObject));
+        payorder.setDiscountAmount(MapUtils.getInteger("discount_amount", dataObject));
+        payorder.setIgnoreAmount(MapUtils.getInteger("ignore_amount", dataObject));
+        payorder.setTradeAccount(MapUtils.getString("trade_account", dataObject).equals("null") ? null : MapUtils.getString("trade_account", dataObject));
+        payorder.setTradeNo(MapUtils.getString("trade_no", dataObject).equals("null") ? null : MapUtils.getString("trade_no", dataObject));
+        payorder.setTradeAmount(MapUtils.getInteger("trade_amount", dataObject));
+        payorder.setTradeQrcode(MapUtils.getString("trade_qrcode", dataObject).equals("null") ? null : MapUtils.getString("trade_qrcode", dataObject));
+        payorder.setAmount(MapUtils.getString("amount", dataObject).equals("null") ? null : MapUtils.getString("amount", dataObject));
+        payorder.setTradeTime(MapUtils.getString("trade_time", dataObject) == null || MapUtils.getString("trade_time", dataObject).equals("null") ? null : DateUtils.strToDate(MapUtils.getString("trade_time", dataObject)));
+        payorder.setTradePayTime(MapUtils.getString("trade_pay_time", dataObject) == null || MapUtils.getString("trade_pay_time", dataObject).equals("null") ? null : DateUtils.strToDate(MapUtils.getString("trade_pay_time", dataObject)));
+        payorder.setPayTime(MapUtils.getString("pay_time", dataObject).equals("null") ? null : MapUtils.getString("pay_time", dataObject));
+        payorder.setStatus(MapUtils.getInteger("status", dataObject));
+        payorder.setTradeResult(MapUtils.getString("trade_result", dataObject).equals("null") ? null : MapUtils.getString("trade_result", dataObject));
+        payorder.setJsapiPayUrl(MapUtils.getString("jsapi_pay_url", dataObject).equals("null") ? null : MapUtils.getString("jsapi_pay_url", dataObject));
+        payorder.setJsapiPayUrl(MapUtils.getString("rand_str", dataObject).equals("null") ? null : MapUtils.getString("rand_str", dataObject));
+        payorder.setAppid(MapUtils.getString("appId", dataObject).equals("null") ? null : MapUtils.getString("appId", dataObject));
+        payorder.setNoncestr(MapUtils.getString("nonceStr", dataObject).equals("null") ? null : MapUtils.getString("nonceStr", dataObject));
+        payorder.setSigntype(MapUtils.getString("signType", dataObject).equals("null") ? null : MapUtils.getString("signType", dataObject));
+        payorder.setPrepayId(MapUtils.getString("package", dataObject).equals("null") ? null : MapUtils.getString("package", dataObject));
+        payorder.setPaysign(MapUtils.getString("paySign", dataObject).equals("null") ? null : MapUtils.getString("paySign", dataObject));
+        return payorder;
+    }
+
+    public static WechatRefundQueryResult buildWechatRefundQueryResult(JSONObject tradeResult, int count) {
+        WechatRefundQueryResult refundQueryResult = new WechatRefundQueryResult();
+        refundQueryResult.setOut_refund_no(MapUtils.getString("out_refund_no_" + (count), tradeResult).equals("null") ? null : MapUtils.getString("out_refund_no_" + (count), tradeResult));
+        refundQueryResult.setRefund_account(MapUtils.getString("refund_account_" + (count), tradeResult).equals("null") ? null : MapUtils.getString("refund_account_" + (count), tradeResult));
+        refundQueryResult.setRefund_channel(MapUtils.getString("refund_channel_" + (count), tradeResult).equals("null") ? null : MapUtils.getString("refund_channel_" + (count), tradeResult));
+        refundQueryResult.setRefund_fee(MapUtils.getString("refund_fee_" + (count), tradeResult).equals("null") ? null : MapUtils.getString("refund_fee_" + (count), tradeResult));
+        refundQueryResult.setRefund_id(MapUtils.getString("refund_id_" + (count), tradeResult).equals("null") ? null : MapUtils.getString("refund_id_" + (count), tradeResult));
+        refundQueryResult.setRefund_recv_accout(MapUtils.getString("refund_recv_accout_" + (count), tradeResult).equals("null") ? null : MapUtils.getString("refund_recv_accout_" + (count), tradeResult));
+        refundQueryResult.setRefund_status(MapUtils.getString("refund_status_" + (count), tradeResult).equals("null") ? null : MapUtils.getString("refund_status_" + (count), tradeResult));
+        refundQueryResult.setRefund_success_time(MapUtils.getString("refund_success_time_" + (count), tradeResult).equals("null") ? null : MapUtils.getString("refund_success_time_" + (count), tradeResult));
+        return refundQueryResult;
+    }
+
+    /**
+     * 平安订单退款接口
+     */
+    public static PinganResponseDto pinganPayRefund(String outNo, String refundOutNo, Integer refundAmount, String tradeNo) {
+        // 初始化参数
+        String timestamp = new Date().getTime() / 1000 + "";    // 时间
+        PinganResponseDto response = null;
+        try {
+            // 固定参数
+            TreeMap<String, String> postmap = new TreeMap<String, String>();    // 请求参数的map
+            postmap.put("open_id", PinganPayPropertiesBuilder.instance().getPayOpenId());
+            postmap.put("timestamp", timestamp);
+
+            TreeMap<String, String> datamap = new TreeMap<String, String>();    // data参数的map
+            datamap.put("out_no", outNo);
+            datamap.put("refund_out_no", refundOutNo);
+            datamap.put("refund_amount", refundAmount + "");
+            datamap.put("trade_no", tradeNo);
+            datamap.put("shop_pass", TLinxSHA1.SHA1("123456"));
+
+            TLinx2Util.handleEncrypt(datamap, postmap);
+            postmap.put("sign_type", "RSA");
+            TLinx2Util.handleSignRSA(postmap);
+
+            String rspStr = TLinx2Util.handlePost(postmap, InterfaceParams.PAYREFUND);
+            System.out.println("返回字符串=" + rspStr);
+
+            JSONObject respObject = JSONObject.fromObject(rspStr);
+            logger.info("返回错误码:【" + MapUtils.getString("errcode", respObject) + "】");
+            logger.info("返回错误提示【" + MapUtils.getString("msg", respObject) + "】");
+            logger.info("平安支付下单返回数据:【" + MapUtils.getString("data", respObject) + "】");
+            logger.info("接口签名【" + MapUtils.getString("sign", respObject) + "】");
+
+            response = new PinganResponseDto();
+            response.setErrcode(MapUtils.getString("errcode", respObject));
+            response.setMsg(MapUtils.getString("msg", respObject));
+            response.setData(MapUtils.getString("data", respObject));
+            response.setSign(MapUtils.getString("sign", respObject));
+            if (StringUtils.isNotEmpty(MapUtils.getString("timestamp", respObject))) {
+                Long tstm = Long.parseLong(MapUtils.getString("timestamp", respObject)) * 1000;
+                response.setTimestamp(new Date(tstm));
+            }
+            response.setReqInterface(InterfaceParams.PAYREFUND);
+
+            if (SUCCESS_CODE.equals(MapUtils.getString("errcode", respObject))) {
+                Object dataStr = MapUtils.getString("data", respObject);
+                if (!rspStr.isEmpty() && (dataStr != null)) {
+                    if (TLinx2Util.verifySign(respObject)) {    // 验签成功
+                        String respData = TLinxAESCoder.decrypt(dataStr.toString(), PinganPayPropertiesBuilder.instance().getPayOpenKey());
+                        System.out.println("==================响应data内容:" + respData);
+                        response.setDatajson(respData);
+                    } else {
+                        System.out.println("=====验签失败=====");
+                    }
+                } else {
+                    System.out.println("=====没有返回data数据=====");
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        return response;
+    }
+
+
+    /**
+     * 平安订单取消接口
+     * 1、接口适用于所有等待支付的订单。
+     * 2、已成功支付的只支持“微信刷卡”类型的订单取消。
+     * 3、仅当日订单可以触发,已支付订单按支付完成时间,未支付订单按订单下单时间。
+     * 4、下单后,系统会在12分钟后自动取消未支付订单,调用本接口前请先查询订单状态。
+     */
+    public static PinganResponseDto pinganPayCancel(String ordNo, String outNo) {
+        // 初始化参数
+        String timestamp = new Date().getTime() / 1000 + "";    // 时间
+        PinganResponseDto response = null;
+        try {
+            // 固定参数
+            TreeMap<String, String> postmap = new TreeMap<String, String>();    // 请求参数的map
+            postmap.put("open_id", PinganPayPropertiesBuilder.instance().getPayOpenId());
+            postmap.put("timestamp", timestamp);
+
+            TreeMap<String, String> datamap = new TreeMap<String, String>();    // data参数的map
+            datamap.put("out_no", outNo);
+            datamap.put("ord_no", ordNo);
+
+            TLinx2Util.handleEncrypt(datamap, postmap);
+
+            //签名方式
+            postmap.put("sign_type", "RSA");
+            System.out.println("postmap---:" + postmap);
+            TLinx2Util.handleSignRSA(postmap);
+
+            String rspStr = TLinx2Util.handlePost(postmap, InterfaceParams.PAYCANCEL);
+            System.out.println("返回字符串=" + new String(rspStr.getBytes("UTF-8")));
+
+            JSONObject respObject = JSONObject.fromObject(rspStr);
+            logger.info("返回错误码:【" + MapUtils.getString("errcode", respObject) + "】");
+            logger.info("返回错误提示【" + MapUtils.getString("msg", respObject) + "】");
+            logger.info("平安支付下单返回数据:【" + MapUtils.getString("data", respObject) + "】");
+            logger.info("接口签名【" + MapUtils.getString("sign", respObject) + "】");
+
+            response = new PinganResponseDto();
+            response.setErrcode(MapUtils.getString("errcode", respObject));
+            response.setMsg(MapUtils.getString("msg", respObject));
+            response.setData(MapUtils.getString("data", respObject));
+            response.setSign(MapUtils.getString("sign", respObject));
+            if (StringUtils.isNotEmpty(MapUtils.getString("timestamp", respObject))) {
+                Long tstm = Long.parseLong(MapUtils.getString("timestamp", respObject)) * 1000;
+                response.setTimestamp(new Date(tstm));
+            }
+            response.setReqInterface(InterfaceParams.PAYCANCEL);
+
+            if (SUCCESS_CODE.equals(MapUtils.getString("errcode", respObject))) {
+                Object dataStr = MapUtils.getString("data", respObject);
+                if (!rspStr.isEmpty() || (dataStr != null)) {
+                    if (TLinx2Util.verifySign(respObject)) {    // 验签成功
+                        String respData = TLinxAESCoder.decrypt(dataStr.toString(), PinganPayPropertiesBuilder.instance().getPayOpenKey());
+                        System.out.println("==================响应data内容:" + respData);
+                        response.setDatajson(respData);
+                    } else {
+                        System.out.println("=====验签失败=====");
+                    }
+                } else {
+                    System.out.println("=====没有返回data数据=====");
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return response;
+    }
+
+
+    /**
+     * 平安查询付款状态
+     */
+    public static PinganResponseDto pinganPaystatus(String outNo) {
+        // 初始化参数
+        String timestamp = new Date().getTime() / 1000 + "";    // 时间
+        PinganResponseDto response = null;
+        try {
+            // 固定参数
+            TreeMap<String, String> postmap = new TreeMap<String, String>();    // 请求参数的map
+            postmap.put("open_id", PinganPayPropertiesBuilder.instance().getPayOpenId());
+            postmap.put("timestamp", timestamp);
+
+            TreeMap<String, String> datamap = new TreeMap<String, String>();    // data参数的map
+            datamap.put("out_no", outNo);
+
+            TLinx2Util.handleEncrypt(datamap, postmap);
+            TLinx2Util.handleSign(postmap);
+
+            String rspStr = TLinx2Util.handlePost(postmap, InterfaceParams.QUERYPAYSTATUS);
+            System.out.println("返回字符串=" + rspStr);
+
+            JSONObject respObject = JSONObject.fromObject(rspStr);
+            logger.info("返回错误码:【" + MapUtils.getString("errcode", respObject) + "】");
+            logger.info("返回错误提示【" + MapUtils.getString("msg", respObject) + "】");
+            logger.info("平安支付下单返回数据:【" + MapUtils.getString("data", respObject) + "】");
+            logger.info("接口签名【" + MapUtils.getString("sign", respObject) + "】");
+
+            response = new PinganResponseDto();
+            response.setErrcode(MapUtils.getString("errcode", respObject));
+            response.setMsg(MapUtils.getString("msg", respObject));
+            response.setData(MapUtils.getString("data", respObject));
+            response.setSign(MapUtils.getString("sign", respObject));
+            if (StringUtils.isNotEmpty(MapUtils.getString("timestamp", respObject))) {
+                Long tstm = Long.parseLong(MapUtils.getString("timestamp", respObject)) * 1000;
+                response.setTimestamp(new Date(tstm));
+            }
+            response.setReqInterface(InterfaceParams.QUERYPAYSTATUS);
+
+            if (SUCCESS_CODE.equals(MapUtils.getString("errcode", respObject))) {
+                Object dataStr = MapUtils.getString("data", respObject);
+                if (!rspStr.isEmpty() || (dataStr != null)) {
+                    if (TLinx2Util.verifySign(respObject)) {    // 验签成功
+                        String respData = TLinxAESCoder.decrypt(dataStr.toString(), PinganPayPropertiesBuilder.instance().getPayOpenKey());
+                        System.out.println("==================响应data内容:" + respData);
+                        response.setDatajson(respData);
+                    } else {
+                        System.out.println("=====验签失败=====");
+                    }
+                } else {
+                    System.out.println("=====没有返回data数据=====");
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return response;
+    }
+
+    /**
+     * 平安订单退款查询
+     */
+    public static PinganResponseDto pinganQueryRefund(String refund_out_no, String refund_ord_no) {
+        // 初始化参数
+        String timestamp = new Date().getTime() / 1000 + "";    // 时间
+        PinganResponseDto response = null;
+        try {
+            // 固定参数
+            TreeMap<String, String> postmap = new TreeMap<String, String>();    // 请求参数的map
+            postmap.put("open_id", PinganPayPropertiesBuilder.instance().getPayOpenId());
+            postmap.put("timestamp", timestamp);
+
+            TreeMap<String, String> datamap = new TreeMap<String, String>();    // data参数的map
+            datamap.put("refund_out_no", refund_out_no);
+            datamap.put("refund_ord_no", refund_ord_no);
+
+            TLinx2Util.handleEncrypt(datamap, postmap);
+            TLinx2Util.handleSign(postmap);
+
+            String rspStr = TLinx2Util.handlePost(postmap, InterfaceParams.QUERYPAYREFUND);
+            System.out.println("返回字符串=" + rspStr);
+
+            JSONObject respObject = JSONObject.fromObject(rspStr);
+            logger.info("返回错误码:【" + MapUtils.getString("errcode", respObject) + "】");
+            logger.info("返回错误提示【" + MapUtils.getString("msg", respObject) + "】");
+            logger.info("平安支付下单返回数据:【" + MapUtils.getString("data", respObject) + "】");
+            logger.info("接口签名【" + MapUtils.getString("sign", respObject) + "】");
+
+            response = new PinganResponseDto();
+            response.setErrcode(MapUtils.getString("errcode", respObject));
+            response.setMsg(MapUtils.getString("msg", respObject));
+            response.setData(MapUtils.getString("data", respObject));
+            response.setSign(MapUtils.getString("sign", respObject));
+            if (StringUtils.isNotEmpty(MapUtils.getString("timestamp", respObject))) {
+                Long tstm = Long.parseLong(MapUtils.getString("timestamp", respObject)) * 1000;
+                response.setTimestamp(new Date(tstm));
+            }
+            response.setReqInterface(InterfaceParams.QUERYPAYREFUND);
+
+            if (SUCCESS_CODE.equals(MapUtils.getString("errcode", respObject))) {
+                Object dataStr = MapUtils.getString("data", respObject);
+                if (!rspStr.isEmpty() && (dataStr != null)) {
+                    if (TLinx2Util.verifySign(respObject)) {    // 验签成功
+                        String respData = TLinxAESCoder.decrypt(dataStr.toString(), PinganPayPropertiesBuilder.instance().getPayOpenKey());
+                        System.out.println("==================响应data内容:" + respData);
+                        response.setDatajson(respData);
+                    } else {
+                        System.out.println("=====验签失败=====");
+                    }
+                } else {
+                    System.out.println("=====没有返回data数据=====");
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return response;
+    }
+}

+ 595 - 0
kmall-common/src/main/java/com/kmall/common/utils/pingan/dto/PinganPayOrderDto.java

@@ -0,0 +1,595 @@
+package com.kmall.common.utils.pingan.dto;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 实体
+ * 表名 pingan_pay_order
+ *
+ * @author emato
+ * @email admin@qhdswl.com
+ * @date 2018-12-06 15:29:43
+ */
+public class PinganPayOrderDto implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 
+     */
+    private Integer id;
+    /**
+     * 商户订单编号
+     */
+    private String outNo;
+    /**
+     * 收单机构名称
+     */
+    private String pmtName;
+    /**
+     * 收单机构标签
+     */
+    private String pmtTag;
+    /**
+     * 商户流水号(从1开始自增长不重复)
+     */
+    private Integer ordMctId;
+    /**
+     * 门店流水号(从1开始自增长不重复)
+     */
+    private Integer ordShopId;
+    /**
+     * 币种
+     */
+    private String ordCurrency;
+    /**
+     * 币种符号
+     */
+    private String currencySign;
+    /**
+     * 平安订单号
+     */
+    private String ordNo;
+    /**
+     * 订单类型(1消费,2辙单)
+     */
+    private Integer ordType;
+    /**
+     * 原始金额(以分为单位,没有小数点)
+     */
+    private Integer originalAmount;
+    /**
+     * 折扣金额(以分为单位,没有小数点)
+     */
+    private Integer discountAmount;
+    /**
+     * 抹零金额(以分为单位,没有小数点)
+     */
+    private Integer ignoreAmount;
+    /**
+     * 交易帐号(银行卡号、支付宝帐号、微信帐号等,某些收单机构没有此数据)
+     */
+    private String tradeAccount;
+    /**
+     * 收单机构交易号
+     */
+    private String tradeNo;
+    /**
+     * 实际交易金额(以分为单位,没有小数点)
+     */
+    private Integer tradeAmount;
+    /**
+     * 二维码字符串
+     */
+    private String tradeQrcode;
+    /**
+     * 交易金额(分为单位)
+     */
+    private String amount;
+    /**
+     * 交易时间
+     */
+    private Date tradeTime;
+    /**
+     * 付款完成时间(以收单机构为准)
+     */
+    private Date tradePayTime;
+    /**
+     * 交易成功时间(yyyymmddhhiiss)
+     */
+    private String payTime;
+    /**
+     * 订单状态(1交易成功,2待支付,4已取消,9等待用户输入密码确认)
+     */
+    private Integer status;
+    /**
+     * 收单机构原始交易数据
+     */
+    private String tradeResult;
+    /**
+     * 公众号订单支付地址,如果为非公众号订单,此参数为空
+     */
+    private String jsapiPayUrl;
+    /**
+     * 随机字符串
+     */
+    private String randStr;
+    /**
+     * 小程序的appid
+     */
+    private String appid;
+    /**
+     * 随机字符串
+     */
+    private String noncestr;
+    /**
+     * 签名方式
+     */
+    private String signtype;
+    /**
+     * 统一下单接口返回prepay_id参数值
+     */
+    private String prepayId;
+    /**
+     * 签名
+     */
+    private String paysign;
+    /**
+     * 创建人编号
+     */
+    private String createrSn;
+    /**
+     * 创建时间
+     */
+    private Date createTime;
+    /**
+     * 修改人编号
+     */
+    private String moderSn;
+    /**
+     * 修改时间
+     */
+    private Date modTime;
+    /**
+     * 时间戳
+     */
+    private Date tstm;
+
+    /**
+     * 设置:
+     */
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    /**
+     * 获取:
+     */
+    public Integer getId() {
+        return id;
+    }
+    /**
+     * 设置:商户订单编号
+     */
+    public void setOutNo(String outNo) {
+        this.outNo = outNo;
+    }
+
+    /**
+     * 获取:商户订单编号
+     */
+    public String getOutNo() {
+        return outNo;
+    }
+    /**
+     * 设置:收单机构名称
+     */
+    public void setPmtName(String pmtName) {
+        this.pmtName = pmtName;
+    }
+
+    /**
+     * 获取:收单机构名称
+     */
+    public String getPmtName() {
+        return pmtName;
+    }
+    /**
+     * 设置:收单机构标签
+     */
+    public void setPmtTag(String pmtTag) {
+        this.pmtTag = pmtTag;
+    }
+
+    /**
+     * 获取:收单机构标签
+     */
+    public String getPmtTag() {
+        return pmtTag;
+    }
+    /**
+     * 设置:商户流水号(从1开始自增长不重复)
+     */
+    public void setOrdMctId(Integer ordMctId) {
+        this.ordMctId = ordMctId;
+    }
+
+    /**
+     * 获取:商户流水号(从1开始自增长不重复)
+     */
+    public Integer getOrdMctId() {
+        return ordMctId;
+    }
+    /**
+     * 设置:门店流水号(从1开始自增长不重复)
+     */
+    public void setOrdShopId(Integer ordShopId) {
+        this.ordShopId = ordShopId;
+    }
+
+    /**
+     * 获取:门店流水号(从1开始自增长不重复)
+     */
+    public Integer getOrdShopId() {
+        return ordShopId;
+    }
+
+    public String getOrdCurrency() {
+        return ordCurrency;
+    }
+
+    public void setOrdCurrency(String ordCurrency) {
+        this.ordCurrency = ordCurrency;
+    }
+
+    public String getCurrencySign() {
+        return currencySign;
+    }
+
+    public void setCurrencySign(String currencySign) {
+        this.currencySign = currencySign;
+    }
+
+    /**
+     * 设置:平安订单号
+     */
+    public void setOrdNo(String ordNo) {
+        this.ordNo = ordNo;
+    }
+
+    /**
+     * 获取:平安订单号
+     */
+    public String getOrdNo() {
+        return ordNo;
+    }
+    /**
+     * 设置:订单类型(1消费,2辙单)
+     */
+    public void setOrdType(Integer ordType) {
+        this.ordType = ordType;
+    }
+
+    /**
+     * 获取:订单类型(1消费,2辙单)
+     */
+    public Integer getOrdType() {
+        return ordType;
+    }
+    /**
+     * 设置:原始金额(以分为单位,没有小数点)
+     */
+    public void setOriginalAmount(Integer originalAmount) {
+        this.originalAmount = originalAmount;
+    }
+
+    /**
+     * 获取:原始金额(以分为单位,没有小数点)
+     */
+    public Integer getOriginalAmount() {
+        return originalAmount;
+    }
+    /**
+     * 设置:折扣金额(以分为单位,没有小数点)
+     */
+    public void setDiscountAmount(Integer discountAmount) {
+        this.discountAmount = discountAmount;
+    }
+
+    /**
+     * 获取:折扣金额(以分为单位,没有小数点)
+     */
+    public Integer getDiscountAmount() {
+        return discountAmount;
+    }
+    /**
+     * 设置:抹零金额(以分为单位,没有小数点)
+     */
+    public void setIgnoreAmount(Integer ignoreAmount) {
+        this.ignoreAmount = ignoreAmount;
+    }
+
+    /**
+     * 获取:抹零金额(以分为单位,没有小数点)
+     */
+    public Integer getIgnoreAmount() {
+        return ignoreAmount;
+    }
+    /**
+     * 设置:交易帐号(银行卡号、支付宝帐号、微信帐号等,某些收单机构没有此数据)
+     */
+    public void setTradeAccount(String tradeAccount) {
+        this.tradeAccount = tradeAccount;
+    }
+
+    /**
+     * 获取:交易帐号(银行卡号、支付宝帐号、微信帐号等,某些收单机构没有此数据)
+     */
+    public String getTradeAccount() {
+        return tradeAccount;
+    }
+    /**
+     * 设置:收单机构交易号
+     */
+    public void setTradeNo(String tradeNo) {
+        this.tradeNo = tradeNo;
+    }
+
+    /**
+     * 获取:收单机构交易号
+     */
+    public String getTradeNo() {
+        return tradeNo;
+    }
+    /**
+     * 设置:实际交易金额(以分为单位,没有小数点)
+     */
+    public void setTradeAmount(Integer tradeAmount) {
+        this.tradeAmount = tradeAmount;
+    }
+
+    /**
+     * 获取:实际交易金额(以分为单位,没有小数点)
+     */
+    public Integer getTradeAmount() {
+        return tradeAmount;
+    }
+    /**
+     * 设置:二维码字符串
+     */
+    public void setTradeQrcode(String tradeQrcode) {
+        this.tradeQrcode = tradeQrcode;
+    }
+
+    /**
+     * 获取:二维码字符串
+     */
+    public String getTradeQrcode() {
+        return tradeQrcode;
+    }
+
+    public String getAmount() {
+        return amount;
+    }
+
+    public void setAmount(String amount) {
+        this.amount = amount;
+    }
+
+    public Date getTradeTime() {
+        return tradeTime;
+    }
+
+    public void setTradeTime(Date tradeTime) {
+        this.tradeTime = tradeTime;
+    }
+
+    /**
+     * 设置:付款完成时间(以收单机构为准)
+     */
+    public void setTradePayTime(Date tradePayTime) {
+        this.tradePayTime = tradePayTime;
+    }
+
+    /**
+     * 获取:付款完成时间(以收单机构为准)
+     */
+    public Date getTradePayTime() {
+        return tradePayTime;
+    }
+    /**
+     * 设置:交易成功时间(yyyymmddhhiiss)
+     */
+    public void setPayTime(String payTime) {
+        this.payTime = payTime;
+    }
+
+    /**
+     * 获取:交易成功时间(yyyymmddhhiiss)
+     */
+    public String getPayTime() {
+        return payTime;
+    }
+    /**
+     * 设置:订单状态(1交易成功,2待支付,4已取消,9等待用户输入密码确认)
+     */
+    public void setStatus(Integer status) {
+        this.status = status;
+    }
+
+    /**
+     * 获取:订单状态(1交易成功,2待支付,4已取消,9等待用户输入密码确认)
+     */
+    public Integer getStatus() {
+        return status;
+    }
+    /**
+     * 设置:收单机构原始交易数据
+     */
+    public void setTradeResult(String tradeResult) {
+        this.tradeResult = tradeResult;
+    }
+
+    /**
+     * 获取:收单机构原始交易数据
+     */
+    public String getTradeResult() {
+        return tradeResult;
+    }
+    /**
+     * 设置:公众号订单支付地址,如果为非公众号订单,此参数为空
+     */
+    public void setJsapiPayUrl(String jsapiPayUrl) {
+        this.jsapiPayUrl = jsapiPayUrl;
+    }
+
+    /**
+     * 获取:公众号订单支付地址,如果为非公众号订单,此参数为空
+     */
+    public String getJsapiPayUrl() {
+        return jsapiPayUrl;
+    }
+    /**
+     * 设置:随机字符串
+     */
+    public void setRandStr(String randStr) {
+        this.randStr = randStr;
+    }
+
+    /**
+     * 获取:随机字符串
+     */
+    public String getRandStr() {
+        return randStr;
+    }
+    /**
+     * 设置:小程序的appid
+     */
+    public void setAppid(String appid) {
+        this.appid = appid;
+    }
+
+    /**
+     * 获取:小程序的appid
+     */
+    public String getAppid() {
+        return appid;
+    }
+    /**
+     * 设置:随机字符串
+     */
+    public void setNoncestr(String noncestr) {
+        this.noncestr = noncestr;
+    }
+
+    /**
+     * 获取:随机字符串
+     */
+    public String getNoncestr() {
+        return noncestr;
+    }
+    /**
+     * 设置:签名方式
+     */
+    public void setSigntype(String signtype) {
+        this.signtype = signtype;
+    }
+
+    /**
+     * 获取:签名方式
+     */
+    public String getSigntype() {
+        return signtype;
+    }
+    /**
+     * 设置:统一下单接口返回prepay_id参数值
+     */
+    public void setPrepayId(String prepayId) {
+        this.prepayId = prepayId;
+    }
+
+    /**
+     * 获取:统一下单接口返回prepay_id参数值
+     */
+    public String getPrepayId() {
+        return prepayId;
+    }
+    /**
+     * 设置:签名
+     */
+    public void setPaysign(String paysign) {
+        this.paysign = paysign;
+    }
+
+    /**
+     * 获取:签名
+     */
+    public String getPaysign() {
+        return paysign;
+    }
+    /**
+     * 设置:创建人编号
+     */
+    public void setCreaterSn(String createrSn) {
+        this.createrSn = createrSn;
+    }
+
+    /**
+     * 获取:创建人编号
+     */
+    public String getCreaterSn() {
+        return createrSn;
+    }
+    /**
+     * 设置:创建时间
+     */
+    public void setCreateTime(Date createTime) {
+        this.createTime = createTime;
+    }
+
+    /**
+     * 获取:创建时间
+     */
+    public Date getCreateTime() {
+        return createTime;
+    }
+    /**
+     * 设置:修改人编号
+     */
+    public void setModerSn(String moderSn) {
+        this.moderSn = moderSn;
+    }
+
+    /**
+     * 获取:修改人编号
+     */
+    public String getModerSn() {
+        return moderSn;
+    }
+    /**
+     * 设置:修改时间
+     */
+    public void setModTime(Date modTime) {
+        this.modTime = modTime;
+    }
+
+    /**
+     * 获取:修改时间
+     */
+    public Date getModTime() {
+        return modTime;
+    }
+    /**
+     * 设置:时间戳
+     */
+    public void setTstm(Date tstm) {
+        this.tstm = tstm;
+    }
+
+    /**
+     * 获取:时间戳
+     */
+    public Date getTstm() {
+        return tstm;
+    }
+}

+ 201 - 0
kmall-common/src/main/java/com/kmall/common/utils/pingan/dto/PinganResponseDto.java

@@ -0,0 +1,201 @@
+package com.kmall.common.utils.pingan.dto;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 实体
+ * 表名 pingan_response
+ *
+ * @author emato
+ * @email admin@qhdswl.com
+ * @date 2018-12-06 15:29:43
+ */
+public class PinganResponseDto implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 
+     */
+    private Integer id;
+    /**
+     * 商户订单编号
+     */
+    private String outNo;
+    /**
+     * 请求方法
+     */
+    private String reqInterface;
+    /**
+     * 返回错误码,为0表示没有错误
+     */
+    private String errcode;
+    /**
+     * 返回错误提示,会根据lang参数返回不同的语言
+     */
+    private String msg;
+    /**
+     * open_key进行aes加密后的数据
+     */
+    private String data;
+    /**
+     * 签名
+     */
+    private String sign;
+    /**
+     * 
+     */
+    private String datajson;
+    /**
+     * 返回时间戳
+     */
+    private Date timestamp;
+    /**
+     * 创建时间
+     */
+    private Date createTime;
+    /**
+     * 时间戳
+     */
+    private Date tstm;
+
+    /**
+     * 设置:
+     */
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    /**
+     * 获取:
+     */
+    public Integer getId() {
+        return id;
+    }
+    /**
+     * 设置:商户订单编号
+     */
+    public void setOutNo(String outNo) {
+        this.outNo = outNo;
+    }
+
+    /**
+     * 获取:商户订单编号
+     */
+    public String getOutNo() {
+        return outNo;
+    }
+    /**
+     * 设置:请求方法
+     */
+    public void setReqInterface(String reqInterface) {
+        this.reqInterface = reqInterface;
+    }
+
+    /**
+     * 获取:请求方法
+     */
+    public String getReqInterface() {
+        return reqInterface;
+    }
+    /**
+     * 设置:返回错误码,为0表示没有错误
+     */
+    public void setErrcode(String errcode) {
+        this.errcode = errcode;
+    }
+
+    /**
+     * 获取:返回错误码,为0表示没有错误
+     */
+    public String getErrcode() {
+        return errcode;
+    }
+    /**
+     * 设置:返回错误提示,会根据lang参数返回不同的语言
+     */
+    public void setMsg(String msg) {
+        this.msg = msg;
+    }
+
+    /**
+     * 获取:返回错误提示,会根据lang参数返回不同的语言
+     */
+    public String getMsg() {
+        return msg;
+    }
+    /**
+     * 设置:open_key进行aes加密后的数据
+     */
+    public void setData(String data) {
+        this.data = data;
+    }
+
+    /**
+     * 获取:open_key进行aes加密后的数据
+     */
+    public String getData() {
+        return data;
+    }
+    /**
+     * 设置:签名
+     */
+    public void setSign(String sign) {
+        this.sign = sign;
+    }
+
+    /**
+     * 获取:签名
+     */
+    public String getSign() {
+        return sign;
+    }
+    /**
+     * 设置:
+     */
+    public void setDatajson(String datajson) {
+        this.datajson = datajson;
+    }
+
+    /**
+     * 获取:
+     */
+    public String getDatajson() {
+        return datajson;
+    }
+
+    public Date getTimestamp() {
+        return timestamp;
+    }
+
+    public void setTimestamp(Date timestamp) {
+        this.timestamp = timestamp;
+    }
+
+    /**
+     * 设置:创建时间
+     */
+    public void setCreateTime(Date createTime) {
+        this.createTime = createTime;
+    }
+
+    /**
+     * 获取:创建时间
+     */
+    public Date getCreateTime() {
+        return createTime;
+    }
+    /**
+     * 设置:时间戳
+     */
+    public void setTstm(Date tstm) {
+        this.tstm = tstm;
+    }
+
+    /**
+     * 获取:时间戳
+     */
+    public Date getTstm() {
+        return tstm;
+    }
+}

+ 9 - 0
kmall-common/src/main/java/com/kmall/common/utils/pingan/properties/PinganPayProperties.java

@@ -13,6 +13,7 @@ public class PinganPayProperties implements Serializable {
 
     private String payOpenId;
     private String payOpenKey;
+    private String payPublicKey;
     private String payPrivateKey;
 
     private String pluginOpenId;
@@ -43,6 +44,14 @@ public class PinganPayProperties implements Serializable {
         this.payOpenKey = payOpenKey;
     }
 
+    public String getPayPublicKey() {
+        return payPublicKey;
+    }
+
+    public void setPayPublicKey(String payPublicKey) {
+        this.payPublicKey = payPublicKey;
+    }
+
     public String getPayPrivateKey() {
         return payPrivateKey;
     }

+ 28 - 0
kmall-common/src/main/java/com/kmall/common/utils/pingan/utils/ChildDemo.java

@@ -0,0 +1,28 @@
+package com.kmall.common.utils.pingan.utils;
+
+ class ChildDemo extends ParentDemo {
+	 private static String name;
+		private static int age;
+
+	public ChildDemo(String name, int age) {
+		super(name, age);
+		
+	}
+
+	public ChildDemo() {
+		this(name, age);
+		
+	}
+	
+	
+public static void main(String[] args) {
+	ParentDemo pd = new ChildDemo();
+}
+
+@Override
+public void study() {
+	// TODO Auto-generated method stub
+	
+}
+}
+

+ 275 - 0
kmall-common/src/main/java/com/kmall/common/utils/pingan/utils/HttpUtil.java

@@ -0,0 +1,275 @@
+/**
+ * @Filename:HttpUtil.java
+ * @Author:caiqf
+ * @Date�?013-9-23
+ */
+package com.kmall.common.utils.pingan.utils;
+
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import java.io.*;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.zip.GZIPInputStream;
+import java.util.zip.ZipException;
+
+/**
+ * @Class:HttpsUtil.java
+ * @Description�?
+ * @Author:caiqf
+ * @Date�?013-9-23
+ */
+@SuppressWarnings("all")
+public class HttpUtil {
+    private static final Log log = LogFactory.getLog(HttpUtil.class);
+
+    /**
+     * HTTP协议GET请求方法
+     */
+    public static String httpMethodGet(String url, String gb) {
+        if (null == gb || "".equals(gb)) {
+            gb = "UTF-8";
+        }
+        StringBuffer sb = new StringBuffer();
+        URL urls;
+        HttpURLConnection uc = null;
+        BufferedReader in = null;
+        try {
+            urls = new URL(url);
+            uc = (HttpURLConnection) urls.openConnection();
+            uc.setRequestMethod("GET");
+            uc.connect();
+            in = new BufferedReader(new InputStreamReader(uc.getInputStream(),
+                    gb));
+            String readLine = "";
+            while ((readLine = in.readLine()) != null) {
+                sb.append(readLine);
+            }
+            if (in != null) {
+                in.close();
+            }
+            if (uc != null) {
+                uc.disconnect();
+            }
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+        } finally {
+            if (uc != null) {
+                uc.disconnect();
+            }
+        }
+        return sb.toString();
+    }
+
+    /**
+     * 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;
+        try {
+            urls = new URL(url);
+            uc = (HttpURLConnection) urls.openConnection();
+            uc.setRequestMethod("POST");
+            uc.setDoOutput(true);
+            uc.setDoInput(true);
+            uc.setUseCaches(false);
+            uc.setRequestProperty("Content-Type",
+                    "application/x-www-form-urlencoded");
+            uc.connect();
+            DataOutputStream 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);
+            }
+            if (in != null) {
+                in.close();
+            }
+            if (uc != null) {
+                uc.disconnect();
+            }
+        } catch (IOException e) {
+            log.error(e.getMessage(), e);
+        } finally {
+            if (uc != null) {
+                uc.disconnect();
+            }
+        }
+        return sb.toString();
+    }
+
+    /**
+     * HTTP协议POST请求方法
+     */
+    public static String httpMethodPost(String url,
+                                        TreeMap<String, String> paramsMap, String gb) {
+        if (null == gb || "".equals(gb)) {
+            gb = "utf-8";
+        }
+        String params = null;
+        if (null != paramsMap) {
+            params = getParamStr(paramsMap);
+        }
+        System.out.println("==================组装业务请求参数 : " + params);
+        StringBuffer sb = new StringBuffer();
+        URL urls;
+        HttpURLConnection uc = null;
+        BufferedReader in = null;
+        try {
+            urls = new URL(url);
+            uc = (HttpURLConnection) urls.openConnection();
+            uc.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
+            uc.setDoOutput(true);
+            uc.setDoInput(true);
+            uc.setRequestMethod("POST");
+            uc.setUseCaches(false);
+            uc.connect();
+            DataOutputStream out = new DataOutputStream(uc.getOutputStream());
+            out.write(params.getBytes(gb));
+            out.flush();
+            out.close();
+            InputStream i = uc.getInputStream();
+            in = new BufferedReader(new InputStreamReader(uc.getInputStream(), gb));
+            String readLine = "";
+            while ((readLine = in.readLine()) != null) {
+                sb.append(readLine).append("\n");
+            }
+            if (in != null) {
+                in.close();
+            }
+            if (uc != null) {
+                uc.disconnect();
+            }
+        } catch (IOException e) {
+            log.error(e.getMessage(), e);
+        } finally {
+            if (uc != null) {
+                uc.disconnect();
+            }
+        }
+        return sb.toString();
+    }
+
+    public static String httpMethodPostGZIP(String url,
+                                            TreeMap<String, String> paramsMap, String gb) {
+        System.out.println("===url:" + url);
+        if (null == gb || "".equals(gb)) {
+            gb = "UTF-8";
+        }
+        String params = null;
+        if (null != paramsMap) {
+            params = getParamStr(paramsMap);
+        }
+
+        StringBuffer sb = new StringBuffer();
+        URL urls;
+        HttpURLConnection uc = null;
+        BufferedReader in = null;
+        try {
+            urls = new URL(url);
+            uc = (HttpURLConnection) urls.openConnection();
+            uc.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
+            uc.setDoOutput(true);
+            uc.setDoInput(true);
+            uc.setRequestMethod("POST");
+            uc.setUseCaches(false);
+            uc.connect();
+            DataOutputStream out = new DataOutputStream(uc.getOutputStream());
+            out.write(params.getBytes(gb));
+            out.flush();
+            out.close();
+            in = new BufferedReader(new InputStreamReader(new GZIPInputStream(uc.getInputStream()), gb));
+
+            String readLine = "";
+            while ((readLine = in.readLine()) != null) {
+                sb.append(readLine).append("\n");
+            }
+            if (in != null) {
+                in.close();
+            }
+            if (uc != null) {
+                uc.disconnect();
+            }
+        } catch (ZipException e) {
+            log.error("暂无数据");
+        } catch (IOException e) {
+            log.error(e.getMessage(), e);
+        } finally {
+            if (uc != null) {
+                uc.disconnect();
+            }
+        }
+        return sb.toString();
+    }
+
+    /**
+     * HTTP协议POST请求添加参数的封装方法
+     */
+    public static String getParamStr(TreeMap<String, String> paramsMap) {
+        StringBuilder param = new StringBuilder();
+        for (Iterator<Map.Entry<String, String>> it = paramsMap.entrySet()
+                .iterator(); it.hasNext(); ) {
+            Map.Entry<String, String> e = it.next();
+            param.append("&").append(e.getKey()).append("=")
+                    .append(e.getValue());
+        }
+        return param.toString().substring(1);
+    }
+
+//	/**
+//	 * 
+//	 * Author:tingzw
+//	 * 
+//	 * @Description:微信摇一�?----上传图片素材
+//	 * @param @param url
+//	 * @param @param paramsMap
+//	 * @param @param fileName
+//	 * @param @param file
+//	 * @param @return
+//	 * @return String
+//	 * @throws
+//	 */
+//	@SuppressWarnings("deprecation")
+//	public static String httpMethodPost(String url,
+//			TreeMap<String, String> paramsMap, String fileName, File file) {
+//		try {
+//			HttpPost post = new HttpPost(url);
+//			HttpResponse httpResponse;
+//			MultipartEntity reEntity = new MultipartEntity();
+//			FileBody filebody = new FileBody(file);
+//
+//			reEntity.addPart(fileName, filebody);
+//			for (Iterator<Map.Entry<String, String>> it = paramsMap.entrySet()
+//					.iterator(); it.hasNext();) {
+//				Map.Entry<String, String> e = it.next();
+//				reEntity.addPart(e.getKey(), new StringBody(e.getValue()));
+//			}
+//
+//			post.setEntity(reEntity);
+//			httpResponse = new DefaultHttpClient().execute(post);
+//			HttpEntity httpEntity = httpResponse.getEntity();
+//			String ret = EntityUtils.toString(httpEntity, "UTF-8");
+//			return ret;
+//		} catch (ClientProtocolException e) {
+//			log.error(e.getMessage(), e);
+//		} catch (IOException e) {
+//			log.error(e.getMessage(), e);
+//		}
+//		return "";
+//	}
+}

+ 418 - 0
kmall-common/src/main/java/com/kmall/common/utils/pingan/utils/HttpsUtil.java

@@ -0,0 +1,418 @@
+/**
+ * @Filename:HttpsUtil.java
+ * @Author:caiqf
+ * @Date�?013-9-23
+ */
+package com.kmall.common.utils.pingan.utils;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import javax.net.ssl.*;
+import java.io.*;
+import java.net.URL;
+import java.net.URLDecoder;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.zip.GZIPInputStream;
+
+/**
+ * @Class:HttpsUtil.java
+ * @Description�?
+ * @Author:caiqf
+ * @Date�?013-9-23
+ */
+public class HttpsUtil {
+	private static final Log log = LogFactory.getLog(HttpsUtil.class);
+
+	private static class MyTrustManager implements X509TrustManager {
+		public void checkClientTrusted(X509Certificate[] chain, String authType)
+				throws CertificateException {
+		}
+
+		public void checkServerTrusted(X509Certificate[] chain, String authType)
+				throws CertificateException {
+		}
+
+		public X509Certificate[] getAcceptedIssuers() {
+			return new X509Certificate[] {};
+		}
+	}
+
+	private static class MyHostnameVerifier implements HostnameVerifier {
+		public boolean verify(String hostname, SSLSession session) {
+			return true;
+		}
+	}
+
+	/**
+	 * 
+	 * HTTP协议GET请求方法
+	 */
+	public static String httpMethodGet(String url, String gb) {
+		if (null == gb || "".equals(gb)) {
+			gb = "UTF-8";
+		}
+		StringBuffer sb = new StringBuffer();
+		URL urls;
+		HttpsURLConnection uc = null;
+		BufferedReader in = null;
+		try {
+			SSLContext sc = SSLContext.getInstance("SSL");
+			sc.init(null, new TrustManager[] { new MyTrustManager() },
+					new java.security.SecureRandom());
+			urls = new URL(url);
+			uc = (HttpsURLConnection) urls.openConnection();
+			uc.setSSLSocketFactory(sc.getSocketFactory());
+			uc.setHostnameVerifier(new MyHostnameVerifier());
+			uc.setRequestMethod("GET");
+			uc.connect();
+			in = new BufferedReader(new InputStreamReader(uc.getInputStream(),
+					"utf-8"));
+			String readLine = "";
+			while ((readLine = in.readLine()) != null) {
+				sb.append(readLine);
+			}
+			if (in != null) {
+				in.close();
+			}
+			if (uc != null) {
+				uc.disconnect();
+			}
+		} catch (Exception e) {
+			log.error(e.getMessage(), e);
+		} finally {
+			if (uc != null) {
+				uc.disconnect();
+			}
+		}
+		return sb.toString();
+	}
+
+	/**
+	 * 
+	 * HTTP协议GET请求方法
+	 */
+	public static byte[] httpMethodGetFile(String url) {
+		byte[] btFile = null;
+		URL urls = null;
+		HttpsURLConnection uc = null;
+		try {
+			SSLContext sc = SSLContext.getInstance("SSL");
+			sc.init(null, new TrustManager[] { new MyTrustManager() },
+					new java.security.SecureRandom());
+			urls = new URL(url);
+			uc = (HttpsURLConnection) urls.openConnection();
+			uc.setSSLSocketFactory(sc.getSocketFactory());
+			uc.setHostnameVerifier(new MyHostnameVerifier());
+			uc.setRequestMethod("GET");
+			uc.connect();
+			InputStream inStream = uc.getInputStream(); // 获取文件流二进制数据
+			ByteArrayOutputStream outStream = new ByteArrayOutputStream();
+			byte[] buffer = new byte[1024];
+			int len = 0;
+			while ((len = inStream.read(buffer)) != -1) {
+				outStream.write(buffer, 0, len);
+			}
+			inStream.close();
+			btFile = outStream.toByteArray();
+		} catch (Exception e) {
+			log.error(e.getMessage(), e);
+		} finally {
+			if (uc != null) {
+				uc.disconnect();
+			}
+		}
+		return btFile;
+	}
+
+	/**
+	 * 
+	 * 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;
+		HttpsURLConnection uc = null;
+		BufferedReader in = null;
+		try {
+			SSLContext sc = SSLContext.getInstance("SSL");
+			sc.init(null, new TrustManager[] { new MyTrustManager() },
+					new java.security.SecureRandom());
+			urls = new URL(url);
+			uc = (HttpsURLConnection) urls.openConnection();
+			uc.setSSLSocketFactory(sc.getSocketFactory());
+			uc.setHostnameVerifier(new MyHostnameVerifier());
+			uc.setRequestMethod("POST");
+			uc.setDoOutput(true);
+			uc.setDoInput(true);
+			uc.setUseCaches(false);
+			uc.setRequestProperty("Content-Type",
+					"application/x-www-form-urlencoded");
+			uc.connect();
+			DataOutputStream 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);
+			}
+			if (in != null) {
+				in.close();
+			}
+			if (uc != null) {
+				uc.disconnect();
+			}
+		} catch (Exception e) {
+			log.error(e.getMessage(), e);
+		} finally {
+			if (uc != null) {
+				uc.disconnect();
+			}
+		}
+		return sb.toString();
+	}
+
+	/**
+	 * 
+	 * HTTP协议POST请求方法
+	 */
+	public static byte[] httpMethodPostFile(String url, String params, String gb) {
+		if (null == gb || "".equals(gb)) {
+			gb = "UTF-8";
+		}
+		byte[] btFile = null;
+		URL urls = null;
+		HttpsURLConnection uc = null;
+		try {
+			SSLContext sc = SSLContext.getInstance("SSL");
+			sc.init(null, new TrustManager[] { new MyTrustManager() },
+					new java.security.SecureRandom());
+			urls = new URL(url);
+			uc = (HttpsURLConnection) urls.openConnection();
+			uc.setSSLSocketFactory(sc.getSocketFactory());
+			uc.setHostnameVerifier(new MyHostnameVerifier());
+			uc.setRequestMethod("POST");
+			uc.setDoOutput(true);
+			uc.setDoInput(true);
+			uc.setUseCaches(false);
+			uc.setRequestProperty("Content-Type",
+					"application/x-www-form-urlencoded");
+			uc.connect();
+			DataOutputStream out = new DataOutputStream(uc.getOutputStream());
+			out.write(params.getBytes(gb));
+			out.flush();
+			out.close();
+			InputStream inStream = uc.getInputStream(); // 获取文件流二进制数据
+			ByteArrayOutputStream outStream = new ByteArrayOutputStream();
+			byte[] buffer = new byte[1024];
+			int len = 0;
+			while ((len = inStream.read(buffer)) != -1) {
+				outStream.write(buffer, 0, len);
+			}
+			inStream.close();
+			btFile = outStream.toByteArray();
+		} catch (Exception e) {
+			log.error(e.getMessage(), e);
+		} finally {
+			if (uc != null) {
+				uc.disconnect();
+			}
+		}
+		return btFile;
+	}
+
+	/**
+	 * 
+	 * HTTP协议POST请求方法
+	 */
+	public static String httpMethodPost(String url,
+                                        TreeMap<String, String> paramsMap, String gb) {
+		if (null == gb || "".equals(gb)) {
+			gb = "UTF-8";
+		}
+		String params = null;
+		if (null != paramsMap) {
+			params = getParamStr(paramsMap);
+		}
+
+		StringBuffer sb = new StringBuffer();
+		URL urls;
+		HttpsURLConnection uc = null;
+		BufferedReader in = null;
+		try {
+			SSLContext sc = SSLContext.getInstance("SSL");
+			sc.init(null, new TrustManager[] { new MyTrustManager() },
+					new java.security.SecureRandom());
+			urls = new URL(url);
+			uc = (HttpsURLConnection) urls.openConnection();
+			uc.setSSLSocketFactory(sc.getSocketFactory());
+			uc.setHostnameVerifier(new MyHostnameVerifier());
+			uc.setRequestMethod("POST");
+			uc.setDoOutput(true);
+			uc.setDoInput(true);
+			uc.setUseCaches(false);
+			uc.setRequestProperty("Content-Type",
+					"application/x-www-form-urlencoded");
+			uc.connect();
+			DataOutputStream 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).append("\n");
+			}
+			if (in != null) {
+				in.close();
+			}
+			if (uc != null) {
+				uc.disconnect();
+			}
+		} catch (Exception e) {
+			log.error(e.getMessage(), e);
+		} finally {
+			if (uc != null) {
+				uc.disconnect();
+			}
+		}
+		return URLDecoder.decode(sb.toString());
+	}
+
+	public static String httpMethodPostGZIP(String url,
+											TreeMap<String, String> paramsMap, String gb) {
+		System.out.println("===url:" + url);
+		if (null == gb || "".equals(gb)) {
+			gb = "UTF-8";
+		}
+		String params = null;
+		if (null != paramsMap) {
+			params = getParamStr(paramsMap);
+		}
+
+		StringBuffer sb = new StringBuffer();
+		URL urls;
+		HttpsURLConnection uc = null;
+		BufferedReader in = null;
+		try {
+			SSLContext sc = SSLContext.getInstance("SSL");
+			sc.init(null, new TrustManager[] { new MyTrustManager() },
+					new java.security.SecureRandom());
+			urls = new URL(url);
+			uc = (HttpsURLConnection) urls.openConnection();
+			uc.setSSLSocketFactory(sc.getSocketFactory());
+			uc.setHostnameVerifier(new MyHostnameVerifier());
+			uc.setRequestMethod("POST");
+			uc.setDoOutput(true);
+			uc.setDoInput(true);
+			uc.setUseCaches(false);
+			uc.setRequestProperty("Content-Type",
+					"application/x-www-form-urlencoded");
+			uc.connect();
+			DataOutputStream out = new DataOutputStream(uc.getOutputStream());
+			out.write(params.getBytes(gb));
+			out.flush();
+			out.close();
+			in = new BufferedReader(new InputStreamReader(new GZIPInputStream(uc.getInputStream()),gb));
+			String readLine = "";
+			while ((readLine = in.readLine()) != null) {
+				//换行"\n"
+				sb.append(readLine).append("\n");
+			}
+			if (in != null) {
+				in.close();
+			}
+			if (uc != null) {
+				uc.disconnect();
+			}
+		} catch (Exception e) {
+			log.error(e.getMessage(), e);
+		} finally {
+			if (uc != null) {
+				uc.disconnect();
+			}
+		}
+		return sb.toString();
+	}
+
+	/**
+	 * 
+	 * HTTP协议POST请求方法
+	 */
+	public static byte[] httpMethodPostFile(String url,
+                                            TreeMap<String, String> paramsMap, String gb) {
+		if (null == gb || "".equals(gb)) {
+			gb = "UTF-8";
+		}
+		String params = null;
+		if (null != paramsMap) {
+			params = getParamStr(paramsMap);
+		}
+
+		byte[] btFile = null;
+		URL urls = null;
+		HttpsURLConnection uc = null;
+		try {
+			SSLContext sc = SSLContext.getInstance("SSL");
+			sc.init(null, new TrustManager[] { new MyTrustManager() },
+					new java.security.SecureRandom());
+			urls = new URL(url);
+			uc = (HttpsURLConnection) urls.openConnection();
+			uc.setSSLSocketFactory(sc.getSocketFactory());
+			uc.setHostnameVerifier(new MyHostnameVerifier());
+			uc.setRequestMethod("POST");
+			uc.setDoOutput(true);
+			uc.setDoInput(true);
+			uc.setUseCaches(false);
+			uc.setRequestProperty("Content-Type",
+					"application/x-www-form-urlencoded");
+			uc.connect();
+			DataOutputStream out = new DataOutputStream(uc.getOutputStream());
+			out.write(params.getBytes(gb));
+			out.flush();
+			out.close();
+			InputStream inStream = uc.getInputStream(); // 获取文件流二进制数据
+			ByteArrayOutputStream outStream = new ByteArrayOutputStream();
+			byte[] buffer = new byte[1024];
+			int len = 0;
+			while ((len = inStream.read(buffer)) != -1) {
+				outStream.write(buffer, 0, len);
+			}
+			inStream.close();
+			btFile = outStream.toByteArray();
+		} catch (Exception e) {
+			log.error(e.getMessage(), e);
+		} finally {
+			if (uc != null) {
+				uc.disconnect();
+			}
+		}
+		return btFile;
+	}
+
+	/**
+	 * 
+	 * HTTP协议POST请求添加参数的封装方�?
+	 */
+	private static String getParamStr(TreeMap<String, String> paramsMap) {
+		StringBuilder param = new StringBuilder();
+		for (Iterator<Map.Entry<String, String>> it = paramsMap.entrySet()
+				.iterator(); it.hasNext();) {
+			Map.Entry<String, String> e = it.next();
+			param.append("&").append(e.getKey()).append("=")
+					.append(e.getValue());
+		}
+		return param.toString().substring(1);
+	}
+}

+ 36 - 0
kmall-common/src/main/java/com/kmall/common/utils/pingan/utils/InterfaceParams.java

@@ -0,0 +1,36 @@
+package com.kmall.common.utils.pingan.utils;
+
+public interface InterfaceParams {
+
+    //回调
+    String NOTIFY = "notify";
+
+     //商户支付配置
+    String MPCONFIGADD = "mpconfig/add";
+    //商户支付配置查询
+    String MPCONFIGQUERY = "mpconfig/query";
+
+    //获取门店支付方式列表
+    String PAYLIST = "paylist";
+    //获取订单列表
+    String ORDERLIST = "order";
+    //查询订单明细
+    String ORDERVIEW = "order/view";
+    //下订单接口
+    String PAYORDER = "payorder";
+    //查询付款状态
+    String QUERYPAYSTATUS = "paystatus";
+    //订单取消接口
+    String PAYCANCEL = "paycancel";
+    //订单退款接口
+    String PAYREFUND = "payrefund";
+    //订单退款查询接口
+    String QUERYPAYREFUND = "payrefundquery";
+    //商户对账单下载
+    String DOWNLOADBILL = "bill/downloadbill";
+    //获取用户openid
+    String AUTHTOOPEN = "authtoopenid";
+
+}
+
+

+ 171 - 0
kmall-common/src/main/java/com/kmall/common/utils/pingan/utils/MD5.java

@@ -0,0 +1,171 @@
+package com.kmall.common.utils.pingan.utils;
+
+//~--- JDK imports ------------------------------------------------------------
+
+import java.math.BigInteger;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.UUID;
+
+//~--- classes ----------------------------------------------------------------
+
+/**
+ * Class MD5
+ * Description
+ * Create 2016-02-25 01:03:21 
+ * @author Ardy    
+ */
+public class MD5 {
+
+    /** 
+     * Field hexDigits
+     * Description 
+     */
+    private final static String[] hexDigits = {
+        "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"
+    };
+
+    /**
+     * Method byteArrayToHexString 
+     * Description 说明:
+     *
+     * @param b 说明:
+     *
+     * @return 返回值说明:
+     */
+    public static String byteArrayToHexString(byte[] b) {
+        StringBuilder resultSb = new StringBuilder();
+
+        for (byte aB : b) {
+            resultSb.append(byteToHexString(aB));
+        }
+
+        return resultSb.toString();
+    }
+
+    /**
+     * Method byteToHexString 
+     * Description 说明:
+     *
+     * @param b 说明:
+     *
+     * @return 返回值说明:
+     */
+    private static String byteToHexString(byte b) {
+        int n = b;
+
+        if (n < 0) {
+            n += 256;
+        }
+
+        int d1 = n >>> 4;
+        int d2 = n % 16;
+
+        return hexDigits[d1] + hexDigits[d2];
+    }
+
+    /**
+     * Method MD5Encode 
+     * Description 说明:
+     *
+     * @param origin 说明:
+     *
+     * @return 返回值说明:
+     */
+    public static String MD5Encode(String origin) {
+        String resultString = null;
+
+        try {
+            resultString = origin;
+
+            MessageDigest md = MessageDigest.getInstance("MD5");
+
+            resultString = byteArrayToHexString(md.digest(resultString.getBytes("utf-8")));
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        return resultString;
+    }
+
+    /**
+     * Method md5 
+     * Description 说明:
+     *
+     * @param password 说明:
+     *
+     * @return 返回值说明:
+     *
+     * @throws NoSuchAlgorithmException 异常:
+     */
+    public static String md5(String password) throws NoSuchAlgorithmException {
+        MessageDigest md = MessageDigest.getInstance("MD5");
+
+        md.update(password.getBytes());
+
+        return new BigInteger(1, md.digest()).toString(16);
+    }
+
+    /**
+     * Method md5 
+     * Description 说明:
+     *
+     * @param username 说明:
+     * @param password 说明:
+     *
+     * @return 返回值说明:
+     *
+     * @throws NoSuchAlgorithmException 异常:
+     */
+    public static String md5(String username, String password) throws NoSuchAlgorithmException {
+        MessageDigest md = MessageDigest.getInstance("MD5");
+
+        md.update(username.getBytes());
+        md.update(password.getBytes());
+
+        return new BigInteger(1, md.digest()).toString(16);
+    }
+
+    public static String md5T16(){
+        String uuid = String.valueOf(UUID.randomUUID());
+        return md5T16(uuid);
+    }
+
+    public static String md5T16(String origin){
+       return  MD5Encode(origin).substring(8, 24);
+    }
+    /**
+     * Method main 
+     * Description 说明:
+     *
+     * @param args 说明:
+     */
+    public static void main(String[] args) throws NoSuchAlgorithmException {
+        String aa = "";
+String aaa= String.valueOf("1" + System.nanoTime()) + Math.ceil(Math.random() * 9 + 1) * 10000;
+        aa = md5T16();
+       String bb = md5(aaa).substring(8,24);
+        System.out.println(aa);
+        System.out.println(bb);
+        System.out.println("1"
+                           + ( ( new SimpleDateFormat("yyyyMMddHHmm") ).format(new Date())
+                               + Math.ceil(( Math.random() * 9 + 1 ) * 100) ));
+
+        System.out.println(String.valueOf(System.nanoTime()) + "|" + aa);
+
+        try {
+            System.out.println(md5("zhangdi", "zhangdi"));
+        } catch (NoSuchAlgorithmException e) {
+
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+
+
+    }
+}
+
+
+//~ Formatted by Jindent --- http://www.jindent.com

+ 37 - 0
kmall-common/src/main/java/com/kmall/common/utils/pingan/utils/ParentDemo.java

@@ -0,0 +1,37 @@
+package com.kmall.common.utils.pingan.utils;
+
+public abstract class ParentDemo {
+	private String name;
+	private int age;
+
+	public ParentDemo(String name, int age) {
+		super();
+		this.name = name;
+		this.age = age;
+	}
+
+	
+	public ParentDemo() {
+		super();
+		// TODO Auto-generated constructor stub
+	}
+
+
+	public String getName() {
+		return name;
+	}
+	public void setName(String name) {
+		this.name = name;
+	}
+	public int getAge() {
+		return age;
+	}
+	public void setAge(int age) {
+		this.age = age;
+	}
+	
+	public abstract void study();
+
+}
+
+

+ 263 - 0
kmall-common/src/main/java/com/kmall/common/utils/pingan/utils/TLinx2Util.java

@@ -0,0 +1,263 @@
+package com.kmall.common.utils.pingan.utils;
+
+//~--- non-JDK imports --------------------------------------------------------
+
+import com.kmall.common.utils.pingan.properties.PinganPayPropertiesBuilder;
+import net.sf.json.JSONObject;
+
+import java.util.*;
+
+//~--- JDK imports ------------------------------------------------------------
+
+//~--- classes ----------------------------------------------------------------
+
+/**
+ * Class TLinx2Util
+ * Description
+ * Create 2017-03-07 14:01:23
+ *
+ * @author Benny.YEE
+ */
+public class TLinx2Util {
+
+
+    /**
+     * 交易签名
+     *
+     * @param postMap
+     * @return
+     */
+    public static String sign(Map<String, String> postMap) {
+        String sortStr = null;
+        String sign = null;
+
+        try {
+
+            /**
+             * 1 A~z排序(已加上open_key)
+             */
+            sortStr = TLinxUtil.sort(postMap);
+            System.out.println("--A~z排序后字符串--" + sortStr);
+
+            /**
+             * 2 sha1加密(小写)
+             */
+            String sha1 = TLinxSHA1.SHA1(sortStr);
+            System.out.println("--sha1加密后--" + sha1);
+
+            /**
+             * 3 md5加密(小写)
+             */
+            sign = MD5.MD5Encode(sha1).toLowerCase();
+            System.out.println("--MD5加密后--" + sign);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        return sign;
+    }
+
+    public static String signRSA(Map<String, String> postMap) {
+        String sortStr = null;
+        String sign = null;
+        try {
+
+            /**
+             * 1 A~z排序(加上open_key)
+             */
+            sortStr = TLinxUtil.sort(postMap);
+            /**
+             * 3 RSA加密(小写),二进制转十六进制
+             */
+            sign = TLinxRSACoder.sign(sortStr.getBytes("utf-8"), PinganPayPropertiesBuilder.instance().getPayPrivateKey());
+            System.out.println("RSA签名sign:" + sign);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        return sign;
+    }
+
+    public static String signRSA1(Map<String, String> postMap) {
+        String sortStr = null;
+        String sign = null;
+        try {
+
+            /**
+             * 1 A~z排序(加上open_key)
+             */
+            sortStr = "data=5930A899FFF9F828F5BC136B8F58C04BC75ED13B144501C65DC7D0E3D94B32B5F1D04EE2B022C8A2DD8A8FBB416328E6DF4F21A0A568EBCF312B25C931685030B369ED242CD1529537E3F060365DB6DB2DFA1ADD5D594EF4B78B1A8352FDF176750501D578A380E64DB1E87E6FDE2543C2F0D4D4ACB6C914563B48E54C0DF8EAB16A818939650EB70519F2BD691905078D74B5BAE11B37B4CB2D9970C0ECC540A8E85095F25EAA618A05668199C3A845FE15EED9E3CF5F0710198C9897D18AD4EFBFF91FEEA36CE527E3B2D6D86F5302030FF80B495B565142008AF8A7597743F6C36D3927EADE43FE3890DB99B337CDB1E2A84047CE916E9BE1E291586740B7B58CB4C925C2ADE17E426ABAA829B655&open_id=73b24f53ffc64486eb40d606456fb04d&open_key=7386072b1f94fdd7acaae83cd0f0f1c1&sign_type=RSA×tamp=1514951422";
+            /**
+             * 3 RSA加密(小写),二进制转十六进制
+             */
+            sign = TLinxRSACoder.sign(sortStr.getBytes("utf-8"), PinganPayPropertiesBuilder.instance().getPayPrivateKey());
+            System.out.println("sign:" + sign);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        return sign;
+    }
+
+    /**
+     * 交易验签
+     *
+     * @param respObject
+     * @return
+     */
+    public static Boolean verifySign(JSONObject respObject) {
+        String respSign = respObject.get("sign").toString();
+
+        respObject.remove("sign");    // 删除sign节点
+        respObject.put("open_key", PinganPayPropertiesBuilder.instance().getPayOpenKey()); // 添加open_key
+        // 按A~z排序,串联成字符串,先进行sha1加密(小写),再进行md5加密(小写),得到签名
+        String veriSign = sign(respObject);
+
+        if (respSign.equals(veriSign)) {
+            System.out.println("=====验签成功=====");
+
+            return true;
+        } else {
+            System.out.println("=====验签失败=====");
+        }
+
+        return false;
+    }
+
+    /**
+     * AES加密,再二进制转十六进制(bin2hex)
+     *
+     * @param postmap 说明:
+     * @throws Exception
+     */
+    public static void handleEncrypt(TreeMap<String, String> datamap, TreeMap<String, String> postmap) throws Exception {
+
+        JSONObject dataobj = JSONObject.fromObject(datamap);
+        System.out.println("---data数据---" + dataobj);
+        String data = TLinxAESCoder.encrypt(dataobj.toString(), PinganPayPropertiesBuilder.instance().getPayOpenKey());    // AES加密,并bin2hex
+        System.out.println("---AES加密后的data数据---" + data);
+        postmap.put("data", data);
+        System.out.println("--postmap1--" + postmap);
+    }
+
+    /**
+     * 签名
+     *
+     * @param postmap
+     */
+    public static void handleSign(TreeMap<String, String> postmap) {
+        Map<String, String> veriDataMap = new HashMap<String, String>();
+
+        veriDataMap.putAll(postmap);
+        veriDataMap.put("open_key", PinganPayPropertiesBuilder.instance().getPayOpenKey());
+        System.out.println("--将要签名的数据--" + veriDataMap);
+        // 签名
+        String sign = sign(veriDataMap);
+
+        postmap.put("sign", sign);
+        System.out.println("--postmap2--" + postmap);
+    }
+
+    /**
+     * 签名
+     *
+     * @param postmap
+     */
+    public static void handleSignRSA(TreeMap<String, String> postmap) {
+        Map<String, String> veriDataMap = new HashMap<String, String>();
+
+        veriDataMap.putAll(postmap);
+        veriDataMap.put("open_key", PinganPayPropertiesBuilder.instance().getPayOpenKey());
+
+        // 签名
+        String sign = signRSA(veriDataMap);
+
+        postmap.put("sign", sign);
+        System.out.println("请求postmap---" + postmap);
+    }
+
+
+    /**
+     * 请求接口
+     *
+     * @param postmap
+     * @return 响应字符串
+     */
+    public static String handlePost(TreeMap<String, String> postmap, String interfaceName) {
+        String url = PinganPayPropertiesBuilder.instance().getPayUrl() + interfaceName;
+        System.out.println("url----:" + url);
+        if (url.contains("https")) {
+            return HttpsUtil.httpMethodPost(url, postmap, "UTF-8");
+        } else {
+            return HttpUtil.httpMethodPost(url, postmap, "UTF-8");
+        }
+    }
+
+    /**
+     * Method main
+     * Description 说明:
+     *
+     * @param args 说明:
+     */
+    public static void main(String[] args) {
+
+        // 初始化参数
+        String pmtType = "0,1,2,3";
+        String timestamp = new Date().getTime() / 1000 + "";    // 时间
+
+        try {
+            // 固定参数
+            TreeMap<String, String> postmap = new TreeMap<String, String>();//请求参数的map
+            postmap.put("open_id", PinganPayPropertiesBuilder.instance().getPayOpenId());
+            postmap.put("timestamp", timestamp);
+
+            TreeMap<String, String> datamap = new TreeMap<String, String>();//data参数的map
+            datamap.put("pmt_type", pmtType);
+
+            /**
+             * 1 data字段内容进行AES加密,再二进制转十六进制(bin2hex)
+             */
+            handleEncrypt(datamap, postmap);
+
+            /**
+             * 2 请求参数签名 按A~z排序,串联成字符串,先进行sha1加密(小写),再进行md5加密(小写),得到签名
+             */
+            handleSign(postmap);
+
+            /**
+             * 3 请求、响应
+             */
+            String rspStr = handlePost(postmap, InterfaceParams.PAYLIST);
+
+
+            /**
+             * 4 验签  有data节点时才验签
+             */
+            JSONObject respObject = JSONObject.fromObject(rspStr);
+
+            Object dataStr = respObject.get("data");
+            System.out.println("返回data字符串=" + dataStr);
+
+            if (!rspStr.isEmpty() || (dataStr != null)) {
+                if (verifySign(respObject)) {    // 验签成功
+
+                    /**
+                     * 5 AES解密,并hex2bin
+                     */
+                    String respData = TLinxAESCoder.decrypt(dataStr.toString(), PinganPayPropertiesBuilder.instance().getPayOpenKey());
+
+                    System.out.println("==================响应data内容:" + respData);
+                } else {
+                    System.out.println("=====验签失败=====");
+                }
+            } else {
+                System.out.println("=====没有返回data数据=====");
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+}
+
+
+//~ Formatted by Jindent --- http://www.jindent.com

File diff suppressed because it is too large
+ 81 - 0
kmall-common/src/main/java/com/kmall/common/utils/pingan/utils/TLinxAESCoder.java


+ 100 - 0
kmall-common/src/main/java/com/kmall/common/utils/pingan/utils/TLinxMapUtil.java

@@ -0,0 +1,100 @@
+/**
+ * @Filename: TLinxMapUtil.java
+ * @Author:caiqf
+ * @Date�?014-10-11
+ */
+package com.kmall.common.utils.pingan.utils;
+
+import java.lang.reflect.Method;
+import java.util.*;
+
+/**
+ * @Class: TLinxMapUtil.java
+ * @Description: 
+ * @Author:caiqf
+ * @Date�?014-10-11
+ */
+@SuppressWarnings("all")
+public class TLinxMapUtil {
+	private Map map = new HashMap();
+	private Set keySet = map.keySet();
+
+	public Object get(String key) {
+		return map.get(key);
+	}
+
+	public void put(String key, Object value) {
+		map.put(key, value);
+	}
+
+	public void sort() {
+		List list = new ArrayList(map.keySet());
+
+//		Collections.sort(list, new Comparator() {
+//			public int compare(Object a, Object b) {
+//				return a.toString().compareTo(b.toString());
+//			}
+//		});
+
+		this.keySet = new TreeSet(list);
+	}
+
+	public Set keySet() {
+		return this.keySet;
+	}
+
+	/**
+	 * @Description: ��Map��ֵ��һ������
+	 * @param @param javabean ��ֵ�Ķ���
+	 * @param @param m
+	 * @return void
+	 * @throws
+	 */
+	public static void mapToBean(Object javabean, Map<String, Object> m) {
+		Method[] methods = javabean.getClass().getDeclaredMethods();
+		for (Method method : methods) {
+			if (method.getName().startsWith("set")) {
+				// �õ��÷����IJ�������
+				Class<?>[] params = method.getParameterTypes();
+				String field = method.getName();
+				field = field.substring(field.indexOf("set") + 3);
+				field = field.toLowerCase().charAt(0) + field.substring(1);
+				Object value = m.get(field.toString());
+				try {
+					if (value != null && !"".equals(value)) {
+						String pa = params[0].getName().toString();
+						if (pa.equals("java.util.Date")) {
+							value = new Date(
+									((Date) value).getTime());
+						} else if (pa.equals("java.lang.String")) {
+							value = new String(value.toString());
+						} else if (pa.equals("java.lang.Integer")
+								|| pa.equals("int")) {
+							value = new Integer(value.toString());
+						} else if (pa.equals("java.lang.Long")) {
+							value = new Long(value.toString());
+						} else if (pa.equals("java.lang.Double")) {
+							value = new Double(value.toString());
+
+						} else if (pa.equals("java.lang.Float")) {
+							value = new Float(value.toString());
+
+						} else if (pa.equals("java.lang.Short")) {
+							value = new Short(value.toString());
+
+						} else if (pa.equals("java.lang.Byte")) {
+							value = new Byte(value.toString());
+
+						} else if (pa.equals("java.lang.Boolean")) {
+							value = new Boolean(value.toString());
+
+						}
+						method.invoke(javabean, value);
+					}
+				} catch (Exception e) {
+					e.printStackTrace();
+				}
+			}
+		}
+	}
+}

+ 242 - 0
kmall-common/src/main/java/com/kmall/common/utils/pingan/utils/TLinxPluginUtil.java

@@ -0,0 +1,242 @@
+package com.kmall.common.utils.pingan.utils;
+
+//~--- non-JDK imports --------------------------------------------------------
+
+import com.kmall.common.utils.pingan.properties.PinganPayPropertiesBuilder;
+import net.sf.json.JSONObject;
+import org.apache.commons.lang.RandomStringUtils;
+
+import java.util.*;
+
+//~--- JDK imports ------------------------------------------------------------
+
+//~--- classes ----------------------------------------------------------------
+
+/**
+ * Class TLinx2Util
+ * Description tlinx api 工具类
+ * Create 2017-03-07 14:01:23
+ * @author Benny.YEE
+ */
+public class TLinxPluginUtil {
+
+    /**
+     * 签名
+     * @param postMap
+     * @param privatekey 说明:
+     * @return
+     */
+    public static String sign(Map<String, String> postMap, String privatekey) {
+        String sortStr = null;
+        String sign    = null;
+
+        try {
+
+            /**
+             * 1 A~z排序
+             */
+            sortStr = sort(postMap);
+      //     System.out.println("=======排序后的明文:" + sortStr);
+
+            /**
+             * 2 sha1加密(小写)
+             */
+            String sha1 = TLinxSHA1.SHA1(sortStr);
+
+     //       System.out.println("=======sha1:" + sha1);
+
+            /**
+             * 3 RSA加密(小写),二进制转十六进制
+             */
+            sign = TLinxRSACoder.sign(sha1.getBytes("utf-8"), privatekey);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        return sign;
+    }
+
+    /**
+     * 进件验签
+     * @param respObject
+     * @param publickey 说明:
+     * @return
+     */
+    public static Boolean verifySign(JSONObject respObject, String publickey) {
+        boolean verify = false;
+        try {
+            String respSign = respObject.getString("sign");
+
+            respObject.remove("sign");                // 删除sign节点
+
+            String rspparm = sortjson(respObject);    
+            String sha1    = TLinxSHA1.SHA1(rspparm);           // sha1加密
+
+            verify = TLinxRSACoder.verify(sha1.getBytes(), publickey, respSign);
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        return verify;
+    }
+
+    /**
+     * AES加密,再二进制转十六进制(bin2hex)
+     * @param datamap 说明:
+     *
+     * @return 返回值说明:
+     * @throws Exception
+     */
+    public static String handleEncrypt(JSONObject datamap) throws Exception {
+    	System.out.println("aes加密data数据:"+datamap.toString());
+        return TLinxAESCoder.encrypt(datamap.toString(), PinganPayPropertiesBuilder.instance().getPayOpenKey());    // AES加密,并bin2hex
+    }
+    
+
+    /**
+     * 签名
+     * @param getmap
+     * @param datamap 说明:
+     *
+     * @return 返回值说明:
+     */
+    public static String handleSign(TreeMap<String, String> getmap, TreeMap<String, String> datamap) {
+        Map<String, String> veriDataMap = new HashMap<String, String>();
+
+        veriDataMap.putAll(getmap);
+        veriDataMap.putAll(datamap);
+
+        // 私钥签名
+        return sign(veriDataMap, PinganPayPropertiesBuilder.instance().getPayPrivateKey());
+    }
+    
+    /**
+     * 签名(不上送datamap时用)
+     * @param getmap
+     *
+     * @return 返回值说明:
+     */
+    public static String handleSign2(TreeMap<String, String> getmap) {
+        Map<String, String> veriDataMap = new HashMap<String, String>();
+
+        veriDataMap.putAll(getmap);
+        // 签名
+        return sign(veriDataMap, PinganPayPropertiesBuilder.instance().getPayPrivateKey());
+    }
+
+    /**
+     * 根据返回格式来选择post请求处理方式
+     * @param postmap
+     * @param uri
+     * @param tarType
+     * @return
+     */
+    public static String handlePostbyTarType(TreeMap<String, String> postmap, String uri, String tarType) {
+        if("gzip".equals(tarType)){
+            return handlePostGZIP(postmap, uri);
+        }else{
+            return handlePost(postmap, uri);
+        }
+    }
+
+    /**
+     * 请求接口
+     * @param postmap
+     * @param uri 说明:
+     * @return      响应字符串
+     */
+    public static String handlePost(TreeMap<String, String> postmap, String uri) {
+        String url = PinganPayPropertiesBuilder.instance().getPayUrl() + uri;
+        System.out.println("==url=="+url);
+        if (url.contains("https")) {
+            return HttpsUtil.httpMethodPost(url, postmap, "UTF-8");
+        } else {
+            return HttpUtil.httpMethodPost(url, postmap, "UTF-8");
+        }
+    }
+    
+    public static String handlePost2(TreeMap<String, String> postmap, String uri) {
+        if (uri.contains("https")) {
+            return HttpsUtil.httpMethodPost(uri, postmap, "UTF-8");
+        } else {
+            return HttpUtil.httpMethodPost(uri, postmap, "UTF-8");
+        }
+    }
+       
+    
+
+    public static String handlePostGZIP(TreeMap<String, String> postmap, String uri) {
+        String url = PinganPayPropertiesBuilder.instance().getPayUrl() + uri;
+        if (url.contains("https")) {
+            return HttpsUtil.httpMethodPostGZIP(url, postmap, "UTF-8");
+        } else {
+            return HttpUtil.httpMethodPostGZIP(url, postmap, "UTF-8");
+        }
+    }
+ 
+
+    // 排序
+    public static String sort(Map paramMap) throws Exception {
+        String sort = "";
+        TLinxMapUtil signMap = new TLinxMapUtil();
+        if (paramMap != null) {
+            String key;
+            for (Iterator it = paramMap.keySet().iterator(); it.hasNext();) {
+                key = (String) it.next();
+                String value = ((paramMap.get(key) != null) && (!(""
+                        .equals(paramMap.get(key).toString())))) ? paramMap
+                        .get(key).toString() : "";
+                signMap.put(key, value);
+            }
+            signMap.sort();
+            for (Iterator it = signMap.keySet().iterator(); it.hasNext();) {
+                key = (String) it.next();
+                sort = sort + key + "=" + signMap.get(key).toString() + "&";
+            }
+            if ((sort != null) && (!("".equals(sort)))) {
+                sort = sort.substring(0, sort.length() - 1);
+            }
+        }
+        return sort;
+    }
+
+
+    // 排序
+    public static String sortjson(JSONObject jsonMap) throws Exception {
+        Map<String ,String > paramMap=new HashMap<String, String>();
+        // 将json字符串转换成jsonObject
+        JSONObject jsonObject = JSONObject.fromObject(jsonMap);
+        Iterator ite = jsonObject.keys();
+        // 遍历jsonObject数据,添加到Map对象
+        while (ite.hasNext()) {
+            String key = ite.next().toString();
+            String value = jsonObject.get(key).toString();
+            paramMap.put(key, value);
+        }
+        String sort = "";
+        TLinxMapUtil signMap = new TLinxMapUtil();
+        if (paramMap != null) {
+            String key1;
+            for (Iterator it = paramMap.keySet().iterator(); it.hasNext();) {
+                key1 = (String) it.next();
+                String value = ((paramMap.get(key1) != null) && (!(""
+                        .equals(paramMap.get(key1).toString())))) ? paramMap
+                        .get(key1).toString() : "";
+                signMap.put(key1, value);
+            }
+            signMap.sort();
+            for (Iterator it = signMap.keySet().iterator(); it.hasNext();) {
+                key1 = (String) it.next();
+                sort = sort + key1 + "=" + signMap.get(key1).toString() + "&";
+            }
+            if ((sort != null) && (!("".equals(sort)))) {
+                sort = sort.substring(0, sort.length() - 1);
+            }
+        }
+        return sort;
+    }
+}
+
+
+//~ Formatted by Jindent --- http://www.jindent.com

+ 211 - 0
kmall-common/src/main/java/com/kmall/common/utils/pingan/utils/TLinxRSACoder.java

@@ -0,0 +1,211 @@
+/**
+ * @Filename: TLinxRSACoder.java
+ * @Author锛歝aiqf
+ * @Date锛�016-4-12
+ */
+package com.kmall.common.utils.pingan.utils;
+
+import sun.misc.BASE64Decoder;
+import sun.misc.BASE64Encoder;
+
+import javax.crypto.Cipher;
+import java.security.*;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @Class: TLinxRSACoder.java
+ * @Description: RSA加解密类
+ * @Author:caiqf
+ * @Date:2016-4-12
+ */
+@SuppressWarnings("all")
+public class TLinxRSACoder {
+    public static final String KEY_ALGORITHM = "RSA";
+    public static final String SIGNATURE_ALGORITHM = "MD5withRSA";
+    private static final String PUBLIC_KEY = "RSAPublicKey";
+    private static final String PRIVATE_KEY = "RSAPrivateKey";
+
+    public static Map<String, Object> initKey() throws Exception {
+        Map keyMap = new HashMap(2);
+        KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
+        keyPairGen.initialize(2048);
+        KeyPair keyPair = keyPairGen.generateKeyPair();
+        keyMap.put("RSAPublicKey", (RSAPublicKey) keyPair.getPublic());
+        keyMap.put("RSAPrivateKey", (RSAPrivateKey) keyPair.getPrivate());
+        return keyMap;
+    }
+
+    public static String getPrivateKey(Map<String, Object> keyMap)
+            throws Exception {
+        Key key = (Key) keyMap.get("RSAPrivateKey");
+        return new BASE64Encoder().encodeBuffer(key.getEncoded());
+    }
+
+    public static String getPublicKey(Map<String, Object> keyMap)
+            throws Exception {
+        Key key = (Key) keyMap.get("RSAPublicKey");
+        return new BASE64Encoder().encodeBuffer(key.getEncoded());
+    }
+
+    public static byte[] encryptByPrivateKey(byte[] data, String key)
+            throws Exception {
+        byte[] keyBytes = new BASE64Decoder().decodeBuffer(key);
+
+        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
+        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
+        Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
+
+        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
+        cipher.init(1, privateKey);
+
+        return cipher.doFinal(data);
+    }
+
+    public static byte[] decryptByPrivateKey(byte[] data, String key)
+            throws Exception {
+        byte[] keyBytes = new BASE64Decoder().decodeBuffer(key);
+
+        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
+        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
+        Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
+
+        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
+        cipher.init(2, privateKey);
+
+        return cipher.doFinal(data);
+    }
+
+    public static byte[] encryptByPublicKey(byte[] data, String key)
+            throws Exception {
+        byte[] keyBytes = new BASE64Decoder().decodeBuffer(key);
+
+        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
+        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
+        Key publicKey = keyFactory.generatePublic(x509KeySpec);
+
+        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
+        cipher.init(1, publicKey);
+
+        return cipher.doFinal(data);
+    }
+
+    public static byte[] decryptByPublicKey(byte[] data, String key)
+            throws Exception {
+        byte[] keyBytes = new BASE64Decoder().decodeBuffer(key);
+
+        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
+        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
+        Key publicKey = keyFactory.generatePublic(x509KeySpec);
+
+        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
+        cipher.init(2, publicKey);
+
+        return cipher.doFinal(data);
+    }
+    /**
+     * RSA签名
+     * @param data
+     * @param privateKey
+     * @return
+     * @throws Exception
+     */
+    public static String sign(byte[] data, String privateKey) throws Exception {
+
+    	byte[] keyBytes = new BASE64Decoder().decodeBuffer(privateKey);
+        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
+
+        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
+
+        PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);
+
+        Signature signature = Signature.getInstance("SHA1withRSA");
+        signature.initSign(priKey);
+        signature.update(data);
+	
+        return  byte2hex(signature.sign());
+    }
+
+    public static boolean verify(byte[] data, String publicKey, String sign)
+            throws Exception {
+        byte[] keyBytes = new BASE64Decoder().decodeBuffer(publicKey);
+
+        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
+
+        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
+
+        PublicKey pubKey = keyFactory.generatePublic(keySpec);
+        Signature signature = Signature.getInstance("SHA1withRSA");
+        signature.initVerify(pubKey);
+        signature.update(data);
+
+        //sign 16进制转换成byte数组
+        return signature.verify(hexStrToBytes(sign));
+    }
+
+    public static String hexString2binaryString(String hexString) {
+        if (hexString == null || hexString.length() % 2 != 0)
+            return null;
+        String bString = "", tmp;
+        for (int i = 0; i < hexString.length(); i++) {
+            tmp = "0000"
+                    + Integer.toBinaryString(Integer.parseInt(hexString
+                    .substring(i, i + 1), 16));
+            bString += tmp.substring(tmp.length() - 4);
+        }
+        return bString;
+    }
+
+    private static byte[] hex2byte(String strhex) {
+        if (strhex == null)
+            return null;
+
+        int l = strhex.length();
+        if (l % 2 == 1)
+            return null;
+
+        byte[] b = new byte[l / 2];
+        for (int i = 0; i != l / 2; ++i)
+            b[i] = (byte) Integer.parseInt(strhex.substring(i * 2, i * 2 + 2),
+                    16);
+
+        return b;
+    }
+    /**
+	 * 二进制转十六进制
+	 */
+    private static String byte2hex(byte[] b) {
+        String hs = "";
+        String stmp = "";
+        for (int n = 0; n < b.length; ++n) {
+            stmp = Integer.toHexString(b[n] & 0xFF);
+            if (stmp.length() == 1)
+                hs = hs + "0" + stmp;
+            else
+                hs = hs + stmp;
+        }
+
+        return hs.toUpperCase();
+    }
+  /**
+  * 将16进制字符串还原为字节数组.
+  */
+ public static final byte[] hexStrToBytes(String s) {
+
+     byte[] bytes;
+
+     bytes = new byte[s.length() / 2];
+
+     for (int i = 0; i < bytes.length; i++) {
+         bytes[i] = (byte) Integer.parseInt(s.substring(2 * i, 2 * i + 2), 16);
+     }
+
+     return bytes;
+ }
+
+
+}

+ 34 - 0
kmall-common/src/main/java/com/kmall/common/utils/pingan/utils/TLinxSHA1.java

@@ -0,0 +1,34 @@
+/**
+ * @Filename: TLinxSHA1.java
+ * @Author:caiqf
+ * @Date�?016-4-12
+ */
+package com.kmall.common.utils.pingan.utils;
+
+import java.security.MessageDigest;
+
+/**
+ * @Class: TLinxSHA1.java
+ * @Description:  SHA1加密
+ */
+public class TLinxSHA1 {
+	public static String SHA1(String decript) {
+		try {
+			MessageDigest digest = MessageDigest.getInstance("SHA-1");
+			digest.update(decript.getBytes("UTF-8"));
+			byte[] messageDigest = digest.digest();
+			StringBuilder hexString = new StringBuilder();
+			for (byte message : messageDigest) {
+				String shaHex = Integer.toHexString(message & 0xFF);
+				if (shaHex.length() < 2)
+					hexString.append(0);
+
+				hexString.append(shaHex);
+			}
+			return hexString.toString().toLowerCase();
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+		return "";
+	}
+}

+ 93 - 0
kmall-common/src/main/java/com/kmall/common/utils/pingan/utils/TLinxUtil.java

@@ -0,0 +1,93 @@
+/**
+ * @Filename: TLinxUtil.java
+ * @Author caiqf
+ * @Date 016-4-12
+ */
+package com.kmall.common.utils.pingan.utils;
+
+import net.sf.json.JSONObject;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * @Class: TLinxUtil.java
+ * @Description: TLinx宸ュ叿绫?
+ * @Author caiqf
+ * @Date 2016-4-12
+ */
+@SuppressWarnings("all")
+public class TLinxUtil {
+	// 排序
+	public static String sort(Map paramMap) throws Exception {
+		String sort = "";
+		TLinxMapUtil signMap = new TLinxMapUtil();
+		if (paramMap != null) {
+			String key;
+			for (Iterator it = paramMap.keySet().iterator(); it.hasNext();) {
+				key = (String) it.next();
+				String value = ((paramMap.get(key) != null) && (!("".equals(paramMap.get(key).toString())))) ? paramMap.get(key).toString() : "";
+				signMap.put(key, value);
+			}
+			signMap.sort();
+			for (Iterator it = signMap.keySet().iterator(); it.hasNext();) {
+				key = (String) it.next();
+				sort = sort + key + "=" + signMap.get(key).toString() + "&";
+			}
+			if ((sort != null) && (!("".equals(sort)))) {
+				sort = sort.substring(0, sort.length() - 1);
+			}
+		}
+		return sort;
+	}
+
+
+	// 排序
+	public static String sortjson(JSONObject jsonMap) throws Exception {
+		Map<String ,String > paramMap=new HashMap<String, String>();
+		// 将json字符串转换成jsonObject
+		JSONObject jsonObject = JSONObject.fromObject(jsonMap);
+		Iterator ite = jsonObject.keys();
+		// 遍历jsonObject数据,添加到Map对象
+		while (ite.hasNext()) {
+			String key = ite.next().toString();
+			String value = jsonObject.get(key).toString();
+			paramMap.put(key, value);
+		}
+		String sort = "";
+		TLinxMapUtil signMap = new TLinxMapUtil();
+		if (paramMap != null) {
+			String key1;
+			for (Iterator it = paramMap.keySet().iterator(); it.hasNext();) {
+				key1 = (String) it.next();
+				String value = ((paramMap.get(key1) != null) && (!(""
+						.equals(paramMap.get(key1).toString())))) ? paramMap
+						.get(key1).toString() : "";
+				signMap.put(key1, value);
+			}
+			signMap.sort();
+			for (Iterator it = signMap.keySet().iterator(); it.hasNext();) {
+				key1 = (String) it.next();
+				sort = sort + key1 + "=" + signMap.get(key1).toString() + "&";
+			}
+			if ((sort != null) && (!("".equals(sort)))) {
+				sort = sort.substring(0, sort.length() - 1);
+			}
+		}
+		return sort;
+	}
+
+	// AES加密
+	public static String AESEncrypt(String jsonData, String aeskey)
+			throws Exception {
+		return TLinxAESCoder.encrypt(jsonData, aeskey);
+	}
+
+	// AES解密
+	public static String AESDecrypt(String data, String aeskey)
+			throws Exception {
+		return TLinxAESCoder.decrypt(data, aeskey);
+	}
+
+}

+ 1 - 0
kmall-common/src/main/java/com/kmall/common/utils/wechat/MD5Util.java

@@ -39,6 +39,7 @@ public class MD5Util {
                 resultString = byteArrayToHexString(md.digest(resultString
                         .getBytes(charsetname)));
         } catch (Exception exception) {
+            exception.printStackTrace();
         }
         return resultString;
     }

+ 4 - 5
kmall-schedule/src/main/java/com/kmall/schedule/dao/QzOrderMapper.java

@@ -54,14 +54,13 @@ public interface QzOrderMapper {
 
     void updateReceiptOrderByCommentCount();
 
+    int insertPinganResponseDto(Map fromObject);
 
-    /**
-     * 根据订单编号查询
-     * @param orderSn 订单编号
-     * @return
-     */
     Map queryOrder(String orderSn);
 
     List<Map> queryWXPaySuccessRecords(String orderSn);
 
+    int updatePayOrderByOutNo(Map fromObject);
+
+    List<Map> queryPinganPayingOrderList();
 }

+ 11 - 0
kmall-schedule/src/main/java/com/kmall/schedule/quartz/OrderTask.java

@@ -69,6 +69,17 @@ public class OrderTask {
     }
 
     /**
+     * 方法描述:查询支付中的订单以及小程序更新支付信息异常订单,查询平安订单信息更新订单状态
+     * 二分钟更新订单
+     */
+    @Scheduled(fixedRate = 1000 * 60 * 1)
+    public void pinganOrderQueryUpdate() {
+        logger.info(">>>>>>>>>>>>>>>>>>>>pinganOrderQueryUpdate is start ");
+        qzOrderService.pinganOrderQueryUpdate();
+        logger.info(">>>>>>>>>>>>>>>>>>>>pinganOrderQueryUpdate is end ");
+    }
+
+    /**
      * 方法描述:商品发货后7天自动确认收货
      */
     @Scheduled(cron = "0 0 2 * * ?")

+ 218 - 8
kmall-schedule/src/main/java/com/kmall/schedule/service/QzOrderService.java

@@ -11,10 +11,22 @@ import com.kmall.schedule.dao.QzGroupMapper;
 import com.kmall.schedule.dao.QzOrderMapper;
 import com.kmall.common.dao.TemplateConfDao;
 import com.kmall.common.entity.TemplateConfVo;
-import com.kmall.schedule.quartz.OrderTask;
+import com.kmall.common.utils.*;
+import com.kmall.common.utils.pingan.PinganUtil;
+import com.kmall.common.utils.pingan.dto.PinganPayOrderDto;
+import com.kmall.common.utils.pingan.dto.PinganResponseDto;
+import com.kmall.common.utils.wechat.ReaderXmlForDOM4J;
+import com.kmall.common.utils.wechat.WechatRefundApiResult;
+import com.kmall.common.utils.wechat.WechatRefundQueryResult;
+import com.kmall.common.utils.wechat.WechatUtil;
 import com.kmall.common.utils.wxtemplate.TemplateData;
 import com.kmall.common.utils.wxtemplate.WxTemplate;
 import com.kmall.common.utils.wxtemplate.WxTemplateUtil;
+import com.kmall.schedule.dao.OrderWXPayRecordMapper;
+import com.kmall.schedule.dao.QzGroupMapper;
+import com.kmall.schedule.dao.QzOrderMapper;
+import com.kmall.schedule.quartz.OrderTask;
+import net.sf.json.JSONObject;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -90,9 +102,7 @@ public class QzOrderService {
                 long second = (time - hour * 3600 - minite * 60);
                 String body = hour + "时" + minite + "分" + second + "秒";
                 paras.add(new TemplateData("keyword3", body, "#000000"));
-                paras.add(new TemplateData("keyword4",
-                                           retail_min_price.setScale(2, BigDecimal.ROUND_HALF_DOWN).toString() + "元",
-                                           "#000000"));
+                paras.add(new TemplateData("keyword4", retail_min_price.setScale(2, BigDecimal.ROUND_HALF_DOWN).toString() + "元", "#000000"));
                 paras.add(new TemplateData("keyword5", templateConfVo.getDesc(), "#000000"));
                 tem.setData(paras);
                 WxTemplateUtil.sendMessage(tem);
@@ -130,7 +140,7 @@ public class QzOrderService {
                 }
                 WxTemplate tem = new WxTemplate();
                 tem.setTemplate_id(templateConfVo.getTemplateId());
-                //                tem.setTopcolor("#00DD00");
+//                tem.setTopcolor("#00DD00");
                 tem.setTouser(open_id);
                 tem.setPage("/pages/groupDetail/groupDetail?id=" + group_id);
                 tem.setForm_id(form_id);
@@ -176,7 +186,7 @@ public class QzOrderService {
                 }
                 WxTemplate tem = new WxTemplate();
                 tem.setTemplate_id(templateConfVo.getTemplateId());
-                //                tem.setTopcolor("#00DD00");
+//                tem.setTopcolor("#00DD00");
                 tem.setTouser(open_id);
                 tem.setPage("/pages/ucenter/orderDetail/orderDetail?id=" + id);
                 tem.setForm_id(form_id);
@@ -232,8 +242,10 @@ public class QzOrderService {
                 if(org.apache.commons.lang.StringUtils.isNotEmpty(pay_flag)) {
                     if (pay_flag.equalsIgnoreCase("wxglobalpay")) {//微信国际支付
                         wxGlobalRefundQuery(map);
-                    } else {//微信支付、平安支付、线下扫码支付
+                    } else if (pay_flag.equalsIgnoreCase("weixin")) {//微信支付、平安支付、线下扫码支付
                         wxRefundquery(map);
+                    } else if (pay_flag.equalsIgnoreCase("pingan")) {
+                        pinganRefundquery(map);
                     }
                 }else{
                     logger.info(">>>>>>>>>>>>>>>>>>>>refundUpdate 订单编号【"+orderId+"】的支付方式不能为空! ");
@@ -246,7 +258,7 @@ public class QzOrderService {
     }
 
     /**
-     * 微信支付、平安支付、线下扫码支付共用微信查询订单api
+     * 微信支付、线下扫码支付共用微信查询订单api
      * @param map
      */
     private void  wxRefundquery(Map map){
@@ -321,6 +333,133 @@ public class QzOrderService {
     }
 
     /**
+     * 平安支付查询订单api
+     * @param map
+     */
+    private void  pinganRefundquery(Map map){
+        logger.info(">>>>>>>>>>>>>>>>>>>>pinganRefundquery 平安退款查询接口调用");
+        String outNo = MapUtils.getString("merch_order_sn", map);
+        String outRefundNo = MapUtils.getString("out_refund_no", map);
+        String orderId = MapUtils.getString("order_id", map);
+
+        PinganResponseDto response = PinganUtil.pinganQueryRefund(null, outRefundNo);
+        if (!Objects.isNull(response)) {
+            response.setOutNo(outNo);
+            response.setCreateTime(new Date());
+            qzOrderMapper.insertPinganResponseDto(MapBeanUtil.fromObject(response));
+
+            if ("0".equals(response.getErrcode()) && StringUtils.isNotEmpty(response.getDatajson())) {
+                JSONObject refundResult = JSONObject.fromObject(response.getDatajson());
+                String tradeResult = refundResult.getString("trade_result");
+
+                JSONObject result = JSONObject.fromObject(tradeResult);
+                Map refundParam = new HashMap();
+                Map orderParam = new HashMap();
+                int msgCount = Integer.parseInt(result.getString("refund_count"));
+                for (int i = 0; i < msgCount; i++) {
+                    WechatRefundQueryResult refundQueryResult = PinganUtil.buildWechatRefundQueryResult(result, i);
+                    if(outRefundNo.equalsIgnoreCase(refundQueryResult.getOut_refund_no())) {
+                        Date successTime = DateUtils.strToDate(refundQueryResult.getRefund_success_time());
+                        refundParam.put("refundTime", successTime);
+                        refundParam.put("outRefundNo", refundQueryResult.getOut_refund_no());
+                        refundParam.put("refundId", refundQueryResult.getRefund_id());
+                        refundParam.put("refundMoney",
+                                BigDecimal.valueOf(Long.valueOf(refundQueryResult.getRefund_fee()))
+                                        .divide(Constant.ONE_HUNDRED));
+                        if (refundQueryResult.getRefund_status().equalsIgnoreCase(WechatUtil.WXTradeState.SUCCESS.getCode())) {
+                            refundParam.put("refundStatus", Dict.RefundStatus.item_2.getItem());
+                            refundParam.put("wechat_refund_status_des", "退款成功");
+                            orderParam.put("payStatus", Dict.payStatus.item_4.getItem());
+                        } else if (refundQueryResult.getRefund_status().equalsIgnoreCase("REFUNDCLOSE")) {
+                            refundParam.put("refundStatus", Dict.RefundStatus.item_4.getItem());
+                            refundParam.put("wechat_refund_status_des", "退款关闭");
+                            orderParam.put("payStatus", Dict.payStatus.item_5.getItem());
+                        } else if (refundQueryResult.getRefund_status().equalsIgnoreCase("CHANGE")) {
+                            refundParam.put("refundStatus", Dict.RefundStatus.item_4.getItem());
+                            refundParam.put("wechat_refund_status_des", "退款异常");
+                            orderParam.put("payStatus", Dict.payStatus.item_6.getItem());
+                        } else if (refundQueryResult.getRefund_status().equalsIgnoreCase("PROCESSING")) {
+                            refundParam.put("refundStatus", Dict.RefundStatus.item_5.getItem());
+                            refundParam.put("wechat_refund_status_des", "退款处理中");
+                            orderParam.put("payStatus", Dict.payStatus.item_3.getItem());
+                        }
+                        refundParam.put("refundRecvAccout", refundQueryResult.getRefund_recv_accout());
+                        refundParam.put("orderRefundId", refundQueryResult.getOut_refund_no());
+                        qzOrderMapper.updateOrderRefund(refundParam);//更新订单退款信息
+                    }
+                }
+                orderParam.put("orderStatus", Dict.orderStatus.item_401.getItem());
+                orderParam.put("orderId", orderId);
+                orderParam.put("payTransactionId", MapUtils.getString("transaction_id", result).equals("null") ? null : MapUtils.getString("transaction_id", result));
+                qzOrderMapper.updateOrderInfo(orderParam);
+            } else {
+                logger.info(">>>>>>>>>>>>>>>>>>>>pinganRefundquery 平安退款查询接口返回失败信息:code 【" + response.getErrcode() + "】,des【" + response.getMsg() + "】");
+            }
+        } else {
+            logger.info(">>>>>>>>>>>>>>>>>>>>pinganRefundquery 平安退款查询接口调用失败");
+        }
+
+        /*WechatRefundQueryResult result = WechatUtil.wxRefundquery(out_trade_no);
+        if (result.getReturn_code().equalsIgnoreCase(WechatUtil.WXTradeState.SUCCESS.getCode())) {
+            if (result.getResult_code().equalsIgnoreCase(WechatUtil.WXTradeState.SUCCESS.getCode())) {
+                Map refundRaram = new HashMap();
+                Map orderRaram = new HashMap();
+                int msgCount = Integer.parseInt(result.getRefund_count());
+                for (int i = 0; i < msgCount; i++) {
+                    WechatRefundQueryResult querySuccessResponseDto =
+                            ReaderXmlForDOM4J.parse(result.getXmlStr(), i);
+                    if(out_refund_no.equalsIgnoreCase(querySuccessResponseDto.getOut_refund_no())) {
+                        result.setRefund_success_time(querySuccessResponseDto.getRefund_success_time());
+                        result.setOut_refund_no(querySuccessResponseDto.getOut_refund_no());
+                        result.setRefund_account(querySuccessResponseDto.getRefund_account());
+                        result.setRefund_channel(querySuccessResponseDto.getRefund_channel());
+                        result.setRefund_fee(querySuccessResponseDto.getRefund_fee());
+                        result.setRefund_id(querySuccessResponseDto.getRefund_id());
+                        result.setRefund_recv_accout(querySuccessResponseDto.getRefund_recv_accout());
+                        result.setRefund_status(querySuccessResponseDto.getRefund_status());
+
+                        Date successTime = DateUtils.strToDate(result.getRefund_success_time());
+                        refundRaram.put("refundTime", successTime);
+                        refundRaram.put("outRefundNo", result.getOut_refund_no());
+                        refundRaram.put("refundId", result.getRefund_id());
+                        refundRaram.put("refundMoney",
+                                BigDecimal.valueOf(Long.valueOf(result.getRefund_fee()))
+                                        .divide(Constant.ONE_HUNDRED));
+                        if (result.getRefund_status().equalsIgnoreCase(WechatUtil.WXTradeState.SUCCESS.getCode())) {
+                            refundRaram.put("refundStatus", Dict.RefundStatus.item_2.getItem());
+                            refundRaram.put("wechat_refund_status_des", "退款成功");
+                            orderRaram.put("payStatus", Dict.payStatus.item_4.getItem());
+                        } else if (result.getRefund_status().equalsIgnoreCase("REFUNDCLOSE")) {
+                            refundRaram.put("refundStatus", Dict.RefundStatus.item_4.getItem());
+                            refundRaram.put("wechat_refund_status_des", "退款关闭");
+                            orderRaram.put("payStatus", Dict.payStatus.item_5.getItem());
+                        } else if (result.getRefund_status().equalsIgnoreCase("CHANGE")) {
+                            refundRaram.put("refundStatus", Dict.RefundStatus.item_4.getItem());
+                            refundRaram.put("wechat_refund_status_des", "退款异常");
+                            orderRaram.put("payStatus", Dict.payStatus.item_6.getItem());
+                        } else if (result.getRefund_status().equalsIgnoreCase("PROCESSING")) {
+                            refundRaram.put("refundStatus", Dict.RefundStatus.item_5.getItem());
+                            refundRaram.put("wechat_refund_status_des", "退款处理中");
+                            orderRaram.put("payStatus", Dict.payStatus.item_3.getItem());
+                        }
+                        refundRaram.put("refundRecvAccout", result.getRefund_recv_accout());
+                        refundRaram.put("orderRefundId", result.getOut_refund_no());
+                        qzOrderMapper.updateOrderRefund(refundRaram);//更新订单退款信息
+                    }
+                }
+                orderRaram.put("orderStatus", Dict.orderStatus.item_401.getItem());
+                orderRaram.put("orderId", order_id);
+                orderRaram.put("payTransactionId", result.getTransaction_id());
+                qzOrderMapper.updateOrderInfo(orderRaram);
+            } else {
+                logger.info(">>>>>>>>>>>>>>>>>>>>pinganRefundquery 平安退款查询接口返回失败信息:code 【" + result.getErr_code() + "】,des【" + result.getErr_code_des() + "】");
+            }
+        } else {
+            logger.info(">>>>>>>>>>>>>>>>>>>>pinganRefundquery 平安退款查询接口调用失败: " + result.getReturn_msg());
+        }*/
+    }
+
+    /**
      * 微信国际支付微信查询订单api
      * @param map
      */
@@ -605,6 +744,75 @@ public class QzOrderService {
     }
 
     /**
+     * 查询支付中的订单以及小程序更新支付信息异常订单,查询平安订单更新订单状态
+     */
+    @Transactional
+    public void pinganOrderQueryUpdate() {
+        logger.info(">>>>>>>>>>>>>>>>>>>>pinganOrderQueryUpdate is start ");
+        logger.info(">>>>>>>>>>>>>>>>>>>>查询支付中的订单以及小程序更新支付信息异常订单,查询平安订单信息更新订单状态 ");
+        // 获取支付中的订单以及小程序更新支付信息异常订单
+        List<Map> orderList = qzOrderMapper.queryPinganPayingOrderList();
+        if (null != orderList && orderList.size() > 0) {
+            for (Map map : orderList) {
+                String outNo = MapUtils.getString("merch_order_sn", map);
+                String orderId = MapUtils.getString("order_id", map);
+                String add_time = MapUtils.getString("add_time", map);
+                Integer number = MapUtils.getInteger("number", map);
+                Integer stockNum = MapUtils.getInteger("stock_num", map);
+                Long storeRelaId = MapUtils.getLong("storeRelaId", map);
+
+                PinganResponseDto response = PinganUtil.pinganPaystatus(outNo);
+
+                if (!Objects.isNull(response)) {
+                    response.setOutNo(outNo);
+                    response.setCreateTime(new Date());
+                    qzOrderMapper.insertPinganResponseDto(MapBeanUtil.fromObject(response));
+
+                    if ("0".equals(response.getErrcode()) && StringUtils.isNotEmpty(response.getDatajson())) {
+                        PinganPayOrderDto payOrderDto = PinganUtil.buildPayOrderDto(JSONObject.fromObject(response.getDatajson()));
+                        qzOrderMapper.updatePayOrderByOutNo(MapBeanUtil.fromObject(payOrderDto));
+
+                        Date addTime = DateUtils.strToDate(add_time);
+                        Date nowDate = new Date();
+                        // 订单状态(1交易成功,2待支付,4已取消,9等待用户输入密码确认)
+                        if (payOrderDto.getStatus() == 1) {
+                            Map orderParam = new HashMap();
+                            orderParam.put("payStatus", 2);//已支付
+                            orderParam.put("orderStatus", 201);//已支付
+                            orderParam.put("payTransactionId", payOrderDto.getTradeNo());
+                            orderParam.put("payTime", payOrderDto.getTradeTime());
+                            orderParam.put("orderId", orderId);
+                            qzOrderMapper.updateOrderInfo(orderParam);
+                        } else {
+                            Map orderRaram = new HashMap();
+                            if (getDateBetween(addTime, nowDate) >= 15) {//订单下单时间超过15分钟直接取消订单
+                                orderRaram.put("payStatus", 0);//支付状态未支付
+                                orderRaram.put("orderStatus", 101);//订单状态已取消
+                                Map param = new HashMap();
+                                param.put("id", storeRelaId);
+                                param.put("stock_num", stockNum + number);
+                                qzOrderMapper.updateStockNum(param);
+                            } else {
+                                orderRaram.put("payStatus", 0);//支付状态未支付
+                                orderRaram.put("orderStatus", 0);//订单状态未支付
+                            }
+                            orderRaram.put("orderId", orderId);
+                            qzOrderMapper.updateOrderInfo(orderRaram);
+                        }
+                    } else {
+                        logger.info(">>>>>>>>>>>>>>>>>>>>pinganOrderQueryUpdate 平安查询接口返回失败信息:code 【" + response.getErrcode() + "】,des【" + response.getMsg() + "】");
+                    }
+                } else {
+                    logger.info(">>>>>>>>>>>>>>>>>>>>pinganOrderQueryUpdate 平安查询接口调用失败");
+                }
+            }
+        } else {
+            logger.info(">>>>>>>>>>>>>>>>>>>>pinganOrderQueryUpdate 未查到订单数据 ");
+        }
+        logger.info(">>>>>>>>>>>>>>>>>>>>pinganOrderQueryUpdate is end ");
+    }
+
+    /**
      *  查询微信支付中且已生成支付单的订单,更新订单状态
      *//*
     @Transactional
@@ -717,6 +925,8 @@ public class QzOrderService {
             logger.info(">>>>>>>>>>>>>>>>>>>>wxGlobalOrderByTransactionIdQueryUpdFail 根据支付单查询微信国际接口调用失败: " + result.getReturn_msg());
         }
     }*/
+
+
     /**
      * 查询付款码支付记录的支付状态
      */

+ 68 - 2
kmall-schedule/src/main/resources/mybatis/mapper/QzOrderMapper.xml

@@ -164,16 +164,82 @@
         #{modTime})
     </update>
 
+    <insert id="insertPinganResponseDto" parameterType="map">
+        insert into pingan_response(
+			`id`,
+			`out_no`,
+			`req_interface`,
+			`errcode`,
+			`msg`,
+			`data`,
+			`sign`,
+			`datajson`,
+			`timestamp`,
+			`create_time`,
+			`tstm`)
+		values(
+			#{id},
+			#{outNo},
+			#{reqInterface},
+			#{errcode},
+			#{msg},
+			#{data},
+			#{sign},
+			#{datajson},
+			#{timestamp},
+			#{createTime},
+			#{tstm})
+    </insert>
 
     <select id="queryOrder" resultType="map">
-		select id,order_status
+        select id,order_status
         from mall_order
         WHERE order_sn = #{orderSn}
     </select>
 
     <select id="queryWXPaySuccessRecords" resultType="map">
-		select id,out_trade_no_wx
+        select id,out_trade_no_wx
         from mall_order_wxpay_record
         WHERE out_trade_no = #{orderSn} AND trade_state='SUCCESS'
     </select>
+
+    <update id="updatePayOrderByOutNo" parameterType="map">
+        update pingan_pay_order
+        <set>
+            <if test="pmtName != null">`pmt_name` = #{pmtName}, </if>
+            <if test="pmtTag != null">`pmt_tag` = #{pmtTag}, </if>
+            <if test="ordMctId != null">`ord_mct_id` = #{ordMctId}, </if>
+            <if test="ordShopId != null">`ord_currency` = #{ordShopId}, </if>
+            <if test="ordCurrency != null">`ord_shop_id` = #{ordCurrency}, </if>
+            <if test="currencySign != null">`currency_sign` = #{currencySign}, </if>
+            <if test="ordNo != null">`ord_no` = #{ordNo}, </if>
+            <if test="ordType != null">`ord_type` = #{ordType}, </if>
+            <if test="originalAmount != null">`original_amount` = #{originalAmount}, </if>
+            <if test="discountAmount != null">`discount_amount` = #{discountAmount}, </if>
+            <if test="ignoreAmount != null">`ignore_amount` = #{ignoreAmount}, </if>
+            <if test="tradeAccount != null">`trade_account` = #{tradeAccount}, </if>
+            <if test="tradeNo != null">`trade_no` = #{tradeNo}, </if>
+            <if test="tradeAmount != null">`trade_amount` = #{tradeAmount}, </if>
+            <if test="tradeQrcode != null">`trade_qrcode` = #{tradeQrcode}, </if>
+            <if test="amount != null">`amount` = #{amount}, </if>
+            <if test="tradeTime != null">`trade_time` = #{tradeTime}, </if>
+            <if test="tradePayTime != null">`trade_pay_time` = #{tradePayTime}, </if>
+            <if test="payTime != null">`pay_time` = #{payTime}, </if>
+            <if test="status != null">`status` = #{status}, </if>
+            <if test="tradeResult != null">`trade_result` = #{tradeResult}, </if>
+            <if test="jsapiPayUrl != null">`jsapi_pay_url` = #{jsapiPayUrl}, </if>
+            <if test="randStr != null">`rand_str` = #{randStr}, </if>
+            <if test="appid != null">`appId` = #{appid}, </if>
+            <if test="noncestr != null">`nonceStr` = #{noncestr}, </if>
+            <if test="signtype != null">`signType` = #{signtype}, </if>
+            <if test="prepayId != null">`prepay_id` = #{prepayId}, </if>
+            <if test="paysign != null">`paySign` = #{paysign}, </if>
+            <if test="createrSn != null">`creater_sn` = #{createrSn}, </if>
+            <if test="createTime != null">`create_time` = #{createTime}, </if>
+            <if test="moderSn != null">`moder_sn` = #{moderSn}, </if>
+            <if test="modTime != null">`mod_time` = #{modTime}, </if>
+            <if test="tstm != null">`tstm` = #{tstm}</if>
+        </set>
+        where `out_no` = #{outNo}
+    </update>
 </mapper>

+ 3 - 0
wx-mall/config/api.js

@@ -56,6 +56,8 @@ module.exports = {
 
     OrderSubmit: NewApiRootUrl + 'order/submit', // 提交订单
     PayPrepayId: NewApiRootUrl + 'pay/pay_prepay', //获取微信统一下单prepay_id
+    Payorder: NewApiRootUrl + 'pay/pingan/payorder', //获取平安支付
+    MpconfigQuery: NewApiRootUrl + 'pay/pingan/mpconfig/setKey', //获取平安支付配置
     refund: NewApiRootUrl + 'pay/refund', //订单申请退款
   
     CheckStore: NewApiRootUrl + 'address/checkStore', //下单前,门店校验
@@ -134,4 +136,5 @@ module.exports = {
   idCardRealName: NewApiRootUrl + 'index/idCardRealName', //身份证实名
   saveApplyRefund: NewApiRootUrl + 'order/saveApplyRefund', //申请维权
   updateLoginUser: NewApiRootUrl + 'auth/updateLoginUser',
+  GlobalPayorder: NewApiRootUrl + '/global/pay/pay_prepay',
 };

+ 23 - 4
wx-mall/pages/pay/pay.js

@@ -6,7 +6,8 @@ Page({
   data: {
     orderIds: [],
     actualPrice: 0.00,
-    isMergePay: ''
+    isMergePay: '',
+    payType: 'wx'
   },
   onLoad: function (options) {
     // 页面初始化 options为页面跳转所带来的参数
@@ -32,24 +33,42 @@ Page({
     // 页面关闭
 
   },
+  //改变支付方式
+  changePayType: function (e) {
+    console.log(e.currentTarget.id);
+    this.setData({
+      payType: e.currentTarget.id
+    });
+  },
   //向服务请求支付参数
   requestPayParam() {
     let that = this;
     wx.showLoading({
       title: '加载中...',
     });
+
+    console.log(this.data.payType);
+    let url = '';
+    if (this.data.payType == 'wx') {
+      url = api.PayPrepayId;
+    } else if (this.data.payType == 'pingan') {
+      url = api.Payorder;
+    } else if (this.data.payType == 'wxGlobal') {
+      url = api.GlobalPayorder;
+    } 
+
     // 测试领取优惠券
     // wx.redirectTo({
     //   url: '/pages/payResult/payResult?status=1&orderId=' + that.data.orderId,
     // })
     // todo
-    util.request(api.PayPrepayId, {
+    util.request(url, {
       orderIds: that.data.orderIds, payType: 1,
       isMergePay: that.data.isMergePay
       }).then(function (res) {
+        wx.hideLoading();
       if (res.errno === 0) {
         let payParam = res.data;
-        wx.hideLoading();
         wx.requestPayment({
           'timeStamp': payParam.timeStamp,
           'nonceStr': payParam.nonceStr,
@@ -77,7 +96,7 @@ Page({
       }
     });
   },
-  startPay() {
+  startPay(e) {
     this.requestPayParam();
   }
 })

+ 17 - 7
wx-mall/pages/pay/pay.wxml

@@ -6,24 +6,34 @@
     <view class="pay-list">
         <view class="h">请选择支付方式</view>
         <view class="b">
-            <!--<view class="item">
-                <view class="checkbox checked"></view>
+            <!-- <view class="item" bindtap="changePayType">
+                <view class="checkbox"></view>
                 <view class="icon-alipay"></view>
                 <view class="name">支付宝</view>
             </view>
-            <view class="item">
+            <view class="item" bindtap="changePayType">
                 <view class="checkbox"></view>
                 <view class="icon-net"></view>
                 <view class="name">网易支付</view>
-            </view>-->
-            <view class="item">
-                <view class="checkbox checked"></view>
+            </view> -->
+            <view class="item" id="wx" bindtap="changePayType">
+                <view class="checkbox {{payType == 'wx'?'checked':''}}"></view>
                 <image src="/static/images/wxpay.png" class="icon"></image>
                 <view class="name">微信支付</view>
             </view>
+            <!-- <view class="item" id="wxGlobal" bindtap="changePayType">
+                <view class="checkbox {{payType == 'wxGlobal'?'checked':''}}"></view>
+                <image src="/static/images/wxpay.png" class="icon"></image>
+                <view class="name">微信国际支付</view>
+            </view>
+            <view class="item" id="pingan" bindtap="changePayType">
+                <view class="checkbox {{payType == 'pingan'?'checked':''}}"></view>
+                <image src="/static/images/pinganpay.png" class="icon"></image>
+                <view class="name">平安支付</view>
+            </view> -->
         </view>
     </view>
-    <view class="tips">小程序只支持微信支付,如需其它支付方式,请在网页版支付</view>
+    <!-- <view class="tips">小程序只支持微信支付,如需其它支付方式,请在网页版支付</view> -->
 
     <view class="pay-btn" bindtap="startPay">确定</view>
 </view>

+ 1 - 1
wx-mall/pages/payResult/payResult.wxml

@@ -13,7 +13,7 @@
     <view class="error" wx:if="{{!status}}">
       <view class="msg">付款失败</view>
       <view class="tips">
-        <view class="p">请在 <text class="time">十分钟</text> 内完成付款</view>
+        <view class="p">请在 <text class="time">十分钟</text> 内完成付款</view>
         <!-- <view class="p">否则订单将会被系统取消</view> -->
       </view>
       <view class="btns">

BIN
wx-mall/static/images/pinganpay.png


Some files were not shown because too many files changed in this diff