update
This commit is contained in:
parent
b9f443f557
commit
2efc279b97
|
|
@ -0,0 +1,367 @@
|
|||
package org.jeecg.modules.mini.controller;
|
||||
|
||||
import cn.hutool.core.date.DatePattern;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.io.file.FileWriter;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.http.ContentType;
|
||||
import cn.hutool.http.HttpStatus;
|
||||
import cn.hutool.json.JSONArray;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.ijpay.core.IJPayHttpResponse;
|
||||
import com.ijpay.core.enums.RequestMethodEnum;
|
||||
import com.ijpay.core.kit.AesUtil;
|
||||
import com.ijpay.core.kit.HttpKit;
|
||||
import com.ijpay.core.kit.PayKit;
|
||||
import com.ijpay.core.kit.WxPayKit;
|
||||
import com.ijpay.core.utils.DateTimeZoneUtil;
|
||||
import com.ijpay.wxpay.WxPayApi;
|
||||
import com.ijpay.wxpay.enums.WxDomainEnum;
|
||||
import com.ijpay.wxpay.enums.v3.BasePayApiEnum;
|
||||
import com.ijpay.wxpay.enums.v3.OtherApiEnum;
|
||||
import com.ijpay.wxpay.model.v3.Amount;
|
||||
import com.ijpay.wxpay.model.v3.Payer;
|
||||
import com.ijpay.wxpay.model.v3.UnifiedOrderModel;
|
||||
import io.swagger.annotations.Api;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.exception.JeecgBootException;
|
||||
import org.jeecg.common.system.vo.LoginUser;
|
||||
import org.jeecg.common.util.AssertUtils;
|
||||
import org.jeecg.modules.mini.dto.VipDTO;
|
||||
import org.jeecg.modules.mini.douyin.model.DouYinOrderModel;
|
||||
import org.jeecg.modules.mini.service.MiniUserService;
|
||||
import org.jeecg.modules.system.entity.SysUser;
|
||||
import org.jeecg.modules.system.service.ISysUserService;
|
||||
import org.jeecg.modules.yx.entity.YxOrder;
|
||||
import org.jeecg.modules.yx.entity.YxVipSku;
|
||||
import org.jeecg.modules.yx.service.IYxOrderService;
|
||||
import org.jeecg.modules.yx.service.IYxVipSkuService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.math.BigDecimal;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @Author: ZhouWenTao
|
||||
* @Date: 2024/04/14 11:52
|
||||
* @Description: 小程序支付控制器
|
||||
*/
|
||||
@Slf4j
|
||||
@Api(tags = "小程序支付控制器v1")
|
||||
@RestController
|
||||
@RequestMapping("/mini/pay/v1")
|
||||
@Scope("prototype")
|
||||
public class MiniPayApiController {
|
||||
|
||||
@Autowired
|
||||
private ISysUserService sysUserService;
|
||||
@Autowired
|
||||
private IYxOrderService yxOrderService;
|
||||
@Autowired
|
||||
private IYxVipSkuService yxVipSkuService;
|
||||
@Autowired
|
||||
private MiniUserService miniUserService;
|
||||
/**
|
||||
* 微信小程序appid
|
||||
**/
|
||||
@Value("${wx.appId}")
|
||||
String appid;
|
||||
/**
|
||||
* 微信小程序secretId
|
||||
**/
|
||||
@Value("${wx.appSecret}")
|
||||
String secret;
|
||||
/**
|
||||
* 商户号
|
||||
**/
|
||||
@Value("${wx.mchid}")
|
||||
String mchid;
|
||||
/**
|
||||
* 商户密钥
|
||||
**/
|
||||
@Value("${wx.mchKey}")
|
||||
String mchKey;
|
||||
/**
|
||||
* 回调地址
|
||||
**/
|
||||
@Value("${wx.notifyUrl}")
|
||||
String notifyUrl;
|
||||
/**
|
||||
* 证书地址
|
||||
**/
|
||||
@Value("${wx.certPath}")
|
||||
String certPath;
|
||||
/**
|
||||
* 证书密钥地址
|
||||
**/
|
||||
@Value("${wx.certKeyPath}")
|
||||
String certKeyPath;
|
||||
/**
|
||||
* 微信平台证书
|
||||
**/
|
||||
@Value("${wx.platFormPath}")
|
||||
String platFormPath;
|
||||
|
||||
|
||||
/**
|
||||
* 微信支付
|
||||
* https://blog.fasterinfo.top/13871.html
|
||||
*/
|
||||
@RequestMapping("/jsApiPay")
|
||||
@ResponseBody
|
||||
public Result<?> jsApiPay(@RequestBody JSONObject requestBody) {
|
||||
String provider = requestBody.getStr("provider");//供应商
|
||||
String skuCode = requestBody.getStr("skuCode");
|
||||
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
SysUser user = sysUserService.getById(sysUser.getId());
|
||||
if (user == null) {
|
||||
throw new JeecgBootException("获取用户信息失败,请联系管理员");
|
||||
}
|
||||
|
||||
//获取库存信息
|
||||
YxVipSku yxVipSku = yxVipSkuService.getBySkuCode(skuCode);
|
||||
AssertUtils.notNull(yxVipSku, "获取商品信息失败,请联系管理员");
|
||||
//判断用户是否已购买过该会员
|
||||
VipDTO userVip = miniUserService.getUserVip(user.getId());
|
||||
if (userVip != null) {
|
||||
//如果这个会员已经买过了,提示不可重复购买
|
||||
AssertUtils.notTrue(yxVipSkuService.convertVipLevel(skuCode) <= userVip.getVipLevel(), "该权益您已购买!不可重复购买");
|
||||
}
|
||||
|
||||
YxOrder yxOrder = new YxOrder();
|
||||
String orderCode = PayKit.generateStr();
|
||||
String openId = user.getWxOpenId();
|
||||
BigDecimal skuPrice = yxVipSku.getSkuPrice();
|
||||
BigDecimal totalAmount = skuPrice.multiply(new BigDecimal("100"));
|
||||
|
||||
String description = "艺体志愿宝VIP";
|
||||
if (StringUtils.isNotBlank(yxVipSku.getSkuName())) {
|
||||
description += "-" + yxVipSku.getSkuName();
|
||||
}
|
||||
if (StringUtils.isNotBlank(yxVipSku.getSkuDetail())) {
|
||||
description += ";" + yxVipSku.getSkuDetail();
|
||||
}
|
||||
|
||||
//判断是抖音平台 还是 微信平台 小程序操作
|
||||
String douyinUrl="https://developer.toutiao.com/api/apps/ecpay/v1/create_order";
|
||||
if ("toutiao".equals(provider)) {
|
||||
//抖音
|
||||
DouYinOrderModel douYinOrderModel = new DouYinOrderModel();
|
||||
}
|
||||
|
||||
|
||||
|
||||
try {
|
||||
String timeExpire = DateTimeZoneUtil.dateToTimeZone(System.currentTimeMillis() + 1000 * 60 * 3);
|
||||
UnifiedOrderModel unifiedOrderModel = new UnifiedOrderModel()
|
||||
// APPID
|
||||
.setAppid(appid)
|
||||
// 商户号
|
||||
.setMchid(mchid)
|
||||
.setDescription(description)
|
||||
.setOut_trade_no(orderCode)
|
||||
.setTime_expire(timeExpire)
|
||||
.setAttach("艺体志愿宝VIP")
|
||||
.setNotify_url(notifyUrl)
|
||||
.setAmount(new Amount().setTotal(totalAmount.intValue()))
|
||||
.setPayer(new Payer().setOpenid(openId));
|
||||
log.info("统一下单参数 {}", JSONUtil.toJsonStr(unifiedOrderModel));
|
||||
IJPayHttpResponse response = WxPayApi.v3(
|
||||
RequestMethodEnum.POST,
|
||||
WxDomainEnum.CHINA.toString(),
|
||||
BasePayApiEnum.JS_API_PAY.toString(),
|
||||
mchid,
|
||||
getSerialNumber(),
|
||||
null,
|
||||
certKeyPath,
|
||||
JSONUtil.toJsonStr(unifiedOrderModel)
|
||||
);
|
||||
log.info("统一下单响应 {}", response);
|
||||
// 根据证书序列号查询对应的证书来验证签名结果
|
||||
boolean verifySignature = WxPayKit.verifySignature(response, platFormPath);
|
||||
log.info("verifySignature: {}", verifySignature);
|
||||
if (response.getStatus() == HttpStatus.HTTP_OK && verifySignature) {
|
||||
String body = response.getBody();
|
||||
JSONObject jsonObject = JSONUtil.parseObj(body);
|
||||
String prepayId = jsonObject.getStr("prepay_id");
|
||||
Map<String, String> map = WxPayKit.jsApiCreateSign(appid, prepayId, certKeyPath);
|
||||
log.info("唤起支付参数:{}", map);
|
||||
String jsonStr = JSONUtil.toJsonStr(map);
|
||||
//==============创建订单信息 Start
|
||||
yxOrder.setOrderCode(orderCode);//orderCode
|
||||
yxOrder.setSkuCode(skuCode);//vip商品Code
|
||||
yxOrder.setOrderStatus("0");//订单状态
|
||||
yxOrder.setTotalAmount(totalAmount);//金额
|
||||
yxOrder.setPaymentUserId(user.getId());//付款人
|
||||
yxOrder.setOrderSign(jsonStr);
|
||||
yxOrder.setOrderStatus("1");
|
||||
yxOrder.setPaymentType("3");//微信支付
|
||||
yxOrderService.save(yxOrder);
|
||||
//==============创建订单信息 End
|
||||
return Result.OK("获取成功", yxOrder.getOrderCode());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return Result.error("唤起失败");
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信支付回调
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
*/
|
||||
@RequestMapping(value = "/payNotify", method = {RequestMethod.POST, RequestMethod.GET})
|
||||
public void payNotify(HttpServletRequest request, HttpServletResponse response) {
|
||||
Map<String, String> map = new HashMap<>(12);
|
||||
String result = HttpKit.readData(request);
|
||||
System.out.println("===================result:"+result);
|
||||
if(false){
|
||||
try {
|
||||
String timestamp = request.getHeader("Wechatpay-Timestamp");
|
||||
String nonce = request.getHeader("Wechatpay-Nonce");
|
||||
String serialNo = request.getHeader("Wechatpay-Serial");
|
||||
String signature = request.getHeader("Wechatpay-Signature");
|
||||
log.info("timestamp:{} nonce:{} serialNo:{} signature:{}", timestamp, nonce, serialNo, signature);
|
||||
log.info("支付通知密文 {}", result);
|
||||
// 需要通过证书序列号查找对应的证书,verifyNotify 中有验证证书的序列号
|
||||
String plainText = WxPayKit.verifyNotify(serialNo, result, signature, nonce, timestamp,
|
||||
mchKey, platFormPath);
|
||||
log.info("支付通知明文 {}", plainText);
|
||||
if (StrUtil.isNotEmpty(plainText)) {
|
||||
com.alibaba.fastjson.JSONObject plainTextJson = com.alibaba.fastjson.JSONObject.parseObject(plainText);
|
||||
//订单号
|
||||
String outTradeNo = plainTextJson.getString("out_trade_no");
|
||||
//支付状态
|
||||
String tradeState = plainTextJson.getString("trade_state");
|
||||
if ("SUCCESS".equals(tradeState)) {
|
||||
//支付成功
|
||||
yxOrderService.update(new LambdaUpdateWrapper<YxOrder>().eq(YxOrder::getOrderCode, outTradeNo).set(YxOrder::getPaymentTime, new Date()).set(YxOrder::getOrderStatus, "2"));
|
||||
}
|
||||
//支付成功,修改订单信息
|
||||
response.setStatus(200);
|
||||
map.put("code", "SUCCESS");
|
||||
map.put("message", "SUCCESS");
|
||||
} else {
|
||||
response.setStatus(500);
|
||||
map.put("code", "ERROR");
|
||||
map.put("message", "签名错误");
|
||||
}
|
||||
response.setHeader("Content-type", ContentType.JSON.toString());
|
||||
response.getOutputStream().write(JSONUtil.toJsonStr(map).getBytes(StandardCharsets.UTF_8));
|
||||
response.flushBuffer();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String getSerialNumber() {
|
||||
// 获取证书序列号
|
||||
X509Certificate certificate = PayKit.getCertificate(certPath);
|
||||
if (null != certificate) {
|
||||
String serialNo = certificate.getSerialNumber().toString(16).toUpperCase();
|
||||
// 提前两天检查证书是否有效
|
||||
boolean isValid = PayKit.checkCertificateIsValid(certificate, mchid, -2);
|
||||
log.info("证书是否可用 {} 证书有效期为 {}", isValid, DateUtil.format(certificate.getNotAfter(), DatePattern.NORM_DATETIME_PATTERN));
|
||||
System.out.println("serialNo:" + serialNo);
|
||||
return serialNo;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@RequestMapping("/get")
|
||||
@ResponseBody
|
||||
public String v3Get() {
|
||||
// 获取平台证书列表
|
||||
try {
|
||||
IJPayHttpResponse response = WxPayApi.v3(
|
||||
RequestMethodEnum.GET,
|
||||
WxDomainEnum.CHINA.toString(),
|
||||
OtherApiEnum.GET_CERTIFICATES.toString(),
|
||||
mchid,
|
||||
getSerialNumber(),
|
||||
null,
|
||||
certKeyPath,
|
||||
""
|
||||
);
|
||||
String serialNumber = response.getHeader("Wechatpay-Serial");
|
||||
String body = response.getBody();
|
||||
int status = response.getStatus();
|
||||
log.info("serialNumber: {}", serialNumber);
|
||||
log.info("status: {}", status);
|
||||
log.info("body: {}", body);
|
||||
int isOk = 200;
|
||||
if (status == isOk) {
|
||||
JSONObject jsonObject = JSONUtil.parseObj(body);
|
||||
JSONArray dataArray = jsonObject.getJSONArray("data");
|
||||
// 默认认为只有一个平台证书
|
||||
JSONObject encryptObject = dataArray.getJSONObject(0);
|
||||
JSONObject encryptCertificate = encryptObject.getJSONObject("encrypt_certificate");
|
||||
String associatedData = encryptCertificate.getStr("associated_data");
|
||||
String cipherText = encryptCertificate.getStr("ciphertext");
|
||||
String nonce = encryptCertificate.getStr("nonce");
|
||||
String serialNo = encryptObject.getStr("serial_no");
|
||||
final String platSerialNo = savePlatformCert(associatedData, nonce, cipherText, platFormPath);
|
||||
log.info("平台证书序列号: {} serialNo: {}", platSerialNo, serialNo);
|
||||
}
|
||||
// 根据证书序列号查询对应的证书来验证签名结果
|
||||
boolean verifySignature = WxPayKit.verifySignature(response, platFormPath);
|
||||
System.out.println("verifySignature:" + verifySignature);
|
||||
return body;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 保存平台证书
|
||||
*
|
||||
* @param associatedData associated_data
|
||||
* @param nonce nonce
|
||||
* @param cipherText cipherText
|
||||
* @param certPath 证书保存路径
|
||||
* @return
|
||||
*/
|
||||
private String savePlatformCert(String associatedData, String nonce, String cipherText, String certPath) {
|
||||
try {
|
||||
AesUtil aesUtil = new AesUtil(mchKey.getBytes(StandardCharsets.UTF_8));
|
||||
// 平台证书密文解密
|
||||
// encrypt_certificate 中的 associated_data nonce ciphertext
|
||||
String publicKey = aesUtil.decryptToString(
|
||||
associatedData.getBytes(StandardCharsets.UTF_8),
|
||||
nonce.getBytes(StandardCharsets.UTF_8),
|
||||
cipherText
|
||||
);
|
||||
// 保存证书
|
||||
FileWriter writer = new FileWriter(certPath);
|
||||
writer.write(publicKey);
|
||||
// 获取平台证书序列号
|
||||
X509Certificate certificate = PayKit.getCertificate(new ByteArrayInputStream(publicKey.getBytes()));
|
||||
return certificate.getSerialNumber().toString(16).toUpperCase();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return e.getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
package org.jeecg.modules.mini.douyin.model;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @author ZhouWenTao
|
||||
* @create 2024-04-14-11:43
|
||||
* 官方文档 https://developer.open-douyin.com/docs/resource/zh-CN/mini-app/develop/server/ecpay/pay-list/pay
|
||||
*/
|
||||
@Data
|
||||
public class DouYinOrderModel implements Serializable {
|
||||
//小程序APPID
|
||||
private String app_id;
|
||||
//开发者侧的订单号。 只能是数字、大小写字母_-*且在同一个app_id下唯一
|
||||
private String out_order_no;
|
||||
//支付价格。 单位为[分]
|
||||
private Integer total_amount;
|
||||
//商品描述。 长度限制不超过 128 字节且不超过 42 字符
|
||||
private String subject;
|
||||
//商品详情 长度限制不超过 128 字节且不超过 42 字符
|
||||
private String body;
|
||||
@ApiModelProperty(value = "订单过期时间(秒)",notes = "订单过期时间(秒)。最小5分钟,最大2天,小于5分钟会被置为5分钟,大于2天会被置为2天")
|
||||
private Integer valid_time;
|
||||
//签名
|
||||
private String sign;
|
||||
@ApiModelProperty(value = "开发者自定义字段",notes = "开发者自定义字段,回调原样回传。 超过最大长度会被截断")
|
||||
private String cp_extra;
|
||||
@ApiModelProperty(value = "商户自定义回调地址", notes = "商户自定义回调地址,必须以 https 开头,支持 443 端口。 指定时,支付成功后抖音会请求该地址通知开发者")
|
||||
private String notify_url;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
package org.jeecg.modules.mini.douyin.util;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.jeecg.common.util.RestUtil;
|
||||
import org.jeecg.config.sign.util.HttpUtils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author ZhouWenTao
|
||||
* @create 2024-04-14-13:10
|
||||
*/
|
||||
public class DouYinTest {
|
||||
public static void main(String[] args) {
|
||||
Map<String, Object> testCase = new HashMap<String, Object>() {{
|
||||
put("app_id", "tt59a72f1ac6964bfa01");
|
||||
//put("thirdparty_id", "");//tta4bad200000xxxxxx
|
||||
put("out_order_no", "test-02");
|
||||
put("total_amount", 1);
|
||||
put("subject", "test-payment_subject-test-paym...");
|
||||
put("body", "测试购买vip");
|
||||
put("valid_time", 172800);
|
||||
put("notify_url", "https://yitisheng.vip/jbt/mini/pay/v1/payNotify");
|
||||
put("cp_extra", "一些附加信息");
|
||||
//put("disable_msg", 0);
|
||||
//put("msg_page", "pages/user/orderDetail/orderDetail?id=997979879879879879");
|
||||
//put("sign", "edc608b160a1be3de0xxxxxx");
|
||||
}};
|
||||
String sign = Sign.requestSign(testCase);
|
||||
System.out.println(sign);
|
||||
//发送post请求
|
||||
String douyinUrl="https://developer.toutiao.com/api/apps/ecpay/v1/create_order";
|
||||
testCase.put("sign",sign);
|
||||
String jsonString = JSONObject.toJSONString(testCase);
|
||||
JSONObject post = RestUtil.post(douyinUrl, JSONObject.parseObject(jsonString));
|
||||
System.out.println(post);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,137 @@
|
|||
/**
|
||||
* Copyright 2022 Beijing Douyin Information Service Co., Ltd.
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
* Package com.bytedance.microapp Sign 签名算法
|
||||
* <p>
|
||||
* Package com.bytedance.microapp Sign implement the signature algorithm
|
||||
*/
|
||||
|
||||
package org.jeecg.modules.mini.douyin.util;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class Sign {
|
||||
|
||||
/**
|
||||
* 担保支付请求不参与签名参数
|
||||
* app_id 小程序appID
|
||||
* thirdparty_id 代小程序进行该笔交易调用的第三方平台服务商id
|
||||
* sign 签名
|
||||
* other_settle_params 其他分账方参数
|
||||
*
|
||||
* Guaranteed payment requests do not participate in signature parameters
|
||||
* app_id Applets appID
|
||||
* thirdparty_id The id of the third-party platform service provider that calls the transaction on behalf of the Applets
|
||||
* sign sign
|
||||
* other_settle_params Other settle params
|
||||
*/
|
||||
public final static List<String> REQUEST_NOT_NEED_SIGN_PARAMS = Arrays.asList("app_id", "thirdparty_id", "sign", "other_settle_params");
|
||||
|
||||
/**
|
||||
* 支付密钥值,需要替换为自己的密钥(完成进件后,开发者可在字节开放平台-【某小程序】-【功能】-【支付】-【担保交易设置】中查看支付系统秘钥 SALT)
|
||||
*
|
||||
* Payment key value, you need to replace it with your own key
|
||||
*/
|
||||
private static final String SALT = "wODf6Bg5BXndJ3IELXNb1w5CDMRjatXAmZVP2DQ7";
|
||||
|
||||
/**
|
||||
* RequestSign 担保支付请求签名算法
|
||||
* @param paramsMap {@code Map<String, Object>} 所有的请求参数
|
||||
* @return:签名字符串
|
||||
*
|
||||
* RequestSign Guaranteed payment request signature algorithm
|
||||
* @param paramsMap {@code Map<String, Object>} all request parameters
|
||||
* @return: Signature string
|
||||
*/
|
||||
public static String requestSign(Map<String, Object> paramsMap) {
|
||||
List<String> paramsArr = new ArrayList<>();
|
||||
for (Map.Entry<String, Object> entry : paramsMap.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
if (REQUEST_NOT_NEED_SIGN_PARAMS.contains(key)) {
|
||||
continue;
|
||||
}
|
||||
String value = entry.getValue().toString();
|
||||
|
||||
value = value.trim();
|
||||
if (value.startsWith("\"") && value.endsWith("\"") && value.length() > 1) {
|
||||
value = value.substring(1, value.length() - 1);
|
||||
}
|
||||
value = value.trim();
|
||||
if (value.equals("") || value.equals("null")) {
|
||||
continue;
|
||||
}
|
||||
paramsArr.add(value);
|
||||
}
|
||||
paramsArr.add(SALT);
|
||||
Collections.sort(paramsArr);
|
||||
StringBuilder signStr = new StringBuilder();
|
||||
String sep = "";
|
||||
for (String s : paramsArr) {
|
||||
signStr.append(sep).append(s);
|
||||
sep = "&";
|
||||
}
|
||||
return md5FromStr(signStr.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* CallbackSign 担保支付回调签名算法
|
||||
* @param params {@code List<String>} 所有字段(验证时注意不包含 sign 签名本身,不包含空字段与 type 常量字段)内容与平台上配置的 token
|
||||
* @return:签名字符串
|
||||
*
|
||||
* CallbackSign Guaranteed payment callback signature algorithm
|
||||
* @param params {@code List<String>} The content of all fields (note that the sign signature itself is not included during verification, and does not include empty fields and type constant fields) content and the token configured on the platform
|
||||
* @return: signature string
|
||||
*/
|
||||
public static String callbackSign(List<String> params) {
|
||||
try {
|
||||
String concat = params.stream().sorted().collect(Collectors.joining(""));
|
||||
byte[] arrayByte = concat.getBytes(StandardCharsets.UTF_8);
|
||||
MessageDigest mDigest = MessageDigest.getInstance("SHA1");
|
||||
byte[] digestByte = mDigest.digest(arrayByte);
|
||||
|
||||
StringBuffer signBuilder = new StringBuffer();
|
||||
for (byte b : digestByte) {
|
||||
signBuilder.append(Integer.toString((b & 0xff) + 0x100, 16).substring(1));
|
||||
}
|
||||
return signBuilder.toString();
|
||||
} catch (Exception exp) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* md5FromStr md5算法对该字符串计算摘要
|
||||
* @param inStr {@code String} 需要签名的字符串
|
||||
* @return:签名字符串
|
||||
*
|
||||
* md5FromStr The md5 algorithm computes a digest of the string
|
||||
* @param inStr {@code String} String to be signed
|
||||
* @return: signature string
|
||||
*/
|
||||
private static String md5FromStr(String inStr) {
|
||||
MessageDigest md5;
|
||||
try {
|
||||
md5 = MessageDigest.getInstance("MD5");
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
return "";
|
||||
}
|
||||
|
||||
byte[] byteArray = inStr.getBytes(StandardCharsets.UTF_8);
|
||||
byte[] md5Bytes = md5.digest(byteArray);
|
||||
StringBuilder hexValue = new StringBuilder();
|
||||
for (byte md5Byte : md5Bytes) {
|
||||
int val = ((int) md5Byte) & 0xff;
|
||||
if (val < 16) {
|
||||
hexValue.append("0");
|
||||
}
|
||||
hexValue.append(Integer.toHexString(val));
|
||||
}
|
||||
return hexValue.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -48,6 +48,10 @@ public class YxOrder implements Serializable {
|
|||
@Excel(name = "商品编号", width = 15)
|
||||
@ApiModelProperty(value = "商品编号")
|
||||
private java.lang.String skuCode;
|
||||
/**供应商*/
|
||||
@Excel(name = "供应商", width = 15)
|
||||
@ApiModelProperty(value = "供应商")
|
||||
private String provider;
|
||||
/**支付方式:1借记卡、2信用卡、3微信、4支付宝、5现金*/
|
||||
@Excel(name = "支付方式:1借记卡、2信用卡、3微信、4支付宝、5现金", width = 15)
|
||||
@ApiModelProperty(value = "支付方式:1借记卡、2信用卡、3微信、4支付宝、5现金")
|
||||
|
|
|
|||
|
|
@ -294,13 +294,13 @@ public class YxSchoolServiceImpl extends ServiceImpl<YxSchoolMapper, YxSchool> i
|
|||
String province = "河南";
|
||||
LambdaQueryWrapper<YxSchool> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(YxSchool::getProvince, province);
|
||||
queryWrapper.eq(YxSchool::getSchoolType, "普通本科");
|
||||
queryWrapper.eq(YxSchool::getSchoolType, "本科");
|
||||
queryWrapper.last("limit 0,10");
|
||||
List<YxSchool> nowProvinceBenSchoolList = this.list(queryWrapper);
|
||||
//获取高职高专
|
||||
queryWrapper.clear();
|
||||
queryWrapper.eq(YxSchool::getProvince, province);
|
||||
queryWrapper.eq(YxSchool::getSchoolType, "专科(高职)");
|
||||
queryWrapper.eq(YxSchool::getSchoolType, "专科");
|
||||
queryWrapper.last("limit 0,10");
|
||||
List<YxSchool> nowProvinceZhuanSchoolList = this.list(queryWrapper);
|
||||
|
||||
|
|
@ -308,13 +308,13 @@ public class YxSchoolServiceImpl extends ServiceImpl<YxSchoolMapper, YxSchool> i
|
|||
//获取本科
|
||||
queryWrapper.clear();
|
||||
queryWrapper.ne(YxSchool::getProvince, province);
|
||||
queryWrapper.eq(YxSchool::getSchoolType, "普通本科");
|
||||
queryWrapper.eq(YxSchool::getSchoolType, "本科");
|
||||
queryWrapper.last("limit 0,10");
|
||||
List<YxSchool> otherProvinceBenSchoolList = this.list(queryWrapper);
|
||||
//获取专科
|
||||
queryWrapper.clear();
|
||||
queryWrapper.ne(YxSchool::getProvince, province);
|
||||
queryWrapper.eq(YxSchool::getSchoolType, "专科(高职)");
|
||||
queryWrapper.eq(YxSchool::getSchoolType, "专科");
|
||||
queryWrapper.last("limit 0,10");
|
||||
List<YxSchool> otherProvinceZhuanSchoolList = this.list(queryWrapper);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue