Просмотр исходного кода

[支付/退款][新增]:虚拟支付

release_toaliyun_real
Stormeye.Wu 7 лет назад
Родитель
Сommit
490b96a297
11 измененных файлов: 192 добавлений и 84 удалений
  1. +3
    -0
      mallinkAdmin/src/main/resources/application.yml
  2. +20
    -5
      mallinkBApi/src/main/java/com/simple/controller/WxRefundOrderController.java
  3. +3
    -0
      mallinkBApi/src/main/resources/application.yml
  4. +4
    -2
      mallinkCApi/src/main/java/com/simple/controller/WxCouponChannelController.java
  5. +1
    -1
      mallinkCApi/src/main/java/com/simple/controller/WxCouponController.java
  6. +1
    -1
      mallinkCApi/src/main/java/com/simple/controller/WxUserGrantController.java
  7. +3
    -0
      mallinkCApi/src/main/resources/application.yml
  8. +24
    -0
      mallinkService/src/main/java/com/simple/pay/PayProperty.java
  9. +2
    -3
      mallinkService/src/main/java/com/simple/service/impl/WxOrderServiceImpl.java
  10. +66
    -43
      mallinkService/src/main/java/com/simple/service/impl/WxPayOrderServiceImpl.java
  11. +65
    -29
      mallinkService/src/main/java/com/simple/service/impl/WxRefundOrderServiceImpl.java

+ 3
- 0
mallinkAdmin/src/main/resources/application.yml Просмотреть файл

@@ -37,3 +37,6 @@ pagehelper:
mapper:
mappers:
- com.simple.common.CommonMapper

pay:
real: false

+ 20
- 5
mallinkBApi/src/main/java/com/simple/controller/WxRefundOrderController.java Просмотреть файл

@@ -5,10 +5,12 @@ import com.simple.common.ErrorCode;
import com.simple.common.Result;
import com.simple.common.ResultData;
import com.simple.domain.po.WxAppinfo;
import com.simple.domain.po.WxCouponVerify;
import com.simple.domain.po.WxMerchantBUser;
import com.simple.domain.po.WxRefundOrder;
import com.simple.enums.EnumPayWay;
import com.simple.exception.MallinkException;
import com.simple.service.WxCouponVerifyService;
import com.simple.service.WxRefundOrderService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
@@ -27,25 +29,37 @@ import java.util.Map;
public class WxRefundOrderController extends BaseController {
private Logger logger = Logger.getLogger(WxRefundOrderController.class);

@Autowired
private WxCouponVerifyService wxCouponVerifyService;

@Autowired
private WxRefundOrderService wxRefundOrderService;

@ApiOperation(value = "发起退款", notes = "{\"orderId\":,\"string\", \"payOrderId\":\"string\"}")
@ApiOperation(value = "发起退款", notes = "{\"couponOrderId\":,\"string\", \"orderId\":,\"string\"}")
@PostMapping("/create")
public ResultData create(@RequestBody Map<String, String> paramMap) {
// couponOrder发起退款
logger.info("/api/refund/create" + paramMap.toString());
//Assert.notNull(wxRefundOrder.getName(), "角色名不能为空");
//Assert.isTrue(!checkUnique(sysRole.getName(), null), "重复的角色名");
String couponOrderIdStr = paramMap.get("couponOrderId");
String orderIdStr = paramMap.get("orderId");
String payOrderIdStr = paramMap.get("payOrderId");
if (StringUtils.isBlank(couponOrderIdStr)) {
logger.error("couponOrderId不能为空: " + paramMap.toString());
return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL);
}
if (StringUtils.isBlank(orderIdStr)) {
logger.error("orderId不能为空: " + paramMap.toString());
return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL);
}
if (StringUtils.isBlank(payOrderIdStr)) {
logger.error("payOrderId不能为空: " + paramMap.toString());
Long couponOrderId = 0L;
try {
couponOrderId = Long.valueOf(couponOrderIdStr);
} catch (NumberFormatException e) {
logger.error("orderId参数不正确: " + paramMap.toString());
return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL);
}

Long orderId = 0L;
try {
orderId = Long.valueOf(orderIdStr);
@@ -53,8 +67,9 @@ public class WxRefundOrderController extends BaseController {
logger.error("orderId参数不正确: " + paramMap.toString());
return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL);
}

WxRefundOrder refundOrder = new WxRefundOrder();
refundOrder.setPayOrderNo(payOrderIdStr);
//refundOrder.setPayOrderNo(payOrderIdStr);
refundOrder.setOrderId(orderId);

WxMerchantBUser bUser = getUser();


+ 3
- 0
mallinkBApi/src/main/resources/application.yml Просмотреть файл

@@ -37,3 +37,6 @@ pagehelper:
mapper:
mappers:
- com.simple.common.CommonMapper

pay:
real: false

+ 4
- 2
mallinkCApi/src/main/java/com/simple/controller/WxCouponChannelController.java Просмотреть файл

@@ -17,13 +17,15 @@ import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;

@RestController
@RequestMapping("wxCouponChannel")
@RequestMapping("/api/wxCouponChannel")
public class WxCouponChannelController extends BaseController
{
private Logger logger = Logger.getLogger(WxCouponChannelController.class);

@Autowired
private WxCouponChannelService wxCouponChannelService;

private Logger logger = Logger.getLogger(WxCouponChannelController.class);
@ApiOperation("分页列表接口")
@GetMapping("list")


+ 1
- 1
mallinkCApi/src/main/java/com/simple/controller/WxCouponController.java Просмотреть файл

@@ -16,7 +16,7 @@ import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;

@RestController
@RequestMapping("wxCoupon")
@RequestMapping("/api/wxCoupon")
public class WxCouponController extends BaseController {
private Logger logger = Logger.getLogger(WxCouponController.class);



+ 1
- 1
mallinkCApi/src/main/java/com/simple/controller/WxUserGrantController.java Просмотреть файл

@@ -237,7 +237,7 @@ public class WxUserGrantController extends BaseController {
* 检查用户状态
* @return
*/
@GetMapping("/checkUserStatus")
@PostMapping("/checkUserStatus")
@ApiOperation(value = "判断是否是老用户", notes="")
public ResultData checkUserStatus() {
Map resultMap = new HashMap();


+ 3
- 0
mallinkCApi/src/main/resources/application.yml Просмотреть файл

@@ -37,3 +37,6 @@ pagehelper:
mapper:
mappers:
- com.simple.common.CommonMapper

pay:
real: false

+ 24
- 0
mallinkService/src/main/java/com/simple/pay/PayProperty.java Просмотреть файл

@@ -0,0 +1,24 @@
package com.simple.pay;

import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.springframework.boot.context.properties.ConfigurationProperties;

/**
* @author Stormeye
*/
@ConfigurationProperties(prefix = "pay")
public class PayProperty {
/**
* 真实支付
*/
private boolean real;

public boolean isReal() {
return real;
}

public void setReal(boolean real) {
this.real = real;
}
}

+ 2
- 3
mallinkService/src/main/java/com/simple/service/impl/WxOrderServiceImpl.java Просмотреть файл

@@ -1,6 +1,5 @@
package com.simple.service.impl;

import java.math.BigDecimal;
import java.util.*;

import com.github.pagehelper.PageHelper;
@@ -11,9 +10,8 @@ import com.simple.domain.vo.OrderVo;
import com.simple.enums.*;
import com.simple.exception.MallinkException;
import com.simple.mapper.*;
import com.simple.pay.PayProperty;
import com.simple.service.WxOrderService;
import com.simple.service.WxPayAccountService;
import com.simple.service.WxUserCouponService;
import com.simple.utils.RedisLock;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
@@ -30,6 +28,7 @@ public class WxOrderServiceImpl implements WxOrderService {
@Autowired
RedisLock redisLock;


@Autowired
WxAppinfoMapper wxAppinfoMapper;



+ 66
- 43
mallinkService/src/main/java/com/simple/service/impl/WxPayOrderServiceImpl.java Просмотреть файл

@@ -17,6 +17,7 @@ import com.simple.enums.EnumPayType;
import com.simple.enums.EnumPayWay;
import com.simple.exception.MallinkException;
import com.simple.mapper.*;
import com.simple.pay.PayProperty;
import com.simple.pay.WxPay;
import com.simple.pay.WxPayOrderP;
import com.simple.pay.WxPayment;
@@ -37,6 +38,8 @@ import org.springframework.transaction.annotation.Transactional;
public class WxPayOrderServiceImpl implements WxPayOrderService {

private Logger logger = Logger.getLogger(getClass());
@Autowired
PayProperty payProperty;

@Autowired
WxAppinfoMapper wxAppinfoMapper;
@@ -122,32 +125,32 @@ public class WxPayOrderServiceImpl implements WxPayOrderService {
}

WxPayAccount payAccount = wxPayAccountMapper.selectByPrimaryKey(appInfo.getPayId());
// 统一下单
String noncestr = Utility.generate32UUID();
WxPayOrderP wxPayOrderP = new WxPayOrderP();
wxPayOrderP.setOpenid(user.getOpenId());
wxPayOrderP.setAppid(user.getAppId());
wxPayOrderP.setMch_id(payAccount.getMchId());
wxPayOrderP.setNonce_str(noncestr);
wxPayOrderP.setBody(order.getDetail());
wxPayOrderP.setOut_trade_no(record.getPayOrderNo());
wxPayOrderP.setTotal_fee(order.getPayment());
wxPayOrderP.setSpbill_create_ip(record.getIp()); // 终端IP
wxPayOrderP.setNotify_url(payAccount.getPayNotifyUrl());
wxPayOrderP.setTrade_type(WxPay.TradeType.JSAPI.name()); // 终端类型
wxPayOrderP.setProduct_id(String.valueOf(order.getId())); // 订单ID
wxPayOrderP.setTime_start(Utility.getDataFormatStringYYYYMMDDHHmmss(currentDate));
Date futureDate = new Date();
futureDate.setTime(currentDate.getTime() + 15*60*1000);
wxPayOrderP.setTime_expire(Utility.getDataFormatStringYYYYMMDDHHmmss(futureDate)); // 15分钟后结束
wxPayOrderP.setSign(WxPayment.createSign(BeanUtils.toStringMap(wxPayOrderP), payAccount.getApiKey()));
String response = WxPay.pushOrder(BeanUtils.toStringMap(wxPayOrderP));
logger.info("pay order, wechat pushOrder, " + wxPayOrderP.toString() + ", response: " + response.toString());
Map<String, String> returnMap = WxPayment.xmlToMap(response);
returnMap.put("payOrderId", payOrderNo);
String result_code = returnMap.get("result_code");
if ("SUCCESS".equals(result_code)) {
if (payProperty.isReal()) {
// 统一下单
String noncestr = Utility.generate32UUID();
WxPayOrderP wxPayOrderP = new WxPayOrderP();
wxPayOrderP.setOpenid(user.getOpenId());
wxPayOrderP.setAppid(user.getAppId());
wxPayOrderP.setMch_id(payAccount.getMchId());
wxPayOrderP.setNonce_str(noncestr);
wxPayOrderP.setBody(order.getDetail());
wxPayOrderP.setOut_trade_no(record.getPayOrderNo());
wxPayOrderP.setTotal_fee(order.getPayment());
wxPayOrderP.setSpbill_create_ip(record.getIp()); // 终端IP
wxPayOrderP.setNotify_url(payAccount.getPayNotifyUrl());
wxPayOrderP.setTrade_type(WxPay.TradeType.JSAPI.name()); // 终端类型
wxPayOrderP.setProduct_id(String.valueOf(order.getId())); // 订单ID
wxPayOrderP.setTime_start(Utility.getDataFormatStringYYYYMMDDHHmmss(currentDate));
Date futureDate = new Date();
futureDate.setTime(currentDate.getTime() + 15*60*1000);
wxPayOrderP.setTime_expire(Utility.getDataFormatStringYYYYMMDDHHmmss(futureDate)); // 15分钟后结束
wxPayOrderP.setSign(WxPayment.createSign(BeanUtils.toStringMap(wxPayOrderP), payAccount.getApiKey()));
String response = WxPay.pushOrder(BeanUtils.toStringMap(wxPayOrderP));
logger.info("pay order, wechat pushOrder, " + wxPayOrderP.toString() + ", response: " + response.toString());
Map<String, String> returnMap = WxPayment.xmlToMap(response);
returnMap.put("payOrderId", payOrderNo);
String result_code = returnMap.get("result_code");
if ("SUCCESS".equals(result_code)) {
/*
Map<String, String> signMap = WxPayment.buildWeappSecondSignMap(returnMap.get("appid"),
String.valueOf(Utility.getCurrentTimeStamp()),
@@ -158,24 +161,44 @@ public class WxPayOrderServiceImpl implements WxPayOrderService {
returnMap.putAll(signMap);
returnMap.put("paySign", signAgent);
*/
String prepay_id = returnMap.get("prepay_id");
String timestamp = String.valueOf(Utility.getCurrentTimeStamp());
Map<String, String> sighMap = MapUtil.getOrderMap();
sighMap.put("appId", returnMap.get("appid"));
sighMap.put("timeStamp", timestamp);
sighMap.put("nonceStr", noncestr);
sighMap.put("package", "prepay_id=" + prepay_id);
sighMap.put("signType", "MD5");
String signAgent = WxPayment.createSign(sighMap, payAccount.getApiKey());
returnMap.put("timeStamp", timestamp);
returnMap.put("nonceStr", noncestr);
returnMap.put("package", "prepay_id=" + prepay_id);
returnMap.put("paySign", signAgent);
logger.info("back to UI: " +returnMap.toString());
return new ResultData(Result.SUCCESS, "创建支付订单成功", returnMap);
String prepay_id = returnMap.get("prepay_id");
String timestamp = String.valueOf(Utility.getCurrentTimeStamp());
Map<String, String> sighMap = MapUtil.getOrderMap();
sighMap.put("appId", returnMap.get("appid"));
sighMap.put("timeStamp", timestamp);
sighMap.put("nonceStr", noncestr);
sighMap.put("package", "prepay_id=" + prepay_id);
sighMap.put("signType", "MD5");
String signAgent = WxPayment.createSign(sighMap, payAccount.getApiKey());
returnMap.put("timeStamp", timestamp);
returnMap.put("nonceStr", noncestr);
returnMap.put("package", "prepay_id=" + prepay_id);
returnMap.put("paySign", signAgent);
logger.info("back to UI: " +returnMap.toString());
return new ResultData(Result.SUCCESS, "创建支付订单成功", returnMap);
} else {
JSONObject errObj = errorMap.getJSONObject(result_code);
return new ResultData(ErrorCode.PAY_ORDER_ERROR.getCode(), errObj.toJSONString(), returnMap);
}
} else {
JSONObject errObj = errorMap.getJSONObject(result_code);
return new ResultData(ErrorCode.PAY_ORDER_ERROR.getCode(), errObj.toJSONString(), returnMap);
WxPayOrderP wxPayOrderP = new WxPayOrderP();
wxPayOrderP.setOpenid(user.getOpenId());
wxPayOrderP.setAppid(user.getAppId());
wxPayOrderP.setMch_id(payAccount.getMchId());
wxPayOrderP.setBody(order.getDetail());
wxPayOrderP.setOut_trade_no(record.getPayOrderNo());
wxPayOrderP.setTotal_fee(order.getPayment());
wxPayOrderP.setSpbill_create_ip(record.getIp()); // 终端IP
wxPayOrderP.setNotify_url(payAccount.getPayNotifyUrl());
wxPayOrderP.setTrade_type(WxPay.TradeType.JSAPI.name()); // 终端类型
wxPayOrderP.setProduct_id(String.valueOf(order.getId())); // 订单ID
wxPayOrderP.setTime_start(Utility.getDataFormatStringYYYYMMDDHHmmss(currentDate));
Date futureDate = new Date();
futureDate.setTime(currentDate.getTime() + 15*60*1000);
wxPayOrderP.setTime_expire(Utility.getDataFormatStringYYYYMMDDHHmmss(futureDate)); // 15分钟后结束
wxPayOrderP.setSign(WxPayment.createSign(BeanUtils.toStringMap(wxPayOrderP), payAccount.getApiKey()));
Map<String, String> returnMap = BeanUtils.toStringMap(wxPayOrderP);
return new ResultData(Result.SUCCESS, "创建支付订单成功", returnMap);
}
} catch (RuntimeException e) {
throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), e.getMessage());


+ 65
- 29
mallinkService/src/main/java/com/simple/service/impl/WxRefundOrderServiceImpl.java Просмотреть файл

@@ -16,9 +16,11 @@ import com.simple.enums.EnumPayWay;
import com.simple.enums.EnumRefundStatus;
import com.simple.exception.MallinkException;
import com.simple.mapper.*;
import com.simple.pay.PayProperty;
import com.simple.pay.WxPay;
import com.simple.pay.WxPayment;
import com.simple.pay.WxRefundOrderP;
import com.simple.service.WxCouponVerifyService;
import com.simple.service.WxOrderService;
import com.simple.service.WxRefundOrderService;
import com.simple.utils.BeanUtils;
@@ -36,12 +38,18 @@ import org.springframework.transaction.annotation.Transactional;
public class WxRefundOrderServiceImpl implements WxRefundOrderService {
private Logger logger = Logger.getLogger(getClass());

@Autowired
PayProperty payProperty;

@Autowired
WxAppinfoMapper wxAppinfoMapper;
@Autowired
WxRefundOrderMapper wxRefundOrderMapper;

@Autowired
WxCouponVerifyMapper wxCouponVerifyMapper;

@Autowired
WxOrderMapper wxOrderMapper;

@@ -260,7 +268,15 @@ public class WxRefundOrderServiceImpl implements WxRefundOrderService {
throw new MallinkException(ErrorCode.REFUND_PAY_ORDER_IS_ZERO);
}

// TODO 检查 是否已核销, 已核销不能退款
// 检查 是否已核销, 已核销不能退款
/*
WxOrder order = wxOrderMapper.selectByPrimaryKey(payOrder.getOrderId());

WxCouponVerify couponVerifyQ = new WxCouponVerify();
couponVerifyQ.setCouponId(payOrder.getOrderId());
WxCouponVerify couponVerify = wxCouponVerifyMapper.select()
*/


// 创建退款订单
final IdWorker idWorker = IdWorker.get();
@@ -300,40 +316,60 @@ public class WxRefundOrderServiceImpl implements WxRefundOrderService {
wxRefundOrderP.setTotal_fee(record.getTotalFee());
wxRefundOrderP.setRefund_fee(record.getRefundFee());

Map signMap = new HashMap();
try {
signMap = BeanUtils.toStringMap(wxRefundOrderP);
} catch (Exception e) {
logger.error("退款签名异常");
throw new MallinkException(ErrorCode.SYS_PARAMETER_CAST_ERROR.getCode(), "退款签名异常");
}
String signAgent = WxPayment.createSign(signMap, payAccount.getApiKey());
signMap.put("sign", signAgent);
String response = WxPay.orderRefund(signMap, payAccount.getCertPath(), payAccount.getApiKey());
logger.info("微信退款订单:" + wxRefundOrderP.toString() + ", response: " + response.toString());
Map<String, String> returnMap = WxPayment.xmlToMap(response);
String result_no = returnMap.get("result_code");
String refund_id = returnMap.get("refund_id");
// 设置 微信退款订单号
record.setRefundId(refund_id);
if ("SUCCESS".equals(result_no)) {
logger.error("微信退款订单申请成功: " + returnMap.toString());
if (payProperty.isReal()) {
Map signMap = new HashMap();
try {
record.setRefundOrderStatus(EnumRefundStatus.REFUND_REQ_SUCCESS.getCode());
wxRefundOrderMapper.updateByPrimaryKey(record);
return new ResultData(Result.SUCCESS, "退款订单申请成功", returnMap);
signMap = BeanUtils.toStringMap(wxRefundOrderP);
} catch (Exception e) {
logger.error("微信退款订单更新入库出错: " + e.getMessage() + ", record: " + record.toString());
throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR);
logger.error("退款签名异常");
throw new MallinkException(ErrorCode.SYS_PARAMETER_CAST_ERROR.getCode(), "退款签名异常");
}

String signAgent = WxPayment.createSign(signMap, payAccount.getApiKey());
signMap.put("sign", signAgent);
String response = WxPay.orderRefund(signMap, payAccount.getCertPath(), payAccount.getApiKey());
logger.info("微信退款订单:" + wxRefundOrderP.toString() + ", response: " + response.toString());
Map<String, String> returnMap = WxPayment.xmlToMap(response);
String result_no = returnMap.get("result_code");
String refund_id = returnMap.get("refund_id");
// 设置 微信退款订单号
record.setRefundId(refund_id);
if ("SUCCESS".equals(result_no)) {
logger.error("微信退款订单申请成功: " + returnMap.toString());
try {
record.setRefundOrderStatus(EnumRefundStatus.REFUND_REQ_SUCCESS.getCode());
wxRefundOrderMapper.updateByPrimaryKey(record);
return new ResultData(Result.SUCCESS, "退款订单申请成功", returnMap);
} catch (Exception e) {
logger.error("微信退款订单更新入库出错: " + e.getMessage() + ", record: " + record.toString());
throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR);
}
} else {
logger.error("微信退款订单申请失败: " + returnMap.toString());
try {
record.setRefundOrderStatus(EnumRefundStatus.REFUND_REQ_FAIL.getCode());
wxRefundOrderMapper.updateByPrimaryKey(record);
JSONObject errObj = errorRefundReqMap.getJSONObject(result_no);
return new ResultData(ErrorCode.PAY_ORDER_ERROR.getCode(), errObj.toJSONString(), returnMap);
} catch(Exception e) {
logger.error("微信退款订单更新入库出错: " + e.getMessage() + ", record: " + record.toString());
throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR);
}
}
} else {
logger.error("微信退款订单申请失败: " + returnMap.toString());
// 虚拟支付
Map returnMap = null;
try {
returnMap = BeanUtils.toStringMap(wxRefundOrderP);
} catch (Exception e) {
logger.error("退款签名异常");
throw new MallinkException(ErrorCode.SYS_PARAMETER_CAST_ERROR.getCode(), "退款签名异常");
}
try {
record.setRefundOrderStatus(EnumRefundStatus.REFUND_REQ_FAIL.getCode());
record.setRefundOrderStatus(EnumRefundStatus.REFUND_REQ_SUCCESS.getCode());
wxRefundOrderMapper.updateByPrimaryKey(record);
JSONObject errObj = errorRefundReqMap.getJSONObject(result_no);
return new ResultData(ErrorCode.PAY_ORDER_ERROR.getCode(), errObj.toJSONString(), returnMap);
} catch(Exception e) {
return new ResultData(Result.SUCCESS, "退款订单申请成功", returnMap);
} catch (Exception e) {
logger.error("微信退款订单更新入库出错: " + e.getMessage() + ", record: " + record.toString());
throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR);
}


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