微信小程序-授权登录-支付-退款

**

微信小程序-授权登录-支付-退款

**

简单的写一下,第一次写小程序支付退款的项目,纪念一下自己一路的学习过程。

微信小程序支付开发文档:https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=7_3&index=1

    /**
     * 微信授权时录入用户数据-需要前端发送一个code值,拿到code获取微信openid返回给前端换取用户信息。
     */
    @RequestMapping(value = "wxLogin")
    @ResponseBody
    @Transactional
    public Map<String,Object> insert(@RequestParam("code")String code, HttpSession session) throws ClientProtocolException, IOException {
        //返回map
        System.err.println("微信授权登录");
        System.err.println("code值: "+code);
        Map<String,Object> resultMap = new HashMap<>();
        String appid = WXPayConstants.APP_ID;
        String secret = WXPayConstants.SECRET;

        String loginUrl="https://api.weixin.qq.com/sns/jscode2session?appid="+appid+"&secret="+secret+"&js_code="+code+"&grant_type=authorization_code";
        try {
            CloseableHttpClient client = null;
            CloseableHttpResponse response = null;
            try {
                // 创建http GET请求
                HttpGet httpGet = new HttpGet(loginUrl);
                client = HttpClients.createDefault();
                // 执行请求
                response = client.execute(httpGet);
                HttpEntity entity = response.getEntity();//得到返回数据

                String result = EntityUtils.toString(entity);
                System.err.println("微信返回的结果"+result);

                resultMap.put("data", result);//进行封装
                System.err.println(resultMap);

                JSONObject json_test = JSONObject.parseObject(result);
                String wxOpenid = json_test.getString("openid");
                String sessionKey = json_test.getString("session_key");
                System.err.println("openid值: "+wxOpenid);//得到微信openID
                System.err.println("sessionKey值: "+sessionKey);
                WxUser user = wxUserService.selectByid(wxOpenid);//根据id数据库数据查询

                System.err.println("用户信息: "+user);

                if (user == null){//如果user等于null说明该用户第一次登录,数据库没有该用户信息。
                    resultMap.put("state", 2000);
                    resultMap.put("data", wxOpenid);
                    resultMap.put("sessionKey", sessionKey);
                    resultMap.put("message", "未查询到用户信息");
                }else {
                    resultMap.put("state", 2000);
                    resultMap.put("data", wxOpenid);//查找的用户信息进行封装返回
                    resultMap.put("sessionKey", sessionKey);
                    resultMap.put("user", user);//查找的用户信息进行封装返回
                    resultMap.put("message", "该用户已存在");
                    return resultMap;
                }
                if(StringUtils.isEmpty(wxOpenid)){
                    resultMap.put("state", 2000);
                    resultMap.put("message", "未获取到openid");
                    return resultMap;
                }
            } finally {
                if (response != null) {
                    response.close();
                }
                if (client != null) {
                    client.close();
                }

            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return resultMap;
    }

调用支付接口时需要注意的是需要:必须要开通微信小程序支付功能,拿到商户id和密钥。还需要小程序APPID和密钥。

	/*调用支付接口*/
	@RequestMapping("prePay")
	@ResponseBody
	public Map<String, Object> prePay(Integer id, HttpServletRequest request){

		// 返回参数
		Map<String, Object> resMap = new HashMap<>();


		//获取请求ip地址
		String ip = request.getHeader("x-forwarded-for");
		if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)){
			ip = request.getHeader("Proxy-Client-IP");
		}
		if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)){
			ip = request.getHeader("WL-Proxy-Client-IP");
		}
		if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)){
			ip = request.getRemoteAddr();
		}
		if(ip.indexOf(",")!=-1){
			String[] ips = ip.split(",");
			ip = ips[0].trim();
		}

		try {


			// 拼接统一下单地址参数
			Map<String, String> paraMap = new HashMap<>();

			Order order =  orderMapper.selectByPrimaryKey(id);
			String body = order.getHeader();//商品名称
			String orderNum = order.getOrdernum();//订单号
			String openId = order.getOpenid();
//			String price = order.getMoney();

			String price = "1";//支付金额,单位:分,这边需要转成字符串类型,否则后面的签名会失败


			// 封装11个必需的参数
			paraMap.put("appid", WXPayConstants.APP_ID);
			paraMap.put("mch_id", WXPayConstants.MCH_ID);//商家ID
			paraMap.put("nonce_str", WXPayUtil.generateNonceStr());//获取随机字符串 Nonce Str
			paraMap.put("body", body);     //商品名称
			paraMap.put("out_trade_no", orderNum);//订单号
			paraMap.put("total_fee",price);    //测试改为固定金额
			paraMap.put("spbill_create_ip", ip);
			paraMap.put("notify_url",WXPayConstants.CALLBACK_URL);// 此路径是微信服务器调用支付结果通知路径
			paraMap.put("trade_type", "JSAPI");
			paraMap.put("openid", openId);

			String sign = WXPayUtil.generateSignature(paraMap, WXPayConstants.PATERNER_KEY);//商户密码
			//生成签名. 注意,若含有sign_type字段,必须和signType参数保持一致。
			paraMap.put("sign", sign);

			//将所有参数(map)转xml格式
			String xml = WXPayUtil.mapToXml(paraMap);
			System.out.println("xml:"+xml);
			// 统一下单 https://api.mch.weixin.qq.com/pay/unifiedorder
			String unifiedorder_url = WXPayConstants.UNIFIEDORDER_URL;//统一下单接口
			System.out.println("unifiedorder_url:"+unifiedorder_url);
			//发送post请求"统一下单接口"返回预支付id:prepay_id
			String xmlStr = HttpClientUtil.sendPost(unifiedorder_url, xml);
			System.out.println("xmlStr:"+xmlStr);

			//以下内容是返回前端页面的json数据
			//预支付id
			String prepay_id = "";

			if (xmlStr.indexOf("SUCCESS") != -1) {
				Map<String, String> map = WXPayUtil.xmlToMap(xmlStr);//XML格式字符串转换为Map
				prepay_id =  map.get("prepay_id");
			}
			Map<String, String> payMap = new HashMap<String, String>();
			// 封装所需6个参数调支付页面
			payMap.put("appId", WXPayConstants.APP_ID);
			payMap.put("timeStamp", WXPayUtil.getCurrentTimestamp()+"");//获取当前时间戳,单位秒
			payMap.put("nonceStr", WXPayUtil.generateNonceStr());//获取随机字符串 Nonce Str
			payMap.put("signType", "MD5");
			payMap.put("package", "prepay_id=" + prepay_id);

			//生成带有 sign 的 XML 格式字符串
			String paySign = WXPayUtil.generateSignature(payMap, WXPayConstants.PATERNER_KEY);
			payMap.put("paySign", paySign);

			// 封装正常情况返回数据
			resMap.put("success",true);
			resMap.put("payMap",payMap);
		} catch (Exception e) {
			// 封装异常情况返回数据
			resMap.put("success",false);
			resMap.put("message","调用统一订单接口错误");
			e.printStackTrace();
		}
		return resMap;
	}

	/*支付成功回调*/
	@RequestMapping("callBack")
	public JsonResult callBack(HttpServletRequest request, HttpServletResponse response){
		JsonResult result = new JsonResult();
		System.err.println("微信支付成功,微信发送的callback信息,请注意修改订单信息");
		InputStream is = null;
		try {
			is = request.getInputStream();//获取请求的流信息(这里是微信发的xml格式所有只能使用流来读)
			String xml = WXPayUtil.inputStream2String(is);
			Map<String, String> notifyMap = WXPayUtil.xmlToMap(xml);//将微信发的xml转map

			if(notifyMap.get("return_code").equals("SUCCESS")){
				result.setData(SUCCESS);
				result.setData("支付回调成功,修改订单状态为支付成功");
				String ordersNum = notifyMap.get("out_trade_no");//商户订单号
				//处理订单状态
//				String openid = notifyMap.get("openid");
				Date zhifutime = new Date();
				Integer ordertype = 1;//1支付完成
				String complete = "待服务";
				try {
					orderMapper.updateByOrdersNum(ordersNum,ordertype,zhifutime,complete);

					//告诉微信服务器收到信息了,不要在调用回调action了========这里很重要回复微信服务器信息用流发送一个xml即可
					response.getWriter().write("");
					is.close();
				}catch (Exception e){
					result.setMessage("订单状态修改失败");
				}


			}

		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}

这些参数大家自己补把

public static final String APP_ID = "";//appid
public static final String MCH_ID = "";//商家ID
public static final String SECRET = "";//APP KEY
public static final String OPENID_URL = "https://api.weixin.qq.com/sns/oauth2/access_token";
public static final String NOTIFY_URL = "";//回调ip
public static final String UNIFIEDORDER_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder";//统一下单接口
public static final String CALLBACK_URL = "";//微信服务器调用支付结果通知路径
public static final String PATERNER_KEY = "";//商户key秘钥
/*退款*/
public static final String REFUND_URL = "https://api.mch.weixin.qq.com/secapi/pay/refund";//申请退款路径接口
public static final String notify_url = "";//微信服务器调用退款结果通知路径

退款和支付类似就不写了。

如果又不懂得可以私聊我。或者加QQ群:1126420499
微信小程序-授权登录-支付-退款_第1张图片


关注公众号:获取更多资源

你可能感兴趣的:(java后台)