赞
踩
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weinxin-java-pay</artifactId>
<version>对应的版本号</version>
</dependency>
官方文档: 直达
/** * @author: Eden4J * @Description: 微信支付商户信息配置类 */ @Data @Component @RefreshScope @ConfigurationProperties(prefix = "wechat.pay") public class WeChatPayProperties { /** * 微信小程序或者微信公众号appId */ private String appid; /** * 商户号 */ private String mchId; /** * 商户密钥 */ private String mchKey; /** * 商户证书序列号 */ private String serialNo; /** * apiV3Key */ private String apiV3Key; /** * 证书 */ private String keyPath; /** * 商户私钥文件 */ private String privateKeyPath; /** * apiclient_cert.pem证书文件 */ private String privateCertPath; /** * 交易类型 * JSAPI--公众号支付 * NATIVE--原生扫码支付 * APP--app支付 */ private String tradeType; /** * 支付结果异步通知回调地址 */ private String notifyUrl; }
/** * @author: Eden4J * @Description: 微信支付配置类 */ @Component @ConditionalOnClass(WxPayService.class) @RequiredArgsConstructor public class WeChatPayConfig { private final WeChatPayProperties properties; @Bean @ConditionalOnMissingBean public WxPayConfig payConfig() { WxPayConfig payConfig = new WxPayConfig(); payConfig.setAppId(StringUtils.trimToNull(this.properties.getAppid())); payConfig.setMchId(StringUtils.trimToNull(this.properties.getMchId())); payConfig.setMchKey(StringUtils.trimToNull(this.properties.getMchKey())); payConfig.setCertSerialNo(StringUtils.trimToNull(this.properties.getSerialNo())); payConfig.setApiV3Key(StringUtils.trimToNull(this.properties.getApiV3Key())); payConfig.setKeyPath(StringUtils.trimToNull(this.properties.getKeyPath())); payConfig.setPrivateKeyPath(StringUtils.trimToNull(this.properties.getPrivateKeyPath())); payConfig.setPrivateCertPath(StringUtils.trimToNull(this.properties.getPrivateCertPath())); payConfig.setTradeType(StringUtils.trimToNull(this.properties.getTradeType())); return payConfig; } @Bean public WxPayService wxPayService(WxPayConfig payConfig) { WxPayService wxPayService = new WxPayServiceImpl(); wxPayService.setConfig(payConfig); return wxPayService; } }
@Data
public class WxPayInfoVO implements Serializable {
private String appId;
private String timeStamp;
private String nonceStr;
private String packageValue;
private String signType;
private String paySign;
}
/** * @author: Eden4J * @Description: 微信支付相关工具类 */ public class WxPayUtil { public static String sign(String signStr, PrivateKey privateKey) { Sign sign = SecureUtil.sign(SignAlgorithm.SHA256withRSA, privateKey.getEncoded(), null); return Base64.encode(sign.sign(signStr.getBytes())); } public static String buildMessage(String appId, String timeStamp, String nonceStr, String body) { return appId + "\n" + timeStamp + "\n" + nonceStr + "\n" + body + "\n"; } public static AutoUpdateCertificatesVerifier getVerifier(WxPayConfig wxPayConfig) throws IOException { PrivateKey privateKey = PemUtils.loadPrivateKey(new ClassPathResource("apiclient_key.pem").getInputStream()); AutoUpdateCertificatesVerifier verifier = new AutoUpdateCertificatesVerifier( new WxPayCredentials(wxPayConfig.getMchId(), new PrivateKeySigner(wxPayConfig.getCertSerialNo(), privateKey)) , wxPayConfig.getApiV3Key().getBytes("utf-8") ); return verifier; } /** * 验证签名 * * @param certificate * @param message * @param signature * @return */ public static boolean verify(AutoUpdateCertificatesVerifier certificate, byte[] message, String signature) { try { Signature sign = Signature.getInstance("SHA256withRSA"); sign.initVerify(certificate.getValidCertificate()); sign.update(message); return sign.verify(java.util.Base64.getDecoder().decode(signature)); } catch (NoSuchAlgorithmException e) { throw new RuntimeException("当前Java环境不支持SHA256withRSA", e); } catch (SignatureException e) { throw new RuntimeException("签名验证过程发生了错误", e); } catch (InvalidKeyException e) { throw new RuntimeException("无效的证书", e); } } }
重点注意:微信支付回调结果通知不要使用JSONObject去做接收
@RestController @RequestMapping("/请求路径") @RequiredArgsConstructor public class AppCustomerUserRechargeOrderController { private final IAppCustomerUserRechargeOrderService rechargeOrderService; @PostMapping("/preOrder") public Result<WxPayInfoVO> preOrder(@RequestParam("goodId") String goodId) { return Result.success(rechargeOrderService.preOrder(goodId)); } // 支付回调 @PostMapping("/back") public Map<String,String> back(@RequestBody Map body,HttpServletRequest request) { return rechargeOrderService.formalOrder(body, request); } }
@Override public WxPayInfoVO preRecharge(String goodId) { try { //看看是否有其他的业务逻辑 // 调用微信的统一下单接口获取预支付单返回前端 createOrderV3(TradeTypeEnum tradeType, WxPayUnifiedOrderV3Request request) WxPayUnifiedOrderV3Request payRequest = new WxPayUnifiedOrderV3Request(); payRequest.setOutTradeNo(rechargeNo);//系统充值订单号 payRequest.setDescription(goodsPackage.getPackageName()); //订单失效时间 SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX"); payRequest.setTimeExpire(dateFormat.format(DateUtil.offset(new Date(), DateField.HOUR_OF_DAY, 1))); WxPayUnifiedOrderV3Request.Payer payer = new WxPayUnifiedOrderV3Request.Payer(); payer.setOpenid(userAccount.getOpenId()); payRequest.setPayer(payer); WxPayUnifiedOrderV3Request.Amount amount = new WxPayUnifiedOrderV3Request.Amount(); amount.setTotal(rechargeOrder.getTotalAmount().multiply(BigDecimal.valueOf(100)).intValue()); amount.setCurrency("CNY"); payRequest.setAmount(amount); payRequest.setNotifyUrl(weChatPayProperties.getNotifyUrl()); WxPayUnifiedOrderV3Result.JsapiResult jsapiResult = wxPayService.createOrderV3(TradeTypeEnum.JSAPI, payRequest); String encode = WxPayUtil.sign(WxPayUtil.buildMessage(weChatPayProperties.getAppid(), jsapiResult.getTimeStamp(), jsapiResult.getNonceStr(), jsapiResult.getPackageValue()) , PemUtils.loadPrivateKey(new ClassPathResource("apiclient_key.pem").getInputStream())); WxPayInfoVO payInfoVO = PojoUtil.exchangePojo(jsapiResult, WxPayInfoVO.class); payInfoVO.setPaySign(encode); return payInfoVO; } catch (WxPayException e) { e.printStackTrace(); throw new BizException("微信支付失败", e); } catch (IOException e) { e.printStackTrace(); throw new BizException("微信支付失败", e); } } @Override public Map<String, String> createFormalOrder(Map body, HttpServletRequest request) { try { Map<String, String> resultMap = new HashMap<>(); resultMap.put("code", "FAIL"); ObjectMapper objectMapper = new ObjectMapper(); try { //官方文档中有说明切记不要改变原始报文主体,如果使用JSONObject接收的话,不能使用JSON转换出来的字符串,会出现验签错误的情况,请注意 String data = objectMapper.writeValueAsString(body); SignatureHeader header = new SignatureHeader(); header.setTimeStamp(request.getHeader("Wechatpay-Timestamp")); header.setNonce(request.getHeader("Wechatpay-Nonce")); header.setSignature(request.getHeader("Wechatpay-Signature")); header.setSerial(request.getHeader("Wechatpay-Serial")); WxPayNotifyV3Result notifyV3Result =wxPayService.parseOrderNotifyV3Result(data, header); WxPayNotifyV3Result.DecryptNotifyResult decryptNotifyResult = notifyV3Result.getResult();//解密后的数据 if ("SUCCESS".equalsIgnoreCase(decryptNotifyResult.getTradeState())) { resultMap.put("code", "SUCCESS"); } } catch (Exception e) { e.printStackTrace(); } return resultMap; } catch (Exception e) { e.printStackTrace(); throw new BizException("微信支付成功回调失败", e); } }
结束!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。