工具类
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";
}