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

[刷卡支付][收银台]:刷卡支付实现查询订单接口及撤销订单接口

release_toaliyun_real
Stormeye Wu 7 лет назад
Родитель
Сommit
eac4fe0f9c
7 измененных файлов: 99 добавлений и 42 удалений
  1. +18
    -11
      mallinkBApi/src/main/java/com/iformall/controller/WxMicroPayController.java
  2. +5
    -5
      mallinkBApi/src/main/resources/application-dev.yml
  3. +1
    -0
      mallinkBApi/src/main/resources/application.yml
  4. +5
    -0
      mallinkService/src/main/java/com/iformall/common/ErrorCode.java
  5. +3
    -2
      mallinkService/src/main/java/com/iformall/enums/EnumPayStatus.java
  6. +57
    -21
      mallinkService/src/main/java/com/iformall/service/impl/WxPayOrderServiceImpl.java
  7. +10
    -3
      mallinkService/src/main/resources/mapper/WxPayOrderMapper.xml

+ 18
- 11
mallinkBApi/src/main/java/com/iformall/controller/WxMicroPayController.java Просмотреть файл

@@ -2,12 +2,9 @@ package com.iformall.controller;


import com.iformall.common.ErrorCode;
import com.iformall.common.Result;
import com.iformall.common.ResultData;
import com.iformall.config.PayProperty;
import com.iformall.domain.po.*;
import com.iformall.domain.vo.WxBillAll;
import com.iformall.enums.EnumMerchantStatus;
import com.iformall.enums.EnumPayWay;
import com.iformall.exception.MallinkException;
import com.iformall.service.*;
@@ -21,8 +18,6 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

