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

Commit c169b508 authored by 姜秀龙's avatar 姜秀龙

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

parents 863cf907 7e0d9d42
......@@ -7,24 +7,57 @@ import java.io.Serializable;
@Data
public class GoblinSqbOrderVo implements Serializable {
private static final long serialVersionUID = 1L;
private String orderId;
private String userId;
private String performancesId;
private String spuId;
private String skuId;
// 数量
private Integer quantity;
// 金额(分为单位)
private Long amount;
// 订单编号
private String sqbOrderSn;
// 订单密钥
private String sqbOrderSignature;
// 收单号
private String sqbAcquiringSn;
// 收单密钥
private String sqbAcquiringSign;
// 结算项ID
private String sqbCheckoutItemsId;
// 收钱吧-券码编号
private String couponSn;
// 收钱吧-券二维码url
private String couponQrCode;
// 券核销时间?
private String couponExpireTime;
private Integer status; // 0-待支付 1-已支付 2-已核销 3-已退款 4-退款中 9-失败
// 0-待支付 1-已支付 2-已核销 3-已退款 4-退款中 5-已取消 9-失败
private Integer status;
// 退款备注
private String refundReason;
// 创建时间
private String createdAt;
// 修改时间
private String updatedAt;
// 扩展属性
......
......@@ -76,8 +76,16 @@ public class SqbBiz {
* @return 收钱吧响应结果;调用失败时返回 null
*/
public SettlementCreateData createSettlement(SettlementCreateRequest request) {
return executeShouQianBaRequest("/optimus/core/mall/createCheckoutItems", "创建结算明细", request, SettlementCreateResponse.class);
return executeShouQianBaRequest("/optimus/core/order/createCheckoutItems", "创建结算明细", request, SettlementCreateResponse.class);
}
/**
* 创建结算明细
* @param mallSn 商城ID
* @param signature 商城密钥
* @param userId 正在用户ID
* @param checkoutItems 商品
* @return
*/
public SettlementCreateData createSettlement(String mallSn, String signature, String userId, List<SettlementCreateRequest.CheckoutItem> checkoutItems) {
SettlementCreateRequest request = new SettlementCreateRequest();
request.setAppid(sqbConfig.getAppId());
......@@ -94,6 +102,16 @@ public class SqbBiz {
public OrderCreateData createOrder(OrderCreateRequest request) {
return executeShouQianBaRequest("/optimus/core/order/placeOrder", "创建订单", request, OrderCreateResponse.class);
}
/**
* 创建订单
* @param mallSn 商城ID
* @param signature 商城密钥
* @param checkoutItemsId 创建结算明细 返回的 结算项ID
* @param userId 正在用户ID
* @param requestId 请求ID
* @param subject 标题
* @return
*/
public OrderCreateData createOrder(String mallSn, String signature, String checkoutItemsId, String userId, String requestId, String subject) {
OrderCreateRequest orderCreateRequest = new OrderCreateRequest();
orderCreateRequest.setAppid(sqbConfig.getAppId());
......@@ -119,6 +137,13 @@ public class SqbBiz {
public CashierQueryData queryCashier(CashierQueryRequest request) {
return executeShouQianBaRequest("/optimus/core/cashier/queryCashierPage", "查询收银台", request, CashierQueryResponse.class);
}
/**
* 查询收银台
* @param acquiringSn 收单号
* @param acquiringSignature 收单密钥
* @param userId 正在用户ID
* @return
*/
public CashierQueryData queryCashier(String acquiringSn, String acquiringSignature, String userId) {
CashierQueryRequest.PaymentEnv paymentEnv = new CashierQueryRequest.PaymentEnv();
paymentEnv.setClient("wechat");
......@@ -140,6 +165,19 @@ public class SqbBiz {
public CreateWechatPrepayOrderData createWechatPrepayOrder(CreateWechatPrepayOrderRequest request) {
return executeShouQianBaRequest("/optimus/core/cashier/proxyPreCreatedPay", "创建微信预支付订单", request, CreateWechatPrepayOrderResponse.class);
}
/**
* 创建微信预支付订单
* @param acquiringSn 收单号
* @param signature 收单签名
* @param userId 正在用户ID
* @param amount 支付金额
* @param requestSn 支付请求号
* @param payTool 支付工具代码
* @param channelExt 通道扩展参数
* @param selectedSignature 支付工具签名
* @param seq 序列号 上一步seq(查询收银台)
* @return
*/
public CreateWechatPrepayOrderData createWechatPrepayOrder(String acquiringSn,
String signature,
String userId,
......@@ -167,6 +205,12 @@ public class SqbBiz {
public CouponQueryData queryCoupon(CouponQueryRequest request) {
return executeShouQianBaRequest("/optimus/core/voucher/queryOrderVoucherList", "查询优惠券", request, CouponQueryResponse.class);
}
/**
* 查询券码
* @param sn 订单ID
* @param signature 订单密码
* @return
*/
public CouponQueryData queryCoupon(String sn, String signature) {
CouponQueryRequest couponQueryRequest = new CouponQueryRequest();
couponQueryRequest.setAppid(sqbConfig.getAppId());
......@@ -182,6 +226,15 @@ public class SqbBiz {
CouponStatusSyncResponse response = executeRequestAndGetResponse("/optimus/core/voucher/modifyOrderVoucherList", "同步优惠券状态", request, CouponStatusSyncResponse.class);
return response != null && Boolean.TRUE.equals(response.getSuccess());
}
/**
* 券码状态同步
* @param redeemMerchantId 用户ID(自定义,核销用户id)
* @param voucherNos 券号
* @param redeemExternalOrderSn 外部单号(${AppCode}+id,AppCode需要分配)
* @param clientSn 核销终端号(自定义)
* @param status 券使用状态(0未核销,1已核销)
* @return
*/
public boolean syncCouponStatus(String redeemMerchantId, List<String> voucherNos, String redeemExternalOrderSn, String clientSn, Byte status) {
CouponStatusSyncRequest couponStatusSyncRequest = new CouponStatusSyncRequest();
couponStatusSyncRequest.setAppid(sqbConfig.getAppId());
......@@ -200,6 +253,16 @@ public class SqbBiz {
public CouponRefundData refundCoupon(CouponRefundRequest request) {
return executeShouQianBaRequest("/optimus/core/aftersale/applyRefund", "退款优惠券", request, CouponRefundResponse.class);
}
/**
* @param sn 单号(前置操作后拿到)
* @param signature 密码(前置操作后拿到)
* @param applyAmount 金额
* @param type 退款类型(1商品 2金额)
* @param item
* @param refundReason 退款原因
* @param requestId 退款请求id(${AppCode}+id)
* @return
*/
public CouponRefundData refundCoupon(String sn,
String signature,
Long applyAmount,
......@@ -223,6 +286,12 @@ public class SqbBiz {
public List<MallListQueryData> queryMallList(MallListQueryRequest request) {
return executeShouQianBaRequest("/optimus/core/open/mall/queryMallList", "查询门店列表", request, MallListQueryResponse.class);
}
/**
* 商城列表接口
* @param endCursor 结束游标 上一页的结束游标(首次查询传 null)
* @param count 查询数量 每页返回的最大订单数
* @return
*/
public List<MallListQueryData> queryMallList(String endCursor, Integer count) {
MallListQueryRequest.Filter filter = new MallListQueryRequest.Filter();
filter.setSeller(cachedSeller);
......@@ -250,6 +319,12 @@ public class SqbBiz {
public List<MallProductsQueryData> queryMallProducts(MallProductsQueryRequest request) {
return executeShouQianBaRequest("/optimus/core/open/mall/queryMallProducts", "查询门店商品", request, MallProductsQueryResponse.class);
}
/**
* 商城商品接口
* @param mallSn 商城ID
* @param signature 商城密码
* @return
*/
public List<MallProductsQueryData> queryMallProducts(String mallSn, String signature) {
MallProductsQueryRequest request = new MallProductsQueryRequest();
request.setAppid(sqbConfig.getAppId());
......@@ -311,6 +386,7 @@ public class SqbBiz {
return null;
}
private String getSign(String bodyJsonStr) {
try {
// 签名算法: sign = MD5( CONCAT( body + appkey ) )
......@@ -325,6 +401,15 @@ public class SqbBiz {
}
}
/**
* 收钱吧回调推送验签
*/
public boolean verifySignature(CallbackParams callbackParams) {
// 签名原串 = eventId + timestamp + nonce + content
String plaintext = callbackParams.getEventId() + callbackParams.getTimestamp() + callbackParams.getNonce() + callbackParams.getContent();
return verifySignatureSHA256WithRSA(plaintext, callbackParams.getSignature(), sqbConfig.getPublicKey());
}
private CommonRequest.Mall buildMall(String mallSn, String signature) {
CommonRequest.Mall mall = new CommonRequest.Mall();
mall.setMallSn(mallSn);
......@@ -355,14 +440,6 @@ public class SqbBiz {
return Collections.singletonList(tool);
}
/**
* 收钱吧回调推送验签
*/
public boolean verifySignature(CallbackParams callbackParams) {
// 签名原串 = eventId + timestamp + nonce + content
String plaintext = callbackParams.getEventId() + callbackParams.getTimestamp() + callbackParams.getNonce() + callbackParams.getContent();
return verifySignatureSHA256WithRSA(plaintext, callbackParams.getSignature(), sqbConfig.getPublicKey());
}
private boolean verifySignatureSHA256WithRSA(String plaintext, String inputSignature, String pubKey) {
return verifySignatureSHA256WithRSA(plaintext.getBytes(StandardCharsets.UTF_8), inputSignature, pubKey);
......
......@@ -5,7 +5,7 @@ import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@ConfigurationProperties(prefix = "liquidnet.shouqianba")
@ConfigurationProperties(prefix = "liquidnet.sqb")
@Component
@Setter
@Getter
......
package com.liquidnet.common.third.sqb.param.response.data;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;
/**
......@@ -13,78 +11,109 @@ import lombok.Data;
@JsonIgnoreProperties(ignoreUnknown = true)
public class CreateWechatPrepayOrderData {
/** 收单号 */
/**
* 收单号
*/
private String acquiringSn;
/** 收单签名 */
/**
* 收单签名
*/
private String signature;
/** 收单状态 */
/**
* 收单状态
*/
private Byte acquiringState;
/** 金额明细 */
/**
* 金额明细
*/
private AmountDetails amount;
/** 支付凭证 */
/**
* 支付凭证
*/
private PaymentVoucher paymentVoucher;
/** 通道信息 */
/**
* 通道信息
*/
private ChannelInfo channelInfo;
@Data
/**
* 订单金额明细
*/
* 订单金额明细
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public static class AmountDetails {
/** 收单总金额 */
/**
* 收单总金额
*/
private Long totalAmount;
/** 已付总金额 */
/**
* 已付总金额
*/
private Long paidAmount;
/** 已退总金额 */
/**
* 已退总金额
*/
private Long refundedAmount;
}
@Data
/**
* 支付凭证详情
*/
* 支付凭证详情
*/
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public static class PaymentVoucher {
/** 时间戳 */
/**
* 时间戳
*/
private String timeStamp;
/** 订单详情扩展字符串 */
/**
* 订单详情扩展字符串
*/
private String packageStr;
/** 签名 */
/**
* 签名
*/
private String paySign;
/** Appid */
/**
* Appid
*/
private String appId;
/** 签名方式 */
/**
* 签名方式
*/
private String signType;
/** 随机字符串 */
/**
* 随机字符串
*/
private String nonceStr;
}
@Data
/**
* 通道信息详情
*/
* 通道信息详情
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public static class ChannelInfo {
/** 收钱吧通道流水号 */
/**
* 收钱吧通道流水号
*/
private String payTsn;
}
}
......@@ -251,4 +251,13 @@ liquidnet:
pubKey: pubKey
privateKey: xxxx
#application-dev-end
\ No newline at end of file
#application-dev-end
sqb:
base-api: 'https://open-apisix.iwosai.com'
app-id: '2025082700005615'
app-key: '4d5c7647853bba34a0b5af42bc2400e7'
app-code: 'DWTY'
public-key: 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3Hlg887xrRWYxPqLDX53oimjsxfd7PDdhQ4zHUYA1eQP6PMyhAo+GU/oq4RQVpW6LrG0PWA6CoD7qva6T0NwsDWn5/fmWhmH+Ad6K5WG5jY9ZVjnys9R+HGeFyE7hSkhqSgiSlEMv9IBJD5p9ZqBZ0FAPotMS/RIBHANVA37J0Zlp9wakvUegcXb3hl9xp+aRsjikhS5h89qiPPXGkWq9dsQrbpDODP8RziqskxzIzu4tYtvLkUZ/Ak9LCRu63SSGX+yAj24mG9Q+4taWGX32AmuVFK9CGDoec0IYx8ouUtiGWVBqZz0dRteKbBbL6MtnPjUxT+wMc6rarPL8zj9vwIDAQAB'
merchant-id: 'fd567f94-9a44-4ae5-879f-9acc919d0f89'
merchant-user-id: '42c556cc-1509-4de0-bfc3-dfbcb48eae57'
role: 'super_admin'
\ No newline at end of file
......@@ -250,4 +250,13 @@ liquidnet:
appId: 2021002131608679
pubKey: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAph6mXcV8gPoEE6ZJJiaSk6x6jwWThLuzHDpZ9CMreZrMRUkGrV0WC920Ktp0tGlpo+BNfF+yBrapTAM8Y0Ztz5XcZWnx7gsfcsV48GHJ09qWbkJfXaBY30iX6O6q59jqWJMITQKz6OLL6HL3wxhoXooKHjXamQ983RTsI6wT4nWsTtBp8mTXCY+8XOQ4rw87AeHHetIoAtogk8H2etKgu1nDaQGXaA+ng+khab+b42pZSBX5g6jWlNCZviAoiy7e3upyu/6lqOhuLDEYzxD0i0oZ/46oIsILvEBCYQvXpbEz8KAM8dD5RBylNSpbu2edrrhytCq+0HFA4f1yp2D7WQIDAQAB
privateKey: MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCR3u0lL7LvLHK0VG8/FXcA6hjLC+oY4ra/zqs7QRg4EVR8GGQ1G3hg5av6LJxBN5lR07ONYojAOgzmxkoPdM4+aTn9XMfk2sAWen7RMMNcdpyx1eNdCFlm1GzT419CXkIS0Z+gUsxF+PasGamjzfB/Lg66DNZ1zHh1YPa/hwt4KKO1YHiReBCO0hLo7/uGTFUdfzB9pCUIzOTQwaYJPqRc0pz0/9MSF65K/Qtc9lqFpsVXmcWQOZZjoDJGIH6XEbyWXzMRPy5MLryvF3s6ZNURuU7j8t16DVkUTx3p+bEm2U3GmL5btltiouduPUBXHZjRUWAAyFVzc9EMQDQDA89rAgMBAAECggEAQPEHkQuoVPTr6D7C/EnZHk4aVaNrSEL+62veLdYwKx4EB+9wBXjCYhk+NHXR5vMSziw6/tIEYdg2UDOtWy48d+qvB45b7BY7eIZ2mTllcG/aGQ5JV+zUqIQgI0FR8qE2N1yd/Wl/ShOp9jrCnIud63Ec21XF0NIEOvW9RM2hnI+G6YLT9j3NbvJvB4zS7U7tejEXfDP1Oxtjk0ba7Qq04yYdeX16TOrs8VTpAzrj+xW/VJDLBoDfgLvE2G/PqhpFOFfH5V6zKTYfk9VQLh1H9dTj1CkFgRHEJfrFc7XcIIb9nxjnV5JXZmcPjmErQUg1t8JLzjJuQIvzCda5Ba9JEQKBgQDL+iSWlSfyJQyx283VIjhIJ3w9ZRAIWsm/Z1205tdnBeFAzsiItLamASf7Y1zMIMYxFyUD41npFUqetjzdxVHiWlOg2/cE7t2SQWbfrbgqwG0z23If4jUdIj3CJq9yLVWAXvvvm/I/Zrj4oGycYkWV0eGZwoAqIIHIOmTPslacUwKBgQC3Eve/jAHkcgCRppwvDvrw9AYKd6rrs9dyCcsj7Zz2sT7CTw89JcjmjwsLx5+v+zSGgkceG21uIusAfWoAbAYadIGP7zCOBWGVdFvt5hqqKtwL7sLdWrauKw5NId8SlVu0Jvy2dVjzyJ3jfYj1tXt/kCNLgf0zL4yZ+q9G+KBdiQKBgQCkNcSu1XVLIziNFv8lzl6w99i1NF8r2qsARB7UO+K9NaaZnd8i7xj7m4Kshtl2HAxyCMfr0WPYmSNxkhR+FRROvZkFrw+2EPaff7dp61iQUkmXrdq6gElyItbFLo+fw49JwS3hQBJNqEzRG5VUcGjErCqKtmKnh3Pz1c7CxjejsQKBgEbJ6cxCGdU4k6m+D7ROiY+z+8X+YbPEFXF+AfOBhGkLPiYqJc1SF+22r+G9La0BaFz+cPteRaEJlW7aD6vcGTwPgq2iIlc4E3STypwhlnvoGK/wgZ7P3cVY1q3ShAwOfqgZTyxKEbwp/YsiVlwT8Y3wsQUYXUx2fVpoyW+a4X9pAoGBAIQSQ/Dig/6kU7yb9F4uFYVGnrArQk9bFC3tXe1rgyw6nUq5txAmc6ovvrmCVMilQ2nfYuzAtuKy6ouf71u+nTDaTV9LxGOxKzSDu+58R8qZrzcnSerfPivocWmlpN5mse45RVRnlw3EvObCwKE3zkDYKk5PgxKsmLrLAgaF4CGg
#application-test-end
\ No newline at end of file
#application-test-end
sqb:
base-api: 'https://open-apisix.iwosai.com'
app-id: '2025082700005615'
app-key: '4d5c7647853bba34a0b5af42bc2400e7'
app-code: 'DWTY'
public-key: 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3Hlg887xrRWYxPqLDX53oimjsxfd7PDdhQ4zHUYA1eQP6PMyhAo+GU/oq4RQVpW6LrG0PWA6CoD7qva6T0NwsDWn5/fmWhmH+Ad6K5WG5jY9ZVjnys9R+HGeFyE7hSkhqSgiSlEMv9IBJD5p9ZqBZ0FAPotMS/RIBHANVA37J0Zlp9wakvUegcXb3hl9xp+aRsjikhS5h89qiPPXGkWq9dsQrbpDODP8RziqskxzIzu4tYtvLkUZ/Ak9LCRu63SSGX+yAj24mG9Q+4taWGX32AmuVFK9CGDoec0IYx8ouUtiGWVBqZz0dRteKbBbL6MtnPjUxT+wMc6rarPL8zj9vwIDAQAB'
merchant-id: 'fd567f94-9a44-4ae5-879f-9acc919d0f89'
merchant-user-id: '42c556cc-1509-4de0-bfc3-dfbcb48eae57'
role: 'super_admin'
\ No newline at end of file
......@@ -26,14 +26,5 @@ liquidnet:
public-key: "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArR8pqWsRMqiunn8uEZGF9AeizJK0vuWjlcNnTbw9Sb96dMVuYu3SRj+Dx4E4SgyEL4CYROou1xwY57kAKEqHdH7o1W41O9jYjXZG38BrtBR+D9Qh9OqGxCZ+e4Gi38XHGg6fn67iXefOqp1kWGd4qc8tIZO1lIDXS19R09D/mESNBMulQdVPyZF7gvd11A+7EEOfRlSOjrtqIoUWV0GIqhLPUtGJk8Uq/d9NLitJyvK3tgz8cvJ4RyK6UpGtRDrqiBiQxbvK9EqMd1sw3zkvM03szSWon4LHFNqvDr6RYfFyFUCvX9UPYmeritENnroEuTBlTFLLb68ed4HZEZDPTQIDAQAB"
private-key: "MIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQDJAOaA1ikJzDL0vUuTyl3/vlHyuSod6/gFLLrSTD6EJkma5Ld34HHu82/5pEojEvbcU113L9j3fUJlpyjX6CFk6j2KjMIuyFxhgrVFi5WT5m74wYohoWNifkQrgwsO3oxI7cewWFu/w7/yCK9dzI4QxasGUKH9iPweI+26IR0DBbOfC9GVudOy2b2xLrGAevEEHdVTNqrQNdlrTzqAH7r3uk8s2vaBZX+O4gyf7eKdHdC4CVSWfYPLO1sA48MxNwI7OExxfGeV+0wmBMGRSoZ5FhWsqZs+f9jGcmfF+uEfAO71PqHjezXYxq7+oWDfDBPCTc5fo9w5v1HV0aZaYOe1AgMBAAECggEBAI4yR98fInse7XF8NOpBwIv6/QhEfAoc9CHdCfFaJOPiHjIo2a5BpvhPWYj288eqU998TmPSAqDbCUzWm6taOb2lhJHukDT+Y3RMPqcLX275Fsp+SJUQEjoMb3eExh7ny8CQDrOvXoDkH3c/M6ic3Gf7Hslh46dz8D/2VOhXIqoObPlSLzniwiMTDBEwB7IRc3Q+r4V6ZnKt8wjKQZpotBA3TlJlEBBj/h5SbWokwMQbTqFkjl7gVe0ase2WfV+cD4qhPZx6CWphPVyWelg+wpDqXOIQdnE8pgri5a9ZkzgPTOrKyCm+EOa9lZAp81tnb2iFhrlkKPSWUW8zLtZzxMECgYEA+sNyF0U9anyxeKxXtlGKKuMHJSnBpZeU6FSvZjTewFH2Sxh3QwZjg6h5BfvTLH1XfNerx3gdpAPJ+EyAZuEibDr47bp+j4CtT27dVolz5XQ5ugOadwzdNZkq6vhuq1aGATmS/mlNE1/pdMEP9F6hi2HYncER6BFOy0xSwMKCnRECgYEAzTNxhvZ0pb2hPKylxHUydkm3Uznq5Zkquv6II6W5aiKvceETHwdRZLoKc+I0kd0/4fBfJI2Jsjexy51ERiG+8y4wVrcrky6NLw6mnXSvnTSQCftbexheJTg9c5dpfKIj+rxtuBeZ3Sj1MJQ6OSBUYu3iTqstO0Rgp/1ofWQJ8GUCgYEAspxzr0+KJ0cZwbI/54S8vT9n33iWjbQiRDnNlScjYij/HQ4YJI1wZF6jlTeBerbskeesWy+bLS/ltA4Jhz3knuKCXBHyA5TL3UBCN1lAS7c1RuE6LIHlLkAi6ap6aV//ou+3W671T0+JobfB/XVJ61WOTQ8wCfQKA5QhfVsOXYECgYEAvzbm3Ysfm6qfazi+p9lGErASov1fhGA8T1AMcJtnsh1sO8Qu20UodaJfRylNL3dqphIltpwl6eq4RTLhgjDEDTvHU6cQdfB1I5qVbDhlxSpL5uFRl91XLXvA18wKQledC3M3Esr7V/loscIOl1knCaD+t6wPVCEdqK0dB2uHT3kCgYEA3p3rlmCmWzkZ/U8jE4087YEkJWV+r86YC63r4YZEqZtfHk4hNchAYke4jYPqkTtmRVZi2C6KuVr5M3ASHmGWorBY0VA9Abd3daniNocZCeMOt4Z7U6MIbqW7KYSrjx8V8HIsdH7HF97ofRuMH6oaz9bFMM6XwrEAMY+zTdH9A4Y="
notify-url: 'https://testgoblin.zhengzai.tv/goblin/bracelet/callback'
shouqianba:
base-api: 'https://open-apisix.iwosai.com'
app-id: '2025082700005615'
app-key: '4d5c7647853bba34a0b5af42bc2400e7'
app-code: 'DWTY'
public-key: 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3Hlg887xrRWYxPqLDX53oimjsxfd7PDdhQ4zHUYA1eQP6PMyhAo+GU/oq4RQVpW6LrG0PWA6CoD7qva6T0NwsDWn5/fmWhmH+Ad6K5WG5jY9ZVjnys9R+HGeFyE7hSkhqSgiSlEMv9IBJD5p9ZqBZ0FAPotMS/RIBHANVA37J0Zlp9wakvUegcXb3hl9xp+aRsjikhS5h89qiPPXGkWq9dsQrbpDODP8RziqskxzIzu4tYtvLkUZ/Ak9LCRu63SSGX+yAj24mG9Q+4taWGX32AmuVFK9CGDoec0IYx8ouUtiGWVBqZz0dRteKbBbL6MtnPjUxT+wMc6rarPL8zj9vwIDAQAB'
merchant-id: 'fd567f94-9a44-4ae5-879f-9acc919d0f89'
merchant-user-id: '42c556cc-1509-4de0-bfc3-dfbcb48eae57'
role: 'super_admin'
......@@ -25,13 +25,4 @@ liquidnet:
sub-app-id: 'wx4732efeaa2b08086'
public-key: "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArR8pqWsRMqiunn8uEZGF9AeizJK0vuWjlcNnTbw9Sb96dMVuYu3SRj+Dx4E4SgyEL4CYROou1xwY57kAKEqHdH7o1W41O9jYjXZG38BrtBR+D9Qh9OqGxCZ+e4Gi38XHGg6fn67iXefOqp1kWGd4qc8tIZO1lIDXS19R09D/mESNBMulQdVPyZF7gvd11A+7EEOfRlSOjrtqIoUWV0GIqhLPUtGJk8Uq/d9NLitJyvK3tgz8cvJ4RyK6UpGtRDrqiBiQxbvK9EqMd1sw3zkvM03szSWon4LHFNqvDr6RYfFyFUCvX9UPYmeritENnroEuTBlTFLLb68ed4HZEZDPTQIDAQAB"
private-key: "MIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQDJAOaA1ikJzDL0vUuTyl3/vlHyuSod6/gFLLrSTD6EJkma5Ld34HHu82/5pEojEvbcU113L9j3fUJlpyjX6CFk6j2KjMIuyFxhgrVFi5WT5m74wYohoWNifkQrgwsO3oxI7cewWFu/w7/yCK9dzI4QxasGUKH9iPweI+26IR0DBbOfC9GVudOy2b2xLrGAevEEHdVTNqrQNdlrTzqAH7r3uk8s2vaBZX+O4gyf7eKdHdC4CVSWfYPLO1sA48MxNwI7OExxfGeV+0wmBMGRSoZ5FhWsqZs+f9jGcmfF+uEfAO71PqHjezXYxq7+oWDfDBPCTc5fo9w5v1HV0aZaYOe1AgMBAAECggEBAI4yR98fInse7XF8NOpBwIv6/QhEfAoc9CHdCfFaJOPiHjIo2a5BpvhPWYj288eqU998TmPSAqDbCUzWm6taOb2lhJHukDT+Y3RMPqcLX275Fsp+SJUQEjoMb3eExh7ny8CQDrOvXoDkH3c/M6ic3Gf7Hslh46dz8D/2VOhXIqoObPlSLzniwiMTDBEwB7IRc3Q+r4V6ZnKt8wjKQZpotBA3TlJlEBBj/h5SbWokwMQbTqFkjl7gVe0ase2WfV+cD4qhPZx6CWphPVyWelg+wpDqXOIQdnE8pgri5a9ZkzgPTOrKyCm+EOa9lZAp81tnb2iFhrlkKPSWUW8zLtZzxMECgYEA+sNyF0U9anyxeKxXtlGKKuMHJSnBpZeU6FSvZjTewFH2Sxh3QwZjg6h5BfvTLH1XfNerx3gdpAPJ+EyAZuEibDr47bp+j4CtT27dVolz5XQ5ugOadwzdNZkq6vhuq1aGATmS/mlNE1/pdMEP9F6hi2HYncER6BFOy0xSwMKCnRECgYEAzTNxhvZ0pb2hPKylxHUydkm3Uznq5Zkquv6II6W5aiKvceETHwdRZLoKc+I0kd0/4fBfJI2Jsjexy51ERiG+8y4wVrcrky6NLw6mnXSvnTSQCftbexheJTg9c5dpfKIj+rxtuBeZ3Sj1MJQ6OSBUYu3iTqstO0Rgp/1ofWQJ8GUCgYEAspxzr0+KJ0cZwbI/54S8vT9n33iWjbQiRDnNlScjYij/HQ4YJI1wZF6jlTeBerbskeesWy+bLS/ltA4Jhz3knuKCXBHyA5TL3UBCN1lAS7c1RuE6LIHlLkAi6ap6aV//ou+3W671T0+JobfB/XVJ61WOTQ8wCfQKA5QhfVsOXYECgYEAvzbm3Ysfm6qfazi+p9lGErASov1fhGA8T1AMcJtnsh1sO8Qu20UodaJfRylNL3dqphIltpwl6eq4RTLhgjDEDTvHU6cQdfB1I5qVbDhlxSpL5uFRl91XLXvA18wKQledC3M3Esr7V/loscIOl1knCaD+t6wPVCEdqK0dB2uHT3kCgYEA3p3rlmCmWzkZ/U8jE4087YEkJWV+r86YC63r4YZEqZtfHk4hNchAYke4jYPqkTtmRVZi2C6KuVr5M3ASHmGWorBY0VA9Abd3daniNocZCeMOt4Z7U6MIbqW7KYSrjx8V8HIsdH7HF97ofRuMH6oaz9bFMM6XwrEAMY+zTdH9A4Y="
notify-url: 'https://testgoblin.zhengzai.tv/goblin/bracelet/callback'
shouqianba:
base-api: 'https://open-apisix.iwosai.com'
app-id: '2025082700005615'
app-key: '4d5c7647853bba34a0b5af42bc2400e7'
app-code: 'DWTY'
public-key: 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3Hlg887xrRWYxPqLDX53oimjsxfd7PDdhQ4zHUYA1eQP6PMyhAo+GU/oq4RQVpW6LrG0PWA6CoD7qva6T0NwsDWn5/fmWhmH+Ad6K5WG5jY9ZVjnys9R+HGeFyE7hSkhqSgiSlEMv9IBJD5p9ZqBZ0FAPotMS/RIBHANVA37J0Zlp9wakvUegcXb3hl9xp+aRsjikhS5h89qiPPXGkWq9dsQrbpDODP8RziqskxzIzu4tYtvLkUZ/Ak9LCRu63SSGX+yAj24mG9Q+4taWGX32AmuVFK9CGDoec0IYx8ouUtiGWVBqZz0dRteKbBbL6MtnPjUxT+wMc6rarPL8zj9vwIDAQAB'
merchant-id: 'fd567f94-9a44-4ae5-879f-9acc919d0f89'
merchant-user-id: '42c556cc-1509-4de0-bfc3-dfbcb48eae57'
role: 'super_admin'
\ No newline at end of file
notify-url: 'https://testgoblin.zhengzai.tv/goblin/bracelet/callback'
\ No newline at end of file
package com.liquidnet.service.goblin.test;
import com.liquidnet.service.goblin.param.shouqianba.request.CommonRequest;
import com.liquidnet.service.goblin.param.shouqianba.request.MallListQueryRequest;
import com.liquidnet.service.goblin.param.shouqianba.request.MallProductsQueryRequest;
import com.liquidnet.service.goblin.param.shouqianba.response.data.MallListQueryData;
import com.liquidnet.service.goblin.param.shouqianba.response.data.MallProductsQueryData;
import com.liquidnet.service.goblin.service.IGoblinShouQianBaService;
import com.liquidnet.common.third.sqb.biz.SqbBiz;
import com.liquidnet.common.third.sqb.param.request.CommonRequest;
import com.liquidnet.common.third.sqb.param.request.MallListQueryRequest;
import com.liquidnet.common.third.sqb.param.request.MallProductsQueryRequest;
import com.liquidnet.common.third.sqb.param.response.data.MallListQueryData;
import com.liquidnet.common.third.sqb.param.response.data.MallProductsQueryData;
import lombok.extern.slf4j.Slf4j;
import org.junit.Assert;
import org.junit.Test;
......@@ -23,7 +23,7 @@ import java.util.List;
public class GoblinShouQianBaServiceImplTest {
@Autowired
private IGoblinShouQianBaService goblinShouQianBaService;
private SqbBiz sqbBiz;
@Test
......@@ -51,7 +51,7 @@ public class GoblinShouQianBaServiceImplTest {
mallListQueryRequest.setCursor(cursor);
mallListQueryRequest.setSort(sort);
List<MallListQueryData> mallListQueryData = goblinShouQianBaService.queryMallList(mallListQueryRequest);
List<MallListQueryData> mallListQueryData = sqbBiz.queryMallList(mallListQueryRequest);
Assert.assertNotNull(mallListQueryData);
}
......@@ -72,7 +72,7 @@ public class GoblinShouQianBaServiceImplTest {
mallProductsQueryRequest.setSeller(seller);
mallProductsQueryRequest.setMallID(mall);
List<MallProductsQueryData> queryData = goblinShouQianBaService.queryMallProducts(mallProductsQueryRequest);
List<MallProductsQueryData> queryData = sqbBiz.queryMallProducts(mallProductsQueryRequest);
Assert.assertNotNull(queryData);
}
......
......@@ -12,12 +12,12 @@ import com.liquidnet.service.base.codec.vo.EncryptedReq;
import com.liquidnet.service.goblin.dto.manage.GoblinSqbOrderParam;
import com.liquidnet.service.goblin.dto.vo.GoblinSqbOrderCreateVo;
import com.liquidnet.service.goblin.service.IGoblinSqbOrderService;
import com.liquidnet.service.goblin.service.IGoblinSqbService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.constraints.NotBlank;
......@@ -38,12 +38,22 @@ public class GoblinSqbOrderController {
*/
@PostMapping("/pre")
@ApiOperation("创建收钱吧下单")
public ResponseDto<GoblinSqbOrderCreateVo> preOrder(EncryptedReq<GoblinSqbOrderParam> param) {
public ResponseDto<GoblinSqbOrderCreateVo> preOrder(@RequestBody EncryptedReq<GoblinSqbOrderParam> param) {
String userId = CurrentUtil.getCurrentUid();
GoblinSqbOrderParam orderParam = param.getData();
return goblinSqbOrderService.createOrder(userId, orderParam);
}
/**
* 创建收钱吧订单
*/
@PostMapping("/fc7bce6d6c2213b866f76493f9222201")
@ApiOperation("创建收钱吧下单")
public ResponseDto<GoblinSqbOrderCreateVo> preOrder(@RequestBody @Validated GoblinSqbOrderParam param) {
String userId = CurrentUtil.getCurrentUid();
return goblinSqbOrderService.createOrder(userId, param);
}
/**
* 查询支付状态
*/
......
......@@ -85,21 +85,11 @@ public class GoblinSqbOrderServiceImpl implements IGoblinSqbOrderService {
}
}
}
if (!skuIdExists) {
log.error("[收钱吧下单] 演出-商品关联不存在或已禁用,performancesId={}, skuId={}", performancesId, skuId);
return ResponseDto.failure("商品与演出关联不存在");
}
// Step 3: 原子扣减库存
int remaining = goblinRedisUtils.decrSkuStock(null, skuId, quantity);
if (remaining < 0) {
goblinRedisUtils.incrSkuStock(null, skuId, quantity);
log.warn("[收钱吧下单] 库存不足,skuId={}, quantity={}", skuId, quantity);
return ResponseDto.failure("库存不足");
}
log.info("[收钱吧下单] 扣减库存成功,skuId={}, remaining={}", skuId, remaining);
GoblinGoodsSkuInfoVo skuVo = goblinRedisUtils.getGoodsSkuInfoVo(skuId);
if (skuVo == null) {
log.error("[收钱吧下单] 未找到商品, skuId: {}, spuId: {}", skuId, spuId);
......@@ -108,6 +98,19 @@ public class GoblinSqbOrderServiceImpl implements IGoblinSqbOrderService {
if (!skuId.equals(skuVo.getSkuId())) {
return ResponseDto.failure("下单失败");
}
if (!skuVo.getShelvesStatus().equals("3")) {
log.info("[收钱吧下单] 商品已下架 skuId: {}, spuId: {}", skuId, spuId);
return ResponseDto.failure("商品已下架");
}
// Step 3: 原子扣减库存
int remaining = goblinRedisUtils.decrSkuStock(null, skuId, quantity);
if (remaining < 0) {
goblinRedisUtils.incrSkuStock(null, skuId, quantity);
log.warn("[收钱吧下单] 库存不足,skuId={}, quantity={}", skuId, quantity);
return ResponseDto.failure("库存不足");
}
log.info("[收钱吧下单] 扣减库存成功,skuId={}, 剩余库存={}", skuId, remaining);
//TODO 获取该商品对应的商城的编号和密码
Map<String, String> sqbInfoMap = sqbConvertUtils.getSqbInfoByzhengzaiSkuIdAndSpuId(skuId, spuId);
......@@ -116,7 +119,8 @@ public class GoblinSqbOrderServiceImpl implements IGoblinSqbOrderService {
sqbInfoMap.get("mallSn"),
sqbInfoMap.get("signature"),
userId,
Collections.singletonList(buildSqbCheckOutItem(skuVo, quantity, sqbInfoMap.get("sqbSkuId"), sqbInfoMap.get("sqbSpuId"))));
Collections.singletonList(buildSqbCheckOutItem(skuVo,
quantity, sqbInfoMap.get("sqbSkuId"), sqbInfoMap.get("sqbSpuId"))));
if (settlementData == null) {
goblinRedisUtils.incrSkuStock(null, skuId, quantity);
return ResponseDto.failure("创建结算明细失败");
......@@ -161,7 +165,7 @@ public class GoblinSqbOrderServiceImpl implements IGoblinSqbOrderService {
String.valueOf(cashierData.getAmount()),
buildRequestId(IDGenerator.nextSnowId()),
cashierData.getPayTools().get(0),
new HashMap<String, Object>(),
new HashMap<String, Object>(), // TODO 设置AppID
selectedSignature,
seq
);
......@@ -252,6 +256,7 @@ public class GoblinSqbOrderServiceImpl implements IGoblinSqbOrderService {
orderVo.setSqbAcquiringSn(sqbAcquiringSn);
orderVo.setSqbAcquiringSign(sqbAcquiringSign);
orderVo.setSqbCheckoutItemsId(checkoutItemsId);
orderVo.setRefundReason("");
// 内部状态同步使用
orderVo.setStatus(0);
orderVo.setCreatedAt(now);
......@@ -330,8 +335,9 @@ public class GoblinSqbOrderServiceImpl implements IGoblinSqbOrderService {
} catch (Exception e) {
log.error("[收钱吧下单] 下单异常,userId={}, skuId={}", userId, skuId, e);
goblinRedisUtils.incrSkuStock(null, skuId, quantity);
return ResponseDto.failure("下单失败");
} finally {
goblinSqbRedisUtils.releaseOrderLock(userId, skuId);
return ResponseDto.failure("下单失败:" + e.getMessage());
}
}
......@@ -344,7 +350,10 @@ public class GoblinSqbOrderServiceImpl implements IGoblinSqbOrderService {
* @param sqbSpuId
* @return
*/
private SettlementCreateRequest.CheckoutItem buildSqbCheckOutItem(GoblinGoodsSkuInfoVo skuVo, Integer quantity, String sqbSkuId, String sqbSpuId) {
private SettlementCreateRequest.CheckoutItem buildSqbCheckOutItem(GoblinGoodsSkuInfoVo skuVo,
Integer quantity,
String sqbSkuId,
String sqbSpuId) {
// 获取商品与收钱吧商品对应的关联的skuId、spuId
SettlementCreateRequest.CheckoutItem checkoutItem = new SettlementCreateRequest.CheckoutItem();
checkoutItem.setSpuId(sqbSpuId);
......@@ -370,35 +379,6 @@ public class GoblinSqbOrderServiceImpl implements IGoblinSqbOrderService {
if (!userId.equals(orderVo.getUserId())) {
return ResponseDto.failure("无权限访问该订单");
}
// 已支付直接返回
if (Integer.valueOf(1).equals(orderVo.getStatus())) {
return ResponseDto.success(1);
}
// 调用收钱吧查询收单状态
CommonRequest.Seller seller = buildSeller();
CashierQueryRequest cashierReq = buildCashierQueryRequest(seller, orderVo.getSqbAcquiringSn(), orderVo.getSqbOrderSignature());
CashierQueryData cashierData = sqbBiz.queryCashier(cashierReq);
if (cashierData == null) {
log.warn("[收钱吧支付状态] queryCashier 调用失败,orderId={}", orderId);
return ResponseDto.success(orderVo.getStatus());
}
// acquiringState 通过 cashierData.getAmount() > 0 && 收单签名有效来推断 —— 实际以收钱吧文档为准
// 简化处理:收银台能正常返回且 selectedSignature 非空,视为已支付
if (cashierData.getSelectedSignature() != null) {
String now = LocalDateTime.now().format(DTF);
orderVo.setStatus(1);
orderVo.setUpdatedAt(now);
goblinSqbRedisUtils.setSqbOrder(orderId, orderVo);
syncOrderStatus(orderId, 1);
log.info("[收钱吧支付状态] 确认支付成功,orderId={}", orderId);
return ResponseDto.success(1);
}
return ResponseDto.success(orderVo.getStatus());
}
......@@ -535,7 +515,8 @@ public class GoblinSqbOrderServiceImpl implements IGoblinSqbOrderService {
}
private CashierQueryRequest buildCashierQueryRequest(CommonRequest.Seller seller,
String acquiringSn, String acquiringSignature) {
String acquiringSn,
String acquiringSignature) {
CashierQueryRequest req = new CashierQueryRequest();
req.setAppid(sqbBiz.getSqbConfig().getAppId());
req.setSeller(seller);
......
......@@ -10,6 +10,7 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Collections;
import java.util.List;
/**
......@@ -29,7 +30,14 @@ public class GoblinSqbRedisUtils {
}
public GoblinSqbOrderVo getSqbOrder(String orderId) {
return (GoblinSqbOrderVo) redisUtil.get(GoblinRedisConst.SQB_ORDER.concat(orderId));
String redisKey = GoblinRedisConst.SQB_ORDER.concat(orderId);
Object object = redisUtil.get(redisKey);
if (null == object) {
return null;
} else {
return (GoblinSqbOrderVo) object;
}
}
public void delSqbOrder(String orderId) {
......@@ -42,8 +50,19 @@ public class GoblinSqbRedisUtils {
redisUtil.set(GoblinRedisConst.SQB_PERFORMANCE_GOODS.concat(performancesId), list, RedisKeyExpireConst.SQB_PERFORMANCE_GOODS_EXPIRE);
}
/**
* 获取演出关联商品
* @param performancesId
* @return
*/
public List<GoblinSqbPerfGoodsVo> getPerfGoods(String performancesId) {
return (List<GoblinSqbPerfGoodsVo>) redisUtil.get(GoblinRedisConst.SQB_PERFORMANCE_GOODS.concat(performancesId));
String key = GoblinRedisConst.SQB_PERFORMANCE_GOODS.concat(performancesId);
Object object = redisUtil.get(key);
if (null == object) {
return Collections.emptyList();
}else {
return (List<GoblinSqbPerfGoodsVo>) object;
}
}
public void delPerfGoods(String performancesId) {
......
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