工具类
import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.security.MessageDigest; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Enumeration; import java.util.Map; import java.util.TreeMap; import javax.servlet.http.HttpServletRequest; /** * @文件名:ZJ_TenpayUtils.java * @作用: * @作者:张剑 * @创建时间:2014年3月6日 */ public class ZJ_TenpayUtils { /** * MD5加密 * * @param s * @return */ private static String MD5(String s, String charsetname) { char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; try { byte[] strTemp; if (null == charsetname || "".equals(charsetname)) { strTemp = s.getBytes(); } else { strTemp = s.getBytes(charsetname); } MessageDigest mdTemp = MessageDigest.getInstance("MD5"); mdTemp.update(strTemp); byte[] md = mdTemp.digest(); int j = md.length; char str[] = new char[j * 2]; int k = 0; for (int i = 0; i < j; i++) { byte byte0 = md[i]; str[k++] = hexDigits[byte0 >>> 4 & 0xf]; str[k++] = hexDigits[byte0 & 0xf]; } return new String(str); } catch (Exception e) { return null; } } /** * 获取参数字符串 * * @param parameters * @return */ public static String getParStr(Map<String, String> parameters, String charsetname) { // 先将参数以其参数名的字典序升序进行排序 parameters = new TreeMap<String, String>(parameters); // 遍历排序后的字典,将所有参数按"key=value"格式拼接在一起 StringBuilder baseBuilder = new StringBuilder(); Object[] keys = parameters.keySet().toArray(); Object mkey = null; for (int i = 0; i < keys.length; i++) { mkey = keys[i]; try { baseBuilder.append("&").append(mkey).append("=").append(URLEncoder.encode(parameters.get(mkey), charsetname)); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } String baseString = baseBuilder.toString(); return baseString = baseString.substring(1); } /** * 获取请求参数集 * * @param request * @return */ public static Map<String, String> getParMap(HttpServletRequest request) { Map<String, String> map = new TreeMap<String, String>(); request.getParameterNames(); Enumeration<String> names = request.getParameterNames(); while (names.hasMoreElements()) { String key = names.nextElement(); String value = request.getParameter(key); map.put(key, value); } return map; } /** * 获取客户端IP * * @param request * @param response * @return */ public static String getClientIp(HttpServletRequest request) { 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(); } return ip; } /** * 获取当前日期和时间 * * @return */ public static String getNowDateTime() { return new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()); } /** * 获取财付通签名 */ public static String getSignature(Map<String, String> parameters, String key, String charsetname) { // 先将参数以其参数名的字典序升序进行排序 parameters = new TreeMap<String, String>(parameters); // 遍历排序后的字典,将所有参数按"key=value"格式拼接在一起 StringBuilder baseBuilder = new StringBuilder(); Object[] keys = parameters.keySet().toArray(); Object mkey = null; for (int i = 0; i < keys.length; i++) { mkey = keys[i]; if (null != mkey && !"".equals(mkey) && null != parameters.get(mkey) && !"".equals(parameters.get(mkey)) && !"sign".equals(mkey)) { baseBuilder.append("&").append(mkey).append("=").append(parameters.get(mkey)); } } String baseString = baseBuilder.toString(); baseString = baseString.substring(1); baseString += "&key=" + key; String sign = MD5(baseString, charsetname).toUpperCase(); return sign; } }
实体类
/** * @文件名:TenpayPojo.java * @作用: * @作者:张剑 * @创建时间:2014年3月6日 */ public class TenpayPojo { // ----------------------------- // 设置支付参数 // ----------------------------- private String partner;// 商户号 private String out_trade_no;// 商家订单号 private String total_fee;// 商品总金额,以分为单位 private String return_url;// 交易完成后跳转的URL private String notify_url;// 接收财付通通知的URL private String body;// 商品描述 private String bank_type = "DEFAULT";// 银行类型 private String spbill_create_ip; // 用户的公网ip private String fee_type = "1";// 现金支付币种,取值:1(人民币),默认值是1,暂只支持1 private String sign;// 签名 // 系统可选参数 private String sign_type = "MD5";// 签名类型,取值:MD5、RSA,默认:MD5 private String service_version = "1.0";// 版本号,默认为1.0 private String input_charset = "UTF-8";// 字符编码,取值:GBK、UTF-8 private String sign_key_index = "1";// 多密钥支持的密钥序号,默认1 // 业务可选参数 private String attach = "";// 附加数据,原样返回 private String product_fee;// 商品费用 private String transport_fee;// 物流费用 private String time_start;// 订单生成时间 private String time_expire;// 订单失效时间 private String buyer_id;// 买方的财付通账户(QQ或EMAIL)。若商户没有传该参数,则在财付通支付页面,买家需要输入其财付通账户。 private String goods_tag;// 商品标记,优惠券时可能用到 public String getPartner() { return partner; } public void setPartner(String partner) { this.partner = partner; } public String getOut_trade_no() { return out_trade_no; } public void setOut_trade_no(String out_trade_no) { this.out_trade_no = out_trade_no; } public String getTotal_fee() { return total_fee; } public void setTotal_fee(String total_fee) { this.total_fee = total_fee; } public String getReturn_url() { return return_url; } public void setReturn_url(String return_url) { this.return_url = return_url; } public String getNotify_url() { return notify_url; } public void setNotify_url(String notify_url) { this.notify_url = notify_url; } public String getBody() { return body; } public void setBody(String body) { this.body = body; } public String getBank_type() { return bank_type; } public void setBank_type(String bank_type) { this.bank_type = bank_type; } public String getSpbill_create_ip() { return spbill_create_ip; } public void setSpbill_create_ip(String spbill_create_ip) { this.spbill_create_ip = spbill_create_ip; } public String getFee_type() { return fee_type; } public void setFee_type(String fee_type) { this.fee_type = fee_type; } public String getSign() { return sign; } public void setSign(String sign) { this.sign = sign; } public String getSign_type() { return sign_type; } public void setSign_type(String sign_type) { this.sign_type = sign_type; } public String getService_version() { return service_version; } public void setService_version(String service_version) { this.service_version = service_version; } public String getInput_charset() { return input_charset; } public void setInput_charset(String input_charset) { this.input_charset = input_charset; } public String getSign_key_index() { return sign_key_index; } public void setSign_key_index(String sign_key_index) { this.sign_key_index = sign_key_index; } public String getAttach() { return attach; } public void setAttach(String attach) { this.attach = attach; } public String getProduct_fee() { return product_fee; } public void setProduct_fee(String product_fee) { this.product_fee = product_fee; } public String getTransport_fee() { return transport_fee; } public void setTransport_fee(String transport_fee) { this.transport_fee = transport_fee; } public String getTime_start() { return time_start; } public void setTime_start(String time_start) { this.time_start = time_start; } public String getTime_expire() { return time_expire; } public void setTime_expire(String time_expire) { this.time_expire = time_expire; } public String getBuyer_id() { return buyer_id; } public void setBuyer_id(String buyer_id) { this.buyer_id = buyer_id; } public String getGoods_tag() { return goods_tag; } public void setGoods_tag(String goods_tag) { this.goods_tag = goods_tag; } }
调用方式
@RequestMapping(value = "/tenpay") public String Tenpay(HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException { String url = "https://gw.tenpay.com/gateway/pay.htm"; Map<String, String> parameters = new HashMap<String, String>(); /* 商户号,上线时务必将测试商户号替换为正式商户号 */ String partner = "1900000109"; // 密钥 String key = "8934e7d15453e97507ef794cf7b0519d"; // 交易完成后跳转的URL String return_url = "http://127.0.0.1:8080/ffzx/service/json/tenpayReturn"; // 接收财付通通知的URL String notify_url = "http://127.0.0.1:8080/ffzx/service/json/tenpayNotify"; // ---------------生成订单号 开始------------------------ // 订单号,此处用时间加随机数生成,商户根据自己情况调整,只要保持全局唯一就行 String out_trade_no = "dingdanhao"; // ----------------------------- // 设置支付参数 // ----------------------------- parameters.put("partner", partner); // 商户号 parameters.put("out_trade_no", out_trade_no); // 商家订单号 parameters.put("total_fee", "1"); // 商品金额,以分为单位 parameters.put("return_url", return_url); // 交易完成后跳转的URL parameters.put("notify_url", notify_url); // 接收财付通通知的URL parameters.put("body", "在线充值");// 商品描述 parameters.put("bank_type", "DEFAULT"); // 银行类型 parameters.put("spbill_create_ip", ZJ_TenpayUtils.getClientIp(request)); // 用户的公网ip parameters.put("fee_type", "1");// 现金支付币种,取值:1(人民币),默认值是1,暂只支持1 // 系统可选参数 parameters.put("input_charset", "UTF-8");// 字符编码,取值:GBK、UTF-8 parameters.put("sign", ZJ_TenpayUtils.getSignature(parameters, key, "UTF-8")); String pars = ZJ_TenpayUtils.getParStr(parameters, "UTF-8"); return "redirect:" + url + "?" + pars; } @ResponseBody @RequestMapping(value = "/tenpayNotify") public String tenpayNotify(HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException { String result = "fail"; Map<String, String> pars = ZJ_TenpayUtils.getParMap(request); System.out.println(pars); System.out.println("调用充值方法"); return result; } @RequestMapping(value = "/tenpayReturn") public String tenpayReturn(HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException { Map<String, String> pars = ZJ_TenpayUtils.getParMap(request); System.out.println(pars); System.out.println(pars.get("sign").equals(ZJ_TenpayUtils.getSignature(pars, "e9ae62616ab488c686f014622556a508", "UTF-8"))); return "/tenpay/success"; }