700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 微信小程序支付(后台JAVA)

微信小程序支付(后台JAVA)

时间:2022-04-21 04:00:19

相关推荐

微信小程序支付(后台JAVA)

前台

//总结很多大神的文章,加上自己的一些理解,希望能帮到更多人,有问题可以评论,留言,看到后会回复

//钱是在后台管理里面配的,在前台页面通过字典取到

//调用微信的login方法,可以直接获取到code,发送code到后台获取openId, sessionKey, unionId

getCode: function () {var that = this;// 登录wx.login({success: function (res) {// 发送 res.code 到后台换取 openId, sessionKey, unionIdif (res.code) {console.log('获取用户登录态success!' + res.code)that.paypay(that, res.code);} else {console.log('获取用户登录态失败!' + res.errMsg)}}})},paypay(that, code) {var token = wx.getStorageSync('token');var memberId = wx.getStorageSync('memberId');var memberMoney = wx.getStorageSync('memberMoney')console.log(code);console.log("token" + token)console.log(memberMoney)wx.request({url: url,data: {code: code,memberId: memberId,price: memberMoney},header: {'content-type': 'application/x-www-form-urlencoded','Authorization': "Bearer " + token},success: function (res) {console.log(res);var result = JSON.parse(res.data.data)wx.requestPayment({'timeStamp': result.timeStamp,'nonceStr': result.nonceStr,'package': result.package,'signType': 'MD5','paySign': result.sign,'success': function (res) {if (res.errMsg == "requestPayment:ok") {that.setData({ showWhich: 2 })}},'fail': function (res) {}})},})},

后台

Controller

import com.alibaba.fastjson.JSON;import com.alibaba.fastjson.JSONObject;import com.github.wxpay.sdk.WXPayUtil;import io.swagger.annotations.Api;import lombok.AllArgsConstructor;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import javax.servlet.ServletInputStream;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.BufferedOutputStream;import java.io.BufferedReader;import java.io.InputStreamReader;import java.math.BigDecimal;import java.time.LocalDateTime;import java.time.format.DateTimeFormatter;import java.util.Map;/*** @date /9/27* <p>* 微信小程序接口*/@RestController@AllArgsConstructor@RequestMapping("/wechatApplet")@Api(value = "wechatApplet", description = "微信小程序接口")public class WechatAppletController {/*** 通过code获取用户openId* @param code 前台wx.login获取到code*/@GetMapping("/paypay")public R doUnifiedOrder(String code,String memberId,String price) {Map<String,String> map = WechatApplet.pay(code,price);String results = map.get("results");//更新订单,在数据库中先添加订单状态为未支付,在支付回调中订单状态改为已支付String orderNo = map.get("out_trade_no");BigDecimal money = new BigDecimal(price);//设置小数位数,第一个变量是小数位数,第二个变量是取舍方法(四舍五入)money = money.setScale(2, BigDecimal.ROUND_HALF_UP);BigDecimal fen = new BigDecimal(0.01);money = money.multiply(fen);MemberOrder order= new MemberOrder();order.setOrderNo(orderNo);order.setPrice(money);order.setPaymentMethod(Constant.PAY_WX);order.setStatus(Constant.ORDER_STATUS_TOPAY);order.setAmount(money);order.setOrderType("1");order.setIsCouponed("0");order.setCouponId("");order.setMemberId(memberId);memberOrderService.save(order);return new R<>(results);}/*** 支付回调* @param request* @param response* @throws InterruptedException*/@PostMapping("/notify")public synchronized void notify(HttpServletRequest request, HttpServletResponse response) throws InterruptedException{try {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为微信返回的xmlString notityXml = sb.toString();String resXml = "";Map map = WXPayUtil.xmlToMap(notityXml);String returnCode = (String) map.get("return_code");String orderNO = map.get("out_trade_no").toString();if("SUCCESS".equals(returnCode)){//验证签名是否正确Map<String, String> validParams = WechatAppletUtil.paraFilter(map); //回调验签时需要去除sign和空值参数String validStr = WechatAppletUtil.createLinkString(validParams);//把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串String sign = WechatAppletUtil.sign(validStr, WechatAppletConfig.API_KEY, "utf-8").toUpperCase();//拼装生成服务器端验证的签名//根据微信官网的介绍,此处不仅对回调的参数进行验签,还需要对返回的金额与系统订单的金额进行比对等if(sign.equals(map.get("sign"))){//此处为业务逻辑resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"+ "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";} else {System.out.println("微信支付回调失败!签名不一致");}}else{memberOrder.setStatus(Constant.ORDER_STATUS_PAYFAIL);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();} catch (Exception e) {// log.error(EPayError.PAY_NOTIFY_ERROR.getName(),orderId,e);}}}

WechatApplet

import com.alibaba.fastjson.JSON;import com.alibaba.fastjson.JSONObject;import com.github.wxpay.sdk.WXPayConstants;import com.github.wxpay.sdk.WXPayUtil;import javax.servlet.ServletInputStream;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.BufferedOutputStream;import java.io.BufferedReader;import java.io.InputStreamReader;import .InetAddress;import .UnknownHostException;import java.text.SimpleDateFormat;import java.time.LocalDateTime;import java.util.Date;import java.util.HashMap;import java.util.Map;import java.util.Random;/*** 微信小程序支付*/public class WechatApplet {/*** 小程序支付* @param code 前台wx.login获取到code* @return String*/public static Map<String,String> pay(String code,String price) {//登录凭证校验String requestUrl = "https://api./sns/jscode2session?appid="+ WechatAppletConfig.APPID +"&secret="+ WechatAppletConfig.APP_SECRET +"&js_code="+ code +"&grant_type=authorization_code";JSONObject jsonObject = PayCommonUtil.httpsRequest(requestUrl,"POST");String openid = jsonObject.get("openid").toString();String url = "https://api.mch./pay/unifiedorder";// String reqStr = getReqStr(openid);//组装预下单的请求数据Map<String,String> map = getReqStr(openid,price);String reqStr = map.get("req_body");String results = PayCommonUtil.httpsRequest(url,"POST",reqStr);//发送post数据到微信预下单Map<String,String> return_data = null;try {return_data = WXPayUtil.xmlToMap(results);//微信的一个工具类} catch (Exception e) {e.printStackTrace();}String return_code = return_data.get("return_code");if("SUCCESS".equals(return_code)){String prepay_id = return_data.get("prepay_id");//组装返回数据results = conPayParam(prepay_id);}else{results ="{\"return_code\":\"fail\"}";}map.put("results",results);return map;}//组装预下单的请求数据public static Map<String,String> getReqStr(String openid,String price){//获取本机的ip地址InetAddress addr = null;try {addr = InetAddress.getLocalHost();} catch (UnknownHostException e) {e.printStackTrace();}String spbill_create_ip = addr.getHostAddress();Map<String,String> data = new HashMap<String,String>();String out_trade_no = setTradeNo();//data.put("appid", WechatAppletConfig.APPID);data.put("mch_id",WechatAppletConfig.MCH_ID);data.put("nonce_str", WXPayUtil.generateNonceStr());data.put("sign_type", WechatAppletConfig.SIGN_TYPE);data.put("body", "");data.put("out_trade_no", out_trade_no);data.put("device_info", "");data.put("fee_type", "CNY");data.put("total_fee", price);data.put("spbill_create_ip", spbill_create_ip);data.put("notify_url", WechatAppletConfig.NOTIFY_URL);data.put("trade_type", "JSAPI");data.put("product_id", "12");data.put("openid", openid);try {String sign = WXPayUtil.generateSignature(data, WechatAppletConfig.API_KEY, WXPayConstants.SignType.MD5);data.put("sign", sign);} catch (Exception e) {e.printStackTrace();}String reqBody = null;try {reqBody = WXPayUtil.mapToXml(data);data.put("req_body",reqBody);} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}return data;}//保证唯一public static String setTradeNo(){SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMddHHmmss");String newDate = sdf.format(new Date());String result="";Random random=new Random();for(int i=0;i<3;i++){result+=random.nextInt(10);}String orderid = newDate + result;return orderid;}//组装返回客户端的请求数据public static String conPayParam(String prepayid){Long timeStamp = System.currentTimeMillis() / 1000;Map<String,String> map = new HashMap<String,String>();map.put("appId", WechatAppletConfig.APPID);LocalDateTime time = LocalDateTime.now();map.put("timeStamp", timeStamp + "");map.put("nonceStr", WXPayUtil.generateNonceStr());map.put("package", "prepay_id=" + prepayid);map.put("signType", "MD5");String sign;try {sign = WXPayUtil.generateSignature(map, WechatAppletConfig.API_KEY, WXPayConstants.SignType.MD5);map.put("sign", sign);} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}return JSON.toJSONString(map);}}

WechatAppletUtil

import mons.codec.digest.DigestUtils;import org.jdom.Document;import org.jdom.Element;import org.jdom.input.SAXBuilder;import java.io.*;import .HttpURLConnection;import .URL;import java.util.*;public class WechatAppletUtil {/*** 签名字符串* @param text 需要签名的字符串* @param key 密钥* @param input_charset 编码格式* @return 签名结果*/public static String sign(String text, String key, String input_charset) {text = text + "&key=" + key;return DigestUtils.md5Hex(getContentBytes(text, input_charset));}/*** 签名字符串* @param text 需要签名的字符串* @param sign 签名结果* @param key 密钥* @param input_charset 编码格式* @return 签名结果*/public static boolean verify(String text, String sign, String key, String input_charset) {text = text + key;String mysign = DigestUtils.md5Hex(getContentBytes(text, input_charset));if (mysign.equals(sign)) {return true;} else {return false;}}/*** @param content* @param charset* @return* @throws SignatureException* @throws UnsupportedEncodingException*/public static byte[] getContentBytes(String content, String charset) {if (charset == null || "".equals(charset)) {return content.getBytes();}try {return content.getBytes(charset);} catch (UnsupportedEncodingException e) {throw new RuntimeException("MD5签名过程中出现错误,指定的编码集不对,您目前指定的编码集是:" + charset);}}private static boolean isValidChar(char ch) {if ((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z')){return true;}if ((ch >= 0x4e00 && ch <= 0x7fff) || (ch >= 0x8000 && ch <= 0x952f)){return true;// 简体中文汉字编码}return false;}/*** 除去数组中的空值和签名参数* @param sArray 签名参数组* @return 去掉空值与签名参数后的新签名参数组*/public static Map<String, String> paraFilter(Map<String, String> sArray) {Map<String, String> result = new HashMap<String, String>();if (sArray == null || sArray.size() <= 0) {return result;}for (String key : sArray.keySet()) {String value = sArray.get(key);if (value == null || value.equals("") || key.equalsIgnoreCase("sign")|| key.equalsIgnoreCase("sign_type")) {continue;}result.put(key, value);}return result;}/*** 把数组所有元素排序,并按照“参数=参数值”的模式用“&”字符拼接成字符串* @param params 需要排序并参与字符拼接的参数组* @return 拼接后字符串*/public static String createLinkString(Map<String, String> params) {List<String> keys = new ArrayList<String>(params.keySet());Collections.sort(keys);String prestr = "";for (int i = 0; i < keys.size(); i++) {String key = keys.get(i);String value = params.get(key);if (i == keys.size() - 1) {// 拼接时,不包括最后一个&字符prestr = prestr + key + "=" + value;} else {prestr = prestr + key + "=" + value + "&";}}return prestr;}/**** @param requestUrl 请求地址* @param requestMethod 请求方法* @param outputStr 参数*/public static String httpRequest(String requestUrl,String requestMethod,String outputStr) {// 创建SSLContextStringBuffer buffer = null;try {URL url = new URL(requestUrl);HttpURLConnection conn = (HttpURLConnection) url.openConnection();conn.setRequestMethod(requestMethod);conn.setDoOutput(true);conn.setDoInput(true);conn.connect();//往服务器端写内容if (null != outputStr) {OutputStream os = conn.getOutputStream();os.write(outputStr.getBytes("utf-8"));os.close();}// 读取服务器端返回的内容InputStream is = conn.getInputStream();InputStreamReader isr = new InputStreamReader(is, "utf-8");BufferedReader br = new BufferedReader(isr);buffer = new StringBuffer();String line = null;while ((line = br.readLine()) != null) {buffer.append(line);}br.close();}catch(Exception e){e.printStackTrace();}return buffer.toString();}public static String urlEncodeUTF8(String source){String result=source;try {result=.URLEncoder.encode(source, "UTF-8");} catch (UnsupportedEncodingException e) {// TODO Auto-generated catch blocke.printStackTrace();}return result;}/*** 解析xml,返回第一级元素键值对。如果第一级元素有子节点,则此节点的值是子节点的xml数据。* @param strxml* @return* @throws JDOMException* @throws IOException*/public static Map doXMLParse(String strxml) throws Exception {if(null == strxml || "".equals(strxml)) {return null;}Map m = new HashMap();InputStream in = String2Inputstream(strxml);SAXBuilder builder = new SAXBuilder();Document doc = builder.build(in);Element root = doc.getRootElement();List list = root.getChildren();Iterator it = list.iterator();while(it.hasNext()) {Element e = (Element) it.next();String k = e.getName();String v = "";List children = e.getChildren();if(children.isEmpty()) {v = e.getTextNormalize();} else {v = getChildrenText(children);}m.put(k, v);}//关闭流in.close();return m;}/*** 获取子结点的xml* @param children* @return String*/public static String getChildrenText(List children) {StringBuffer sb = new StringBuffer();if(!children.isEmpty()) {Iterator it = children.iterator();while(it.hasNext()) {Element e = (Element) it.next();String name = e.getName();String value = e.getTextNormalize();List list = e.getChildren();sb.append("<" + name + ">");if(!list.isEmpty()) {sb.append(getChildrenText(list));}sb.append(value);sb.append("</" + name + ">");}}return sb.toString();}public static InputStream String2Inputstream(String str) {return new ByteArrayInputStream(str.getBytes());}}

WechatAppletConfig

/*** 微信小程序相关配置*/public class WechatAppletConfig {/*** APPID*/public final static String APPID = "";/*** 商户号*/public final static String MCH_ID = "";/*** AppSecret*/public final static String APP_SECRET = "";/*** API密钥*/public final static String API_KEY = "";/*** 签名加密方式*/public final static String SIGN_TYPE = "MD5";/*** 价格(分)*/public final static String MONEY = "1";/*** 内网穿透软件natapp* 支付回调地址(可先内网穿透,进行测试)*/public final static String NOTIFY_URL = "/controller/wechatApplet/notify";}

PayCommonUtil

import com.alibaba.fastjson.JSONObject;import .ssl.HttpsURLConnection;import .ssl.SSLContext;import .ssl.SSLSocketFactory;import .ssl.TrustManager;import javax.servlet.http.HttpServletRequest;import java.io.*;import java.math.BigDecimal;import .ConnectException;import .URL;import java.util.*;public class PayCommonUtil {/*** 发送https请求* @param requestUrl 请求地址* @param requestMethod 请求方式(GET、POST)* @param outputStr 提交的数据* @return 返回微信服务器响应的信息*/public static String httpsRequest(String requestUrl, String requestMethod, String outputStr) {try {// 创建SSLContext对象,并使用我们指定的信任管理器初始化TrustManager[] tm = { new MyX509TrustManager() };SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");sslContext.init(null, tm, new java.security.SecureRandom());// 从上述SSLContext对象中得到SSLSocketFactory对象SSLSocketFactory ssf = sslContext.getSocketFactory();URL url = new URL(requestUrl);HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();//conn.setSSLSocketFactory(ssf);conn.setDoOutput(true);conn.setDoInput(true);conn.setUseCaches(false);// 设置请求方式(GET/POST)conn.setRequestMethod(requestMethod);conn.setRequestProperty("content-type", "application/x-www-form-urlencoded");// 当outputStr不为null时向输出流写数据if (null != outputStr) {OutputStream outputStream = conn.getOutputStream();// 注意编码格式outputStream.write(outputStr.getBytes("UTF-8"));outputStream.close();}// 从输入流读取返回内容InputStream inputStream = conn.getInputStream();InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "UTF-8");BufferedReader bufferedReader = new BufferedReader(inputStreamReader);String str = null;StringBuffer buffer = new StringBuffer();while ((str = bufferedReader.readLine()) != null) {buffer.append(str);}// 释放资源bufferedReader.close();inputStreamReader.close();inputStream.close();inputStream = null;conn.disconnect();return buffer.toString();} catch (ConnectException ce) {//log.error("连接超时:{}", ce);} catch (Exception e) {//log.error("https请求异常:{}", e);}return null;}/*** 发送https请求** @param requestUrl 请求地址* @param requestMethod 请求方式(GET、POST)* @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)*/public static JSONObject httpsRequest(String requestUrl, String requestMethod) {JSONObject jsonObject = null;try {// 创建SSLContext对象,并使用我们指定的信任管理器初始化TrustManager[] tm = { new MyX509TrustManager() };SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");sslContext.init(null, tm, new java.security.SecureRandom());// 从上述SSLContext对象中得到SSLSocketFactory对象SSLSocketFactory ssf = sslContext.getSocketFactory();URL url = new URL(requestUrl);HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();//conn.setSSLSocketFactory(ssf);conn.setDoOutput(true);conn.setDoInput(true);conn.setUseCaches(false);conn.setConnectTimeout(3000);// 设置请求方式(GET/POST)conn.setRequestMethod(requestMethod);//conn.setRequestProperty("content-type", "application/x-www-form-urlencoded");// 当outputStr不为null时向输出流写数据// 从输入流读取返回内容InputStream inputStream = conn.getInputStream();InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "UTF-8");BufferedReader bufferedReader = new BufferedReader(inputStreamReader);String str = null;StringBuffer buffer = new StringBuffer();while ((str = bufferedReader.readLine()) != null) {buffer.append(str);}// 释放资源bufferedReader.close();inputStreamReader.close();inputStream.close();inputStream = null;conn.disconnect();jsonObject = JSONObject.parseObject(buffer.toString());} catch (ConnectException ce) {//log.error("连接超时:{}", ce);} catch (Exception e) {System.out.println(e);//log.error("https请求异常:{}", e);}return jsonObject;}}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。