微信支付後臺程式碼
阿新 • • 發佈:2019-02-03
/**
* @Title:getPayparams
* @Description:根據支付方式獲取相應的支付引數
* @param orderMain
* @param payType
* @param request
* @return
* @throws Exception Result<Map<String,Object>> 返回型別
*/
public Result<Map<String, Object>> getPayparams(OrderMain orderMain, String payType, HttpServletRequest request) throws Exception{
Result<Map<String, Object>> result = new Result<Map<String, Object>>();
switch (payType) {
case PaymentConst.PAY_METHOD_WECHACT://微信支付方式
result = getWechatPayparams(orderMain, request);
break;
case PaymentConst.PAY_METHOD_ALI://支付寶支付方式
break;
default:
break;
}
return result;
}
/**
* @Title:getWechatPayparams
* @Description:生成微信支付需要的引數
* @param orderMain
* @param request
* @return
* @throws Exception Result<Map<String,Object>> 返回型別
*/
public Result<Map<String, Object>> getWechatPayparams(OrderMain orderMain, HttpServletRequest request) throws Exception{
Result<Map<String, Object>> result = new Result<Map<String, Object>>();
//Map<String, Object> paramMap = new HashMap<String, Object>();
/*StringBuilder getCodeID = new StringBuilder();
getCodeID.append("https://open.weixin.qq.com/connect/oauth2/authorize?appid=");
getCodeID.append(PaymentConst.WECHAT_APPID);
getCodeID.append("&redirect_uri=" + authorizeNotifyUrl);
getCodeID.append("&response_type=code&scope=snsapi_base#wechat_redirect");
String openid = HttpClientUtil.post(getCodeID.toString(), "");
LOGGER.info("微信認證返回結果:"+openid);
LOGGER.info("終端ip:"+Util.getIpAddr(request));*/
/*if("".equals(openid)){
throw new MessageException("微信授權失敗");
}*/
String openid=request.getSession().getAttribute("bd").toString();
if("".equals(openid)){
LOGGER.info("微信支付openid為空重新認證wxUserAuth():"+openid);
wxUserAuth(request);
}
/*String openid=request.getSession().getAttribute("wxOpenid").toString();
if("".equals(openid)){
LOGGER.info("微信支付openid為空重新認證wxUserAuth():"+openid);
wxUserAuth(request);
}*/
System.out.println(openid+"3213213213213213214214214214");
TreeMap paramMap = new TreeMap();
paramMap.put("appid", PaymentConst.WECHAT_APPID);//公眾賬號ID
paramMap.put("mch_id", PaymentConst.WECHAT_MCHID);//商戶號
paramMap.put("nonce_str", Util.getRandomString(30, null));//隨機字串
paramMap.put("sign_type", PaymentConst.WECHAT_SIGNTYPE);//簽名型別
paramMap.put("body", "Melical Fee");//商品描述
paramMap.put("out_trade_no", orderMain.getNumber());//商戶訂單號
//交易金額預設為人民幣交易,介面中引數支付金額單位為【分】,引數值不能帶小數。
paramMap.put("total_fee", (int)(orderMain.getTotalamount()*100));//標價金額
paramMap.put("spbill_create_ip", Util.getIpAddr(request));//終端IP
paramMap.put("notify_url", weChatNotifyUrl);//通知地址
paramMap.put("trade_type", PaymentConst.WECHAT_TRADETYPE_JSAPI);//交易型別
paramMap.put("openid", openid);//使用者標識
paramMap.put("sign",Signature.createSign("UTF-8", paramMap));//簽名
LOGGER.info("簽名:"+paramMap.get("sign"));
//String response = HttpClientUtil.post(PaymentConst.wechatPayUrl, XMLUtils.simpleMapToXml(paramMap));
String response = HttpClientUtil.post(PaymentConst.wechatPayUrl,new String( XMLUtils.simpleMapToXml(paramMap).getBytes(), "UTF-8"));
System.out.println("預支付返回結果:"+response);
Map<String, String> resultParams = getWechatXmlToMap(response);
if (PaymentConst.WECHAT_STATUSCODE_FAIL.equals(resultParams.get("return_code"))){
throw new MessageException(resultParams.get("return_msg"));
}else{
if (PaymentConst.WECHAT_STATUSCODE_FAIL.equals(resultParams.get("result_code"))){
throw new MessageException(resultParams.get("return_msg"));
}else{
String prepay_id = resultParams.get("prepay_id");
TreeMap paramMap1 = new TreeMap();
paramMap1.put("appId", paramMap.get("appid"));//公眾賬號ID
String s = String.valueOf(Util.getSecond());
paramMap1.put("timeStamp", s);
paramMap1.put("nonceStr", Util.getRandomString(30, null));
paramMap1.put("package", "prepay_id="+prepay_id);//簽名型別
paramMap1.put("signType", paramMap.get("sign_type"));//簽名型別
paramMap1.put("sign1",Signature.createSign("UTF-8", paramMap1));//簽名
LOGGER.info("最終簽名:"+paramMap1.get("sign1"));
//生成前臺支付需要的資料
Map<String, Object> map = new HashMap<String, Object>();
map.put("appId", paramMap.get("appid"));
String s1 = String.valueOf(Util.getSecond());
map.put("timeStamp", s1);
map.put("nonceStr", Util.getRandomString(30, null));
map.put("package", "prepay_id="+prepay_id);
map.put("signType", paramMap.get("sign_type"));
map.put("paySign", paramMap1.get("sign1"));
System.out.println("tttttttttttttttttttttttttttttt9999999999999tttttttttttttttttttttttttttttttttttttt");
result.setT(map);
}
}
return result;
}
/**
* @Title:wxUserAuth
* @Description:微信認證
* @param request
* @return
* @return String 返回型別
*/
@RequestMapping(value = "/wxUserAuth", method ={RequestMethod.POST,RequestMethod.GET})
@ResponseBody
public Object wxUserAuth(HttpServletRequest request){
StringBuilder getCodeID = new StringBuilder();
getCodeID.append("https://open.weixin.qq.com/connect/oauth2/authorize?appid=");
getCodeID.append(PaymentConst.WECHAT_APPID);
getCodeID.append("&redirect_uri=" + authorizeNotifyUrl);
getCodeID.append("&response_type=code&scope=snsapi_base#wechat_redirect");
LOGGER.info("微信認證wxUserAuth:");
return getCodeID.toString();
}
/**
* @Title:getOpenId
* @Description:獲取openid----授權後重定向的回撥連結地址(獲取code後重定向到這裡)
* @param request
* @return String 返回型別
*/
@RequestMapping(value = "/authorizeNotify", method = RequestMethod.GET)
public void getOpenId(HttpServletRequest request){
String code = request.getParameter("code");
StringBuilder getOpenIDUrl = new StringBuilder();
getOpenIDUrl.append("https://api.weixin.qq.com/sns/oauth2/access_token?appid=");
getOpenIDUrl.append(PaymentConst.WECHAT_APPID);
getOpenIDUrl.append("&secret=" + PaymentConst.WECHAT_PUBLICKEY);
getOpenIDUrl.append("&code=");
getOpenIDUrl.append(code);
getOpenIDUrl.append("&grant_type=authorization_code");
String openIDResponse = HttpClientUtil.sendGetRequest(getOpenIDUrl.toString(), "UTF-8");
LOGGER.info("微信認證authorizeNotify返回結果:"+openIDResponse);
ObjectMapper mapper = new ObjectMapper();
Map<String, Object> params = new HashMap<String,Object>();
String openid = "";
try {
params = mapper.readValue(openIDResponse, Map.class);
if(!params.containsKey("errcode")){
openid = Util.getMapString(params, "openid");
}
} catch (IOException e) {
LOGGER.error("獲取openid異常" ,e);
}
request.getSession().setAttribute("wxOpenid", openid);
}
/**
* @Title:weixinPayBack
* @Description:支付回撥(微信支付)
* @param request
* @return String 返回型別
*/
@RequestMapping(value="/weiXinPayNotify")
public String weixinPayBack(HttpServletRequest request){
try {
InputStream inStream = request.getInputStream();
ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = 0;
while ((len = inStream.read(buffer)) != -1) {
outSteam.write(buffer, 0, len);
}
outSteam.close();
inStream.close();
String resultStr = new String(outSteam.toByteArray(),"utf-8");
System.out.println("微信支付的回撥:"+resultStr);
Map<String, String> resultMap = getWechatXmlToMap(resultStr);
String return_code = resultMap.get("return_code");
if("SUCCESS".equals(return_code)){
//檢驗API返回的資料裡面的簽名是否合法,避免資料在傳輸的過程中被第三方篡改
if(!Signature.checkIsSignValidFromResponseString(resultStr)){
throw new MessageException("微信回撥引數簽名不合法");
}
String result_code = resultMap.get("result_code");
if("SUCCESS".equals(result_code)){
//支付成功的業務邏輯
String out_trade_no = resultMap.get("out_trade_no");
OrderMain orderMain = orderMainService.findUniqueByProperty("number", out_trade_no);
//修改訂單狀態為已付款
if (null!=orderMain.getStatus()) {
if ("10".equals(orderMain.getStatus())){
orderMainService.updateOrderStatus(out_trade_no, "20");
}
}
//通知微信.非同步確認成功.必寫.不然微信會一直通知後臺.八次之後就認為交易失敗了.
return "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
}
}
} catch (Exception e) {
LOGGER.error(e.getMessage() ,e);
}
return "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[ERROR]]></return_msg></xml>";
}
/**
* @Title:getWechatXmlToMap
* @Description:微信返回xml結果轉為Map
* @param result
* @return
* @throws Exception Map<String,String> 返回型別
*/
private Map<String, String> getWechatXmlToMap(String result) throws Exception{
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser();
XMLHandler xmlHandler = new XMLHandler();
parser.parse(new ByteArrayInputStream(result.getBytes("UTF-8")), xmlHandler);
return xmlHandler.getParams();
}
* @Title:getPayparams
* @Description:根據支付方式獲取相應的支付引數
* @param orderMain
* @param payType
* @param request
* @return
* @throws Exception Result<Map<String,Object>> 返回型別
*/
public Result<Map<String, Object>> getPayparams(OrderMain orderMain, String payType, HttpServletRequest request) throws Exception{
Result<Map<String, Object>> result = new Result<Map<String, Object>>();
switch (payType) {
case PaymentConst.PAY_METHOD_WECHACT://微信支付方式
result = getWechatPayparams(orderMain, request);
break;
case PaymentConst.PAY_METHOD_ALI://支付寶支付方式
break;
default:
break;
}
return result;
}
/**
* @Title:getWechatPayparams
* @Description:生成微信支付需要的引數
* @param orderMain
* @param request
* @return
* @throws Exception Result<Map<String,Object>> 返回型別
*/
public Result<Map<String, Object>> getWechatPayparams(OrderMain orderMain, HttpServletRequest request) throws Exception{
Result<Map<String, Object>> result = new Result<Map<String, Object>>();
//Map<String, Object> paramMap = new HashMap<String, Object>();
/*StringBuilder getCodeID = new StringBuilder();
getCodeID.append("https://open.weixin.qq.com/connect/oauth2/authorize?appid=");
getCodeID.append(PaymentConst.WECHAT_APPID);
getCodeID.append("&redirect_uri=" + authorizeNotifyUrl);
getCodeID.append("&response_type=code&scope=snsapi_base#wechat_redirect");
String openid = HttpClientUtil.post(getCodeID.toString(), "");
LOGGER.info("微信認證返回結果:"+openid);
LOGGER.info("終端ip:"+Util.getIpAddr(request));*/
/*if("".equals(openid)){
throw new MessageException("微信授權失敗");
}*/
String openid=request.getSession().getAttribute("bd").toString();
if("".equals(openid)){
LOGGER.info("微信支付openid為空重新認證wxUserAuth():"+openid);
wxUserAuth(request);
}
/*String openid=request.getSession().getAttribute("wxOpenid").toString();
if("".equals(openid)){
LOGGER.info("微信支付openid為空重新認證wxUserAuth():"+openid);
wxUserAuth(request);
}*/
System.out.println(openid+"3213213213213213214214214214");
TreeMap paramMap = new TreeMap();
paramMap.put("appid", PaymentConst.WECHAT_APPID);//公眾賬號ID
paramMap.put("mch_id", PaymentConst.WECHAT_MCHID);//商戶號
paramMap.put("nonce_str", Util.getRandomString(30, null));//隨機字串
paramMap.put("sign_type", PaymentConst.WECHAT_SIGNTYPE);//簽名型別
paramMap.put("body", "Melical Fee");//商品描述
paramMap.put("out_trade_no", orderMain.getNumber());//商戶訂單號
//交易金額預設為人民幣交易,介面中引數支付金額單位為【分】,引數值不能帶小數。
paramMap.put("total_fee", (int)(orderMain.getTotalamount()*100));//標價金額
paramMap.put("spbill_create_ip", Util.getIpAddr(request));//終端IP
paramMap.put("notify_url", weChatNotifyUrl);//通知地址
paramMap.put("trade_type", PaymentConst.WECHAT_TRADETYPE_JSAPI);//交易型別
paramMap.put("openid", openid);//使用者標識
paramMap.put("sign",Signature.createSign("UTF-8", paramMap));//簽名
LOGGER.info("簽名:"+paramMap.get("sign"));
//String response = HttpClientUtil.post(PaymentConst.wechatPayUrl, XMLUtils.simpleMapToXml(paramMap));
String response = HttpClientUtil.post(PaymentConst.wechatPayUrl,new String( XMLUtils.simpleMapToXml(paramMap).getBytes(), "UTF-8"));
System.out.println("預支付返回結果:"+response);
Map<String, String> resultParams = getWechatXmlToMap(response);
if (PaymentConst.WECHAT_STATUSCODE_FAIL.equals(resultParams.get("return_code"))){
throw new MessageException(resultParams.get("return_msg"));
}else{
if (PaymentConst.WECHAT_STATUSCODE_FAIL.equals(resultParams.get("result_code"))){
throw new MessageException(resultParams.get("return_msg"));
}else{
String prepay_id = resultParams.get("prepay_id");
TreeMap paramMap1 = new TreeMap();
paramMap1.put("appId", paramMap.get("appid"));//公眾賬號ID
String s = String.valueOf(Util.getSecond());
paramMap1.put("timeStamp", s);
paramMap1.put("nonceStr", Util.getRandomString(30, null));
paramMap1.put("package", "prepay_id="+prepay_id);//簽名型別
paramMap1.put("signType", paramMap.get("sign_type"));//簽名型別
paramMap1.put("sign1",Signature.createSign("UTF-8", paramMap1));//簽名
LOGGER.info("最終簽名:"+paramMap1.get("sign1"));
//生成前臺支付需要的資料
Map<String, Object> map = new HashMap<String, Object>();
map.put("appId", paramMap.get("appid"));
String s1 = String.valueOf(Util.getSecond());
map.put("timeStamp", s1);
map.put("nonceStr", Util.getRandomString(30, null));
map.put("package", "prepay_id="+prepay_id);
map.put("signType", paramMap.get("sign_type"));
map.put("paySign", paramMap1.get("sign1"));
System.out.println("tttttttttttttttttttttttttttttt9999999999999tttttttttttttttttttttttttttttttttttttt");
result.setT(map);
}
}
return result;
}
/**
* @Title:wxUserAuth
* @Description:微信認證
* @param request
* @return
* @return String 返回型別
*/
@RequestMapping(value = "/wxUserAuth", method ={RequestMethod.POST,RequestMethod.GET})
@ResponseBody
public Object wxUserAuth(HttpServletRequest request){
StringBuilder getCodeID = new StringBuilder();
getCodeID.append("https://open.weixin.qq.com/connect/oauth2/authorize?appid=");
getCodeID.append(PaymentConst.WECHAT_APPID);
getCodeID.append("&redirect_uri=" + authorizeNotifyUrl);
getCodeID.append("&response_type=code&scope=snsapi_base#wechat_redirect");
LOGGER.info("微信認證wxUserAuth:");
return getCodeID.toString();
}
/**
* @Title:getOpenId
* @Description:獲取openid----授權後重定向的回撥連結地址(獲取code後重定向到這裡)
* @param request
* @return String 返回型別
*/
@RequestMapping(value = "/authorizeNotify", method = RequestMethod.GET)
public void getOpenId(HttpServletRequest request){
String code = request.getParameter("code");
StringBuilder getOpenIDUrl = new StringBuilder();
getOpenIDUrl.append("https://api.weixin.qq.com/sns/oauth2/access_token?appid=");
getOpenIDUrl.append(PaymentConst.WECHAT_APPID);
getOpenIDUrl.append("&secret=" + PaymentConst.WECHAT_PUBLICKEY);
getOpenIDUrl.append("&code=");
getOpenIDUrl.append(code);
getOpenIDUrl.append("&grant_type=authorization_code");
String openIDResponse = HttpClientUtil.sendGetRequest(getOpenIDUrl.toString(), "UTF-8");
LOGGER.info("微信認證authorizeNotify返回結果:"+openIDResponse);
ObjectMapper mapper = new ObjectMapper();
Map<String, Object> params = new HashMap<String,Object>();
String openid = "";
try {
params = mapper.readValue(openIDResponse, Map.class);
if(!params.containsKey("errcode")){
openid = Util.getMapString(params, "openid");
}
} catch (IOException e) {
LOGGER.error("獲取openid異常" ,e);
}
request.getSession().setAttribute("wxOpenid", openid);
}
/**
* @Title:weixinPayBack
* @Description:支付回撥(微信支付)
* @param request
* @return String 返回型別
*/
@RequestMapping(value="/weiXinPayNotify")
public String weixinPayBack(HttpServletRequest request){
try {
InputStream inStream = request.getInputStream();
ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = 0;
while ((len = inStream.read(buffer)) != -1) {
outSteam.write(buffer, 0, len);
}
outSteam.close();
inStream.close();
String resultStr = new String(outSteam.toByteArray(),"utf-8");
System.out.println("微信支付的回撥:"+resultStr);
Map<String, String> resultMap = getWechatXmlToMap(resultStr);
String return_code = resultMap.get("return_code");
if("SUCCESS".equals(return_code)){
//檢驗API返回的資料裡面的簽名是否合法,避免資料在傳輸的過程中被第三方篡改
if(!Signature.checkIsSignValidFromResponseString(resultStr)){
throw new MessageException("微信回撥引數簽名不合法");
}
String result_code = resultMap.get("result_code");
if("SUCCESS".equals(result_code)){
//支付成功的業務邏輯
String out_trade_no = resultMap.get("out_trade_no");
OrderMain orderMain = orderMainService.findUniqueByProperty("number", out_trade_no);
//修改訂單狀態為已付款
if (null!=orderMain.getStatus()) {
if ("10".equals(orderMain.getStatus())){
orderMainService.updateOrderStatus(out_trade_no, "20");
}
}
//通知微信.非同步確認成功.必寫.不然微信會一直通知後臺.八次之後就認為交易失敗了.
return "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
}
}
} catch (Exception e) {
LOGGER.error(e.getMessage() ,e);
}
return "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[ERROR]]></return_msg></xml>";
}
/**
* @Title:getWechatXmlToMap
* @Description:微信返回xml結果轉為Map
* @param result
* @return
* @throws Exception Map<String,String> 返回型別
*/
private Map<String, String> getWechatXmlToMap(String result) throws Exception{
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser();
XMLHandler xmlHandler = new XMLHandler();
parser.parse(new ByteArrayInputStream(result.getBytes("UTF-8")), xmlHandler);
return xmlHandler.getParams();
}