APP 微信支付JAVA服务器端

本文介绍了一个用于微信支付的Java类实现细节,包括预支付交易的处理流程、随机字符串生成、本地IP获取、签名生成及XML数据构造等核心功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.支付类:

import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Random;
import java.util.Set;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

/**
 * @ClassName: WeixinPay
 * @Description: TODO(微信支付)
 * @author ******@qq.com
 * @date 2018年1月13日 上午9:24:10
 */
public class WeixinPay {
	private static final String URL = "https://api.mch.weixin.qq.com/pay/unifiedorder";
	public static final String APP_ID = "*******";
	public static final String MCH_ID = "******";
	private static final String APP_SERCRET = "**************";
	private final static String[] strDigits = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d","e", "f" };
	/**
	 * 获取预支付
	 * @param body
	 * @param orderNum
	 * @param totalMoney
	 * @param notify_url
	 * @return
	 */
	public Map<String, String> getPreyId(String body, String orderNum, String totalMoney, String notify_url) {
		Map<String, String> reqMap = new HashMap<String, String>();
		reqMap.put("appid", APP_ID);
		reqMap.put("mch_id", MCH_ID);
		reqMap.put("nonce_str", getRandomString());
		reqMap.put("body", body);
		reqMap.put("out_trade_no", orderNum); // 商户系统内部的订单号,
		reqMap.put("total_fee", totalMoney); // 订单总金额,单位为分
		reqMap.put("spbill_create_ip", getHostIp()); // 用户端实际ip
		reqMap.put("notify_url", notify_url); // 通知地址
		reqMap.put("trade_type", "APP"); // 交易类型
		reqMap.put("sign", getSign(reqMap));
		String reqStr = creatXml(reqMap);
		String retStr = "";
		try {
			retStr = HttpClientUtil.postHtpps(URL, reqStr);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
		return getInfoByXml(retStr);
	}
	
	
	public static String creatXml(Map<String, String> reqMap) {
		Set<String> set = reqMap.keySet();
		StringBuffer b = new StringBuffer();
		//b.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
		//b.append("<xml>");
		b.append("<xml>");
		for (String key : set) {
			b.append("<" + key + ">").append(reqMap.get(key)).append("</" + key + ">");
		}
		b.append("</xml>");
		return b.toString();
	}

	/**
	 * 得到随机字符串
	 * 
	 * @param length
	 * @return
	 */
	public static String getRandomString() {
		int length = 32;
		String str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
		Random random = new Random();
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < length; ++i) {
			int number = random.nextInt(62);// [0,62)
			sb.append(str.charAt(number));
		}
		return sb.toString();
	}

	/**
	 * 得到本地机器的IP
	 * 
	 * @return
	 */
	private static String getHostIp() {
		String ip = "";
		try {
			ip = InetAddress.getLocalHost().getHostAddress();
		} catch (UnknownHostException e) {
			e.printStackTrace();
		}
		return ip;
	}

	/**
	 * 得到加密值
	 * 
	 * @param map
	 * @return
	 */
	public static String getSign(Map<String, String> map) {
		String[] keys = map.keySet().toArray(new String[0]);
		Arrays.sort(keys);
		StringBuffer reqStr = new StringBuffer();
		for (String key : keys) {
			String v = map.get(key);
			if (v != null && !v.equals("")) {
				reqStr.append(key).append("=").append(v).append("&");
			}
		}
		reqStr.append("key").append("=").append(APP_SERCRET);
		String string = encode(reqStr.toString()).toUpperCase();
		return string;
	}

	public static String encode(String strObj) {
		String resultString = null;
		try {
			resultString = new String(strObj);
			MessageDigest md = MessageDigest.getInstance("MD5");
			// md.digest() 该函数返回值为存放哈希值结果的byte数组
			try {
				resultString = byteToString(md.digest(strObj.getBytes("UTF-8")));
			} catch (UnsupportedEncodingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		} catch (NoSuchAlgorithmException ex) {
			ex.printStackTrace();
		}
		return resultString;
	}

	// 转换字节数组为16进制字串
	private static String byteToString(byte[] bByte) {
		StringBuffer sBuffer = new StringBuffer();
		for (int i = 0; i < bByte.length; i++) {
			sBuffer.append(byteToArrayString(bByte[i]));
		}
		return sBuffer.toString();
	}

	// 返回形式为数字跟字符串
	private static String byteToArrayString(byte bByte) {
		int iRet = bByte;
		if (iRet < 0) {
			iRet += 256;
		}
		int iD1 = iRet / 16;
		int iD2 = iRet % 16;
		return strDigits[iD1] + strDigits[iD2];
	}

	public static Map<String, String> getInfoByXml(String xmlStr) {
		try {
			Map<String, String> m = new HashMap<String, String>();
			Document d = DocumentHelper.parseText(xmlStr);
			Element root = d.getRootElement();
			for (Iterator<?> i = root.elementIterator(); i.hasNext();) {
				Element element = (Element) i.next();
				String name = element.getName();
				if (!element.isTextOnly()) {
					// 不是字符串 跳过。确定了微信放回的xml只有根目录
					continue;
				} else {
					m.put(name, element.getTextTrim());
				}
			}
			// 对返回结果做校验.去除sign 字段再去加密
			String retSign = m.get("sign");
			String sign = m.remove("sign");
			String rightSing = getSign(m);
			if (rightSing.equals(retSign)) {
				m.put("sign", sign);
				return m;
			}
		} catch (DocumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

}
2.调用支付类

String url = "https://" + getRequest().getServerName()+ "/********";
				Map<String, String> map = new WeixinPay().getPreyId(body, orderNum, ((int)(Double.valueOf(total_money)*100))+"", url);
				//签名
				Map<String, String> appMap = new HashMap<String, String>();
				appMap.put("appid", WeixinPay.APP_ID);
				appMap.put("partnerid", WeixinPay.MCH_ID);
				appMap.put("prepayid", map.get("prepay_id"));
				appMap.put("package", "Sign=WXPay");
				appMap.put("timestamp", ((int)(System.currentTimeMillis()/1000))+"");
				appMap.put("noncestr", WeixinPay.getRandomString());
				String sign = WeixinPay.getSign(appMap);




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梦里藍天

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值