第一步:
申请小程序,然后在小程序管理后台,申请接入微信支付
第二步:
接入微信支付之后,配置支付相关秘钥以及下载商户证书
第三步: pom中添加如下依赖
第四步: 创建微信请求工具类
public class WxHttpClient{
public static String appid = "XX"; // 小程序id
public static String mchId = "XX"; // 商户号
public static String mchSerialNo = "XX"; // 商户证书序列号
private static String apiV3Key = "XX"; // api密钥
public static String notify_url=""; //微信支付通知回调
private static volatile CloseableHttpClient wxHttpClient;
private static AutoUpdateCertificatesVerifier verifier;
private WxHttpClient(){}
public static CloseableHttpClient getWxHttpClient() {
if(wxHttpClient==null){
synchronized (WxHttpClient.class){
if(wxHttpClient==null){
//加载私钥
PrivateKey merchantPrivateKey = loadPrivateKey();
//使用自动更新的签名验证器,不需要传入证书
try {
verifier = new AutoUpdateCertificatesVerifier(
new WechatPay2Credentials(mchId, new PrivateKeySigner(mchSerialNo, merchantPrivateKey)),
apiV3Key.getBytes("utf-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
System.out.println("构建签名验证器失败!!!");
}
//构建HttpClient
wxHttpClient = WechatPayHttpClientBuilder.create()
.withMerchant(mchId, mchSerialNo, merchantPrivateKey)
.withValidator(new WechatPay2Validator(verifier))
.build();
}
}
}
return wxHttpClient;
}
public static PrivateKey loadPrivateKey(){
PrivateKey merchantPrivateKey = null;
try {
merchantPrivateKey = PemUtil.loadPrivateKey(
new FileInputStream("apiclient_key.pem"));
} catch (FileNotFoundException e) {
System.out.println(DateUtil.getCurrentDate()+"商户私钥加载异常");
e.printStackTrace();
}
return merchantPrivateKey;
}
//第三方工具类需要的配置
public static WxPayConfigStorage getWxPayConfigStorage(){
WxPayConfigStorage wxPayConfigStorage = new WxPayConfigStorage();
wxPayConfigStorage.setMchId(mchId);//支付商户号
wxPayConfigStorage.setAppid(appid);//小程序appid
// wxPayConfigStorage.setKeyPublic("转账公钥,转账时必填");
wxPayConfigStorage.setSecretKey("");// 商户支付密钥(之前设置的商户apiv3秘钥)
wxPayConfigStorage.setSignType("MD5");
wxPayConfigStorage.setInputCharset("utf-8");
return wxPayConfigStorage;
}
}
第五步:小程序调用下单获取预支付订单号及微信支付通知回调Controller
@RestController
@RequestMapping("/wxpay")
public class WxPayController {
@Resource
private UserService userService;
@Autowired
private WxPayService wxPayService;
@Autowired
private UserCreditService userCreditService;
private com.egzosn.pay.wx.api.WxPayService wxUserPayService=new com.egzosn.pay.wx.api.WxPayService(WxHttpClient.getWxPayConfigStorage());
/**
* @Desc 统一下单
* @Date 2021/5/22 13:38
*/
@RequestMapping("/unifiedOrder")
@SysLog(name="统一下单")
public ResultVO unifiedOrder(@RequestBody UserCredit userCredit) throws IOException {
//校验参数是否为空
BeanValidator.validate(userCredit, Creation.class);
//判断当前用户是否存在于系统中
User user=new User();
user.setId(userCredit.getUserId());
user.setOpenId(userCredit.getOpenId());
List
if(CollectionUtils.isEmpty(users)){
throw new BusinessException(0,"非系统用户,拒绝访问");
}
String outTradeNo=WxPayUtil.getOutTradeNo(userCredit.getUserId()+"");
userCredit.setAddTime(DateUtil.getCurrentDate());
userCredit.setOutTradeNo(outTradeNo);
userCredit.setTradeStatus(0);
//调用微信下单接口
String prepay_id_str = wxPayService.unifiedOrder(userCredit);
JSONObject rsobject=JSONObject.parseObject(prepay_id_str);
return ResultVOUtil.success(rsobject,"下单成功");
}
/**
*
* 微信用户支付回调接口
*/
@RequestMapping("/userPayCallBack")
public String wxUserPaycallback(HttpServletRequest request) {
try {
Map
request.getInputStream());
if (null == params) {
throw new Exception("回调参数为空");
}
// 校验
if (!wxUserPayService.verify(params)) {
throw new Exception("校验失败");
}
payDone(params);//支付处理
return wxUserPayService.getPayOutMessage("SUCCESS", "成功").toMessage();
} catch (Exception e) {
e.printStackTrace();
return wxUserPayService.getPayOutMessage("FALL", "失败").toMessage();
}
}
/**
* 支付结果处理
*/
private void payDone(Map
System.out.println("支付回调:" + JSON.toJSONString(dataMap));
String result_code = dataMap.get("result_code").toString(); //支付结果code
String out_trade_no = dataMap.get("out_trade_no").toString(); //商户交易订单id,此为支付记录id
if (!result_code.equals("SUCCESS")) {
throw new Exception("支付回调失败:" + JSON.toJSONString(dataMap));
}
UserCredit userCredit=new UserCredit();
userCredit.setOutTradeNo(out_trade_no);
List
if (CollectionUtils.isEmpty(userCredits)) {
throw new Exception("无支付记录,回调处理失败!!!");
}
userCredit.setTradeStatus(result_code.equals("SUCCESS") ? 1 : 2);
userCredit.setOutTradeNo(out_trade_no);
int updateFlag=userCreditService.updateCredit(userCredit);//根据回调结果更改支付结果状态
if(updateFlag==0){
throw new Exception("更新用户打赏表状态失败!!!");
}
}
}
第六步:创建微信支付服务类
@Service
public class WxPayServiceImpl implements WxPayService {
@Autowired
private UserCreditService userCreditService;
private CloseableHttpClient wxHttpClient=WxHttpClient.getWxHttpClient();
/**
* @Desc 统一下单接口
* @Date 2021/5/22 15:39
*/
@Override
public String unifiedOrder(UserCredit userCredit) throws IOException {
//添加微信下单记录
userCreditService.insertUserCredit(userCredit);
HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi");
httpPost.addHeader("Accept", "application/json");
httpPost.addHeader("Content-type","application/json; charset=utf-8");
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectMapper objectMapper = new ObjectMapper();
ObjectNode rootNode = objectMapper.createObjectNode();
rootNode.put("mchid", WxHttpClient.mchId)
.put("appid", WxHttpClient.appid)
.put("description", "Image形象店-深圳腾大-QQ公仔")
.put("notify_url", WxHttpClient.notify_url)
.put("out_trade_no", userCredit.getOutTradeNo());
rootNode.putObject("amount")
.put("total", userCredit.getAmount());
rootNode.putObject("payer")
.put("openid", userCredit.getOpenId());
objectMapper.writeValue(bos, rootNode);
httpPost.setEntity(new StringEntity(bos.toString("UTF-8"), "UTF-8"));
CloseableHttpResponse response = wxHttpClient.execute(httpPost);
String prepay_id_str = EntityUtils.toString(response.getEntity());
JSONObject object=JSONObject.parseObject(prepay_id_str);
Object code = object.get("code");
if(code!=null){
if(code.toString().equals("PARAM_ERROR")){
throw new BusinessException(0,"下单失败:"+object.get("message"));
}
}
return prepay_id_str;
}
}