微信小程序发起支付 Java后台处理代码----
直接上代码吧!
我把自己的业务逻辑代码删了,但是都有注释的 莫慌!
package com.mvc.controller;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.sf.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.mvc.entity.MoneyVo;
import com.mvc.entity.StudentVo;
import com.mvc.entity.TeacherVo;
import com.mvc.entity.TpayRecord;
import com.mvc.service.MoneyService;
import com.mvc.service.StudentService;
import com.mvc.service.TeacherService;
import com.mvc.service.TpayRecordService;
import com.mvc.util.DateUtil;
import com.mvc.util.StringofUtils;
import com.mvc.util.wxUtils.HttpRequest;
import com.mvc.util.wxUtils.IpUtils;
import com.mvc.util.wxUtils.StringUtils;
import com.mvc.util.wxUtils.weixin.PayUtil;
import com.mvc.util.wxUtils.weixin.config.WxPayConfig;
/**
* @Description: 本示例仅供参考,请根据自己的使用情景进行修改
* @Date: 2019-03-12
* @Author: gxp
*/
@Controller
@RequestMapping("/weixin")
public class WeixinController{
private static final String appid = "你自己的小程序appid"; //微信小程序appid
private static final String secret = "当然还是你自己的小程序密钥"; //微信小程序密钥
private static final String grant_type = "authorization_code";
// 这是我自己的Service
@Autowired
private TpayRecordService tpayRecordDao;
@Autowired
private MoneyService moneyService;
@Autowired
private StudentService studentService;
@Autowired
private TeacherService teacherService;
/**
* 小程序后台登录,向微信平台发送获取access_token请求,并返回openId
*
* @param code
* @return openid
* @throws WeixinException
* @throws IOException
*/
@RequestMapping("Wxlogin")
@ResponseBody
public Object login(HttpServletRequest request,HttpServletResponse response){
Map<String, Object> resultMap=new HashMap<String, Object>();
String code =request.getParameter("code");
if(StringofUtils.hasEmpty(code)){
resultMap.put("flag", false);
resultMap.put("msg", "业务参数不完整");
return resultMap;
}
//拼接参数
String param = "?grant_type=" + grant_type + "&appid=" + appid + "&secret=" + secret + "&js_code=" + code;
String sr = HttpRequest.sendGet("https://api.weixin.qq.com/sns/jscode2session", param);
// analysis request content
JSONObject json = JSONObject.fromObject(sr);
// getting open_id
String openId = json.get("openid").toString();
resultMap.put("flag", true);
resultMap.put("msg", "请求成功");
resultMap.put("data", openId);
return resultMap;
}
/**
* @Description: 发起微信支付
* @param openid
* @param request
* @author: gxp
*/
@RequestMapping("wxPay")
@ResponseBody
public Object wxPay(HttpServletRequest request,HttpServletResponse response){
Map<String, Object> resultMap=new HashMap<String, Object>();
String openid =request.getParameter("openid");
String campusCard =request.getParameter("campusCard");
String oldMeney=request.getParameter("oldMeney").toString();
String money = getMoney(oldMeney);//支付金额,单位:分,这边需要转成字符串类型,否则后面的签名会失败
String userId =request.getParameter("userId").toString();
String userType =request.getParameter("userType").toString();
if(StringofUtils.hasEmpty(openid,oldMeney,userId,userType,campusCard)){
resultMap.put("flag", false);
resultMap.put("msg", "业务参数不完整");
return resultMap;
}
try{
//生成的随机字符串
String nonce_str = StringUtils.getRandomStringByLength();
//商品名称
String body = "XX商品充值";
//获取本机的ip地址
String spbill_create_ip = IpUtils.getIpAddr(request);
String orderNo = nonce_str;
Map<String, String> packageParams = new HashMap<String, String>();
packageParams.put("appid", WxPayConfig.appid);
packageParams.put("body", body);
packageParams.put("mch_id", WxPayConfig.mch_id);
packageParams.put("nonce_str", nonce_str);
packageParams.put("notify_url", WxPayConfig.notify_url);
packageParams.put("openid", openid);
packageParams.put("out_trade_no", orderNo);//商户订单号
packageParams.put("spbill_create_ip", spbill_create_ip);
packageParams.put("total_fee", money);//支付金额,这边需要转成字符串类型,否则后面的签名会失败
packageParams.put("trade_type", WxPayConfig.TRADETYPE);
// 除去数组中的空值和签名参数
packageParams = PayUtil.paraFilter(packageParams);
String prestr = PayUtil.createLinkString(packageParams); // 把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串
//MD5运算生成签名,这里是第一次签名,用于调用统一下单接口
String mysign = PayUtil.sign(prestr, WxPayConfig.key, "utf-8").toUpperCase();
//拼接统一下单接口使用的xml数据,要将上一步生成的签名一起拼接进去
String xml = "<xml>" + "<appid>" + WxPayConfig.appid + "</appid>"
+ "<body><![CDATA[" + body + "]]></body>"
+ "<mch_id>" + WxPayConfig.mch_id + "</mch_id>"
+ "<nonce_str>" + nonce_str + "</nonce_str>"
+ "<notify_url>" + WxPayConfig.notify_url + "</notify_url>"
+ "<openid>" + openid + "</openid>"
+ "<out_trade_no>" + orderNo + "</out_trade_no>"
+ "<spbill_create_ip>" + spbill_create_ip + "</spbill_create_ip>"
+ "<total_fee>" + money + "</total_fee>"
+ "<trade_type>" + WxPayConfig.TRADETYPE + "</trade_type>"
+ "<sign>" + mysign + "</sign>"
+ "</xml>";
//调用统一下单接口,并接受返回的结果
String result = PayUtil.httpRequest(WxPayConfig.pay_url, "POST", xml);
// 将解析结果存储在HashMap中
Map map = PayUtil.doXMLParse(result);
String return_code = (String) map.get("return_code");//返回状态码
//返回给移动端需要的参数
Map<String, Object> responses = new HashMap<String, Object>();
if(return_code == "SUCCESS" || return_code.equals(return_code)){
// 业务结果
String prepay_id = (String) map.get("prepay_id");//返回的预付单信息
responses.put("nonceStr", nonce_str);
responses.put("package", "prepay_id=" + prepay_id);
Long timeStamp = System.currentTimeMillis() / 1000;
responses.put("timeStamp", timeStamp + "");//这边要将返回的时间戳转化成字符串,不然小程序端调用wx.requestPayment方法会报签名错误
String stringSignTemp = "appId=" + WxPayConfig.appid + "&nonceStr=" + nonce_str + "&package=prepay_id=" + prepay_id+ "&signType=" + WxPayConfig.SIGNTYPE + "&timeStamp=" + timeStamp;
//再次签名,这个签名用于小程序端调用wx.requesetPayment方法
String paySign = PayUtil.sign(stringSignTemp, WxPayConfig.key, "utf-8").toUpperCase();
responses.put("paySign", paySign);
//更新订单信息
//业务逻辑代码
}
responses.put("appid", WxPayConfig.appid);
resultMap.put("flag", true);
resultMap.put("msg", "发起支付成功");
resultMap.put("date",responses);
}catch(Exception e){
e.printStackTrace();
resultMap.put("flag", false);
resultMap.put("msg", "发起支付失败");
}
return resultMap;
}
/**
* @Description:微信支付
* @return
* @author gxp
* @throws Exception
* @throws WeixinException
*/
@RequestMapping(value="/wxNotify")
@ResponseBody
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 = "";
Map map = PayUtil.doXMLParse(notityXml);
String returnCode = (String) map.get("return_code");
String orderNo = (String) map.get("out_trade_no");
if("SUCCESS".equals(returnCode)){
//收到微信支付成功通知
resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
+ "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
//这里写你自己的业务逻辑代码
}else{
resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
+ "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
}
System.out.println("--------------微信回调---------------");
BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
out.write(resXml.getBytes());
out.flush();
out.close();
}
/**
* 元转换成分
* @param amount
* @return
*/
public static String getMoney(String amount) {
if(amount==null){
return "";
}
// 金额转化为分为单位
// 处理包含, ¥ 或者$的金额
String currency = amount.replaceAll("\\$|\\¥|\\,", "");
int index = currency.indexOf(".");
int length = currency.length();
Long amLong = 0l;
if(index == -1){
amLong = Long.valueOf(currency+"00");
}else if(length - index >= 3){
amLong = Long.valueOf((currency.substring(0, index+3)).replace(".", ""));
}else if(length - index == 2){
amLong = Long.valueOf((currency.substring(0, index+2)).replace(".", "")+0);
}else{
amLong = Long.valueOf((currency.substring(0, index+1)).replace(".", "")+"00");
}
return amLong.toString();
}
}
emm....剩下的工具类啥的 我直接发资源包你们下载吧!