记得上下班打卡 | git大法好,push需谨慎

Commit 3ad34a00 authored by 姜秀龙's avatar 姜秀龙

Merge remote-tracking branch 'origin/dev-1.6-shouqianba' into dev-1.6-shouqianba

parents 254ed70b 9fc041df
......@@ -3,7 +3,11 @@ package com.liquidnet.service.goblin.param.shouqianba.request;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
public class CommonRequest {
......@@ -11,6 +15,8 @@ public class CommonRequest {
@Data
@ApiModel(value = "商城信息")
@JsonIgnoreProperties(ignoreUnknown = true)
@AllArgsConstructor
@NoArgsConstructor
public static class Mall{
@ApiModelProperty(required = true, value = "商城ID")
......@@ -23,6 +29,8 @@ public class CommonRequest {
@Data
@ApiModel(value = "卖家信息/商户信息")
@JsonIgnoreProperties(ignoreUnknown = true)
@AllArgsConstructor
@NoArgsConstructor
public static class Seller {
@ApiModelProperty(required = true, value = "商户ID")
private String merchantId;
......@@ -36,6 +44,8 @@ public class CommonRequest {
@Data
@ApiModel("买家信息")
@AllArgsConstructor
@NoArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public static class Buyer{
@ApiModelProperty(required = true, value = "买家ID(用户唯一标识)")
......@@ -44,6 +54,8 @@ public class CommonRequest {
@Data
@ApiModel("付款人信息")
@AllArgsConstructor
@NoArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public static class Payer{
@ApiModelProperty(required = true, value = "付款人ID")
......@@ -53,6 +65,8 @@ public class CommonRequest {
@ApiModel(value = "收单信息")
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
@AllArgsConstructor
@NoArgsConstructor
public static class Acquiring{
@ApiModelProperty(value = "收单号")
private String acquiringSn;
......@@ -60,4 +74,36 @@ public class CommonRequest {
@ApiModelProperty(value = "收单密钥")
private String signature;
}
@Data
@ApiModel(value = "金额构成信息")
@JsonIgnoreProperties(ignoreUnknown = true)
public static class AmountComposition {
@ApiModelProperty(required = true, value = "金额构成项列表")
private List<CompositionItem> compositionItems;
}
@Data
@ApiModel(value = "金额构成项详情")
@JsonIgnoreProperties(ignoreUnknown = true)
public static class CompositionItem {
@ApiModelProperty(required = true, value = "构成项类目")
private String category;
@ApiModelProperty(required = true, value = "构成项金额")
private Long amount;
}
@Data
@ApiModel(value = "订单信息")
@AllArgsConstructor
@NoArgsConstructor
public static class OrderInfo {
@ApiModelProperty(required = true, value = "订单ID")
private String sn;
@ApiModelProperty(required = true, value = "订单密码")
private String signature;
}
}
......@@ -12,21 +12,10 @@ public class CouponQueryRequest {
private String appid;
@ApiModelProperty(required = true, value = "订单信息")
private OrderInfo orderID;
private CommonRequest.OrderInfo orderID;
@ApiModelProperty(required = true, value = "卖家信息", example = "4")
private CommonRequest.Seller seller;
@Data
@ApiModel(value = "订单信息")
public static class OrderInfo {
@ApiModelProperty(required = true, value = "订单ID")
private String sn;
@ApiModelProperty(required = true, value = "订单密码")
private String signature;
}
}
......@@ -2,10 +2,11 @@ package com.liquidnet.service.goblin.param.shouqianba.request;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
import java.util.Map;
@Data
@ApiModel(value = "券退款请求参数")
......@@ -18,7 +19,7 @@ public class CouponRefundRequest {
private CommonRequest.Seller seller;
@ApiModelProperty(required = true, value = "订单信息")
private OrderInfo orderID;
private CommonRequest.OrderInfo orderID;
@ApiModelProperty(required = true, value = "申请退款信息不能为空")
private RefundInfo refundInfo;
......@@ -29,19 +30,11 @@ public class CouponRefundRequest {
@ApiModelProperty(required = true, value = "退款来源(固定值:EXTERN)")
private String requestSource;
@Data
@ApiModel(value = "订单信息")
public static class OrderInfo {
@ApiModelProperty(required = true, value = "单号(前置操作后拿到)")
private String sn;
@ApiModelProperty(required = true, value = "密码(前置操作后拿到)")
private String signature;
}
@Data
@ApiModel(value = "退款信息")
@AllArgsConstructor
@NoArgsConstructor
public static class RefundInfo {
@ApiModelProperty(required = true, value = "金额")
private Long applyAmount;
......
......@@ -51,7 +51,7 @@ public class CreateWechatPrepayOrderRequest {
private String amount;
@ApiModelProperty(required = true, value = "金额构成")
private AmountComposition amountComposition;
private CommonRequest.AmountComposition amountComposition;
@ApiModelProperty(required = true, value = "用户身份信息", example = "wzwl")
private String identity;
......@@ -86,20 +86,5 @@ public class CreateWechatPrepayOrderRequest {
private String latitude;
}
@Data
@ApiModel(value = "金额构成信息")
public static class AmountComposition {
@ApiModelProperty(required = true, value = "金额构成项列表")
private List<CompositionItem> compositionItems;
}
@Data
@ApiModel(value = "金额构成项详情")
public static class CompositionItem {
@ApiModelProperty(required = true, value = "构成项类目")
private String category;
@ApiModelProperty(required = true, value = "构成项金额")
private Long amount;
}
}
package com.liquidnet.service.goblin.param.shouqianba.response.data;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.liquidnet.service.goblin.param.shouqianba.request.CommonRequest;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
......@@ -65,27 +66,10 @@ public class CashierQueryData {
private List<String> tips;
@ApiModelProperty(value = "金额构成")
private AmountComposition amountComposition;
private CommonRequest.AmountComposition amountComposition;
}
@Data
@ApiModel(value = "金额构成信息")
@JsonIgnoreProperties(ignoreUnknown = true)
public static class AmountComposition {
@ApiModelProperty(required = true, value = "金额构成项列表")
private List<CompositionItem> compositionItems;
}
@Data
@ApiModel(value = "金额构成项详情")
@JsonIgnoreProperties(ignoreUnknown = true)
public static class CompositionItem {
@ApiModelProperty(required = true, value = "构成项类目")
private String category;
@ApiModelProperty(required = true, value = "构成项金额")
private Long amount;
}
@Data
@ApiModel(value = "收款方信息")
......
......@@ -5,6 +5,7 @@ import com.liquidnet.service.goblin.param.shouqianba.request.*;
import com.liquidnet.service.goblin.param.shouqianba.response.data.*;
import java.util.List;
import java.util.Map;
/**
* 收钱吧对接接口定义
......@@ -25,6 +26,16 @@ public interface IGoblinShouQianBaService {
*/
SettlementCreateData createSettlement(SettlementCreateRequest request);
/**
*
* @param mallSn 商城ID
* @param signature 商城密钥
* @param userId 正在用户ID
* @param checkoutItems 商品
* @return
*/
SettlementCreateData createSettlement(String mallSn, String signature, String userId, List<SettlementCreateRequest.CheckoutItem> checkoutItems);
/**
* 创建订单
*
......@@ -33,6 +44,18 @@ public interface IGoblinShouQianBaService {
*/
OrderCreateData createOrder(OrderCreateRequest request);
/**
*
* @param mallSn 商城ID
* @param signature 商城密钥
* @param checkoutItemsId 创建结算明细 返回的 结算项ID
* @param userId 正在用户ID
* @param requestId 请求ID
* @param subject 标题
* @return
*/
OrderCreateData createOrder(String mallSn, String signature, String checkoutItemsId, String userId, String requestId, String subject);
/**
* 创建收单
* 如果上一步创建收单失败 可以使用这个接口重新创建收单
......@@ -49,6 +72,15 @@ public interface IGoblinShouQianBaService {
*/
CashierQueryData queryCashier(CashierQueryRequest request);
/**
* 查询收银台
* @param acquiringSn 收单号
* @param acquiringSignature 收单密钥
* @param userId 正在用户ID
* @return
*/
CashierQueryData queryCashier(String acquiringSn, String acquiringSignature, String userId);
/**
* 创建微信预支付订单
*
......@@ -57,6 +89,30 @@ public interface IGoblinShouQianBaService {
*/
CreateWechatPrepayOrderData createWechatPrepayOrder(CreateWechatPrepayOrderRequest request);
/**
* 创建微信预支付订单
*
* @param acquiringSn 收单号
* @param signature 收单签名
* @param userId 正在用户ID
* @param amount 支付金额
* @param requestSn 支付请求号
* @param payTool 支付工具代码
* @param channelExt 通道扩展参数
* @param selectedSignature 支付工具签名
* @param seq 序列号 上一步seq(查询收银台)
* @return
*/
CreateWechatPrepayOrderData createWechatPrepayOrder(String acquiringSn,
String signature,
String userId,
String amount,
String requestSn,
CashierQueryData.PayTool payTool,
Map<String, Object> channelExt,
String selectedSignature,
String seq);
/**
* 查询券码
*
......@@ -65,6 +121,14 @@ public interface IGoblinShouQianBaService {
*/
CouponQueryData queryCoupon(CouponQueryRequest request);
/**
* 查询券码
* @param sn 订单ID
* @param signature 订单密码
* @return
*/
CouponQueryData queryCoupon(String sn, String signature);
/**
* 券码状态同步
*
......@@ -73,6 +137,21 @@ public interface IGoblinShouQianBaService {
*/
boolean syncCouponStatus(CouponStatusSyncRequest request);
/**
* 券码状态同步
* @param redeemMerchantId 用户ID(自定义,核销用户id)
* @param voucherNos 券号
* @param redeemExternalOrderSn 外部单号(${AppCode}+id,AppCode需要分配)
* @param clientSn 核销终端号(自定义)
* @param status 券使用状态(0未核销,1已核销)
* @return
*/
boolean syncCouponStatus(String redeemMerchantId,
List<String> voucherNos,
String redeemExternalOrderSn,
String clientSn,
Byte status);
/**
* 券退款
*
......@@ -81,6 +160,24 @@ public interface IGoblinShouQianBaService {
*/
CouponRefundData refundCoupon(CouponRefundRequest request);
/**
* @param sn 单号(前置操作后拿到)
* @param signature 密码(前置操作后拿到)
* @param applyAmount 金额
* @param type 退款类型(1商品 2金额)
* @param item
* @param refundReason 退款原因
* @param requestId 退款请求id(${AppCode}+id)
* @return
*/
CouponRefundData refundCoupon(String sn,
String signature,
Long applyAmount,
Byte type,
List<CouponRefundRequest.RefundItem> item,
String refundReason,
String requestId);
/**
* 商城列表接口
*
......@@ -89,6 +186,14 @@ public interface IGoblinShouQianBaService {
*/
List<MallListQueryData> queryMallList(MallListQueryRequest request);
/**
*
* @param endCursor 结束游标 上一页的结束游标(首次查询传 null)
* @param count 查询数量 每页返回的最大订单数
* @return
*/
List<MallListQueryData> queryMallList(String endCursor, Integer count);
/**
* 商城商品接口
*
......@@ -97,6 +202,14 @@ public interface IGoblinShouQianBaService {
*/
List<MallProductsQueryData> queryMallProducts(MallProductsQueryRequest request);
/**
* 商城商品接口
* @param mallSn 商城ID
* @param signature 商城密码
* @return
*/
List<MallProductsQueryData> queryMallProducts(String mallSn, String signature);
/**
* 验签
* @param callbackParams
......
......@@ -26,7 +26,9 @@ import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.util.Collections;
import java.util.List;
import java.util.Map;
/**
* 收钱吧对接实现类
......@@ -40,12 +42,18 @@ public class GoblinShouQianBaServiceImpl implements IGoblinShouQianBaService {
private final ShouqianbaProperties shouqianbaProperties;
private final CommonRequest.Seller cachedSeller;
public GoblinShouQianBaServiceImpl(ShouqianbaProperties properties) {
this.shouqianbaProperties = properties;
if (this.shouqianbaProperties == null) {
throw new IllegalArgumentException("找不到应用配置");
}
// 商户信息来自配置,整个生命周期内不变,提前构建并缓存
this.cachedSeller = new CommonRequest.Seller();
this.cachedSeller.setMerchantId(properties.getMerchantId());
this.cachedSeller.setMerchantUserId(properties.getMerchantUserId());
this.cachedSeller.setRole(properties.getRole());
}
private static final ObjectMapper objectMapper;
......@@ -74,6 +82,30 @@ public class GoblinShouQianBaServiceImpl implements IGoblinShouQianBaService {
return executeShouQianBaRequest("/optimus/core/mall/createCheckoutItems", "创建结算明细", request, SettlementCreateResponse.class);
}
@Override
public SettlementCreateData createSettlement(String mallSn, String signature, String userId, List<SettlementCreateRequest.CheckoutItem> checkoutItems) {
SettlementCreateRequest request = new SettlementCreateRequest();
request.setAppid(shouqianbaProperties.getAppId());
request.setMallID(buildMall(mallSn, signature));
request.setSeller(cachedSeller);
request.setBuyer(buildBuyer(userId));
request.setCheckoutItems(checkoutItems);
return createSettlement(request);
}
private CommonRequest.Mall buildMall(String mallSn, String signature) {
CommonRequest.Mall mall = new CommonRequest.Mall();
mall.setMallSn(mallSn);
mall.setSignature(signature);
return mall;
}
private CommonRequest.Buyer buildBuyer(String userId) {
CommonRequest.Buyer buyer = new CommonRequest.Buyer();
buyer.setBuyerId(userId);
return buyer;
}
/**
* 创建订单
*
......@@ -85,6 +117,19 @@ public class GoblinShouQianBaServiceImpl implements IGoblinShouQianBaService {
return executeShouQianBaRequest("/optimus/core/order/placeOrder", "创建订单", request, OrderCreateResponse.class);
}
@Override
public OrderCreateData createOrder(String mallSn, String signature, String checkoutItemsId, String userId, String requestId, String subject) {
OrderCreateRequest orderCreateRequest = new OrderCreateRequest();
orderCreateRequest.setAppid(shouqianbaProperties.getAppId());
orderCreateRequest.setMallID(buildMall(mallSn, signature));
orderCreateRequest.setSeller(cachedSeller);
orderCreateRequest.setCheckoutItemsId(checkoutItemsId);
orderCreateRequest.setBuyer(buildBuyer(userId));
orderCreateRequest.setRequestId(requestId);
orderCreateRequest.setSubject(subject);
return createOrder(orderCreateRequest);
}
/**
* 创建收单
* 如果上一步创建收单失败 可以使用这个接口重新创建收单
......@@ -107,6 +152,22 @@ public class GoblinShouQianBaServiceImpl implements IGoblinShouQianBaService {
return executeShouQianBaRequest("/optimus/core/cashier/queryCashierPage", "查询收银台", request, CashierQueryResponse.class);
}
@Override
public CashierQueryData queryCashier(String acquiringSn, String acquiringSignature, String userId) {
CashierQueryRequest.PaymentEnv paymentEnv = new CashierQueryRequest.PaymentEnv();
paymentEnv.setClient("wechat");
CashierQueryRequest cashierQueryRequest = new CashierQueryRequest();
cashierQueryRequest.setAppid(shouqianbaProperties.getAppId());
cashierQueryRequest.setSeller(cachedSeller);
cashierQueryRequest.setPaymentMode(4);
cashierQueryRequest.setPaymentEnv(paymentEnv);
cashierQueryRequest.setPayer(new CommonRequest.Payer(userId));
cashierQueryRequest.setAcquiringInfo(new CommonRequest.Acquiring(acquiringSn, acquiringSignature));
return queryCashier(cashierQueryRequest);
}
/**
* 创建微信预支付订单
*
......@@ -118,6 +179,45 @@ public class GoblinShouQianBaServiceImpl implements IGoblinShouQianBaService {
return executeShouQianBaRequest("/optimus/core/cashier/proxyPreCreatedPay", "创建微信预支付订单", request, CreateWechatPrepayOrderResponse.class);
}
@Override
public CreateWechatPrepayOrderData createWechatPrepayOrder(String acquiringSn,
String signature,
String userId,
String amount,
String requestSn,
CashierQueryData.PayTool payTool,
Map<String, Object> channelExt,
String selectedSignature,
String seq) {
CreateWechatPrepayOrderRequest orderRequest = new CreateWechatPrepayOrderRequest();
orderRequest.setAppid(shouqianbaProperties.getAppId());
orderRequest.setSeller(cachedSeller);
orderRequest.setAcquiringSn(acquiringSn);
orderRequest.setSignature(signature);
orderRequest.setUsingPayTools(buildUsingPayTools(requestSn, payTool, channelExt, amount, userId));
orderRequest.setSelectedSignature(selectedSignature);
orderRequest.setSeq(seq);
return createWechatPrepayOrder(orderRequest);
}
private List<CreateWechatPrepayOrderRequest.UsingPayTool> buildUsingPayTools(String requestSn,
CashierQueryData.PayTool payTool,
Map<String, Object> channelExt,
String amount,
String userId) {
CreateWechatPrepayOrderRequest.UsingPayTool tool = new CreateWechatPrepayOrderRequest.UsingPayTool();
tool.setId(payTool.getId());
tool.setPayTool(Integer.valueOf(payTool.getCode()));
tool.setPayMode(4); // TODO 需要确认
tool.setAmount(amount);
tool.setIdentity(userId);
tool.setAmountComposition(payTool.getAmountComposition());
tool.setRequestSn(requestSn);
tool.setChannelExt(channelExt);
return Collections.singletonList(tool);
}
/**
* 查询券码
*
......@@ -129,6 +229,15 @@ public class GoblinShouQianBaServiceImpl implements IGoblinShouQianBaService {
return executeShouQianBaRequest("/optimus/core/voucher/queryOrderVoucherList", "查询优惠券", request, CouponQueryResponse.class);
}
@Override
public CouponQueryData queryCoupon(String sn, String signature) {
CouponQueryRequest couponQueryRequest = new CouponQueryRequest();
couponQueryRequest.setAppid(shouqianbaProperties.getAppId());
couponQueryRequest.setSeller(cachedSeller);
couponQueryRequest.setOrderID(new CommonRequest.OrderInfo(sn, signature));
return queryCoupon(couponQueryRequest);
}
/**
* 券码状态同步
*
......@@ -141,6 +250,19 @@ public class GoblinShouQianBaServiceImpl implements IGoblinShouQianBaService {
return response != null && Boolean.TRUE.equals(response.getSuccess());
}
@Override
public boolean syncCouponStatus(String redeemMerchantId, List<String> voucherNos, String redeemExternalOrderSn, String clientSn, Byte status) {
CouponStatusSyncRequest couponStatusSyncRequest = new CouponStatusSyncRequest();
couponStatusSyncRequest.setAppid(shouqianbaProperties.getAppId());
couponStatusSyncRequest.setVoucherNos(voucherNos);
couponStatusSyncRequest.setRedeemSource("EXTERN");
couponStatusSyncRequest.setRedeemExternalOrderSn(redeemExternalOrderSn);
couponStatusSyncRequest.setRedeemMerchantId(redeemMerchantId);
couponStatusSyncRequest.setClientSn(clientSn);
couponStatusSyncRequest.setStatus(status);
return syncCouponStatus(couponStatusSyncRequest);
}
/**
* 券退款
*
......@@ -152,6 +274,24 @@ public class GoblinShouQianBaServiceImpl implements IGoblinShouQianBaService {
return executeShouQianBaRequest("/optimus/core/aftersale/applyRefund", "退款优惠券", request, CouponRefundResponse.class);
}
@Override
public CouponRefundData refundCoupon(String sn,
String signature,
Long applyAmount,
Byte type,
List<CouponRefundRequest.RefundItem> item,
String refundReason,
String requestId) {
CouponRefundRequest couponRefundRequest = new CouponRefundRequest();
couponRefundRequest.setAppid(shouqianbaProperties.getAppId());
couponRefundRequest.setSeller(cachedSeller);
couponRefundRequest.setOrderID(new CommonRequest.OrderInfo(sn, signature));
couponRefundRequest.setRefundInfo(new CouponRefundRequest.RefundInfo(applyAmount, type, item, refundReason));
couponRefundRequest.setRequestId(requestId);
couponRefundRequest.setRequestSource("EXTERN");
return refundCoupon(couponRefundRequest);
}
/**
* 商城列表接口
*
......@@ -163,6 +303,29 @@ public class GoblinShouQianBaServiceImpl implements IGoblinShouQianBaService {
return executeShouQianBaRequest("/optimus/core/open/mall/queryMallList", "查询门店列表", request, MallListQueryResponse.class);
}
@Override
public List<MallListQueryData> queryMallList(String endCursor, Integer count) {
MallListQueryRequest.Filter filter = new MallListQueryRequest.Filter();
filter.setSeller(cachedSeller);
MallListQueryRequest.Cursor cursor = new MallListQueryRequest.Cursor();
cursor.setCursorField("id");
cursor.setEndCursor(endCursor);
cursor.setCount(count);
MallListQueryRequest.Sort sort = new MallListQueryRequest.Sort();
sort.setSortField("id");
sort.setSort("DESC");
MallListQueryRequest mallListQueryRequest = new MallListQueryRequest();
mallListQueryRequest.setAppid(shouqianbaProperties.getAppId());
mallListQueryRequest.setFilter(filter);
mallListQueryRequest.setCursor(cursor);
mallListQueryRequest.setSort(sort);
return queryMallList(mallListQueryRequest);
}
/**
* 商城商品接口
*
......@@ -174,6 +337,15 @@ public class GoblinShouQianBaServiceImpl implements IGoblinShouQianBaService {
return executeShouQianBaRequest("/optimus/core/open/mall/queryMallProducts", "查询门店商品", request, MallProductsQueryResponse.class);
}
@Override
public List<MallProductsQueryData> queryMallProducts(String mallSn, String signature) {
MallProductsQueryRequest request = new MallProductsQueryRequest();
request.setAppid(shouqianbaProperties.getAppId());
request.setSeller(cachedSeller);
request.setMallID(new CommonRequest.Mall(mallSn, signature));
return queryMallProducts(request);
}
/**
* 发送HTTP请求并返回Response对象
*/
......@@ -183,14 +355,7 @@ public class GoblinShouQianBaServiceImpl implements IGoblinShouQianBaService {
log.info("[收钱吧] {}, 请求URL: {}, 请求参数: {}", businessName, url, request);
try {
// body进行序列化成TreeMap以后 最后转成json(为了排序稳定)
// TreeMap<String, Object> map = objectMapper.convertValue(
// request,
// new TypeReference<TreeMap<String, Object>>() {
// }
// );
String requestBody = objectMapper.writeValueAsString(request);
// 去除可能存在的空格和换行符,以保证签名通过
log.info("request body: {}", requestBody);
// 构建请求头(添加签名参数)
......
......@@ -3,6 +3,7 @@ package com.liquidnet.service.goblin.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.liquidnet.commons.lang.util.IDGenerator;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.goblin.config.properties.ShouqianbaProperties;
import com.liquidnet.service.goblin.dto.vo.*;
import com.liquidnet.service.goblin.entity.GoblinSqbPerformanceGoods;
import com.liquidnet.service.goblin.mapper.GoblinSqbPerformanceGoodsMapper;
......@@ -14,8 +15,8 @@ import com.liquidnet.service.goblin.param.shouqianba.response.data.*;
import com.liquidnet.service.goblin.service.IGoblinShouQianBaService;
import com.liquidnet.service.goblin.service.IGoblinSqbOrderService;
import com.liquidnet.service.goblin.util.GoblinRedisUtils;
import com.liquidnet.service.goblin.util.GoblinSqbConvertUtils;
import com.liquidnet.service.goblin.util.GoblinSqbRedisUtils;
import com.liquidnet.service.goblin.config.properties.ShouqianbaProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
......@@ -55,6 +56,9 @@ public class GoblinSqbOrderServiceImpl implements IGoblinSqbOrderService {
@Autowired
private ShouqianbaProperties shouqianbaProperties;
@Autowired
private GoblinSqbConvertUtils sqbConvertUtils;
// ================================ 创建订单 ================================
@Override
......@@ -91,67 +95,76 @@ public class GoblinSqbOrderServiceImpl implements IGoblinSqbOrderService {
}
log.info("[收钱吧下单] 扣减库存成功,skuId={}, remaining={}", skuId, remaining);
// Step 4: 构建收钱吧公共请求参数
CommonRequest.Seller seller = buildSeller();
GoblinGoodsSkuInfoVo skuVo = goblinRedisUtils.getGoodsSkuInfoVo(skuId);
if (skuVo == null) {
log.error("[收钱吧下单] 未找到商品, skuId: {}, spuId: {}", skuId, spuId);
}
if (!skuId.equals(skuVo.getSkuId())) {
return ResponseDto.failure("下单失败");
}
// Step 4.1: createSettlement → 得 checkoutItemsId
// TODO: 从商品数据中获取价格、图片、标题等信息填充 CheckoutItem
SettlementCreateRequest settlementReq = new SettlementCreateRequest();
settlementReq.setAppid(shouqianbaProperties.getAppId());
settlementReq.setSeller(seller);
CommonRequest.Buyer buyer = new CommonRequest.Buyer();
buyer.setBuyerId(userId);
settlementReq.setBuyer(buyer);
// TODO: settlementReq.setCheckoutItems(...); settlementReq.setAmount(...);
SettlementCreateData settlementData = goblinShouQianBaService.createSettlement(settlementReq);
//TODO 获取该商品对应的商城的编号和密码
Map<String, String> sqbInfoMap = sqbConvertUtils.getSqbInfoByzhengzaiSkuIdAndSpuId(skuId, spuId);
SettlementCreateData settlementData = goblinShouQianBaService.createSettlement(
sqbInfoMap.get("mallSn"),
sqbInfoMap.get("signature"),
userId,
Collections.singletonList(buildSqbCheckOutItem(skuVo, quantity, sqbInfoMap.get("sqbSkuId"), sqbInfoMap.get("sqbSpuId"))));
if (settlementData == null) {
goblinRedisUtils.incrSkuStock(null, skuId, quantity);
return ResponseDto.failure("创建结算明细失败");
}
String checkoutItemsId = settlementData.getCheckoutItemsId();
log.info("[收钱吧下单] createSettlement 成功,checkoutItemsId={}", checkoutItemsId);
final String checkoutItemsId = settlementData.getCheckoutItemsId();
log.info("[收钱吧下单] 创建结算明细成功,checkoutItemsId={}", checkoutItemsId);
// Step 4.2: createOrder → 得 sqbOrderSn + sqbOrderSignature + sqbAcquiringSn
OrderCreateRequest orderReq = new OrderCreateRequest();
orderReq.setAppid(shouqianbaProperties.getAppId());
orderReq.setSeller(seller);
orderReq.setCheckoutItemsId(checkoutItemsId);
orderReq.setBuyer(buyer);
orderReq.setRequestId(IDGenerator.nextSnowId());
orderReq.setSubject("收钱吧商品");
OrderCreateData orderData = goblinShouQianBaService.createOrder(orderReq);
OrderCreateData orderData = goblinShouQianBaService.createOrder(
sqbInfoMap.get("mallSn"),
sqbInfoMap.get("signature"),
checkoutItemsId,
userId,
"", // TODO 构建请求ID
"" // TODO 构建标题
);
if (orderData == null) {
goblinRedisUtils.incrSkuStock(null, skuId, quantity);
return ResponseDto.failure("创建收钱吧订单失败");
}
String sqbOrderSn = orderData.getOrderSn();
String sqbOrderSignature = orderData.getOrderSignature();
String sqbAcquiringSn = orderData.getAcquiring() != null ? orderData.getAcquiring().getAcquiringSn() : null;
log.info("[收钱吧下单] createOrder 成功,sqbOrderSn={}, sqbAcquiringSn={}", sqbOrderSn, sqbAcquiringSn);
String sqbOrderSn = orderData.getOrderSn(); // 订单编号
String sqbOrderSignature = orderData.getOrderSignature(); // 订单密钥
String sqbAcquiringSn = orderData.getAcquiring() != null ? orderData.getAcquiring().getAcquiringSn() : null; // 收单号
String sqbAcquiringSign = orderData.getAcquiring() != null ? orderData.getAcquiring().getSignature() : null; // 收单密钥
log.info("[收钱吧下单] 创建订单成功,订单编号={}, 收单号={}", sqbOrderSn, sqbAcquiringSn);
// Step 4.3: queryCashier → 得 selectedSignature + seq
CashierQueryRequest cashierReq = buildCashierQueryRequest(seller, sqbAcquiringSn, sqbOrderSignature);
CashierQueryData cashierData = goblinShouQianBaService.queryCashier(cashierReq);
CashierQueryData cashierData = goblinShouQianBaService.queryCashier(sqbAcquiringSn, sqbAcquiringSign, userId);
if (cashierData == null) {
goblinRedisUtils.incrSkuStock(null, skuId, quantity);
return ResponseDto.failure("查询收银台失败");
}
String selectedSignature = cashierData.getSelectedSignature();
String seq = cashierData.getSeq();
log.info("[收钱吧下单] queryCashier 成功,selectedSignature={}, seq={}", selectedSignature, seq);
// Step 4.4: createWechatPrepayOrder → 得 paymentVoucher
CreateWechatPrepayOrderRequest prepayReq = buildWechatPrepayRequest(
seller, sqbAcquiringSn, sqbOrderSignature, selectedSignature, seq, cashierData);
CreateWechatPrepayOrderData prepayData = goblinShouQianBaService.createWechatPrepayOrder(prepayReq);
String selectedSignature = cashierData.getSelectedSignature(); // 支付工具签名
String seq = cashierData.getSeq(); // 响应唯一序列号
log.info("[收钱吧下单] 查询收银台成功,selectedSignature={}, seq={}", selectedSignature, seq);
CreateWechatPrepayOrderData prepayData = goblinShouQianBaService.createWechatPrepayOrder(sqbAcquiringSn,
sqbAcquiringSign,
userId,
"",
"",
cashierData.getPayTools().get(0),
new HashMap<String, Object>(),
selectedSignature,
seq
);
if (prepayData == null || prepayData.getPaymentVoucher() == null) {
goblinRedisUtils.incrSkuStock(null, skuId, quantity);
return ResponseDto.failure("创建微信预支付失败");
}
CreateWechatPrepayOrderData.PaymentVoucher pv = prepayData.getPaymentVoucher();
log.info("[收钱吧下单] createWechatPrepayOrder 成功,timeStamp={}", pv.getTimeStamp());
log.info("[收钱吧下单] 创建微信预支付订单成功,timeStamp={}", pv.getTimeStamp());
String orderId = IDGenerator.nextSnowId();
String masterOrderCode = IDGenerator.nextTimeId();
......@@ -271,7 +284,7 @@ public class GoblinSqbOrderServiceImpl implements IGoblinSqbOrderService {
});
// 借用 Base 模块中 ConsumerGoblinOrderCPRdsReceiver 这个队列消费类进行写库
if(queueUtils != null) {
if (queueUtils != null) {
queueUtils.sendMsgByRedis(com.liquidnet.service.base.constant.MQConst.GoblinQueue.GOBLIN_ORDER_CREATE_PAY.getKey(),
com.liquidnet.service.base.SqlMapping.gets(sqls, sqlDataSku, sqlDataOrder));
// 待支付超时回调等处理也可放入原有股票队列逻辑,暂省略
......@@ -302,6 +315,27 @@ public class GoblinSqbOrderServiceImpl implements IGoblinSqbOrderService {
}
}
/**
* 构建收钱吧-结算明细条目
* @param skuVo
* @param quantity
* @param sqbSkuId
* @param sqbSpuId
* @return
*/
private SettlementCreateRequest.CheckoutItem buildSqbCheckOutItem(GoblinGoodsSkuInfoVo skuVo, Integer quantity, String sqbSkuId, String sqbSpuId) {
// 获取商品与收钱吧商品对应的关联的skuId、spuId
SettlementCreateRequest.CheckoutItem checkoutItem = new SettlementCreateRequest.CheckoutItem();
checkoutItem.setSpuId(sqbSpuId);
checkoutItem.setSkuId(sqbSkuId);
checkoutItem.setPrice(sqbConvertUtils.yuanToFen(skuVo.getPrice()));
checkoutItem.setQuantity(String.valueOf(quantity));
checkoutItem.setType((byte) 0);
checkoutItem.setTitle(skuVo.getName());
checkoutItem.setImage(skuVo.getSkuPic());
return checkoutItem;
}
// ================================ 查询支付状态 ================================
@Override
......@@ -371,10 +405,6 @@ public class GoblinSqbOrderServiceImpl implements IGoblinSqbOrderService {
CouponQueryRequest req = new CouponQueryRequest();
req.setAppid(shouqianbaProperties.getAppId());
req.setSeller(buildSeller());
CouponQueryRequest.OrderInfo orderInfo = new CouponQueryRequest.OrderInfo();
orderInfo.setSn(orderVo.getSqbOrderSn());
orderInfo.setSignature(orderVo.getSqbOrderSignature());
req.setOrderID(orderInfo);
CouponQueryData couponData = goblinShouQianBaService.queryCoupon(req);
if (couponData == null) return ResponseDto.failure("获取券码失败");
......@@ -424,11 +454,6 @@ public class GoblinSqbOrderServiceImpl implements IGoblinSqbOrderService {
refundReq.setRequestSource("EXTERN");
refundReq.setRequestId(IDGenerator.nextSnowId());
CouponRefundRequest.OrderInfo orderInfo = new CouponRefundRequest.OrderInfo();
orderInfo.setSn(orderVo.getSqbOrderSn());
orderInfo.setSignature(orderVo.getSqbOrderSignature());
refundReq.setOrderID(orderInfo);
CouponRefundRequest.RefundInfo refundInfo = new CouponRefundRequest.RefundInfo();
// amount 字段待接入实际金额(GoblinSqbOrderVo 需补充 amount)
refundInfo.setApplyAmount(0L); // TODO: 替换为实际订单金额
......
package com.liquidnet.service.goblin.util;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.HashMap;
import java.util.Map;
/**
* 收钱吧参数转换工具类
* 1. 金额转换:元(BigDecimal) -> 分(Long)
*/
@Slf4j
@Component
public class GoblinSqbConvertUtils {
/**
* 元转分 (BigDecimal -> Long)
* @param amount 元
* @return 分
*/
public Long yuanToFen(BigDecimal amount) {
if (amount == null) {
return 0L;
}
// 乘以 100 并设置四舍五入,确保转换后的精度
return amount.multiply(new BigDecimal("100"))
.setScale(0, RoundingMode.HALF_UP)
.longValue();
}
/**
* 根据正在的skuId、spuId获取收钱吧信息
* @param skuId
* @param spuId
* @return
*/
public Map<String, String> getSqbInfoByzhengzaiSkuIdAndSpuId(String skuId, String spuId) {
return new HashMap<>();
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment