java微信小程序支付

微信支付的流程:统一下单----->前端支付------>支付回调
流程很简单首先先看下官方统一下单文档:
官方文档:https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_1

在这里插入图片描述
官方统一下单接口,只需要我们后端调用这个接口就能完成统一下单,接下来是参数:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
参数中有必传和非必传根据我们的需要选定好参数,我做的是小程序所以我需要的参数都有:

					"<xml>"
                    +"<appid>小程序appid</appid>"
                    +"<mch_id>商户号</mch_id>"
                    +"<nonce_str>"+nonce_str+"</nonce_str>"
                    +"<body>支付测试</body>"
                    +"<out_trade_no>"+id+"</out_trade_no>"
                    +"<total_fee>1</total_fee>"
                    +"<spbill_create_ip>终端IP</spbill_create_ip>"
                    +"<notify_url>"+notify_url+"</notify_url>"
                    +"<trade_type>JSAPI</trade_type>"
                    +"<openid>"+openid+"</openid>"
                    +"<sign>"+sign+"</sign>"
                    +"</xml>";

这是最后传的参数,微信支付的参数和返回值都是xml格式

下面上代码
用的pom依赖

		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
			<version>1.2.48</version>
		</dependency>
		<dependency>
			<groupId>dom4j</groupId>
			<artifactId>dom4j</artifactId>
			<version>1.6.1</version>
		</dependency>

主体方法

@Override
    public JSONObject payOrder(String id,String openid) {
        String nonce_str= UUID.randomUUID().toString().replace("-", "");//32位随机数我直接用的uuid
        String notify_url = "https://localhost:1013/pay_back";//微信回调的地址,必须是外网能直接访问的https接口
        String sign = sign("wx161332eed75bbba8","1521752201",nonce_str,"支付测试",
                id,"1","47.92.254.214",notify_url,"JSAPI",openid);//签名方法
        String aa ="<xml>"
                    +"<appid>小程序appid</appid>"
                    +"<mch_id>商户号</mch_id>"
                    +"<nonce_str>"+nonce_str+"</nonce_str>"
                    +"<body>支付测试</body>"
                    +"<out_trade_no>"+id+"</out_trade_no>"
                    +"<total_fee>1</total_fee>"
                    +"<spbill_create_ip>47.92.254.214</spbill_create_ip>"
                    +"<notify_url>"+notify_url+"</notify_url>"
                    +"<trade_type>JSAPI</trade_type>"
                    +"<openid>"+openid+"</openid>"
                    +"<sign>"+sign+"</sign>"
                    +"</xml>";
        String bb = HttpClientUtil.doPostJson("https://api.mch.weixin.qq.com/pay/unifiedorder",aa);//请求微信统一下单接口 这样统一下单就完成了 如果成功会返回我们支付时候需要的值,将前端支付需要的值返回就可以了
        System.out.println(bb.toString());
        //返回值是xml格式,所以要进行转化
        Document doc = null;
        try {
            doc = DocumentHelper.parseText(bb);
        } catch (DocumentException e) {
            e.printStackTrace();
        }
        Map<String,String> map = new HashMap<>();
        Element root = doc.getRootElement();
        //前端发起支付的需要的签名
        String paySign = paySing("小程序appid",String.valueOf(new Date().getTime()),
                UUID.randomUUID().toString().replace("-", ""),root.element("prepay_id").getTextTrim(),
                "MD5");
        map.put("package","prepay_id="+root.element("prepay_id").getTextTrim());//统一下单返回的预支付交易会话标识
        map.put("timeStamp", String.valueOf(new Date().getTime()));//时间戳
        map.put("nonceStr", UUID.randomUUID().toString().replace("-", ""));//随机字符串
        map.put("signType", "MD5");//加密方式
        map.put("paySign", paySign);//前端发起支付的签名
        //打包返回给前端
        JSONObject end = new JSONObject();
        end.put("status","200");
        end.put("prepay_order",map);
        end.put("order_id",id);
        return end;
    }

同意下签名方法

//统一下单签名算法
    private String sign(String appid,String mch_id,String nonce_str,String body,String out_trade_no,
                        String total_fee,String spbill_create_ip,String notify_url,String trade_type,String openid){
        String A="appid="+appid+"&body="+body+"&mch_id="+mch_id+"&nonce_str="+nonce_str+"&notify_url="+notify_url+
                "&openid="+openid+"&out_trade_no="+out_trade_no+"&spbill_create_ip="+spbill_create_ip+"&total_fee="+
                total_fee+"&trade_type="+trade_type;
        String SignTemp=A+"&key=sfsdf34534wrrewergdfghrty4564564";
        String sign = MD5Util.getMD5(SignTemp).toUpperCase();
        return sign;
    }

