package com.just.justpay.service.impl;
import com.just.justpay.config.WxPayConfig;
import com.just.justpay.service.IWxPayCommonService;
import com.just.justpay.utils.JustWxPayUtils;
import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.RSAPublicKeyConfig;
import com.wechat.pay.java.core.notification.NotificationConfig;
import com.wechat.pay.java.core.notification.NotificationParser;
import com.wechat.pay.java.core.notification.RSAPublicKeyNotificationConfig;
import com.wechat.pay.java.core.notification.RequestParam;
import com.wechat.pay.java.service.payments.jsapi.JsapiServiceExtension;
import com.wechat.pay.java.service.payments.jsapi.model.CloseOrderRequest;
import com.wechat.pay.java.service.payments.jsapi.model.QueryOrderByIdRequest;
import com.wechat.pay.java.service.payments.jsapi.model.QueryOrderByOutTradeNoRequest;
import com.wechat.pay.java.service.payments.model.Transaction;
import com.wechat.pay.java.service.refund.RefundService;
import com.wechat.pay.java.service.refund.model.AmountReq;
import com.wechat.pay.java.service.refund.model.CreateRequest;
import com.wechat.pay.java.service.refund.model.QueryByOutRefundNoRequest;
import com.wechat.pay.java.service.refund.model.Refund;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
* 作者:JustOne
* 微信:andyLau2020smile
* B站教学视频:https://space.bilibili.com/599344027/lists/4661450?type=series
*/
@Service
public class WxPayJsapiServiceImpl implements IWxPayJsapiService {
@Autowired
JsapiServiceExtension jsapiService;
/**
* 微信小程序发起的Jsapi支付的结果通知(使用自己DIY解析)
* @param request 微信管方发来的 "支付结果" 通知
* @return 将"验签结果"回复微信官方,否则微信官方会一直给你回调,规则如下:
* 微信支付会按照(15s/15s/30s/3m/10m/20m/30m/30m/30m/60m/3h/3h/3h/6h/6h)的频次
* 重复发送回调通知,直至微信支付接收到商户应答成功,或达到最大发送次数(15次)
*/
@Override
public Map<String, String> callBackDIY(HttpServletRequest request){
String timestamp = request.getHeader("Wechatpay-Timestamp");//官方说:验签的时间戳
String nonce = request.getHeader("Wechatpay-Nonce"); //官方说:验签的随机字符串
String signature = request.getHeader("Wechatpay-Signature");//官方说:待验签的签名值
String Serial = request.getHeader("Wechatpay-Serial"); //官方说:微信支付公钥ID,PUB_xxx
StringBuilder body = new StringBuilder(); //官方说:应答报文主体
try{
String str = null;
BufferedReader br = request.getReader();
while( (str=br.readLine())!=null){
body.append(str);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
System.out.println("回调的时间戳《timestamp》"+timestamp); //官方说:验签的时间戳
System.out.println("回调的随机串《nonce》"+nonce); //官方说:验签的随机字符串
System.out.println("回调的签名值《signature》"+signature); //官方说:待验签的签名值
System.out.println("回调的微信支付公钥ID《Serial》"+Serial); //官方说:微信支付公钥ID,PUB_xxx
System.out.println("回调的微信应答报文主体的密文"+body); //官方说:应答报文主体
//part01:验证签名(官方要求的三合一串,待验签的签名值)
StringBuilder threeStr = new StringBuilder();
threeStr.append(timestamp).append("\n");//官方说,只要这三个,即时间戳,随机串,报文主体
threeStr.append(nonce).append("\n");
threeStr.append(body).append("\n");
boolean signaturePass = JustWxPayUtils.signatureVerify(threeStr.toString(), signature );
Map<String, String> map = new HashMap();
if(!signaturePass){
map.put("code","FAIL");
map.put("msg","验签失败");
System.out.println("【【验签失败】】");
return map;//这是响应给微信官方,表达验签失败
}
System.out.println("【【验签成功,接下来验证订单】】");
//part02:解密回调密文。。。明文Plaintext,密文Ciphertext,里面含有商户订单号、微信支付订单号等
String plainText = JustWxPayUtils.decryptOrder(body.toString());
System.out.println("回调的微信应答报文主体的明文"+ plainText+"\n");
boolean orderNumberPass = false;
if(!orderNumberPass){
//TODO:在此应验证订单是否存在
map.put("code","FAIL");
map.put("msg","单号异常");
return map;//这是响应给微信官方,表达付款失败
}
//TODO:在此应将商家相应的订单状态改为"已付款"
map.put("code","SUCCESS");
map.put("msg","验签成功");
return map;
}
}
代码100%以可运行,如果不明,可以看我B站教学视频,链接:心有柠溪的个人空间-心有柠溪个人主页-哔哩哔哩视频