微信小程序支付,简单易上手
·
1.准备jar包
<dependency>
<groupId>com.github.wechatpay-apiv3</groupId>
<artifactId>wechatpay-java</artifactId>
<version>0.2.6</version>
</dependency>
2.配置yaml
# 微信小程序支付配置信息
wechat:
pay:
# 微信小程序appid
app-id: xxx
# 商户号
mch-id: xxxx
# 证书序列号
mch-serial-no: xxxx
# 小程序密钥
app-secret: xxxxx
# api密钥
api-key: xxxxxx
# 回调接口地址
notify-url: xxxx
# 证书地址
key-path: xxxxxxx

3.配置config
3.1: 参数信息
@Component
@ConfigurationProperties(prefix = "wechat.pay")
@Data
public class WxPayV3Bean {
private String appId; // 小程序appid
private String mchId; // 商户号
private String notifyUrl; // 支付回调地址
private String tradeType = "JSAPI"; // 交易类型
//证书序列号
private String mchSerialNo;
//小程序密钥
private String appSecret;
//商户API私钥
private String apiKey;
//商户API证书
private String keyPath;
}
3.2: 单例config
@Configuration
public class wxConfig {
@Resource
private WxPayV3Bean wxPayV3Bean;
@Bean
public Config getConfig(){
// 一个商户号只能初始化一个配置,否则会因为重复的下载任务报错
return new RSAAutoCertificateConfig.Builder()
.merchantId(wxPayV3Bean.getMchId())
.privateKeyFromPath(wxPayV3Bean.getKeyPath())
.merchantSerialNumber(wxPayV3Bean.getMchSerialNo())
.apiV3Key(wxPayV3Bean.getApiKey())
.build();
}
}
4.写个微信支付的工具类
好多方法里面都是自己封装的vo,根据自己的要求来
@Component
@Slf4j
public class WXPayUtil {
private static final String SYMBOLS = "0123456789abcdefghijklmnopqrstuvwxyz";
private static final Random RANDOM = new SecureRandom();
@Resource
private WxPayV3Bean wxPayV3Bean;
@Resource
private Config config;
public String getSign(String signatureStr, String privateKey) throws InvalidKeyException, NoSuchAlgorithmException, SignatureException,
IOException, URISyntaxException {
//replace 根据实际情况,不一定都需要
String replace = privateKey.replace("\\n", "\n");
PrivateKey merchantPrivateKey = PemUtil.loadPrivateKeyFromPath(replace);
Signature sign = Signature.getInstance("SHA256withRSA");
sign.initSign(merchantPrivateKey);
sign.update(signatureStr.getBytes(StandardCharsets.UTF_8));
return Base64Utils.encodeToString(sign.sign());
}
/**
* 获取随机字符串 Nonce Str
*
* @return String 随机字符串
*/
public static String generateNonceStr(String prefix) {
char[] nonceChars = new char[32];
for (int index = 0; index < nonceChars.length; ++index) {
nonceChars[index] = SYMBOLS.charAt(RANDOM.nextInt(SYMBOLS.length()));
}
return prefix + new String(nonceChars);
}
/**
* 获取微信支付参数
*
* @param req
* @param openId
* @return
*/
public WxPayRespVO getWxPayRespVO(ApplyForTransferDO req, String openId) {
// request.setXxx(val)设置所需参数,具体参数可见Request定义
PrepayRequest request = new PrepayRequest();
Amount amount = new Amount(); amount.setTotal(req.getAmountPayable().multiply(BigDecimal.valueOf(100)).intValue());
amount.setTotal(1);
request.setAmount(amount);
request.setAppid(wxPayV3Bean.getAppId());
request.setMchid(wxPayV3Bean.getMchId());
request.setDescription("xxxx");
request.setNotifyUrl(wxPayV3Bean.getNotifyUrl());
request.setOutTradeNo(req.getOrderNo());
request.setAttach(req.getPaymentMethod());
Payer payer = new Payer();
payer.setOpenid(openId);
request.setPayer(payer);
// 调用下单方法,得到应答
JsapiService service = new JsapiService.Builder().config(config).build();
PrepayResponse response = service.prepay(request);
WxPayRespVO vo = new WxPayRespVO();
Long timeStamp = System.currentTimeMillis() / 1000;
vo.setTimeStamp(timeStamp);
String substring = UUID.randomUUID().toString().replaceAll("-", "").substring(0, 32);
vo.setNonceStr(substring);
String signatureStr = Stream.of(wxPayV3Bean.getAppId(), String.valueOf(timeStamp), substring, "prepay_id=" + response.getPrepayId())
.collect(Collectors.joining("\n", "", "\n"));
String sign = getSign(signatureStr, wxPayV3Bean.getKeyPath());
vo.setPaySign(sign);
vo.setPrepayId(response.getPrepayId());
return vo;
}
/**
* 回调
*
* @param request
*/
public void callback(HttpServletRequest request) {
try {
//读取请求体的信息
ServletInputStream inputStream = request.getInputStream();
StringBuffer stringBuffer = new StringBuffer();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String s;
//读取回调请求体
while ((s = bufferedReader.readLine()) != null) {
stringBuffer.append(s);
}
String s1 = stringBuffer.toString();
String timestamp = request.getHeader(WECHAT_PAY_TIMESTAMP);
String nonce = request.getHeader(WECHAT_PAY_NONCE);
String signType = request.getHeader("Wechatpay-Signature-Type");
String serialNo = request.getHeader(WECHAT_PAY_SERIAL);
String signature = request.getHeader(WECHAT_PAY_SIGNATURE);
NotificationParser parser = new NotificationParser((NotificationConfig) config);
// 验签、解密并转换成 Transaction
RequestParam requestParam = new RequestParam.Builder()
.serialNumber(serialNo)
.nonce(nonce)
.signature(signature)
.timestamp(timestamp)
// 若未设置signType,默认值为 WECHATPAY2-SHA256-RSA2048
.signType(signType)
.body(s1)
.build();
Transaction parse = parser.parse(requestParam, Transaction.class);
System.out.println("parse = " + parse);
} catch (Exception e) {
log.error("微信支付回调异常," + e.getMessage());
}
}
/**
* 查询状态
* @param transferDO
* @return
*/
public Object findOrderStatus(ApplyForTransferDO transferDO) {
QueryOrderByOutTradeNoRequest queryRequest = new QueryOrderByOutTradeNoRequest ();
queryRequest.setMchid(wxPayV3Bean.getMchId());
queryRequest.setOutTradeNo(transferDO.getOrderNo());
try {
JsapiServiceExtension service =
new JsapiServiceExtension.Builder()
.config(config)
.signType("RSA")
.build();
Transaction result = service.queryOrderByOutTradeNo(queryRequest);
if (Transaction.TradeStateEnum.SUCCESS.equals(result.getTradeState())) {
return true;
}
} catch (ServiceException e) {
log.error("订单查询失败,返回码:{},返回信息:{}");
}
return false;
}
5.封装的实体类
别的就不提供了,差不多自己定义
@Data
@Accessors(chain = true)
public class WxPayRespVO implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 预支付交易会话标识小程序下单接口返回的prepay_id参数值
*/
private String prepayId;
/**
* 随机字符串
*/
private String nonceStr;
/**
* 时间戳
*/
private Long timeStamp;
/**
* 签名
*/
private String paySign;
}
更多推荐

所有评论(0)