这里主要涉及的是扫码支付以及公众号支付
需要遵循以下步骤:
1.请求生成支付订单
首先,您需要通过微信开放平台的API,向微信支付系统发送请求来生成一个支付订单。这可以通过向微信支付网关提交相关参数完成。
2.获得预付款ID
一旦您已经成功生成支付订单后,微信支付系统将会返回一个预付款ID,用于后续的支付操作。请注意,此时您还不能直接进行支付。
3.获取支付配置信息
接下来,您需要从微信支付系统中获取支付配置信息。这些信息包括微信商户ID、密钥等必要的信息。
4.调用微信支付系统完成支付
当您已经获取了以上信息之后,你就可以使用Java代码来调用微信支付系统来完成支付操作。这通常涉及到将相关参数传递给微信支付系统,并解析返回结果。
总体来说,在Java中实现微信支付可以通过使用微信支付SDK,或编写自己的代码来完成。但无论如何,都需要遵循微信支付系统的标准协议和规则,以确保顺利完成支付。
微信公众平台
微信商户平台
微信公众号开发文档
配置微信支付目录https://*.com/
配置微信公众号域名(业务域名、JS接口安全域名、网页授权域名)
商户证书采用apiclient_cert.p12 证书密码为商户号
(一) Native原生支付
Native原生支付即前文说的扫码支付,商户根据微信支付协议格式生成的二维码,用户通过微信“扫一扫”扫描二维码后即进入付款确认界面,输入密码即完成支付。
(二) JSAPI网页支付
JSAPI网页支付即公众号支付,可在微信公众号、朋友圈、聊天会话中点击页面链接,或者用微信“扫一扫”扫描页面地址二维码在微信中打开商户HTML5页面,在页面内下单完成支付。
开发前需要进行的配置:
(1)微信公众平台-开发配置
(2)微信商户平台-开发配置 设置回调url
支付代码:
(1)统一下单
public <T> T createOrder(@RequestBody WxPayUnifiedOrderRequest request, HttpServletRequest req, HttpServletResponse res) throws WxPayException {
logger.info("测试统一下单接口。。。。。。。");
String orderNo = DateUtil.getCurrentDateStr();//生成订单号
logger.info("请求信息:{},生成的订单号:{}",request,orderNo);
// 存储支付信息到数据库
//拼接必要参数
try {
orderInfoService.saveOrderInfo(orderDto);//暂不保存
} catch (Exception e) {
e.printStackTrace();
}
logger.info("即将下单的请求信息:{}",request);
return this.wxService.createOrder(request);
}
(2)根据code_url生成二维码
@PostMapping("/createCode")
public byte[] createScanPayQrcodeMode2(String code_url, File logoFile, Integer sideLength{
return this.wxService.createScanPayQrcodeMode2(codeUrl, null, 400);;
}
公众号支付
(1)获取用户授权,拿到openId;
链接地址:
https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
注意:
scope:设置为snsapi_base;
redirect_uri需要urlEncode处理;
redirect_uri:使用https链接来确保授权code的安全性。 一般为controller,拿到code后在其中做后续步骤,如wxpay.xxx.com/wechat/unifiedOrder
code:作为换取access_token的票据,每次用户授权带上的code将不一样,只能使用一次,5分钟未被使用自动过期。
(2)通过code换取网页授权access_token
在 wxpay.xxx.com/wechat/unifiedOrder Controller中做后续逻辑
String code = request.getParameter(“code”);
获取code后,请求以下链接获取access_token:
https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
代码如下:
public static AuthToken getTokenByAuthCode(String code) {
AuthToken authToken = null;
StringBuilder json = new StringBuilder();
try {
URL url = new URL(Constant.Authtoken_URL(code));
URLConnection urlConnection = url.openConnection();
urlConnection.connect();
BufferedReader in = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null) {
json.append(inputLine);
}
in.close();
// 将json文本转化为authToken对象
authToken = jsonToEntity(json.toString(), AuthToken.class);
} catch (IOException e) {
logger.error("*****获取access_token异常*****");
e.printStackTrace();
}
return authToken;
//json转换为实体类,AuthToken是返回数据的实体类
public static <T> T jsonToEntity(String jsonString, Class<T> entityType) {
T entity = null;
try {
entity = jsonObjectMapper.readValue(jsonString, entityType);
} catch (Exception e) {
logger.error("*****json转化异常*****");
e.printStackTrace();
}
return entity;
}
调用统一下单接口,获取参数值,传递给前台H5支付页面并调起支付
appId、timeStamp、nonceStr、prepayid、signType、paySign
前台JS代码如下:
function onBridgeReady() {
WeixinJSBridge.invoke(
'getBrandWCPayRequest',
{
"appId" : appId,
"timeStamp" : timeStamp,
"nonceStr" : nonceStr,
"package" : prepayId,
"signType" : "MD5",
"paySign" : paySign
},
function(res) {
if (res.err_msg == "get_brand_wcpay_request:ok") {
location.href = "xxxx";
} else {//这里支付失败和支付取消统一处理
location.href = "xxxxxx";
}
});
}
$(document).ready(
function() {
if (typeof WeixinJSBridge == "undefined") {
if (document.addEventListener) {
document.addEventListener('WeixinJSBridgeReady',
onBridgeReady, false);
} else if (document.attachEvent) {
document.attachEvent('WeixinJSBridgeReady',
onBridgeReady);
document.attachEvent('onWeixinJSBridgeReady',
onBridgeReady);
}
} else {
onBridgeReady();
}
});