微信jsapi支付过程
·
1、获取用户openId
- 需要在微信公众平台获取appId,appSecret。
- 前端获取code,传入后端调用获取openId
var fullUrl = window.location.href; // 就是当前页面的url
const oriCode = urlParams.get('code');
if (!oriCode) {
// 第一次访问,后端会重定向到微信获取 code
var oriRedrictUrl = encodeURIComponent(fullUrl).replace(/!/g, '%21').replace(/'/g, '%27').replace(/\(/g, '%28').replace(/\)/g, '%29').replace(/\*/g, '%2A').replace(/%20/g, '+');
var CodeUrl = "https://open.weixin.qq.com/connect/oauth2/authorize"
+ "?appid=" + this.merchantSettings.userAppId //即微信公众平台appId
+ "&redirect_uri=" + oriRedrictUrl
+ "&response_type=code"
+ "&scope=snsapi_base"
+ "&state=1"
+ "&connect_redirect=1#wechat_redirect";
window.location.href = CodeUrl;
} else {
// 已有 code → 请求后端接口直接拿 openid
const codeData = {
userId: this.userId,
code: oriCode
};
const response = await getUserOpenId(codeData);
if (response && response.code === 200 && response.data) {
// 后端返回的是微信用户的 openid
this.openId = response.data;
}
}
public String getOpenId(String userId, String code) throws JsonProcessingException {
String url = UriComponentsBuilder.fromHttpUrl("https://api.weixin.qq.com/sns/oauth2/access_token?")
.queryParam("appid",webAppConfig.getAppId() )//微信公众平台appId
.queryParam("secret", webAppConfig.getAppSecret()) //微信公众平台appSecret
.queryParam("code", code)
.queryParam("grant_type", "authorization_code")
.toUriString();
// 微信返回的是 JSON
String responseStr = restTemplate.getForObject(url, String.class);
ObjectMapper objectMapper = new ObjectMapper();
Map<String, Object> resp = objectMapper.readValue(responseStr, Map.class);
if (resp != null && resp.get("openid") != null) {
return resp.get("openid").toString();
} else {
return null;
}
}
2、正常支付
- 使用https://pay.weixin.qq.com/doc/global/v3/zh/4012354174的客户端初始化。
public void init(String merchantId,PrivateKey merchantPrivateKey,String merchantSerialNumber, String apiV3Key) throws Exception {
certificatesManager = CertificatesManager.getInstance();
certificatesManager.putMerchant(
merchantId,
new WechatPay2Credentials(
merchantId,
new PrivateKeySigner(merchantSerialNumber, merchantPrivateKey)
),
apiV3Key.getBytes(StandardCharsets.UTF_8)
);
verifier = certificatesManager.getVerifier(merchantId);
WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
.withMerchant(merchantId, merchantSerialNumber, merchantPrivateKey)
.withValidator(new WechatPay2Validator(verifier));
httpClient = builder.build();
}
- 使用https://pay.weixin.qq.com/doc/v3/merchant/4012791856的url进行请求,签名参考https://pay.weixin.qq.com/doc/global/v3/zh/4013014169这里的,转换为对应代码实现方式即可,apiV3和私钥等在https://pay.weixin.qq.com/index.php/core/home/login申请。
public MarketingPayVo wxH5Pay(String userId, String finalAmount, String openid) throws Exception {
WechatMarketingSettings queryCondition = new WechatMarketingSettings();
queryCondition.setUserId(String.valueOf(userId));
WechatMarketingSettings settings = settingsMapper.selectOne(queryCondition);
PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(settings.getPaymentKey());
init(settings.getMerchantId() ,merchantPrivateKey, settings.getMerchantserialnumber(), settings.getApiv3key());
Integer totalAmount = Integer.valueOf((int) (Double.valueOf(finalAmount)*100));
long timestampSeconds = System.currentTimeMillis() / 1000;
String outTradeNo = userId + System.currentTimeMillis(); // 用户ID+时间戳
// 1. 构造请求体
Map<String, Object> body = new HashMap<>();
body.put("appid", webAppConfig.getAppId());
body.put("mchid", settings.getMerchantId());
body.put("out_trade_no", outTradeNo);
body.put("description", "Image形象店-深圳腾大-QQ公仔");
body.put("notify_url", "xxxxxx");
Map<String, String> payer = new HashMap<>();
payer.put("openid", openid);
body.put("payer", payer);
Map<String, Object> amount = new HashMap<>();
amount.put("total", totalAmount); // 整数
amount.put("currency", "CNY");
body.put("amount", amount);
String jsonBody = new ObjectMapper().writeValueAsString(body);
// 2. 构造 POST 请求
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");
httpPost.setEntity(new StringEntity(jsonBody));
CloseableHttpResponse response = httpClient.execute(httpPost);
String responseString = EntityUtils.toString(response.getEntity(), "UTF-8");
// 4. 解析响应
JSONObject jsonObject = JSONObject.parseObject(responseString);
MarketingPayVo marketingPayVo = new MarketingPayVo();
marketingPayVo.setAppId(webAppConfig.getAppId());
marketingPayVo.setTimeStamp(String.valueOf(timestampSeconds));
marketingPayVo.setSignType("RSA");
marketingPayVo.setNonceStr(getNonceStr());
marketingPayVo.setPkg("prepay_id="+jsonObject.get("prepay_id"));
marketingPayVo.setPaySign(generatePaySign(marketingPayVo.getAppId(),String.valueOf(timestampSeconds),marketingPayVo.getNonceStr(),marketingPayVo.getPkg(),merchantPrivateKey));
return marketingPayVo;
}
更多推荐




所有评论(0)