package mr.ali.videoapp.portal.Bo;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderResult;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import lombok.extern.slf4j.Slf4j;
import mr.ali.videoapp.portal.model.OpenId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
@Service
@Slf4j
public class WeChatPayService {
@Resource
RedisTemplate redisTemplate;
@Autowired
private WxPayService wxPayService;
@Resource
private HttpServletRequest request;
// 获取Logger
Logger logger = LoggerFactory.getLogger(WeChatPayService.class);
public WxPayUnifiedOrderResult createOrder(String orderId, String totalFee) throws WxPayException {
String userIp = request.getRemoteAddr();
// 用户信息通过redis获取项目中
OpenId open = (OpenId) redisTemplate.opsForValue().get("cont");
log.info("用户userIp:{}",userIp);
log.info("用户openId:{}",open.getOpenId());
// 创建统一下单请求
// WxPayUnifiedOrderRequest request = new WxPayUnifiedOrderRequest();
// request.setOutTradeNo(orderId);
// request.setTotalFee(Integer.parseInt(totalFee));
// request.setBody("商品描述");
// request.setTradeType("JSAPI");
// request.setSpbillCreateIp(userIp);
// request.setOpenid(open.getOpenId());
// request.setNotifyUrl("https://app.erkantv.cn:443/pay/notify");
WxPayUnifiedOrderRequest request = WxPayUnifiedOrderRequest.newBuilder()
.openid(open.getOpenId())
.body("商品描述")
.outTradeNo(orderId)
.totalFee(Integer.parseInt(totalFee))
.spbillCreateIp(userIp)
.notifyUrl("https://app.erkantv.cn:443/pay/notify")
.tradeType("JSAPI")
.build();
// 打印请求参数
logger.info("OpenID: {}", open.getOpenId());
logger.info("商品描述: {}", "商品描述");
logger.info("订单号: {}", orderId);
logger.info("订单金额: {}", totalFee);
logger.info("用户IP: {}", userIp);
logger.info("异步通知URL: {}", "https://app.erkantv.cn:443/pay/notify");
logger.info("交易类型: {}", "JSAPI");
// 调用微信支付接口
try {
WxPayUnifiedOrderResult result = wxPayService.unifiedOrder(request);
logger.info("统一下单结果: {}", result);
} catch (WxPayException e) {
logger.error("微信支付异常: {}", e.getMessage());
}
log.info("微信统一下单请求:{}",request);
log.info("微信统一下单请求toXML():{}",request.toXML());
// 发送请求并获取结果
return wxPayService.createOrder(request);
}
}
package mr.ali.videoapp.portal.Bo;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.beans.factory.annotation.Value;
@Configuration
public class WeChatPayConfig {
@Value("${wxpay.appId}")
private String appId;
@Value("${wxpay.mchId}")
private String mchId;
@Value("${wxpay.key}")
private String key;
@Value("${wxpay.notifyUrl}")
private String notifyUrl;
@Bean
public WxPayService wxPayService() {
WxPayConfig config = new WxPayConfig();
config.setAppId(appId);
config.setMchId(mchId);
config.setMchKey(key);
config.setNotifyUrl(notifyUrl);
WxPayService wxPayService = new WxPayServiceImpl();
wxPayService.setConfig(config);
return wxPayService;
}
}
package mr.ali.videoapp.portal.controller;
import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderResult;
import com.github.binarywang.wxpay.exception.WxPayException;
import lombok.extern.slf4j.Slf4j;
import mr.ali.videoapp.portal.Bo.Order;
import mr.ali.videoapp.portal.Bo.WeChatPayService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/pay")
@Slf4j
public class PayController {
@Autowired
private WeChatPayService weChatPayService;
@PostMapping("/unifiedorder")
public WxPayUnifiedOrderResult createOrder(@RequestBody Order order) {
log.info("获取的orderId:{}",order.getOrderId());
log.info("获取的totalFee:{}",order.getTotalFee());
if (order.getOrderId() == null) {
order.setOrderId("your_order_id");
}
if (order.getTotalFee() == null) {
order.setTotalFee("100");
}
log.info("if之后获取的orderId:{}",order.getOrderId());
log.info("if之后获取的totalFee:{}",order.getTotalFee());
try {
// 创建订单并返回预支付信息
WxPayUnifiedOrderResult result = weChatPayService.createOrder(order.getOrderId(), order.getTotalFee());
return result;
} catch (WxPayException e) {
e.printStackTrace();
throw new RuntimeException("统一下单失败: " + e.getMessage());
}
}
}
package mr.ali.videoapp.portal.controller;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/pay")
@Slf4j
public class PayCallbackController {
@Autowired
private WxPayService wxPayService;
@PostMapping("/notify")
public String paymentNotify(@RequestBody String xmlData) {
log.info("支付回调通知: {}", xmlData);
try {
// 解析微信支付结果通知
WxPayOrderNotifyResult notifyResult = wxPayService.parseOrderNotifyResult(xmlData);
// TODO: 根据业务逻辑处理支付成功的订单
// 例如:更新订单状态等
// 返回成功的结果
return "支付成功";
} catch (WxPayException e) {
// 返回 fail 表示接收失败
e.printStackTrace();
return "支付失败";
}
}
}
服务器返回的错误提示
2024-10-10 12:53:11.701 信息 4273 --- [-nio-443-exec-1] m.a.videoapp.portal.Bo.WeChatPayService : 微信统一下单请求toXML():<xml>
<appid>wx68b7ece486eb3e32</appid>
<mch_id>1694806774</mch_id>
<nonce_str>1728535991527</nonce_str>
<sign>1C9A076CE0ECE3701BE0D8A395619F80</sign>
<body>商品描述</body>
<out_trade_no>your_order_id1728535991007</out_trade_no>
<total_fee>1000</total_fee>
<spbill_create_ip>36.184.0.24</spbill_create_ip>
<notify_url>https://app.erkantv.cn:443/pay/notify</notify_url>
<trade_type>JSAPI</trade_type>
<openid>oycKq5dEp9JUOR0NI1uQTLPbWGqs</openid>
</xml>
2024-10-10 12:53:11.849 信息 4273 --- [-nio-443-exec-1] c.g.b.w.service.impl.WxPayServiceImpl :
【请求地址】:https://api.mch.weixin.qq.com/pay/unifiedorder
【请求数据】:<xml>
<appid>wx68b7ece486eb3e32</appid>
<mch_id>1694806774</mch_id>
<nonce_str>1728535991527</nonce_str>
<sign>1C9A076CE0ECE3701BE0D8A395619F80</sign>
<body>商品描述</body>
<out_trade_no>your_order_id1728535991007</out_trade_no>
<total_fee>1000</total_fee>
<spbill_create_ip>36.184.0.24</spbill_create_ip>
<notify_url>https://app.erkantv.cn:443/pay/notify</notify_url>
<trade_type>JSAPI</trade_type>
<openid>oycKq5dEp9JUOR0NI1uQTLPbWGqs</openid>
</xml>
【响应数据】:<xml><return_code><![CDATA[FAIL]]></return_code>
<return_msg><![CDATA[签名错误,请检查后再试]]></return_msg>
</xml>
2024-10-10 12:53:11.852 ERROR 4273 --- [-nio-443-exec-1] c.g.b.w.b.r.WxPayUnifiedOrderResult :
结果业务代码异常,返回结果:{return_msg=签名错误,请检查后再试, return_code=FAIL},
返回代码:FAIL,返回信息:签名错误,请检查后再试
WxPayException(customErrorMsg=null, returnCode=FAIL, returnMsg=签名错误,请检查后再试, resultCode=null, errCode=null, errCodeDes=null, xmlString=<xml><return_code><![CDATA[失败]]></return_code>
<return_msg><![CDATA[签名错误,请检查后再试]]></return_msg>
</xml>)
可以用在线校验工具验证一下https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=20_1,另外你的key是正确的么?
appid=wx68b7ece486eb3e32&body=商品描述&mch_id=1694806774&nonce_str=1728537368548¬ify_url=https://app.erkantv.cn:443/pay/notify&openid=oycKq5dEp9JUOR0NI1uQTLPbWGqs&out_trade_no=your_order_id1728537369088&spbill_create_ip=36.184.0.24&total_fee=1000&trade_type=JSAPI
#2.连接密钥key:
appid=wx68b7ece486eb3e32&body=商品描述&mch_id=1694806774&nonce_str=1728537368548¬ify_url=https://app.erkantv.cn:443/pay/notify&openid=oycKq5dEp9JUOR0NI1uQTLPbWGqs&out_trade_no=your_order_id1728537369088&spbill_create_ip=36.184.0.24&total_fee=1000&trade_type=JSAPI&key=******
#3.生成sign并转成大写:
sign=BCDF0CB3EA9FE1CA099BA54E15B9AF60
#4.校验结果:
原sign值:BCDF0CB3EA9FE1CA099BA54E15B9AF60
新sign值:BCDF0CB3EA9FE1CA099BA54E15B9AF60