/**
@@ -49,9 +44,12 @@ public class WxMicroPayController extends BaseController {
@Autowired
WxPayOrderService wxPayOrderService;

@ApiOperation(value = "刷卡支付订单", notes = "{\"authCode\":\"String\",\"totalFee\":\"String\"}")
@ApiOperation(value = "刷卡支付订单", notes = "params:{\"authCode\":\"String\",\"totalFee\":\"String\"},\n" +
"注意:\n" +
"提醒1:提交支付请求后微信会同步返回支付结果。当返回结果为“系统错误”时,商户系统等待5秒后调用【查询订单API】,查询支付实际交易结果;当返回结果为“USERPAYING”时,商户系统可设置间隔时间(建议10秒)重新查询支付结果,直到支付成功或超时(建议30秒);\n" +
"提醒2:在调用查询接口返回后,如果交易状况不明晰,请调用【撤销订单API】,此时如果交易失败则关闭订单,该单不能再支付成功;如果交易成功,则将扣款退回到用户账户。当撤销无返回或错误时,请再次调用。注意:请勿扣款后立即调用【撤销订单API】,建议至少15秒后再调用。撤销订单API需要双向证书。")
@PostMapping("order_create")
public ResultData saveMicopayOrder(@RequestBody Map<String, String> paramMap, HttpServletRequest request) {
public ResultData saveMicopayOrder(@RequestBody Map<String, String> paramMap, HttpServletRequest request) {
logger.info("saveMicopayOrder: " + paramMap.toString());
//Assert.notNull(wxOrders.getName(), "角色名不能为空");
//Assert.isTrue(!checkUnique(sysRole.getName(), null), "重复的角色名");
@@ -101,7 +99,7 @@ public class WxMicroPayController extends BaseController {

@ApiOperation(value = "查询刷卡支付订单", notes = "{\"payOrderId\":\"String\",\"orderId\":\"String\"}")
@PostMapping("order_query")
public ResultData queryMicopayOrder(@RequestBody Map<String, String> paramMap) {
public ResultData queryMicopayOrder(@RequestBody Map<String, String> paramMap) {
logger.info("queryMicopayOrder: " + paramMap.toString());
String payOrderIdStr = paramMap.get("payOrderId");
String orderIdStr = paramMap.get("orderId");
@@ -138,7 +136,14 @@ public class WxMicroPayController extends BaseController {
record.setOrderId(orderId);

try {
wxPayOrderService.payOrderQuery(appInfo, record);
ResultData resultData = wxPayOrderService.payOrderQuery(appInfo, record);
if (resultData.code == ErrorCode.PAY_ORDER_PAYING.getCode()) {
return resultData;
} else if (resultData.code == ErrorCode.PAY_ORDER_NOT_PAY.getCode()) {
return resultData;
} else if (resultData.code == ErrorCode.PAY_ORDER_ERROR.getCode()) {
return resultData;
}
} catch (MallinkException e) {
logger.error("payment wechat, order query error, req 2: " + record.toString() + ", e:" + e.getMessage());
return new ResultData(e.getErrorCode(), e.getMessage());
@@ -149,16 +154,17 @@ public class WxMicroPayController extends BaseController {


WxPayOrder payOrder = wxPayOrderService.getById(payOrderId);
if(payOrder != null) {
if (payOrder != null) {
return new ResultData(payOrder);
} else {
logger.error("payment wechat, order query error, req 4: payOrderId" + payOrderId);
return new ResultData(ErrorCode.PAY_ORDER_NOT_FOUND.getCode(), "支付订单未找到");
}
}

@ApiOperation(value = "撤销刷卡支付订单", notes = "{\"payOrderId\":\"String\",\"orderId\":\"String\"}")
@PostMapping("order_reverse")
public ResultData reverseMicopayOrder(@RequestBody Map<String, String> paramMap) {
public ResultData reverseMicopayOrder(@RequestBody Map<String, String> paramMap) {
logger.info("reverseMicopayOrder: " + paramMap.toString());
String payOrderIdStr = paramMap.get("payOrderId");
String orderIdStr = paramMap.get("orderId");
@@ -191,6 +197,7 @@ public class WxMicroPayController extends BaseController {

WxPayOrder record = new WxPayOrder();
record.setId(payOrderId);
record.setPayOrderNo(payOrderIdStr);
record.setbUserId(user.getId());
record.setOrderId(orderId);



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

@@ -1,9 +1,9 @@
spring:
# JDBC
datasource:
url: jdbc:mysql://202.165.179.86:3306/mallink?useUnicode=true&characterEncoding=UTF-8&useSSL=false
username: ENC(dZ8fmrtuBMQYaRytKQgTqg==)
password: ENC(OZXsE6/Tj+V1Yu2wdjnIGbNOaBVQzi9W)
url: jdbc:mysql://localhost:3306/mallink?useUnicode=true&characterEncoding=UTF-8&useSSL=false
username: userone
password: wgq2WYJ2018Mb@#$
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
filters: stat
@@ -24,9 +24,9 @@ spring:

# REDIS
redis:
host: 202.165.179.86
host: localhost
port: 6379
password: ENC(aYJ3Wr2UWtkORRQjjrWWpz2ZeTISsHOA)
password: F2ol8m@11
timeout: 3600
expire: 1800 #30分钟
database: 1


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

@@ -1,3 +1,4 @@
debug: true
server:
port: 8000
servlet:


+ 5
- 0
mallinkService/src/main/java/com/iformall/common/ErrorCode.java Просмотреть файл

@@ -157,6 +157,11 @@ public enum ErrorCode{
/**
* 支付
*/
PAY_ORDER_REFUND(11994, "订单退款中"),
PAY_ORDER_PAYING(11995, "订单支付中"),
PAY_ORDER_NOT_PAY(11996, "订单未支付"),
PAY_ORDER_CLOSED(11997, "订单已关闭"),
PAY_ORDER_REVERSE(11998, "订单已撤销"),
PAY_ORDER_NOT_FOUND(12000, "支付订单不存在"),
PAY_ORDER_EXIST(12001, "支付订单已存在"),
PAY_ORDER_ERROR(12002, "支付订单异常"),


+ 3
- 2
mallinkService/src/main/java/com/iformall/enums/EnumPayStatus.java Просмотреть файл

@@ -4,6 +4,7 @@ package com.iformall.enums;
* Created by Stormeye on 2018/08/09.
*/
public enum EnumPayStatus {
PAY_STATUS_NOTPAY(-2, "未支付"),
PAY_STATUS_UNKNOWN(-1, "未知"),
PAY_STATUS_WAIT(0, "支付中"),
PAY_STATUS_SUCCESS(1, "支付成功"),
@@ -12,8 +13,8 @@ public enum EnumPayStatus {
PAY_STATUS_CANCEL_FAIL(4,"取消支付失败"),
PAY_STATUS_CLOSE(5, "关闭支付订单"),
PAY_STATUS_CLOSE_FAIL(6,"关闭支付订单失败"),
PAY_STATUS_REVERSE(7, "关闭支付订单"),
PAY_STATUS_REVERSE_FAIL(8,"关闭支付订单失败"),
PAY_STATUS_REVERSE(7, "撤销支付订单"),
PAY_STATUS_REVERSE_FAIL(8,"撤销支付订单失败"),
PAY_STATUS_REFUND(9,"支付转退款")
;



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

@@ -391,6 +391,7 @@ public class WxPayOrderServiceImpl implements WxPayOrderService {
record.setPayOrderStatus(EnumPayStatus.PAY_STATUS_WAIT.getCode());
List<WxPayOrder> list = wxPayOrderMapper.findList(record);
String payOrderNo = "";
String orderNo = String.valueOf(order.getId());
if (list.size() <= 0) {
// 3. 创建支付订单
Long id = idworker.nextId();
@@ -452,6 +453,7 @@ public class WxPayOrderServiceImpl implements WxPayOrderService {
logger.info("pay order, wechat micropay, " + wxPayOrderP.toString() + ", response: " + response.toString());
Map<String, String> returnMap = WxPayment.xmlToMap(response);
returnMap.put("payOrderId", payOrderNo);
returnMap.put("orderId", orderNo);
String return_code = returnMap.get("return_code");
String result_code = returnMap.get("result_code");
if("SUCCESS".equalsIgnoreCase(return_code)) {
@@ -534,6 +536,7 @@ public class WxPayOrderServiceImpl implements WxPayOrderService {
logger.info("pay order, wechat micropay, " + wxPayOrderSP.toString() + ", response: " + response.toString());
Map<String, String> returnMap = WxPayment.xmlToMap(response);
returnMap.put("payOrderId", payOrderNo);
returnMap.put("orderId", orderNo);
String return_code = returnMap.get("return_code");
String result_code = returnMap.get("result_code");
if("SUCCESS".equalsIgnoreCase(return_code)) {
@@ -689,28 +692,35 @@ public class WxPayOrderServiceImpl implements WxPayOrderService {
//USERPAYING--用户支付中
//PAYERROR--支付失败(其他原因,如银行返回失败)
if ("SUCCESS".equals(trade_state)) {
String transactionId = returnMap.get("transaction_id");
record.setPayOrderStatus(EnumPayStatus.PAY_STATUS_SUCCESS.getCode());
handlePayOrderStatusUpdate(record);
handleOrderPaySuccess(record, transactionId);
return new ResultData(Result.SUCCESS, "订单支付成功", returnMap);
} else if ("REFUND".equals(trade_state)) {
record.setPayOrderStatus(EnumPayStatus.PAY_STATUS_REFUND.getCode());
handlePayOrderStatusUpdate(record);
// handlePayOrderStatusUpdate(record);
return new ResultData(ErrorCode.PAY_ORDER_REFUND, returnMap);
} else if ("NOTPAY".equals(trade_state)) {
record.setPayOrderStatus(EnumPayStatus.PAY_STATUS_WAIT.getCode());
handlePayOrderStatusUpdate(record);
record.setPayOrderStatus(EnumPayStatus.PAY_STATUS_NOTPAY.getCode());
//handlePayOrderStatusUpdate(record);
return new ResultData(ErrorCode.PAY_ORDER_NOT_PAY, returnMap);
} else if ("CLOSED".equals(trade_state)) {
record.setPayOrderStatus(EnumPayStatus.PAY_STATUS_CLOSE.getCode());
handlePayOrderStatusUpdate(record);
///handlePayOrderStatusUpdate(record);
return new ResultData(ErrorCode.PAY_ORDER_CLOSED, returnMap);
} else if ("REVOKED".equals(trade_state)) {
record.setPayOrderStatus(EnumPayStatus.PAY_STATUS_REVERSE.getCode());
handlePayOrderStatusUpdate(record);
// handlePayOrderStatusUpdate(record);
return new ResultData(ErrorCode.PAY_ORDER_REVERSE, returnMap);
} else if ("USERPAYING".equals(trade_state)) {
record.setPayOrderStatus(EnumPayStatus.PAY_STATUS_WAIT.getCode());
handlePayOrderStatusUpdate(record);
// handlePayOrderStatusUpdate(record);
return new ResultData(ErrorCode.PAY_ORDER_PAYING, returnMap);
} else {
record.setPayOrderStatus(EnumPayStatus.PAY_STATUS_ERR.getCode());
handlePayOrderStatusUpdate(record);
// handlePayOrderStatusUpdate(record);
return new ResultData(ErrorCode.PAY_ORDER_ERROR, returnMap);
}
return new ResultData(Result.SUCCESS, "订单查询成功", returnMap);
} else {
String errMsg = "";
JSONObject errObj = errorMapQuery.getJSONObject(result_code);
@@ -923,9 +933,25 @@ public class WxPayOrderServiceImpl implements WxPayOrderService {
String result_code = returnMap.get("result_code");
if("SUCCESS".equalsIgnoreCase(return_code)) {
if ("SUCCESS".equals(result_code)) {
record.setPayOrderStatus(EnumPayStatus.PAY_STATUS_CANCEL.getCode());
handlePayOrderStatusUpdate(record);
return new ResultData(Result.SUCCESS, "订单关闭成功", returnMap);
record.setPayOrderStatus(EnumPayStatus.PAY_STATUS_REVERSE.getCode());
record.setUpdateTime(new Date());
try {
wxPayOrderMapper.updateByPrimaryKeySelective(record);
} catch (Exception e) {
logger.error("pay order update error: " + record.toString());
throw new MallinkException(ErrorCode.DB_FAIL);
}
WxOrder order = new WxOrder();
order.setId(record.getOrderId());
order.setOrderStatus(EnumOrderStatus.ORDER_STATUS_OVERTIME_CANCEL.getCode());
order.setUpdateDate(new Date());
try {
wxPayOrderMapper.updateByPrimaryKeySelective(record);
} catch (Exception e) {
logger.error("pay order update error: " + record.toString());
throw new MallinkException(ErrorCode.DB_FAIL);
}
return new ResultData(Result.SUCCESS, "订单撤销成功", returnMap);
} else {
String errMsg = "";
JSONObject errObj = errorMapClose.getJSONObject(result_code);
@@ -1108,7 +1134,7 @@ public class WxPayOrderServiceImpl implements WxPayOrderService {
}
WxOrder order = wxOrderMapper.selectByPrimaryKey(record.getOrderId());
if (order == null) {
logger.error("pay success handle, order " + record.getOrderId() + " not found , payOrderGid : " + record.getPayOrderNo());
logger.error("pay success handle, order " + record.getOrderId() + " not found , payOrderid : " + record.getPayOrderNo());
throw new MallinkException(ErrorCode.ORDER_IS_NOT_FIND);
}

@@ -1164,16 +1190,17 @@ public class WxPayOrderServiceImpl implements WxPayOrderService {
}
WxOrder order = wxOrderMapper.selectByPrimaryKey(record.getOrderId());
if (order == null) {
logger.error("pay handle, order " + record.getOrderId() + " not found , payOrderGid : " + record.getPayOrderNo());
logger.error("pay handle, order " + record.getOrderId() + " not found , payOrderid : " + record.getPayOrderNo());
throw new MallinkException(ErrorCode.ORDER_IS_NOT_FIND);
}
WxCUser user = wxCUserMapper.selectByPrimaryKey(order.getCUserId());
if (user == null) {
logger.error("pay handle, order " + record.getOrderId() + " not found , payOrderGid : " + record.getPayOrderNo());
throw new MallinkException(ErrorCode.USER_IS_EMPTY);
if(order.getType().equals(EnumOrderType.COUPON.getCode())) {
WxCUser user = wxCUserMapper.selectByPrimaryKey(order.getCUserId());
if (user == null) {
logger.error("pay handle, order " + record.getOrderId() + " not found , payOrderid : " + record.getPayOrderNo());
throw new MallinkException(ErrorCode.USER_IS_EMPTY);
}
}


if (order.getPayment() > 0) {
// 订单金额不为0时, 支付订单未创建, 返回异常
if (!(record.getId() >0)) {
@@ -1187,7 +1214,14 @@ public class WxPayOrderServiceImpl implements WxPayOrderService {
WxAppinfo appInfo = null;
WxAppinfo appinfoQ = new WxAppinfo();
appinfoQ.setTenantId(order.getTenantId());
appinfoQ.setType(EnumAppType.C.getCode());
if(order.getType().equals(EnumOrderType.COUPON.getCode())) {
appinfoQ.setType(EnumAppType.C.getCode());
} else if(order.getType().equals(EnumOrderType.MICROPAY.getCode())) {
appinfoQ.setType(EnumAppType.B.getCode());
} else {
appinfoQ.setType(EnumAppType.C.getCode());
}

List<WxAppinfo> appList = wxAppinfoMapper.select(appinfoQ);
if (appList.size() > 0) {
appInfo = appList.get(0);
@@ -1222,7 +1256,7 @@ public class WxPayOrderServiceImpl implements WxPayOrderService {
} else {
// 支付订单成功?
if (updateOrder.getPayOrderStatus().equals(EnumPayStatus.PAY_STATUS_SUCCESS.getCode())) {
if (StringUtils.isBlank(updateOrder.getTransactionId())) {
if (StringUtils.isNotBlank(updateOrder.getTransactionId())) {
// 回调已设置成功
// 继续修改订单状态
} else {
@@ -1250,6 +1284,8 @@ public class WxPayOrderServiceImpl implements WxPayOrderService {
if ("SUCCESS".equals(trade_state)) {
// 查询支付订单 -- 已支付
// 继续更改状态
} else if ("USERPAYING".equals(trade_state)) {
// 继续检查状态
} else {
// 支付订单未成功,返回异常
throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), "支付订单未成功");


+ 10
- 3
mallinkService/src/main/resources/mapper/WxPayOrderMapper.xml Просмотреть файл

@@ -8,8 +8,8 @@
<result column="update_time" jdbcType="TIMESTAMP" property="updateTime"/>
<result column="order_id" jdbcType="BIGINT" property="orderId"/>
<result column="c_user_id" jdbcType="BIGINT" property="cUserId"/>
<result column="b_user_id" jdbcType="TINYINT" property="bUserId"/>
<result column="auth_code" jdbcType="String" property="authCode"/>
<result column="b_user_id" jdbcType="BIGINT" property="bUserId"/>
<result column="auth_code" jdbcType="VARCHAR" property="authCode"/>
<result column="ip" jdbcType="VARCHAR" property="ip"/>
<result column="pay_amount" jdbcType="INTEGER" property="payAmount"/>
<result column="pay_time_start" jdbcType="TIMESTAMP" property="payTimeStart"/>
@@ -25,7 +25,10 @@
</resultMap>

<sql id="allColumns">
`id`,`tenant_id`,`create_time`,`update_time`,`order_id`,`c_user_id`,`b_user_id`,`auth_code`,`ip`,`pay_amount`,`pay_time_start`,`pay_time_end`,`prepay_id`,`transaction_id`,`pay_vendor`,`pay_order_no`,`pay_order_status`,`share`,`share_amount`,`fail_reason`
`id`,`tenant_id`,`create_time`,`update_time`,`order_id`,`c_user_id`,`b_user_id`,
`auth_code`,`ip`,`pay_amount`,`pay_time_start`,`pay_time_end`,
`prepay_id`,`transaction_id`,`pay_vendor`,`pay_order_no`,
`pay_order_status`,`share`,`share_amount`,`fail_reason`
</sql>

<sql id="dynamicWhereConditions">
@@ -55,6 +58,10 @@
and `c_user_id` = #{cUserId}
</if>

<if test=" null != bUserId ">
and `b_user_id` = #{bUserId}
</if>

<if test=" null != authCode ">
and `auth_code` = #{authCode}
</if>


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