微信小程序支付 Java后端代码详解

微信小程序发起支付 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....剩下的工具类啥的 我直接发资源包你们下载吧!

https://download.csdn.net/download/qq_19385067/12244077

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值