发起支付签名算法

 //发起支付签名算法
    private String paySing(String appid,String timeStamp,String nonceStr,String prepay_id,String signType){
        String A = "appid="+appid+"&nonceStr="+nonceStr+"&package="+prepay_id+"&signType="+signType+
                "&timeStamp="+timeStamp;
        String sign = MD5Util.getMD5(A).toUpperCase();
        return sign;
    }

MD5加密工具类

package com.mengxiang.utils;

import java.security.MessageDigest;

public class MD5Util {

	private final static String[] HEXDIGITS = { "0", "1", "2", "3", "4", "5",
			"6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };

	public final static String getMD5(String str) {
		if (str != null) {
			try {
				// 创建具有指定算法名称的信息摘要
				MessageDigest md = MessageDigest.getInstance("MD5");
				// 使用指定的字节数组对摘要进行最后更新,然后完成摘要计算
				byte[] results = md.digest(str.getBytes()); // 将得到的字节数组变成字符串返回
				StringBuffer resultSb = new StringBuffer();
				String a = "";
				for (int i = 0; i < results.length; i++) {
					int n = results[i];
					if (n < 0)
						n = 256 + n;
					int d1 = n / 16;
					int d2 = n % 16;
					a = HEXDIGITS[d1] + HEXDIGITS[d2];
					resultSb.append(a);
				}
				return resultSb.toString();
			} catch (Exception ex) {
				ex.printStackTrace();
			}
		}
		return null;
	}

	private static String byteArrayToHexString(byte b[]) {
		StringBuffer resultSb = new StringBuffer();
		for (int i = 0; i < b.length; i++)
			resultSb.append(byteToHexString(b[i]));

		return resultSb.toString();
	}

	private static String byteToHexString(byte b) {
		int n = b;
		if (n < 0)
			n += 256;
		int d1 = n / 16;
		int d2 = n % 16;
		return HEXDIGITS[d1] + HEXDIGITS[d2];
	}

	public static String MD5Encode(String origin, String charsetname) {
		String resultString = null;
		try {
			resultString = new String(origin);
			MessageDigest md = MessageDigest.getInstance("MD5");
			if (charsetname == null || "".equals(charsetname))
				resultString = byteArrayToHexString(md.digest(resultString
						.getBytes()));
			else
				resultString = byteArrayToHexString(md.digest(resultString
						.getBytes(charsetname)));
		} catch (Exception exception) {
		}
		return resultString;
	}

	/***
	 * MD5加码 生成32位md5码
	 */
	public static String string2MD5(String inStr) {
		MessageDigest md5 = null;
		try {
			md5 = MessageDigest.getInstance("MD5");
		} catch (Exception e) {
			System.out.println(e.toString());
			e.printStackTrace();
			return "";
		}
		char[] charArray = inStr.toCharArray();
		byte[] byteArray = new byte[charArray.length];

		for (int i = 0; i < charArray.length; i++)
			byteArray[i] = (byte) charArray[i];
		byte[] md5Bytes = md5.digest(byteArray);
		StringBuffer hexValue = new StringBuffer();
		for (int i = 0; i < md5Bytes.length; i++) {
			int val = ((int) md5Bytes[i]) & 0xff;
			if (val < 16)
				hexValue.append("0");
			hexValue.append(Integer.toHexString(val));
		}
		return hexValue.toString();

	}

	// 测试主函数
	public static void main(String args[]) {
		String s = new String("ale123123");
		System.out.println("原始:" + s);
		System.out.println("MD5后:" + string2MD5(s));
	}
}

回调接口

/**
     * 接收返回值
     * */
    @RequestMapping("/pay_back")
    @ResponseBody
    public String pay_back(HttpServletRequest req, HttpServletResponse resp){
        InputStream ins = null;
        try {
            ins = req.getInputStream();
            byte[] rebyte = readStream(ins);
            String remess = new String(rebyte);
            System.out.println("XML报文内容为:" + remess);
        } catch (Exception e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        return "success";
    }

接收返回值主要就是将接收到的xml格式解析,读取返回值,有一点主意微信会回调多次,所以需要自行根据业务判断数据是否已经修改

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值