JSAPI支付适用于线下场所、公众号场景和PC网站场景。(以下讲解的是PC二维码支付)。下面只是成功的案例,需要自己去优化代码。(需要帮助可以联系作者)
Maven
加入以下依赖
<dependency>
<groupId>com.github.wechatpay-apiv3</groupId>
<artifactId>wechatpay-java</artifactId>
<version>0.2.12</version>
</dependency>
发起支付,微信会返回一个支付字符串codeUrl,把codeUrl生成二维码就可以了。
package com.wechat.pay.java.service;
import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.service.payments.nativepay.NativePayService;
import com.wechat.pay.java.service.payments.nativepay.model.Amount;
import com.wechat.pay.java.service.payments.nativepay.model.PrepayRequest;
import com.wechat.pay.java.service.payments.nativepay.model.PrepayResponse;
/** Native 支付下单为例 */
public class QuickStart {
/** 商户号 */
public static String merchantId = "190000****";
/** 商户API私钥路径 */
public static String privateKeyPath = "/Users/yourname/your/path/apiclient_key.pem";
/** 商户证书序列号 */
public static String merchantSerialNumber = "5157F09EFDC096DE15EBE81A47057A72********";
/** 商户APIV3密钥 */
public static String apiV3Key = "...";
public static void main(String[] args) {
// 使用自动更新平台证书的RSA配置
// 一个商户号只能初始化一个配置,否则会因为重复的下载任务报错
Config config =
new RSAAutoCertificateConfig.Builder()
.merchantId(merchantId)
.privateKeyFromPath(privateKeyPath)
.merchantSerialNumber(merchantSerialNumber)
.apiV3Key(apiV3Key)
.build();
// 构建service
NativePayService service = new NativePayService.Builder().config(config).build();
// request.setXxx(val)设置所需参数,具体参数可见Request定义
PrepayRequest request = new PrepayRequest();
Amount amount = new Amount();
amount.setTotal(100);
request.setAmount(amount);
request.setAppid("wxa9d9651ae******");
request.setMchid("190000****");
request.setDescription("测试商品标题");
request.setNotifyUrl("https://notify_url");
request.setOutTradeNo("out_trade_no_001");
// 调用下单方法,得到应答
PrepayResponse response = service.prepay(request);
// 使用微信扫描 code_url ,将codeUrl生成二维码,就可以使用微信扫码支付了
System.out.println(response.getCodeUrl());
}
}
支付成功回调通知:回调通知的接口就是上面的request.setNotifyUrl("http://你的域名+api地址"),地址最好使用RequestMapping注解,不设置请求方式。不要token拦截。
@RequestMapping("/qrcodeNotify")
public ResponseEntity.BodyBuilder qrcodeNotify(HttpServletRequest request){
RequestParam requestParam = getRequestParam(request);
//这里面的参数一定要跟上面支付的一样,要不然会验证签名失败
NotificationConfig config = new RSAAutoCertificateConfig.Builder()
.merchantId(sqMerchantId)
.privateKeyFromPath(sqPrivateKeyPath)
.merchantSerialNumber(sqMerchantSerialNumber)
.apiV3Key(sqApiV3Key)
.build();
NotificationParser n = new NotificationParser(config);
Transaction transaction = n.parse(requestParam, Transaction.class);
log.info("二维码支付通知回调:{}",transaction);
Transaction.TradeStateEnum state = transaction.getTradeState();
if (!StringUtils.equals("SUCCESS", state.toString())) {
log.error("微信回调失败,JsapiPayController.payNotify.transaction:{}",transaction.toString());
//通知微信回调失败
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR);
}
//这个是获取你自己的订单号
String o = transaction.getOutTradeNo();
payRecordService.updateSuccess(o);
return ResponseEntity.status(HttpStatus.OK);
}
public RequestParam getRequestParam(HttpServletRequest request){
String body = getRequestBody(request);
//随机串
String nonceStr = request.getHeader("Wechatpay-Nonce");
//微信传递过来的签名
String signature = request.getHeader("Wechatpay-Signature");
//证书序列号(微信平台)
String serialNo = request.getHeader("Wechatpay-Serial");
//时间戳
String timestamp = request.getHeader("Wechatpay-Timestamp");
return new RequestParam.Builder()
.serialNumber(serialNo)
.nonce(nonceStr)
.signature(signature)
.timestamp(timestamp)
.body(body)
.build();
}
/**
* 读取请求数据流
* @param request
* @return
*/
private String getRequestBody(HttpServletRequest request) {
StringBuilder sb = new StringBuilder();
try (ServletInputStream inputStream = request.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
) {
String line;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
return sb.toString();
}
请作者喝杯咖啡
买手机更划算,上心机