1. 準備
首先導入jar包(maven導入jar包)
<dependency>
<groupId>com.github.wxpay</groupId>
<artifactId>wxpay-sdk</artifactId>
<version>0.0.3</version>
</dependency>
2. 配置類
import java.io.InputStream;
import com.github.wxpay.sdk.WXPayConfig;
import com.qx.rdes.wx.util.PropertiesUtils;
/**
* 配置類
*
* @author 豆漿油條
* @date
**/
public class MyConfig implements WXPayConfig {
@Override
public String getAppID() {
return "自己的appid";
}
public String getSecret() {
return "自己的祕鑰";
}
public String getNotifyUrl() {
return "回調地址";
}
@Override
public String getMchID() {
return "商戶號";
}
@Override
public String getKey() {
return "商戶祕鑰";
}
@Override
public InputStream getCertStream() {
return null;
}
@Override
public int getHttpConnectTimeoutMs() {
return 8000;
}
@Override
public int getHttpReadTimeoutMs() {
return 10000;
}
}
3. 代碼實現
1.微信統一下單接口
/**
* 微信統一下單接口
* @return
*/
@RequestMapping(value = "/doUnifiedOrder", method = RequestMethod.POST)
public synchronized Map doUnifiedOrder(HttpServletRequest request, HttpServletResponse response) {
// BaseResponse<Map> response = new BaseResponse<>();
Map resultMap=new HashMap();
String openid = "openid";
MyConfig config = null;
WXPay wxpay =null;
try {
config = new MyConfig();
wxpay= new WXPay(config);
} catch (Exception e) {
e.printStackTrace();
}
//生成的隨機字符串
String nonce_str = WXPayUtil.generateNonceStr();
//獲取客戶端的ip地址
//獲取本機的ip地址
InetAddress addr = null;
try {
addr = InetAddress.getLocalHost();
} catch (UnknownHostException e) {
e.printStackTrace();
}
String spbill_create_ip = addr.getHostAddress();
//支付金額,需要轉成字符串類型,否則後面的簽名會失敗
int total_fee= 100;
//商品描述
String body = "描述";
//商戶訂單號
// String out_trade_no= WXPayUtil.generateNonceStr();
String currTime = TenpayUtil.getCurrTime();
// 8位日期
String strTime = currTime.substring(8, currTime.length());
// 四位隨機數
String strRandom = TenpayUtil.buildRandom(4) + "";
// 10位序列號,可以自行調整。
String strReq = currTime + strRandom;
// 訂單號,此處用時間加隨機數生成,商戶根據自己情況調整,只要保持全局唯一就行
String out_trade_no = strReq;
//統一下單接口參數
HashMap<String, String> data = new HashMap<String, String>();
data.put("appid", config.getAppID());
data.put("mch_id", config.getMchID());
data.put("nonce_str", nonce_str);
data.put("body", body);
data.put("out_trade_no",out_trade_no);
data.put("total_fee", String.valueOf(total_fee));
data.put("spbill_create_ip", spbill_create_ip);
data.put("notify_url", config.getNotifyUrl());
data.put("trade_type","JSAPI");
data.put("openid", openid);
try {
Map<String, String> rMap = wxpay.unifiedOrder(data);
System.out.println("統一下單接口返回: " + rMap);
String return_code = (String) rMap.get("return_code");
String result_code = (String) rMap.get("result_code");
String nonceStr = WXPayUtil.generateNonceStr();
resultMap.put("nonceStr", nonceStr);
Long timeStamp = System.currentTimeMillis() / 1000;
if ("SUCCESS".equals(return_code) && return_code.equals(result_code)) {
String prepayid = rMap.get("prepay_id");
resultMap.put("package", "prepay_id="+prepayid);
resultMap.put("signType", "MD5");
//這邊要將返回的時間戳轉化成字符串,不然小程序端調用wx.requestPayment方法會報簽名錯誤
resultMap.put("timeStamp", timeStamp + "");
//再次簽名,這個簽名用於小程序端調用wx.requesetPayment方法
resultMap.put("appId",config.getAppID());
String sign = WXPayUtil.generateSignature(resultMap, config.getKey());
resultMap.put("paySign", sign);
System.out.println("生成的簽名paySign : "+ sign);
// response.setData(resultMap);
return resultMap;
}else{
resultMap.put("msg", "支付異常,請聯繫管理員");
return resultMap;
}
} catch (Exception e) {
e.printStackTrace();
resultMap.put("msg", "下單失敗!");
return resultMap;
}
}
2.支付回調
/**
* 微信小程序支付成功回調函數
* @param request
* @param response
* @throws Exception
*/
@RequestMapping(value = "/callback")
public void wxNotify(HttpServletRequest request,HttpServletResponse response) throws Exception{
BufferedReader br = new BufferedReader(new InputStreamReader((ServletInputStream)request.getInputStream()));
String line = null;
StringBuilder sb = new StringBuilder();
while((line = br.readLine()) != null){
sb.append(line);
}
br.close();
//sb爲微信返回的xml
String notityXml = sb.toString();
String resXml = "";
System.out.println("接收到的報文:" + notityXml);
MyConfig config = new MyConfig();
WXPay wxPay = new WXPay(config);
Map map = WXPayUtil.xmlToMap(notityXml);
String returnCode = (String) map.get("return_code");
//驗證簽名是否正確
if("SUCCESS".equals(returnCode)){
//回調驗籤時需要去除sign和空值參數
Map<String, String> validParams = WXPayUtil.paraFilter(map);
//把數組所有元素,按照“參數=參數值”的模式用“&”字符拼接成字符串
String validStr = PayUtil.createLinkString(validParams);
//拼裝生成服務器端驗證的簽名
String sign = PayUtil.sign(validStr, Configure.getKey(), "utf-8").toUpperCase();
// 因爲微信回調會有八次之多,所以當第一次回調成功了,那麼我們就不再執行邏輯了
//根據微信官網的介紹,此處不僅對回調的參數進行驗籤,還需要對返回的金額與系統訂單的金
//額進行比對等
if(sign.equals(map.get("sign"))){
/**此處添加自己的業務邏輯代碼start**/
// bla bla bla....
/**此處添加自己的業務邏輯代碼end**/
//通知微信服務器已經支付成功
resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
+ "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
} else {
System.out.println("微信支付回調失敗!簽名不一致");
}
}else{
resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
+ "<return_msg><![CDATA[報文爲空]]></return_msg>" + "</xml> ";
}
System.out.println(resXml);
System.out.println("微信支付回調數據結束");
BufferedOutputStream out = new BufferedOutputStream(
response.getOutputStream());
out.write(resXml.getBytes());
out.flush();
out.close();
}