一、准备工作
1、注册微信公众号并认证企业
进入官网:https://mp.weixin.qq.com/
前往认证认证成功后,牢记AppID(开发者ID)和AppSecret(开发者密码)
2、注册微信支付商户号并认证
进入官网:https://pay.weixin.qq.com/
注册认证成功后,进入产品中心,修改开发配置,添加支付配置中的JSAPI支付授权目录地址;配置完成后,只可以在配置好的地址下才能调用微信地址(无法输入ip地址)
添加成功后,进入AppID账号管理,绑定已经创建并且认证好的微信公众号
3、准备微信支付密钥及证书等配置
具体操作请查看官方给出的指引,很简单
二、创建配置文件
首先在pom.xml中引入微信支付工具类
<dependency>
<groupId>com.github.wechatpay-apiv3</groupId>
<artifactId>wechatpay-java</artifactId>
<version>0.2.12</version>
</dependency>
在SpringBoot项目中创建WxPayConfig.java文件
package ***********************;
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
import lombok.Data;
import org.springframework.context.annotation.Configuration;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.security.PrivateKey;
import java.security.Signature;
import java.util.Base64;
@Configuration
@Data
public class WxPayConfig {
//商户号
private String mchId = "*********";
//商户API证书序列号
private String mchSerialNo = "******************************";
//商户私钥文件路径-如果是本地验证,请输入绝对路径
public String privateKeyPath = "**************";
//APIv3密钥
private String apiV3Key = "*******************************";
//APPID
private String appid = "wx**************";
//APIV2密钥
public String apiV2Key = "***********************";
//读取证书pem文件获取私钥
public PrivateKey getPrivateKey() {
try {
return PemUtil.loadPrivateKey(new FileInputStream(privateKeyPath));
} catch (FileNotFoundException e) {
throw new RuntimeException("私钥不存在", e);
}
}
//下面三个是微信商户给出的获取支付签名的方法
//https://pay.weixin.qq.com/docs/merchant/sdk-tools/quickstart-java.html
public String getSign(String appId, String timestamp, String nonceStr, String pack) throws Exception{
String message = buildMessage(appId, timestamp, nonceStr, pack);
String paySign= sign(message.getBytes("utf-8"));
return paySign;
}
private String buildMessage(String appId, String timestamp, String nonceStr, String pack) {
return appId + "\n"
+ timestamp + "\n"
+ nonceStr + "\n"
+ pack + "\n";
}
private String sign(byte[] message) throws Exception{
Signature sign = Signature.getInstance("SHA256withRSA");
//这里需要一个PrivateKey类型的参数,就是商户的私钥。
//获取商户私钥
PrivateKey privateKey = getPrivateKey();
sign.initSign(privateKey);
sign.update(message);
return Base64.getEncoder().encodeToString(sign.sign());
}
}
实体类Entity.java文件
import lombok.Data;
@Data
public class Entity {
private Integer id;
private String order_no;
private String price;
private String card_name;
private String openid;
}
创建QuickStart.java文件,开始调用微信JSAPI支付
package *****************************;
import com.example.vue2_servers.entity.Entity;
import com.github.wxpay.sdk.WXPayUtil;
import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.service.payments.jsapi.JsapiService;
import com.wechat.pay.java.service.payments.jsapi.model.Amount;
import com.wechat.pay.java.service.payments.jsapi.model.Payer;
import com.wechat.pay.java.service.payments.jsapi.model.PrepayRequest;
import com.wechat.pay.java.service.payments.jsapi.model.PrepayResponse;
import lombok.extern.slf4j.Slf4j;
import okhttp3.HttpUrl;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.methods.HttpPost;
import org.jose4j.json.internal.json_simple.JSONObject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.security.PrivateKey;
import java.security.Signature;
import java.util.*;
@Slf4j
@RestController
@Controller
public class QuickStart {
// 注入创建的WxPayConfig.java读取配置信息
@Resource
private WxPayConfig wxPayConfig;
@PostMapping("/jsapi_pay")
public Map<String, Object> jsapi_pay(@RequestBody Entity entity) {
// 使用自动更新平台证书的RSA配置
// 一个商户号只能初始化一个配置,否则会因为重复的下载任务报错
Config config =
new RSAAutoCertificateConfig.Builder()
.merchantId(wxPayConfig.getMchId())
.privateKeyFromPath(wxPayConfig.getPrivateKeyPath())
.merchantSerialNumber(wxPayConfig.getMchSerialNo())
.apiV3Key(wxPayConfig.getApiV3Key())
.build();
// 构建service
JsapiService service = new JsapiService.Builder().config(config).build();
// request.setXxx(val)设置所需参数,具体参数可见Request定义
com.wechat.pay.java.service.payments.jsapi.model.PrepayRequest request = new PrepayRequest();
com.wechat.pay.java.service.payments.jsapi.model.Amount amount = new Amount();
//amount.setTotal(1); //金额,单位:分
amount.setTotal((int) (Double.parseDouble(entity.getPrice()) * 100)); //金额,单位:分,输入的是string类型金额,在这里转化为分并且转int类型
request.setAmount(amount);
request.setAppid(wxPayConfig.getAppid());
Payer payer = new Payer();
payer.setOpenid(entity.getOpenid());
request.setPayer(payer);
request.setMchid(wxPayConfig.getMchId());
request.setDescription(entity.getCard_name());
request.setNotifyUrl("https://url"); //通知地址,只能是https: 暂时随便填
request.setOutTradeNo(entity.getOrder_no());
// 调用下单方法,得到应答
PrepayResponse response = service.prepay(request);
Map<String, Object> map = new HashMap<>();
map.put("code", 200);
map.put("prepay_id", response.getPrepayId()); //微信支付接口返回的是prepay_id,为后续接口做准备
return map;
}
}