生成预下单
private final RSAAutoCertificateConfig rsaAutoCertificateConfig;
/***
* 预支付订单
* @return
*/
public AjaxResult createWxOrder(String orderNo, BigDecimal totalP, String openId, String description) {
//请求微信支付相关配置
JsapiServiceExtension service =
new JsapiServiceExtension.Builder()
.config(rsaAutoCertificateConfig)
.signType("RSA") // 不填默认为RSA
.build();
PrepayWithRequestPaymentResponse response = new PrepayWithRequestPaymentResponse();
try {
PrepayRequest request = new PrepayRequest();
request.setAppid(wxPayConfig.getAppId());
request.setMchid(wxPayConfig.getMerchantId());
request.setDescription(description);
request.setOutTradeNo(orderNo);
request.setNotifyUrl(wxPayConfig.getPayNotifyUrl());
Amount amount = new Amount();
//todo 默认一分钱
totalP = new BigDecimal(1);
// amount.setTotal(totalP.multiply(new BigDecimal("100")).intValue());
amount.setTotal(totalP.intValue());
request.setAmount(amount);
Payer payer = new Payer();
payer.setOpenid(openId);
request.setPayer(payer);
log.info("请求预支付下单,请求参数:{}", JSONObject.toJSONString(request));
// 调用预下单接口
response = service.prepayWithRequestPayment(request);
// 拿到返回内容
log.info("订单【{}】发起预支付成功,返回信息:{}", orderNo, response);
return AjaxResult.success(response);
} catch (HttpException e) { // 发送HTTP请求失败
log.error("微信下单发送HTTP请求失败,错误信息:{}", e.getHttpRequest());
return AjaxResult.error("下单失败");
} catch (ServiceException e) { // 服务返回状态小于200或大于等于300,例如500
log.error("微信下单服务状态错误,错误信息:{}", e.getErrorMessage());
return AjaxResult.error("下单失败");
} catch (MalformedMessageException e) { // 服务返回成功,返回体类型不合法,或者解析返回体失败
log.error("服务返回成功,返回体类型不合法,或者解析返回体失败,错误信息:{}", e.getMessage());
return AjaxResult.error("下单失败");
}
}
退款订单
private final RSAAutoCertificateConfig rsaAutoCertificateConfig;
/***
* 退款订单
* @return
*/
public AjaxResult createWxRefundOrder(String orderNo, BigDecimal totalP, String openId) {
//请求微信支付相关配置
RefundService service =
new RefundService.Builder()
.config(rsaAutoCertificateConfig)
.build();
Refund response = new Refund();
try {
CreateRequest request = new CreateRequest();
request.setNotifyUrl(wxPayConfig.getPayNotifyUrl());
request.setOutTradeNo(orderNo);
request.setOutRefundNo(orderNo);
AmountReq amount = new AmountReq();
//todo 默认一分钱
totalP = new BigDecimal(1);
// amount.setRefund(totalP.multiply(new BigDecimal("100")).intValue());
// amount.setTotal(totalP.multiply(new BigDecimal("100")).intValue());
amount.setTotal(totalP.longValue());
amount.setRefund(totalP.longValue());
amount.setCurrency("CNY");
request.setAmount(amount);
Payer payer = new Payer();
payer.setOpenid(openId);
// request.setPayer(payer);
log.info("请求退款下单,请求参数:{}", JSONObject.toJSONString(request));
// 调用预下单接口
response = service.create(request);
// 拿到返回内容
log.info("订单【{}】发起退款成功,返回信息:{}", orderNo, JSONObject.toJSONString(response));
return AjaxResult.success(response);
} catch (HttpException e) { // 发送HTTP请求失败
log.error("微信退款发送HTTP请求失败,错误信息:{}", e.getHttpRequest());
return AjaxResult.error("退款失败");
} catch (ServiceException e) { // 服务返回状态小于200或大于等于300,例如500
log.error("微信退款服务状态错误,错误信息:{}", e.getErrorMessage());
return AjaxResult.error("退款失败");
} catch (MalformedMessageException e) { // 服务返回成功,返回体类型不合法,或者解析返回体失败
log.error("服务返回成功,返回体类型不合法,或者解析返回体失败,错误信息:{}", e.getMessage());
return AjaxResult.error("退款失败");
}
}
支付回调
public Map handleWeChatPayCallback(JSONObject jsonObject) {
String json = jsonObject.toString();
JSONObject decryptDataObj = medicalDecryptData(jsonObject);
if ("支付成功".equals(decryptDataObj.get("trade_state_desc"))) {
try {
// 1 看订单是否回调成功
TOrder tOrder = new TOrder();
tOrder.setOrderNo(decryptDataObj.getString("out_trade_no"));
tOrder.setPayRefund("0");
tOrder.setIsDel("0");
tOrder.setPayStatus("1");
tOrder.setOrderCancel("0");
List<TOrder> orderList = tOrderMapper.selectTOrderList(tOrder);
if (orderList.size() > 0) {
tOrder = orderList.get(0);
tOrder.setPayTime(DateUtils.getNowDate());
tOrder.setPayStatus("0");
tOrder.setUpdateTime(DateUtils.getNowDate());
tOrderMapper.updateTOrder(tOrder);
// 2 没处理过则补全 订单数据,补偿 关联票可用
TDataCompensation tDataCompensation = new TDataCompensation();
tDataCompensation.setcContent(tOrder.getOrderNo());
List<TDataCompensation> list = tDataCompensationMapper.selectTDataCompensationList(tDataCompensation);
if (list.size() > 0) {
tDataCompensation = list.get(0);
tDataCompensation.setcStatus("0");
tDataCompensation.setUpdateTime(DateUtils.getNowDate());
tDataCompensation.setEndTime(DateUtils.getNowDate());
tDataCompensationMapper.updateTDataCompensation(tDataCompensation);
}
// 变更 关联信息为能用 并且未使用
tTicketRelevanceUserMapper.updateByOrderNo(tOrder.getOrderNo());
}
} catch (Exception e) {
e.printStackTrace();
}
}
//解密
public JSONObject medicalDecryptData(JSONObject jsonObject) {
String key = wxPayConfig.getApiV3Key();
// String json = jsonObject.toString();
//解密 jsonObject 对象
JSONObject resource = jsonObject.getJSONObject("resource");
String associatedData = resource.getString("associated_data");
String ciphertext = resource.getString("ciphertext");
String nonce = resource.getString("nonce");
String decryptData = null;
try {
decryptData = new AesUtil(key.getBytes(StandardCharsets.UTF_8)).decryptToString
(associatedData.getBytes(StandardCharsets.UTF_8),
nonce.getBytes(StandardCharsets.UTF_8),
ciphertext);
} catch (GeneralSecurityException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
JSONObject decryptDataObj = JSONObject.parseObject(decryptData, JSONObject.class);
return decryptDataObj;
}
返回bean
package com.ruoyi.common.core.domain;
import java.util.HashMap;
import java.util.Objects;
import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.utils.StringUtils;
/**
* 操作消息提醒
*
* @author ruoyi
*/
public class AjaxResult extends HashMap<String, Object>
{
private static final long serialVersionUID = 1L;
/** 状态码 */
public static final String CODE_TAG = "code";
/** 返回内容 */
public static final String MSG_TAG = "msg";
/** 数据对象 */
public static final String DATA_TAG = "data";
/**
* 初始化一个新创建的 AjaxResult 对象,使其表示一个空消息。
*/
public AjaxResult()
{
}
/**
* 初始化一个新创建的 AjaxResult 对象
*
* @param code 状态码
* @param msg 返回内容
*/
public AjaxResult(int code, String msg)
{
super.put(CODE_TAG, code);
super.put(MSG_TAG, msg);
}
/**
* 初始化一个新创建的 AjaxResult 对象
*
* @param code 状态码
* @param msg 返回内容
* @param data 数据对象
*/
public AjaxResult(int code, String msg, Object data)
{
super.put(CODE_TAG, code);
super.put(MSG_TAG, msg);
if (StringUtils.isNotNull(data))
{
super.put(DATA_TAG, data);
}
}
/**
* 返回成功消息
*
* @return 成功消息
*/
public static AjaxResult success()
{
return AjaxResult.success("操作成功");
}
/**
* 返回成功数据
*
* @return 成功消息
*/
public static AjaxResult success(Object data)
{
return AjaxResult.success("操作成功", data);
}
/**
* 返回成功消息
*
* @param msg 返回内容
* @return 成功消息
*/
public static AjaxResult success(String msg)
{
return AjaxResult.success(msg, null);
}
/**
* 返回成功消息
*
* @param msg 返回内容
* @param data 数据对象
* @return 成功消息
*/
public static AjaxResult success(String msg, Object data)
{
return new AjaxResult(HttpStatus.SUCCESS, msg, data);
}
/**
* 返回警告消息
*
* @param msg 返回内容
* @return 警告消息
*/
public static AjaxResult warn(String msg)
{
return AjaxResult.warn(msg, null);
}
/**
* 返回警告消息
*
* @param msg 返回内容
* @param data 数据对象
* @return 警告消息
*/
public static AjaxResult warn(String msg, Object data)
{
return new AjaxResult(HttpStatus.WARN, msg, data);
}
/**
* 返回错误消息
*
* @return 错误消息
*/
public static AjaxResult error()
{
return AjaxResult.error("操作失败");
}
/**
* 返回错误消息
*
* @param msg 返回内容
* @return 错误消息
*/
public static AjaxResult error(String msg)
{
return AjaxResult.error(msg, null);
}
/**
* 返回错误消息
*
* @param msg 返回内容
* @param data 数据对象
* @return 错误消息
*/
public static AjaxResult error(String msg, Object data)
{
return new AjaxResult(HttpStatus.ERROR, msg, data);
}
/**
* 返回错误消息
*
* @param code 状态码
* @param msg 返回内容
* @return 错误消息
*/
public static AjaxResult error(int code, String msg)
{
return new AjaxResult(code, msg, null);
}
/**
* 是否为成功消息
*
* @return 结果
*/
public boolean isSuccess()
{
return Objects.equals(HttpStatus.SUCCESS, this.get(CODE_TAG));
}
/**
* 是否为警告消息
*
* @return 结果
*/
public boolean isWarn()
{
return Objects.equals(HttpStatus.WARN, this.get(CODE_TAG));
}
/**
* 是否为错误消息
*
* @return 结果
*/
public boolean isError()
{
return Objects.equals(HttpStatus.ERROR, this.get(CODE_TAG));
}
/**
* 方便链式调用
*
* @param key 键
* @param value 值
* @return 数据对象
*/
@Override
public AjaxResult put(String key, Object value)
{
super.put(key, value);
return this;
}
}
WxPayConfig
package com.ruoyi.common.utils.wx.v3;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Data
@Component
@ConfigurationProperties(prefix = "wx.pay")
public class WxPayConfig {
//APPID
private String appId;
//mchid
private String merchantId;
//商户API私钥
private String privateKey;
//商户证书序列号
private String merchantSerialNumber;
//商户APIv3密钥
private String apiV3Key;
//支付通知地址
private String payNotifyUrl;
//退款通知地址
private String refundNotifyUrl;
}