新增微信订单查询

This commit is contained in:
wanggeng 2021-08-27 11:17:55 +08:00
parent 4e56543082
commit 052e220707
6 changed files with 749 additions and 13 deletions

View File

@ -1,19 +1,18 @@
package ink.wgink.module.wechat.controller.app.miniapp;
package ink.wgink.module.wechat.controller.api.miniapp;
import ink.wgink.interfaces.consts.ISystemConstant;
import ink.wgink.module.wechat.pojo.pay.v3.PaySign;
import ink.wgink.module.wechat.pojo.pay.v3.jsapi.pojo.PayPlaceOrder;
import ink.wgink.module.wechat.pojo.pay.v3.order.OrderSearch;
import ink.wgink.module.wechat.service.pay.v3.jsapi.IJsapiService;
import ink.wgink.module.wechat.service.pay.v3.order.IOrderSearchService;
import ink.wgink.pojo.result.ErrorResult;
import ink.wgink.util.OrderUtil;
import io.swagger.annotations.*;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
/**
* @ClassName: MiniappPayAppController
@ -22,21 +21,20 @@ import org.springframework.web.bind.annotation.RestController;
* @Date: 2021/8/20 5:48 下午
* @Version: 1.0
*/
@Api(tags = ISystemConstant.API_TAGS_APP_PREFIX + "小程序用户")
@Api(tags = ISystemConstant.API_TAGS_SYSTEM_PREFIX + "小程序支付")
@RestController
@RequestMapping(ISystemConstant.APP_PREFIX + "/miniapp/pay")
public class MiniappPayAppController {
@RequestMapping(ISystemConstant.API_PREFIX + "/miniapp/pay-demo")
public class MiniappPayDemoController {
@Autowired
private IJsapiService jsapiService;
@Autowired
private IOrderSearchService orderSearchService;
@ApiOperation(value = "下订单测试", notes = "下订单测试接口")
@ApiImplicitParams({
@ApiImplicitParam(name = "token", value = "token", paramType = "header")
})
@ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
@PostMapping("save-place-order-demo")
public PaySign savePlaceOrderDemo(@RequestHeader("token") String token) throws Exception {
public PaySign savePlaceOrderDemo() throws Exception {
String atomicOrder = OrderUtil.getAtomicOrder("0001");
System.out.println("订单号:" + atomicOrder);
@ -57,4 +55,24 @@ public class MiniappPayAppController {
return jsapiService.placeOrder(payPlaceOrder);
}
@ApiOperation(value = "商家订单查询测试", notes = "商家订单查询测试接口")
@ApiImplicitParams({
@ApiImplicitParam(name = "token", value = "token", paramType = "header")
})
@ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
@GetMapping("get-business-order/{businessOrderId}")
public OrderSearch getBusinessOrder(@PathVariable("businessOrderId") String businessOrderId) throws Exception {
return orderSearchService.getBusinessOrder(businessOrderId);
}
@ApiOperation(value = "商家订单查询测试", notes = "商家订单查询测试接口")
@ApiImplicitParams({
@ApiImplicitParam(name = "token", value = "token", paramType = "header")
})
@ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
@GetMapping("get-order/{transactionId}")
public OrderSearch getOrder(@PathVariable("transactionId") String transactionId) throws Exception {
return orderSearchService.getOrder(transactionId);
}
}

View File

@ -8,6 +8,7 @@ import ink.wgink.module.wechat.utils.pay.PaySignAuthorizationUtil;
import ink.wgink.properties.wechat.pay.v3.PayProperties;
import ink.wgink.util.UUIDUtil;
import ink.wgink.util.string.WStringUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.RequestMethod;
import java.io.File;
@ -80,7 +81,7 @@ public class PayManager {
String randomSubStr = WStringUtil.randomSubStr(UUIDUtil.get32UUID(), 10).toUpperCase();
return PaySignAuthorizationUtil.buildAuthorization(requestMethod, urlSuffix,
payProperties.getMchid(), serialNumber,
payProperties.getKeyFilePath(), jsonBody, randomSubStr, System.currentTimeMillis() / 1000,
payProperties.getKeyFilePath(), StringUtils.isBlank(jsonBody) ? "" : jsonBody, randomSubStr, System.currentTimeMillis() / 1000,
payAuthorizationTypeEnum.getValue());
}

View File

@ -0,0 +1,592 @@
package ink.wgink.module.wechat.pojo.pay.v3.order;
import ink.wgink.module.wechat.pojo.pay.v3.PayNoticeCiphertext;
/**
* @ClassName: OrderBusiness
* @Description: 订单查询
* @Author: wanggeng
* @Date: 2021/8/27 10:27 上午
* @Version: 1.0
*/
public class OrderSearch {
/**
* 应用ID
*/
private String appid;
/**
* 直连商户号
*/
private String mchid;
/**
* 商户订单号
*/
private String out_trade_no;
/**
* 微信支付订单号
*/
private String transaction_id;
/**
* 交易类型
*/
private String trade_type;
/**
* 交易状态
*/
private String trade_state;
/**
* 交易状态描述
*/
private String trade_state_desc;
/**
* 付款银行
*/
private String bank_type;
/**
* 附加数据
*/
private String attach;
/**
* 支付完成时间
*/
private String success_time;
/**
* 支付者
*/
private Payer payer;
/**
* 订单金额
*/
private Amount amount;
/**
* 场景信息
*/
private SceneInfo scene_info;
/**
* 优惠功能
*/
private PromotionDetail promotion_detail;
public String getAppid() {
return appid == null ? "" : appid.trim();
}
public void setAppid(String appid) {
this.appid = appid;
}
public String getMchid() {
return mchid == null ? "" : mchid.trim();
}
public void setMchid(String mchid) {
this.mchid = mchid;
}
public String getOut_trade_no() {
return out_trade_no == null ? "" : out_trade_no.trim();
}
public void setOut_trade_no(String out_trade_no) {
this.out_trade_no = out_trade_no;
}
public String getTransaction_id() {
return transaction_id == null ? "" : transaction_id.trim();
}
public void setTransaction_id(String transaction_id) {
this.transaction_id = transaction_id;
}
public String getTrade_type() {
return trade_type == null ? "" : trade_type.trim();
}
public void setTrade_type(String trade_type) {
this.trade_type = trade_type;
}
public String getTrade_state() {
return trade_state == null ? "" : trade_state.trim();
}
public void setTrade_state(String trade_state) {
this.trade_state = trade_state;
}
public String getTrade_state_desc() {
return trade_state_desc == null ? "" : trade_state_desc.trim();
}
public void setTrade_state_desc(String trade_state_desc) {
this.trade_state_desc = trade_state_desc;
}
public String getBank_type() {
return bank_type == null ? "" : bank_type.trim();
}
public void setBank_type(String bank_type) {
this.bank_type = bank_type;
}
public String getAttach() {
return attach == null ? "" : attach.trim();
}
public void setAttach(String attach) {
this.attach = attach;
}
public String getSuccess_time() {
return success_time == null ? "" : success_time.trim();
}
public void setSuccess_time(String success_time) {
this.success_time = success_time;
}
public Payer getPayer() {
return payer;
}
public void setPayer(Payer payer) {
this.payer = payer;
}
public Amount getAmount() {
return amount;
}
public void setAmount(Amount amount) {
this.amount = amount;
}
public SceneInfo getScene_info() {
return scene_info;
}
public void setScene_info(SceneInfo scene_info) {
this.scene_info = scene_info;
}
public PromotionDetail getPromotion_detail() {
return promotion_detail;
}
public void setPromotion_detail(PromotionDetail promotion_detail) {
this.promotion_detail = promotion_detail;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("{");
sb.append("\"appid\":\"")
.append(appid).append('\"');
sb.append(",\"mchid\":\"")
.append(mchid).append('\"');
sb.append(",\"out_trade_no\":\"")
.append(out_trade_no).append('\"');
sb.append(",\"transaction_id\":\"")
.append(transaction_id).append('\"');
sb.append(",\"trade_type\":\"")
.append(trade_type).append('\"');
sb.append(",\"trade_state\":\"")
.append(trade_state).append('\"');
sb.append(",\"trade_state_desc\":\"")
.append(trade_state_desc).append('\"');
sb.append(",\"bank_type\":\"")
.append(bank_type).append('\"');
sb.append(",\"attach\":\"")
.append(attach).append('\"');
sb.append(",\"success_time\":\"")
.append(success_time).append('\"');
sb.append(",\"payer\":")
.append(payer);
sb.append(",\"amount\":")
.append(amount);
sb.append(",\"scene_info\":")
.append(scene_info);
sb.append(",\"promotion_detail\":")
.append(promotion_detail);
sb.append('}');
return sb.toString();
}
/**
* 支付者
*/
public static class Payer {
/**
* 用户标识
*/
private String openid;
public String getOpenid() {
return openid == null ? "" : openid.trim();
}
public void setOpenid(String openid) {
this.openid = openid;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("{");
sb.append("\"openid\":\"")
.append(openid).append('\"');
sb.append('}');
return sb.toString();
}
}
/**
* 订单金额
*/
public static class Amount {
/**
* 总金额
*/
private int total;
/**
* 用户支付金额
*/
private int payer_total;
/**
* 货币类型
*/
private String currency;
/**
* 用户支付币种
*/
private String payer_currency;
public int getTotal() {
return total;
}
public void setTotal(int total) {
this.total = total;
}
public int getPayer_total() {
return payer_total;
}
public void setPayer_total(int payer_total) {
this.payer_total = payer_total;
}
public String getCurrency() {
return currency == null ? "" : currency.trim();
}
public void setCurrency(String currency) {
this.currency = currency;
}
public String getPayer_currency() {
return payer_currency == null ? "" : payer_currency.trim();
}
public void setPayer_currency(String payer_currency) {
this.payer_currency = payer_currency;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("{");
sb.append("\"total\":")
.append(total);
sb.append(",\"payer_total\":")
.append(payer_total);
sb.append(",\"currency\":\"")
.append(currency).append('\"');
sb.append(",\"payer_currency\":\"")
.append(payer_currency).append('\"');
sb.append('}');
return sb.toString();
}
}
/**
* 场景信息
*/
public static class SceneInfo {
/**
* 商户端设备号
*/
private String device_id;
public String getDevice_id() {
return device_id == null ? "" : device_id.trim();
}
public void setDevice_id(String device_id) {
this.device_id = device_id;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("{");
sb.append("\"device_id\":\"")
.append(device_id).append('\"');
sb.append('}');
return sb.toString();
}
}
/**
* 优惠功能
*/
public static class PromotionDetail {
/**
* 券ID
*/
private String coupon_id;
/**
* 优惠名称
*/
private String name;
/**
* 优惠范围
*/
private String scope;
/**
* 优惠类型
*/
private String type;
/**
* 优惠券面额
*/
private Integer amount;
/**
* 活动ID
*/
private String stock_id;
/**
* 微信出资
*/
private Integer wechatpay_contribute;
/**
* 商户出资
*/
private Integer merchant_contribute;
/**
* 其他出资
*/
private Integer other_contribute;
/**
* 优惠币种
*/
private String currency;
/**
* 单品列表
*/
private PayNoticeCiphertext.PromotionDetail.GoodsDetail goods_detail;
public String getCoupon_id() {
return coupon_id == null ? "" : coupon_id.trim();
}
public void setCoupon_id(String coupon_id) {
this.coupon_id = coupon_id;
}
public String getName() {
return name == null ? "" : name.trim();
}
public void setName(String name) {
this.name = name;
}
public String getScope() {
return scope == null ? "" : scope.trim();
}
public void setScope(String scope) {
this.scope = scope;
}
public String getType() {
return type == null ? "" : type.trim();
}
public void setType(String type) {
this.type = type;
}
public Integer getAmount() {
return amount == null ? 0 : amount;
}
public void setAmount(Integer amount) {
this.amount = amount;
}
public String getStock_id() {
return stock_id == null ? "" : stock_id.trim();
}
public void setStock_id(String stock_id) {
this.stock_id = stock_id;
}
public Integer getWechatpay_contribute() {
return wechatpay_contribute == null ? 0 : wechatpay_contribute;
}
public void setWechatpay_contribute(Integer wechatpay_contribute) {
this.wechatpay_contribute = wechatpay_contribute;
}
public Integer getMerchant_contribute() {
return merchant_contribute == null ? 0 : merchant_contribute;
}
public void setMerchant_contribute(Integer merchant_contribute) {
this.merchant_contribute = merchant_contribute;
}
public Integer getOther_contribute() {
return other_contribute == null ? 0 : other_contribute;
}
public void setOther_contribute(Integer other_contribute) {
this.other_contribute = other_contribute;
}
public String getCurrency() {
return currency == null ? "" : currency.trim();
}
public void setCurrency(String currency) {
this.currency = currency;
}
public PayNoticeCiphertext.PromotionDetail.GoodsDetail getGoods_detail() {
return goods_detail;
}
public void setGoods_detail(PayNoticeCiphertext.PromotionDetail.GoodsDetail goods_detail) {
this.goods_detail = goods_detail;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("{");
sb.append("\"coupon_id\":\"")
.append(coupon_id).append('\"');
sb.append(",\"name\":\"")
.append(name).append('\"');
sb.append(",\"scope\":\"")
.append(scope).append('\"');
sb.append(",\"type\":\"")
.append(type).append('\"');
sb.append(",\"amount\":")
.append(amount);
sb.append(",\"stock_id\":\"")
.append(stock_id).append('\"');
sb.append(",\"wechatpay_contribute\":")
.append(wechatpay_contribute);
sb.append(",\"merchant_contribute\":")
.append(merchant_contribute);
sb.append(",\"other_contribute\":")
.append(other_contribute);
sb.append(",\"currency\":\"")
.append(currency).append('\"');
sb.append(",\"goods_detail\":")
.append(goods_detail);
sb.append('}');
return sb.toString();
}
/**
* 单品列表
*/
public static class GoodsDetail {
/**
* 商品编码
*/
private String goods_id;
/**
* 商品数量
*/
private Integer quantity;
/**
* 商品单价
*/
private Integer unit_price;
/**
* 商品优惠金额
*/
private Integer discount_amount;
/**
* 商品备注
*/
private String goods_remark;
public String getGoods_id() {
return goods_id == null ? "" : goods_id.trim();
}
public void setGoods_id(String goods_id) {
this.goods_id = goods_id;
}
public Integer getQuantity() {
return quantity == null ? 0 : quantity;
}
public void setQuantity(Integer quantity) {
this.quantity = quantity;
}
public Integer getUnit_price() {
return unit_price == null ? 0 : unit_price;
}
public void setUnit_price(Integer unit_price) {
this.unit_price = unit_price;
}
public Integer getDiscount_amount() {
return discount_amount == null ? 0 : discount_amount;
}
public void setDiscount_amount(Integer discount_amount) {
this.discount_amount = discount_amount;
}
public String getGoods_remark() {
return goods_remark == null ? "" : goods_remark.trim();
}
public void setGoods_remark(String goods_remark) {
this.goods_remark = goods_remark;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("{");
sb.append("\"goods_id\":\"")
.append(goods_id).append('\"');
sb.append(",\"quantity\":")
.append(quantity);
sb.append(",\"unit_price\":")
.append(unit_price);
sb.append(",\"discount_amount\":")
.append(discount_amount);
sb.append(",\"goods_remark\":\"")
.append(goods_remark).append('\"');
sb.append('}');
return sb.toString();
}
}
}
}

View File

@ -0,0 +1,42 @@
package ink.wgink.module.wechat.request.pay.v3.order;
import com.alibaba.fastjson.JSONObject;
import ink.wgink.exceptions.base.SystemException;
import ink.wgink.module.wechat.pojo.pay.v3.PayErrorResponse;
import ink.wgink.module.wechat.pojo.pay.v3.order.OrderSearch;
import ink.wgink.module.wechat.request.pay.v3.AbstractPayRequest;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.HttpClientErrorException;
/**
* @ClassName: OrderSearchPayRequestImpl
* @Description: 订单查询
* @Author: wanggeng
* @Date: 2021/8/27 10:21 上午
* @Version: 1.0
*/
public class OrderSearchPayRequestImpl extends AbstractPayRequest<String, String, OrderSearch> {
@Override
public String bodyJson(String s) {
return null;
}
@Override
public OrderSearch response(ResponseEntity<String> responseEntity) {
LOG.debug("Response success status code: {}", responseEntity.getStatusCode());
if (responseEntity.getStatusCode() == HttpStatus.OK) {
return JSONObject.parseObject(responseEntity.getBody(), OrderSearch.class);
}
return null;
}
@Override
public void error(HttpClientErrorException e) {
LOG.debug("Response error status code{}", e.getStatusCode());
PayErrorResponse payErrorResponse = JSONObject.parseObject(e.getResponseBodyAsString(), PayErrorResponse.class);
LOG.debug("Response error detail: {}", payErrorResponse.getDetail());
throw new SystemException(payErrorResponse.getMessage());
}
}

View File

@ -0,0 +1,30 @@
package ink.wgink.module.wechat.service.pay.v3.order;
import ink.wgink.module.wechat.pojo.pay.v3.order.OrderSearch;
/**
* @ClassName: IOrderSearchService
* @Description: 订单查询业务
* @Author: wanggeng
* @Date: 2021/8/27 10:47 上午
* @Version: 1.0
*/
public interface IOrderSearchService {
/**
* 微信支付订单查询
*
* @param transactionId 微信支付订单号
* @return
*/
OrderSearch getOrder(String transactionId) throws Exception;
/**
* 商家订单查询
*
* @param businessOrderId 商家订单号
* @return
*/
OrderSearch getBusinessOrder(String businessOrderId) throws Exception;
}

View File

@ -0,0 +1,53 @@
package ink.wgink.module.wechat.service.pay.v3.order.impl;
import ink.wgink.exceptions.ParamsException;
import ink.wgink.module.wechat.enums.PayAuthorizationTypeEnum;
import ink.wgink.module.wechat.pojo.pay.v3.order.OrderSearch;
import ink.wgink.module.wechat.request.pay.v3.order.OrderSearchPayRequestImpl;
import ink.wgink.module.wechat.service.pay.BasePayService;
import ink.wgink.module.wechat.service.pay.v3.order.IOrderSearchService;
import ink.wgink.properties.wechat.pay.v3.PayProperties;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestMethod;
/**
* @ClassName: OrderSearchServiceImpl
* @Description: 订单查询
* @Author: wanggeng
* @Date: 2021/8/27 10:51 上午
* @Version: 1.0
*/
@Service
public class OrderSearchServiceImpl extends BasePayService implements IOrderSearchService {
@Autowired
private PayProperties payProperties;
@Override
public OrderSearch getOrder(String transactionId) throws Exception {
if (StringUtils.isBlank(transactionId)) {
throw new ParamsException("微信订单号参数不能为空");
}
String urlSuffix = "/v3/pay/transactions/id/" + transactionId + "?mchid=" + payProperties.getMchid();
return getOrderInfo(urlSuffix);
}
@Override
public OrderSearch getBusinessOrder(String businessOrderId) throws Exception {
if (StringUtils.isBlank(businessOrderId)) {
throw new ParamsException("商家订单号参数不能为空");
}
String urlSuffix = "/v3/pay/transactions/out-trade-no/" + businessOrderId + "?mchid=" + payProperties.getMchid();
return getOrderInfo(urlSuffix);
}
private OrderSearch getOrderInfo(String urlSuffix) throws Exception {
OrderSearchPayRequestImpl orderSearchPayRequest = new OrderSearchPayRequestImpl();
String url = getPayBaseUrl() + urlSuffix;
String serialNumber = getSerialNumber();
String authorization = getAuthorization(RequestMethod.GET, urlSuffix, serialNumber, payProperties, null, PayAuthorizationTypeEnum.WECHATPAY2_SHA256_RSA2048);
return orderSearchPayRequest.get(url, authorization, serialNumber);
}
}