这篇文章只是说一下个人的实现思路,大家了解一下实现的思路就行了,并不是全流程可以粘贴复制就能用的案例,个人觉得整体比较麻烦的地方就是前期准备工作,你要去注册账号获取 商户ID 商户证书,商户证书下载后直接拉进项目里,后期需要读取证书里面的序列号。我放到resources下了,也就是我项目的所有的xml文件目录。放哪里都行。
1.前期准备
需要去微信公众平台注册账号,获取APPID 商户证书等参数,这里不细说了可以具体看以下链接:https://blog.csdn.net/qq_41693150/article/details/102488653
2.前期准备完成后,项目中需要导入微信的工具包,这是我自己用的包可以下载
链接:https://pan.baidu.com/s/1IO2Y3YQhN_hUCqXhrg9ksw
提取码:ABBS
下面是我的案例(我拿APP支付来说)官方API地址:https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_2_1.shtml
在这先说下我的实现逻辑,我做的是订单支付,订单的订单号、订单ID、用户手机号等等参数这些都不说了,这是你自己的东西跟微信没关系,你支付的时候只是需要把你的支付金额、订单号(自己生成的)调用微信支付接口的时候传过去就行了(还有微信官方上写的必填参数)。
看着微信的官方文档把需要的参数传过去就行了,微信也给的有官方示例
{
"mchid": "1900006XXX",
"out_trade_no": "APP1217752501201407033233368018",
"appid": "wxb4ba3c02aa476XXX",
"description": "Image形象店-深圳腾大-QQ公仔",
"notify_url": "https://weixin.qq.com/",
"amount": {
"total": 1,
"currency": "CNY"
}
}
上面的是官网的例子, 下面是我实现的例子,封装参数,读取证书里的序列号
orderNum:订单号,payMoney:支付金额,APP:app端支付(小程序就写成JSAPI),subject这个参数不用管 是我自己加了个识别的参数,ip:支付完成后微信回调的通知地址,openid:小程序支付的时候用。
resPayObj = WechatPayUtil.creatOrder_v3(orderNum, payMoney, "APP", subject, null,
"".equals(ip) ? "127.0.0.1" : ip, null,"");
public static JSONObject creatOrder_v3(String orderNum, BigDecimal total, String tradeType, String body, String detail, String ip, String openid, String appid) {
JSONObject json_param = new JSONObject();
JSONObject amount = new JSONObject();
JSONObject payer = new JSONObject();
DateTimeFormatter ldt = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
String URL = "";
if (StrKit.notBlank(openid)) {
URL = D1BusWebConfig.WECHAT_JSAPI_URL;
if(StrKit.isBlank(appid))appid = D1BusWebConfig.DD_WEHCAT_MINIPROGRAM_APPID;//小程序appid
json_param.put("appid", appid);
payer.put("openid",openid);
json_param.put("payer", payer);
}else if(tradeType.equals("H5")){
URL = D1BusWebConfig.WECHAT_H5_URL;
if(StrKit.isBlank(appid)) appid = D1BusWebConfig.DD_WECHAT_APPID;//应用ID
json_param.put("appid", appid);
} else {
URL = D1BusWebConfig.WECHAT_APP_URL;
if(StrKit.isBlank(appid)) appid = D1BusWebConfig.DD_WECHAT_APPID;//应用ID
json_param.put("appid", appid);
}
json_param.put("mchid", D1BusWebConfig.DD_WECHAT_MCH_ID);//直连商户号
if (StringUtils.isNotEmpty(detail)) {
json_param.put("description", detail);//商品描述
}else{
json_param.put("description", "订单支付");//商品描述
}
json_param.put("out_trade_no", orderNum);//商户订单编号
json_param.put("notify_url", D1BusWebConfig.WECHAT_CALLBLACK_ORDER_URL);// 通知URL必须为直接可访问的URL,不允许携带查询串。
//订单金额
amount.put("total", (int)(total.floatValue()*100));//订单总金额,单位为分。所以*100
amount.put("currency", "CNY");
json_param.put("amount", amount);
if(tradeType.equals("H5")){
JSONObject json = new JSONObject();
JSONObject js = new JSONObject();
json.put("payer_client_ip","127.0.0.1");
js.put("type","Wap");
json.put("h5_info",js);
json_param.put("scene_info", json);
}
String jsonStr = "";
JSONObject resObj = new JSONObject(16, true);
try {
//读取证书里的序列号,在调用微信支付的时候作为参数传过去
PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(
new FileInputStream(D1BusWebConfig.WEIXINPAY_PRIVATEKEY+"apiclient_key.pem"));
File file = new File(D1BusWebConfig.WEIXINPAY_certificate+"614DDE7717364EEBF4DBB95AC15A2623B256ACA4.pem");
BufferedReader br = new BufferedReader(new FileReader(file));//构造一个BufferedReader类来读取文件
String s = null;
StringBuilder result = new StringBuilder();
while((s = br.readLine())!=null){//使用readLine方法,一次读一行
result.append(System.lineSeparator()+s);
}
br.close();
String certificate = result.toString();
String preOrder = WXPayRequest.requestOncePOST(URL,
json_param.toJSONString(), D1BusWebConfig.DD_WECHAT_MCH_ID,D1BusWebConfig.WECHAT_MERCHANTSERIANUMBER,
merchantPrivateKey, certificate);
System.out.println(preOrder);
JSONObject json = (JSONObject) JSONObject.parse(preOrder);
if(json.getString("prepay_id") == null){
return resObj;
}
String prepay_id = json.getString("prepay_id");
if (StrKit.notBlank(openid)) {
resObj.put("appId", appid);
resObj.put("nonceStr", WXPayUtil.generateNonceStr());
resObj.put("package", "prepay_id=" + prepay_id);
resObj.put("signType", "MD5");
resObj.put("timeStamp", System.currentTimeMillis() / 1000 + "");
} else {
resObj.put("appid", appid);
resObj.put("noncestr", WXPayUtil.generateNonceStr());
resObj.put("package", "Sign=WXPay");
resObj.put("partnerid", D1BusWebConfig.DD_WECHAT_MCH_ID);
resObj.put("prepayid", prepay_id);// 预支付id
resObj.put("timestamp", System.currentTimeMillis() / 1000 + "");
}
resObj.put(WXPayConstants.FIELD_SIGN, createSign("UTF-8", resObj));
resObj.put("status", 1);
} catch (Exception e) {
Tools.LogOut("WechatPayUtil::creatOrder", "creatOrder_v3ERROR==" + e.toString());
}
Tools.LogOut("WechatPayUtil::creatOrder", "creatOrder_v3==" + resObj.toJSONString());
return resObj;
}
post方法
public static String requestOncePOST(String url, String data, String merchantId, String merchantSerialNumber,
PrivateKey merchantPrivateKey, String certificate ){
String res = "";
try {
Tools.LogOut("WXPayRequest::requestOncePOST", "url ==" + url + " \ndata ==" + data);
KeyFactory kf = KeyFactory.getInstance("RSA");
CertificateFactory cf = CertificateFactory.getInstance("X.509");
ArrayList<X509Certificate> listCertificates = (ArrayList<X509Certificate>) cf.generateCertificates(new ByteArrayInputStream(certificate.getBytes("utf-8")));
WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
.withMerchant(merchantId, merchantSerialNumber, merchantPrivateKey).withWechatpay(listCertificates);
CloseableHttpClient httpClient = builder.build();
HttpPost httpPost = new HttpPost(url);
InputStream stream = new ByteArrayInputStream(data.getBytes("utf-8"));
InputStreamEntity reqEntity = new InputStreamEntity(stream);
reqEntity.setContentType("application/json");
httpPost.setEntity(reqEntity);
httpPost.addHeader("Accept", "application/json");
CloseableHttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
res = EntityUtils.toString(httpEntity, "UTF-8");
Tools.LogOut("WXPayRequest::requestOncePOST", "url ==" + url + " \nres ==" + res);
} catch (Exception e) {
e.printStackTrace();
Tools.LogOut("WXPayRequest::requestOncePOST", "ERR ==" + e.toString());
}
return res;
}