欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

第三方支付-java 返回success,带双引号的解决方法-支付流程

程序员文章站 2024-03-23 15:50:04
...


解决方法:

原来的 return “SUCCESS”;

正确的:

/**
	 * 返回不带双引号的SUCCESS
	 * @param data
	 * @param resp
	 */
	private void printData(String data,HttpServletResponse resp) {
		PrintWriter out;
		try {
			out = resp.getWriter();
			out.print(data);
			out.flush();
	        out.close();
	        out = null;
		} catch (Exception e) {
			e.printStackTrace();
		}
       
	}


微信为例:支付流程图

第三方支付-java 返回success,带双引号的解决方法-支付流程


首先生成订单,进行签名加密

其次在notifyURL异步回调中校验签名

再次,在callbackURL返回订单支付成功,跳转情况


代码:

第三方银联支付:

package cn.lvche.PocketScoreShopApi;

import java.util.Base64.Decoder;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.X509EncodedKeySpec;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.protocol.HTTP;
import org.json.JSONObject;
import org.nutz.dao.Cnd;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.json.Json;
import org.nutz.lang.Strings;
import org.nutz.log.Log;
import org.nutz.log.Logs;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.By;
import org.nutz.mvc.annotation.Filters;
import org.nutz.mvc.annotation.GET;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.POST;
import org.nutz.mvc.annotation.Param;
import org.nutz.mvc.filter.CrossOriginFilter;

import com.alibaba.druid.util.Base64;
import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.internal.util.StreamUtil;
import com.google.gson.JsonObject;
import com.lvche.QiuBaoHaoConfigInfo.MyAppGrobleConfigInfo;

import cn.lvche.PocketScoreShopApi.cardpay.CardPayBySign;
import cn.lvche.PocketScoreShopApi.cardpay.HttpClient4;
import cn.lvche.api.AuthenticationFilter.annotation.Authentication;
import cn.lvche.api.AuthenticationFilter.annotation.AuthenticationType;
import cn.lvche.fw.api.ApiResult;
import cn.lvche.fw.api.ReturnCode;
import cn.lvche.ps.mb.models.Member;
import cn.lvche.ps.mb.models.MemberScoreRecord;
import cn.lvche.ps.mb.services.MemberGiftService;
import cn.lvche.ps.mb.services.MemberScoreRecordService;
import cn.lvche.ps.mb.services.MemberService;
import cn.lvche.ps.shop.models.ShopIngotOrder;
import cn.lvche.ps.shop.models.ShopTopUpMenu;
import cn.lvche.ps.shop.services.ShopGiftOrderService;
import cn.lvche.ps.shop.services.ShopGiftService;
import cn.lvche.ps.shop.services.ShopIngotOrderService;
import cn.lvche.ps.shop.services.ShopTopUpMenuService;
import cn.lvche.security.util.LvcheCrossOriginFilter;
import cn.lvche.util.MemberConstants;
import cn.lvche.util.QBH_ResultUtil;
import cn.lvche.util.ShopConstants;
import cn.wizzer.app.sys.modules.models.Sys_config;
import cn.wizzer.app.sys.modules.services.SysConfigService;

/**
 * @category 第三方卡支付
 * @author William
 * @since 2018年4月25日10:49:31
 */
@At("/shopapi")
@Ok("json:full")
@IocBean
@Filters(@By(type = LvcheCrossOriginFilter.class))
public class CardPayApiController {
	
	private static final Log log = Logs.get();
	@Inject
	private MemberService memberService;
	@Inject
	private ShopGiftService shopGiftService;
	@Inject
	private MemberGiftService memberGiftService;
	@Inject
	private ShopGiftOrderService shopGiftOrderService;
	@Inject
	private MemberScoreRecordService memberScoreRecordService;
	
	@Inject
	private SysConfigService sysConfigService;
	
	@Inject
	private ShopIngotOrderService shopIngotOrderService;
	
	@Inject
	private ShopTopUpMenuService shopTopUpMenuService;
	
	@POST
	@At("/createCardPayOrder")
	@Authentication(checkarea=AuthenticationType.session)
	@Filters(@By(type = LvcheCrossOriginFilter.class))
	public Object createCardPayOrder(@Param("deputyId")String deputyId,@Param("storeOiType") int storeOiType,@Param("amount")int amount,@Param("body") String body,@Param("description") String description ,@Param("subject") String subject,HttpServletRequest req) {
		try {
			Member mb = (Member) req.getAttribute("member");
			if (Strings.isBlank(deputyId)) {
				return ApiResult.New(ReturnCode.ERROR).addMsg("充值信息获取失败,请联系管理员");
			}
			ShopTopUpMenu stum = shopTopUpMenuService.fetch(Cnd.NEW().and("deputyId", "=", deputyId));
			if (stum == null) {
				return ApiResult.New(ReturnCode.ERROR).addMsg("不存在该商品或已下架");
			}
			//			tring deputyId, String memberId, Integer platform, String feeType, String tradeType,
			//			Integer orderStatus, String gmtCreate, String gmtModified
			ShopIngotOrder sio = new ShopIngotOrder(stum.getId(),mb.getId(),stum.getTgtQty(),ShopConstants.SIO_PLATFORM_ALIPAY,ShopConstants.SIO_FEE_TYPE_CNY,ShopConstants.SIO_TRADE_TYPE_ZFB_APP,
					0,new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(System.currentTimeMillis()),new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(System.currentTimeMillis()));
			
			String currTime = "" + System.currentTimeMillis();//时间戳
			SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHssmm");
			String out_trade_no = "QBH"+sdf.format(new Date())+""+currTime;
			
			sio.setOutTradeNo(out_trade_no);
			sio = shopIngotOrderService.insert(sio);
			
			if (sio == null) return  QBH_ResultUtil.getResult(QBH_ResultUtil.getResultError(), ReturnCode.ERROR.getCode(),"支付订单无法生成,请联系管理员",new JsonObject());
			/*
			 * 请求例子
			 * {
			    "amount": "10000",
			    "orderNo": "1146645644fdfsdf1524623039426",
			    "channel": "7013",
			    "timePaid": "1524623039426",
			    "mchNo": "rm1505XXXXXX603",
			    "body": "556646466",
			    "description": "描述",
			    "subject": "美的空调",
			    "extra": {
			        "storeOiType": "1",
			        "pay_id": "unionquickpay",
			        "notifyUrl":"http://120.78.87.172:8088/order/notifyUrl",
			        "callbackUrl":"http://120.78.87.172:8088/order/callbackUrl"
			    },
			    "version": "2.0",
			    "sign": "VJoVcJfsGqWZHOpnruYMH9w7eUjwtqlZ/7Q4shA17L2oldqY1awr6EZrALATKuIRtArbcGy4nczf5XNLZs0fXAFAruMK4ek/bsndHnRfrSwy1hvDoy4QYlIichgBSi6SQQhxV0/jSap9qAXK/bH9T1vVU0DT7NOxs5o3yJtxSj0="
			}*/
			
			//7013类型 -- 拓展字段帮助文档
			//storeOiType	网关类型 0-PC版网关 1-手机版网关	是
			//pay_id	              默认:unionquickpay	              是
			//notifyUrl	              支付完成后结果通知url	                            是
			//callbackUrl	交易完成后跳转的 URL, 需给绝对路径, 255字 符 内 格 式如:http://wap. tenpay. com/callback.asp注: 该地址只作为前端页面的一个跳转, 需使用 notifyUrl 通知结果作为支付最终结果。	是
	
	
			JsonObject jsonExtra = new JsonObject();
			jsonExtra.addProperty("storeOiType", storeOiType+"");//网关类型: 0-PC版网关 1-手机版网关
			jsonExtra.addProperty("pay_id", "unionquickpay");//支付id
			Sys_config config = sysConfigService.fetch(MyAppGrobleConfigInfo.NotifyURLDomain);
		    if (config == null || StringUtils.isEmpty(config.getConfigValue()))  return  QBH_ResultUtil.getResult(QBH_ResultUtil.getResultError(), ReturnCode.ERROR.getCode(), "服务器端订单支付同步主域名未配置",new JsonObject());
			jsonExtra.addProperty("notifyUrl",   config.getConfigValue().trim() + "/shopapi/notifyUrl");//同步通知路径
			jsonExtra.addProperty("callbackUrl", config.getConfigValue().trim() + "/shopapi/callbackUrl");//异步通知路径
	
			String extraStr = jsonExtra.toString();
			extraStr = extraStr.replace("/", "\\/");
	
			HashMap<String, Object> keyMap = new HashMap<String, Object>();
			keyMap.put("amount", amount+"");//订单金额,单位:分
			keyMap.put("channel", MyAppGrobleConfigInfo.CardPayChannel);//支付渠道类型
			keyMap.put("orderNo",out_trade_no);//商户支付订单号
			System.out.println(currTime);
			keyMap.put("timePaid", currTime);//时间戳
			keyMap.put("mchNo", MyAppGrobleConfigInfo.MchNo);//商户号:rm1505XXXXXX603
                        KMap.put("body", body);//商品描述
			keyMap.put("description", description);//附加数据
			keyMap.put("subject", subject);//商品的标题
			keyMap.put("version", "2.0");//版本
			keyMap.put("extra", extraStr);//扩展字段
	
			/*
			 * 生成签名: 1:把请求数组先按数组键名排序,
			 * 
			 * 2:(如果数组参数值有数组的先转成json字符串)然后把数组参数用##链接起来,
			 * 
			 * 3:最后用私钥(rsa_private_key)生成签名sign
			 */
	
			String[] keys = CardPayBySign.getUrlParam(new String[] { "amount", "orderNo", "channel", "timePaid", "mchNo", "body",
					"description", "subject", "version", "extra" });
	
			StringBuilder sb = new StringBuilder();
			for (String key : keys) {
				/*
				 * 签名后拼接的规则
				 * 
				 * 100##556646466##7017##描述##
				 * ["[mobileNo:13433886372,bankCard:6236272202000008539,userId :rm1505XXXXXX603,notifyUrl:http:\/\/asda\/m\/minsheng_pay\/weixinpay_notify.php,callbackUrl:http:\/\/asda\/m\/minsheng_pay\/weixinpay_notify.php]"
				 * ]##rm1505XXXXXX603##1146645644fdfsdf##美的空调##1523156284##2.0
				 */
				/*
				 * if (key.equals("extra")) sb.append("[\""+keyMap.get(key)+"\"]" +
				 * "##") ; else ;
				 */
				sb.append(keyMap.get(key) + "##");
			}
	
			String sign = sb.toString().substring(0, sb.toString().lastIndexOf("##"));
	
			//==============================================开始拼接json
			StringBuilder sbJsonParam = new StringBuilder();
	//		{
			sbJsonParam.append("{");
	//		    "amount": "10000",
			sbJsonParam.append("\"amount\"" + ":" + "\""+keyMap.get("amount")+"\",");
	//		    "orderNo": "1146645644fdfsdf1524643401565",
			sbJsonParam.append("\"orderNo\"" + ":" + "\""+keyMap.get("orderNo")+"\",");
	//		    "channel": "7013",
			sbJsonParam.append("\"channel\"" + ":" + "\""+keyMap.get("channel")+"\",");
	//		    "timePaid": "1524643401565",
			sbJsonParam.append("\"timePaid\"" + ":" + "\""+keyMap.get("timePaid")+"\",");
	//		    "mchNo": "rm15ZZZZZZZZZ",
			sbJsonParam.append("\"mchNo\"" + ":" + "\""+keyMap.get("mchNo")+"\",");
	//		    "body": "556646466",
			sbJsonParam.append("\"body\"" + ":" + "\""+keyMap.get("body")+"\",");
	//		    "description": "描述",
			sbJsonParam.append("\"description\"" + ":" + "\""+keyMap.get("description")+"\",");
	//		    "subject": "美的空调",
			sbJsonParam.append("\"subject\"" + ":" + "\""+keyMap.get("subject")+"\",");
			StringBuilder sbExtra = new StringBuilder();
	//		    "extra": {
			sbExtra.append("{");
	//		        "storeOiType": "1",
			sbExtra.append("\"storeOiType\"" + ":" + "\""+storeOiType+"\",");
	//		        "pay_id": "unionquickpay",
			sbExtra.append("\"pay_id\"" + ":" + "\""+"unionquickpay"+"\",");
	//		        "notifyUrl":"http://120.78.87.172:8088/order/notifyUrl",
			sbExtra.append("\"notifyUrl\"" + ":" + "\""+config.getConfigValue().trim() + "/shopapi/notifyUrl"+"\",");
	//		        "callbackUrl":"http://120.78.87.172:8088/order/callbackUrl"
			sbExtra.append("\"callbackUrl\"" + ":" + "\""+config.getConfigValue().trim() + "/shopapi/callbackUrl"+"\"");
	//		    },
			sbExtra.append("}");
			sbJsonParam.append("\"extra\"" + ":" + ""+sbExtra.toString()+",");
	//		    "version": "2.0",
			sbJsonParam.append("\"version\"" + ":" + "\""+keyMap.get("version")+"\",");
	//		    "sign": "L270U6Dnuwit8r6tGulXpJSf39ASRwzfoXrNNZPJqEK7qWnPsFktGkYhK9trQttJVH5mPeI3P+8s2Y5EL3CPhTvSBlAW5Z9WgxIPL81YSTg6NRKUld5f2brLomEP/DHD1i3kFQ7VPT2Q45RP/+Rcu4RRHjE/ItOHGb112QqF4ns="
			try {
				sbJsonParam.append("\"sign\"" + ":" + "\""+AlipaySignature.rsaSign(sign,
						MyAppGrobleConfigInfo.qiubaohaoCardPayRSAPrivateKeyPKCS8Key, "UTF-8")+"\"");
			} catch (AlipayApiException e1) {
				e1.printStackTrace();
			}
	//		}
			sbJsonParam.append("}");
			//==============================================开始拼接json
			
			System.out.println("sign签名:" + sign);
	
			//这种实现问题方式,不对
	//		keyMap.remove("extra");
	//		try {
	//			keyMap.put("sign", AlipaySignature.rsaSign(sign,
	//					MyAppGrobleConfigInfo.qiubaohaoCardPayRSAPrivateKeyPKCS8Key, "UTF-8"));
	//		} catch (AlipayApiException e) {
	//			e.printStackTrace();
	//		}
	//		String extraJson = "{\"extra\":"+jsonExtra.toString()+",";
	//		net.sf.json.JSONObject jsonObject = net.sf.json.JSONObject.fromObject(keyMap);
	//		System.out.println("json参数:" + extraJson + jsonObject.toString().substring(1));
			String tokenString = HttpClient4.doPost(MyAppGrobleConfigInfo.CardPayUrl,sbJsonParam.toString());
			JSONObject jsonResult = new JSONObject(tokenString);
			if (jsonResult.has("code") && jsonResult.getInt("code") == 200)
	//			{\"code\":200,\"cpOrderNo\":\"20180425165828785443\",\"mchNo\":\"rm15058ZZZZZZZZ\",\"orderNo\":\"1146645644fdfsdf1524646683999\",\"tokenId\":\"0t5b659dcf330y9povjawujqr\",\"sign\":\"DhWnMEjlZmGN6sLJxL4i\\/xQek2IyKylyN8E6eQjyQYsIJLE24Wh2Zp1pfeEu\\/\\/0QN5h5yN+9H2fYChhGV7KjqLi+4d+QMEXAse3OqLDVg0rK4JjwcDDyzkpCBGCYpOlAstT63gfH8W4InQzfZrVateoFnJ\\/QpOWol05j0fpXedE=\"}
				//return  QBH_ResultUtil.getResult(QBH_ResultUtil.getResultSuccess(), ReturnCode.SUCCESS.getCode(),"请求成功,正在进行下一步支付",tokenString);
				return  QBH_ResultUtil.getResult(QBH_ResultUtil.getResultSuccess(), ReturnCode.SUCCESS.getCode(),"请求成功,正在进行下一步支付",MyAppGrobleConfigInfo.CardPayH5Url+"?tokenId="+jsonResult.getString("tokenId"));
			else {
				return  QBH_ResultUtil.getResult(QBH_ResultUtil.getResultError(), ReturnCode.ERROR.getCode(),jsonResult.getString("msg"),tokenString);
			}
		} catch (Exception e) {
			e.printStackTrace();
			return  QBH_ResultUtil.getResult(QBH_ResultUtil.getResultError(), ReturnCode.ERROR.getCode(),"支付订单生成错误,请联系管理员",new JsonObject());
		}
	}
	
	
	@At("/callbackUrl")
	@POST
	public Object callbackUrl(HttpServletRequest req) throws AlipayApiException{
		try {
			String requestData = readParamToTxt(req,"callbackUrl","","");
			
			readParamToTxt(null,"callbackUrl","record1_","requestData"+requestData);
			JSONObject jsonResult = new JSONObject(requestData);
			readParamToTxt(null,"callbackUrl","record2_","jsonResult"+jsonResult);
			
			readParamToTxt(null,"callbackUrl","record3_","jsonResult.getString(mchOrderNo)"+jsonResult.getString("mchOrderNo"));
			
			//trade_no  支付宝交易凭证号                out_trade_no  支付宝商户订单号(本地生成唯一)
			ShopIngotOrder sio =  shopIngotOrderService.fetch(Cnd.where("out_trade_no","=",jsonResult.getString("mchOrderNo")));
			readParamToTxt(null,"callbackUrl","record4_","sio"+sio);
			//sio.setOrderStatus(1);//订单状态(0未处理 1成功 2返还)
			if(sio!=null){
				readParamToTxt(null,"callbackUrl","record5_","开始返回sio.getOrderStatus()"+sio.getOrderStatus());
				if(sio.getOrderStatus()==1){
					return ApiResult.New(ReturnCode.SUCCESS).addMsg("元宝购买成功");
				}
				if(sio.getOrderStatus()==0){
					return ApiResult.New(ReturnCode.SUCCESS).addMsg("订单已提交成功请稍等....");
				}
			}
			
			readParamToTxt(null,"callbackUrl","record6_","交易失败");
			return ApiResult.New(ReturnCode.ERROR).addMsg("交易失败");
		} catch (Exception  e) {
			try {
				readParamToTxt(null,"callbackUrl","record6_","异常信息"+getErrorInfoFromException(e));
			} catch (UnsupportedEncodingException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			return ApiResult.New(ReturnCode.ERROR);
		}
	}


	private String readParamToTxt(HttpServletRequest req,String methodName,String fileOtherName,String otherData) throws IOException, UnsupportedEncodingException {
		String logStr = "";
		String reqBody = "";
		if (req != null) {
			req.setCharacterEncoding("utf-8");
			
			// 读取请求内容
			BufferedReader br = new BufferedReader(new InputStreamReader(req.getInputStream(), "UTF-8"));
			String line = null;
			logStr = "\r\n开始记录==========/"+methodName+"接口postbody========的数据\r\n\r\n";
			StringBuilder sb = new StringBuilder("");
			while((line = br.readLine())!=null){
			    sb.append(line);
			}
			// 将资料解码
			reqBody = sb.toString();
			//System.out.println(URLDecoder.decode(reqBody, HTTP.UTF_8));这句话会把+号变成空格
			System.out.println(reqBody);
			logStr += "\r\n"+reqBody+"\r\n";
			logStr += "\r\n结束记录==========/"+methodName+"接口postbody========的数据\r\n\r\n";
			logStr += "\r\n开始记录==========/"+methodName+"接口param========的数据\r\n\r\n";
			if (req != null && req.getParameterNames() != null) {
				Enumeration<String> enu = req.getParameterNames();
				while (enu.hasMoreElements()) {
					String key = enu.nextElement();
					String[] value = req.getParameterValues(key);
					logStr += key +":";
					if (value == null) {
						
					} else if (value.length == 1) {
						try {
							String str = new String(value[0].getBytes("ISO-8859-1"), "UTF-8");
							logStr += str+"\r\n";
						} catch (Exception e) {
							logStr += URLDecoder.decode(value[0], HTTP.UTF_8)+"\r\n";
						}
					}  else if (value.length == 1) {
						for (String var : value) {
							try {
								String str = new String(var.getBytes("ISO-8859-1"), "UTF-8");
								logStr += str+"\r\n";
							} catch (Exception e) {
								logStr += URLDecoder.decode(var, HTTP.UTF_8)+"\r\n";
							}
						}
					}
				}
			}
			
			logStr += "\r\n开始记录==========/"+methodName+"接口param========的数据\r\n\r\n";
		}
		
		logStr += "\r\n开始记录==========/"+methodName+"过程数据========的数据\r\n\r\n";
		
		logStr += otherData;
		
		logStr += "\r\n开始记录==========/"+methodName+"过程数据========的数据\r\n\r\n";
		
		WriteMyLog(logStr,methodName,fileOtherName);
		
		return reqBody;
	}
	
	public String WriteMyLog(String content,String methodName,String fileOtherName)
	{
		//写日志
		try { // 防止文件建立或读取失败,用catch捕捉错误并打印,也可以throw  

			File parentDir  = new File("C:" + File.separator + "lvche_cardPay" + methodName);
			if (!parentDir.exists()) {
				parentDir.mkdirs();
			}
			
			SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
			File fileTxt = new File(parentDir,"lvche_cardPay"+fileOtherName+sdf.format(new Date())+System.currentTimeMillis()+".txt");// 绝对路径或相对路径都可以,这里是绝对路径,写入文件时演示相对路径
			if (!fileTxt.exists()) {
				try {
					fileTxt.createNewFile();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}

	        /* 写入Txt文件 */  
	        BufferedWriter output = new BufferedWriter(new FileWriter(fileTxt,true));//true,则追加写入text文本  
	        output.write(content+"\r\n,"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss " +System.currentTimeMillis()).format(new Date())); // \r\n即为换行  
	        output.write("\r\n");
	        output.flush(); // 把缓存区内容压入文件  
	        output.close(); // 最后记得关闭文件  

	    } catch (Exception e) {  
	        e.printStackTrace();  
	    }  
		return content;
	}
	
	@POST
	@At("/notifyUrl")
	public void notifyUrl(HttpServletRequest req,HttpServletResponse resp) throws AlipayApiException{
		try {
			
			String requestData = readParamToTxt(req,"notifyUrl","","");
			
			//{"code":200,"cpOrderNo":"20180504143902353923","mchNo":"rm15058931168603","mchOrderNo":"1146645644fdfsdf1525415942064","payResult":"0","timeEnd":1525416027,"totalFee":2500,"transactionId":0,"sign":"OvKHVqhTbO3ni56rtuBFy3ba98NoEE6y5lk5CwtLah9SxGJjXcRbT51kIjY1do63xRhB53mrPXfseIL4U5GGeZKMAIJNcPyapsExktOOh2j3I4tN PHxELLilL1QRcBlK1uXESoXte0uHtI5xQcs HJNV4iJxLRAp0uWg2fPmTM="}
			//{
			//	"code": 200,
			//	"cpOrderNo": "20180504143902353923",
			//	"mchNo": "rm15058931168603",
			//	"mchOrderNo": "1146645644fdfsdf1525415942064",
			//	"payResult": "0",
			//	"timeEnd": 1525416027,
			//	"totalFee": 2500,
			//	"transactionId": 0,
			//	"sign": "OvKHVqhTbO3ni56rtuBFy3ba98NoEE6y5lk5CwtLah9SxGJjXcRbT51kIjY1do63xRhB53mrPXfseIL4U5GGeZKMAIJNcPyapsExktOOh2j3I4tN PHxELLilL1QRcBlK1uXESoXte0uHtI5xQcs HJNV4iJxLRAp0uWg2fPmTM="
			//}
			//code cpOrderNo mchNo mchOrderNo payResult timeEnd totalFee transactionId sign
			
			readParamToTxt(null,"notifyUrl","record1_","开始记录数据");
			JSONObject jsonResult = new JSONObject(requestData);
			readParamToTxt(null,"notifyUrl","record2_",""+jsonResult.toString());
			String keys[] = CardPayBySign.getUrlParam(new String[]{"code","cpOrderNo","mchNo","mchOrderNo","payResult","timeEnd","totalFee","transactionId"});
			String signOriginal = jsonResult.get("sign").toString();
			readParamToTxt(null,"notifyUrl","record3_","记录数据");
			
			HashMap<String, Object> keyMap = new HashMap<String, Object>();
			for (int i=0;i<keys.length;i++) {
				keyMap.put(keys[i], jsonResult.get(keys[i]));
			}
			
			readParamToTxt(null,"notifyUrl","record4_","数据存放在keyMap完成");
			
			StringBuilder sb = new StringBuilder();
			for (String key : keys) {
				/*
				 * 签名后拼接的规则
				 * 
				 * 100##556646466##7017##描述##
				 * ["[mobileNo:13433886372,bankCard:6236272202000008539,userId :rm15058931168603,notifyUrl:http:\/\/asda\/m\/minsheng_pay\/weixinpay_notify.php,callbackUrl:http:\/\/asda\/m\/minsheng_pay\/weixinpay_notify.php]"
				 * ]##rm15058931168603##1146645644fdfsdf##美的空调##1523156284##2.0
				 */
				/*
				 * if (key.equals("extra")) sb.append("[\""+keyMap.get(key)+"\"]" +
				 * "##") ; else ;
				 */
				sb.append(keyMap.get(key) + "##");
			}

			String content = sb.toString().substring(0, sb.toString().lastIndexOf("##"));
			
			readParamToTxt(null,"notifyUrl","record5_","AscII排序完成" + content);
			
//			System.out.println("支付回调信息-------------------------------");
//			//获取支付宝POST过来反馈信息
//			Map<String,String> params = new HashMap<String,String>();
//			Map requestParams = req.getParameterMap();
//			for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
//				String name = (String) iter.next();
//				String[] values = (String[]) requestParams.get(name);
//				String valueStr = "";
//				for (int i = 0; i < values.length; i++) {
//					valueStr = (i == values.length - 1) ? valueStr + values[i]
//							: valueStr + values[i] + ",";
//				}
//				//乱码解决,这段代码在出现乱码时使用。
//				//valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
//				params.put(name, valueStr);
//			}
			//切记alipaypublickey是支付宝的公钥,请去open.alipay.com对应应用下查看。
			//boolean AlipaySignature.rsaCheckV1(Map<String, String> params, String publicKey, String charset, String sign_type)
			boolean flag = AlipaySignature.rsaCheck(content,signOriginal, MyAppGrobleConfigInfo.qiubaohaoCardPayRSAPublicKey,"UTF-8", "RSA");
			if(flag){
				readParamToTxt(null,"notifyUrl","record6_","签名通过.....");
				System.out.println("签名通过.....");
				boolean isSuccess = updateFillSio(keyMap);
				readParamToTxt(null,"notifyUrl","record7_",""+isSuccess);
				if (isSuccess)
					printData("SUCCESS",resp);
				else
					printData("ERROR",resp);
			}
			readParamToTxt(null,"notifyUrl","record8_","返回错误");
			printData("ERROR",resp);
		} catch (Exception  e) {
			try {
				readParamToTxt(null,"notifyUrl","record9_","出现异常"+getErrorInfoFromException(e));
			} catch (UnsupportedEncodingException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			e.printStackTrace();
//			return ApiResult.New(ReturnCode.ERROR);
			try {
				printData("ERROR",resp);
			} catch (Exception e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		}
	}
	
	/**
	 * 返回不带双引号的SUCCESS
	 * @param data
	 * @param resp
	 */
	private void printData(String data,HttpServletResponse resp) {
		PrintWriter out;
		try {
			out = resp.getWriter();
			out.print(data);
			out.flush();
	        out.close();
	        out = null;
		} catch (Exception e) {
			e.printStackTrace();
		}
       
	}
	
	public String getErrorInfoFromException(Exception e) {
        try {
            StringWriter sw = new StringWriter();
            PrintWriter pw = new PrintWriter(sw);
            e.printStackTrace(pw);
            return "\r\n" + sw.toString() + "\r\n";
        } catch (Exception e2) {
            return "ErrorInfoFromException";
        }
    }
	
	public static void main(String args[]) {
		//String requestData = "{\"code\":200,\"cpOrderNo\":\"20180504143902353923\",\"mchNo\":\"rm15058931168603\",\"mchOrderNo\":\"1146645644fdfsdf1525415942064\",\"payResult\":\"0\",\"timeEnd\":1525416027,\"totalFee\":2500,\"transactionId\":0,\"sign\":\"OvKHVqhTbO3ni56rtuBFy3ba98NoEE6y5lk5CwtLah9SxGJjXcRbT51kIjY1do63xRhB53mrPXfseIL4U5GGeZKMAIJNcPyapsExktOOh2j3I4tN PHxELLilL1QRcBlK1uXESoXte0uHtI5xQcs HJNV4iJxLRAp0uWg2fPmTM=\"}";
		String requestData = "{\"code\":200,\"cpOrderNo\":\"20180504143902353923\",\"mchNo\":\"rm15058931168603\",\"mchOrderNo\":\"1146645644fdfsdf1525415942064\",\"payResult\":\"0\",\"timeEnd\":1525416027,\"totalFee\":2500,\"transactionId\":0,\"sign\":\"OvKHVqhTbO3ni56rtuBFy3ba98NoEE6y5lk5CwtLah9SxGJjXcRbT51kIjY1do63xRhB53mrPXfseIL4U5GGeZKMAIJNcPyapsExktOOh2j3I4tN+PHxELLilL1QRcBlK1uXESoXte0uHtI5xQcs+HJNV4iJxLRAp0uWg2fPmTM=\"}";
		JSONObject jsonResult = new JSONObject(requestData);
		String keys[] = CardPayBySign.getUrlParam(new String[]{"code","cpOrderNo","mchNo","mchOrderNo","payResult","timeEnd","totalFee","transactionId"});
		
		String signOriginal = jsonResult.get("sign").toString();
		
		HashMap<String, Object> keyMap = new HashMap<String, Object>();
		for (int i=0;i<keys.length;i++) {
			keyMap.put(keys[i], jsonResult.get(keys[i]));
		}
		
		StringBuilder sb = new StringBuilder();
		for (String key : keys) {
			/*
			 * 签名后拼接的规则
			 * 
			 * 100##556646466##7017##描述##
			 * ["[mobileNo:13433886372,bankCard:6236272202000008539,userId :rm15058931168603,notifyUrl:http:\/\/asda\/m\/minsheng_pay\/weixinpay_notify.php,callbackUrl:http:\/\/asda\/m\/minsheng_pay\/weixinpay_notify.php]"
			 * ]##rm15058931168603##1146645644fdfsdf##美的空调##1523156284##2.0
			 */
			/*
			 * if (key.equals("extra")) sb.append("[\""+keyMap.get(key)+"\"]" +
			 * "##") ; else ;
			 */
			sb.append(keyMap.get(key) + "##");
		}

		String content = sb.toString().substring(0, sb.toString().lastIndexOf("##"));
		try {
			PublicKey e = getPublicKeyFromX509("RSA", new ByteArrayInputStream(MyAppGrobleConfigInfo.qiubaohaoCardPayRSAPublicKey.getBytes()));
			Signature signature = Signature.getInstance("SHA1WithRSA");
			signature.initVerify(e);
			if (StringUtils.isEmpty("UTF-8")) {
				signature.update(content.getBytes());
			} else {
				signature.update(content.getBytes("UTF-8"));
			}

			boolean flag = signature.verify(com.alipay.api.internal.util.codec.Base64.decodeBase64(signOriginal.getBytes()));
			//boolean flag = AlipaySignature.rsaCheck(content,signOriginal, MyAppGrobleConfigInfo.qiubaohaoCardPayRSAPublicKey,"UTF-8", "RSA");
			if (flag)
				System.out.println("签名通过!~");
			else 
				System.out.println("签名未通过!~");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public static PublicKey getPublicKeyFromX509(String algorithm, InputStream ins) throws Exception {
		KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
		StringWriter writer = new StringWriter();
		StreamUtil.io(new InputStreamReader(ins), writer);
		byte[] encodedKey = writer.toString().getBytes();
		encodedKey = com.alipay.api.internal.util.codec.Base64.decodeBase64(encodedKey);
		return keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
	}
	
	
	/**
	 * 收到第三方回调,把订单信息完善
	 * @param stum  购买的元宝商品对象
	 * @return
	 */
	public boolean updateFillSio(Map<String,Object> params){
		try {
			readParamToTxt(null,"notifyUrl","record10_","开始记录订单状态");
			//{"code","cpOrderNo","mchNo","mchOrderNo","payResult","timeEnd","totalFee","transactionId"}
			/*
			 业务结果	code	是	String(1)	业务结果状态
			200:成功、其他:失败
			错误代码描述	msg	否	String(128)	错误返回的信息描述
			以下字段在code为200时才有返回
			商户号	    mchNo	是	String(32)	由平台分配的商户号
			商户订单号	mchOrderNo	是	String(32)	
			平台订单号	cpOrderNo	是	String(32)	
			支付结果	payResult	是	Int	0:支付成功  其他:支付失败
			结果描述	payInfo	否	String(64)	为其他时有值
			通道订单号	transactionId	是	String(32)	
			交易时间	timeEnd	是	String(14)	
			交易金额	totalFee	否	Decimal	
			签名	sign	是	String(32)	*/
			//String requestData = "{\"code\":200,\"cpOrderNo\":\"20180504143902353923\",\"mchNo\":\"rm150ZZZZZZZZZZZ\",\"mchOrderNo\":\"1146645644fdfsdf1525415942064\",\"payResult\":\"0\",\"timeEnd\":1525416027,\"totalFee\":2500,\"transactionId\":0,\"sign\":\"OvKHVqhTbO3ni56rtuBFy3ba98NoEE6y5lk5CwtLah9SxGJjXcRbT51kIjY1do63xRhB53mrPXfseIL4U5GGeZKMAIJNcPyapsExktOOh2j3I4tN PHxELLilL1QRcBlK1uXESoXte0uHtI5xQcs HJNV4iJxLRAp0uWg2fPmTM=\"}";
			String tradeNo = params.get("mchOrderNo").toString();   //支付宝交易凭证号
			String ouTtradeNo = params.get("cpOrderNo").toString();   //支付宝商户订单号(本地生成唯一)
			String notifyTtime = params.get("timeEnd").toString();   //支付宝回调通知时间
			String buyerId = params.get("mchNo").toString();   //买家支付宝用户号
			String sellerId = params.get("transactionId").toString();   //卖家支付宝用户号
			String buyerPayAmount = params.get("totalFee").toString();   //支付宝用户在交易中支付的金额
			String receiptAmount = params.get("totalFee").toString();   //商家在交易中实际收到的款项,单位为元
			String totalAmount = params.get("totalFee").toString();   //本次交易支付的订单金额,单位为人民币(元)
			String tradeStatus = params.get("code").toString();   //交易状态通知
			readParamToTxt(null,"notifyUrl","record11_","订单记录获取完成");
			if(!"".equals(tradeNo) && tradeNo!=null && !"".equals(ouTtradeNo) && ouTtradeNo != null ){
				readParamToTxt(null,"notifyUrl","record12_","");
				ShopIngotOrder sio =  shopIngotOrderService.fetch(Cnd.where("out_trade_no","=",tradeNo));
				if (sio == null) {
					return  false;
				}
				readParamToTxt(null,"notifyUrl","record13_",""+sio.toString());
				if(sio.getOrderStatus() != 1){ //由于支付宝的回调有可能,
					readParamToTxt(null,"notifyUrl","record14_",""+tradeNo);
					sio.setTradeNo(tradeNo);
					if(tradeStatus!=null && "200".equals(tradeStatus)){
						sio.setOrderStatus(1);//订单状态(0未处理 1成功 2返还)
						sio.setGmtModified(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date().getTime()/1000));//订单修改时间
						
						sio.setTotalFee(Double.valueOf((Double.parseDouble(receiptAmount)/100.00)+"")); //用户支付金钱
						System.out.println("notifyTtime:"+notifyTtime);
					}if(notifyTtime!=null && !"".equals(notifyTtime)){
						sio.setNotifyTtime(notifyTtime);;
					}if(buyerId!=null && !"".equals(buyerId)){
						sio.setBuyerId(buyerId);
					}if(sellerId!=null && !"".equals(sellerId)){
						sio.setSellerId(sellerId);;
					}if(buyerPayAmount!=null && !"".equals(buyerPayAmount)){
						sio.setBuyerPayAmount((Double.parseDouble(buyerPayAmount)/100.00)+"");
					}if(receiptAmount!=null && !"".equals(receiptAmount)){
						sio.setReceiptAmount((Double.parseDouble(receiptAmount)/100.00)+"");
					}if(totalAmount!=null && !"".equals(totalAmount)){
						sio.setTotalAmount((Double.parseDouble(totalAmount)/100.00)+"");
					}
					readParamToTxt(null,"notifyUrl","record15_",""+tradeNo);
					//更新服务器的订单信息
					shopIngotOrderService.updateIgnoreNull(sio);
					readParamToTxt(null,"notifyUrl","record16_","更新完成");
					log.debug("银联快捷支付更新订单信息");
					//系统通知记录
					MemberScoreRecord memberScoreRecord =new MemberScoreRecord();
					memberScoreRecord.setMemberId(sio.getMemberId());
					memberScoreRecord.setType(MemberConstants.MSR_TYPE_INCOME);
					memberScoreRecord.setDescp("交易成功,获得"+sio.getIngotNum()+"钻石");
					memberScoreRecordService.insert(memberScoreRecord);
					log.debug("银联快捷支付订单通知消息生成");
					//会员获得去元宝
					Member member = memberService.fetch(sio.getMemberId());
					member.setTotalGold(member.getTotalGold()+sio.getIngotNum());
					memberScoreRecordService.updateIgnoreNull(member);
					log.debug("银联快捷支付订单成功"+sio.getMemberId()+"会员获取"+sio.getIngotNum()+"钻石");
					readParamToTxt(null,"notifyUrl","record17_","银联快捷支付订单成功");
				}
			}else{
				log.debug("银联快捷支付订单信息填写异常");
				readParamToTxt(null,"notifyUrl","record18_","银联快捷支付订单信息填写异常");
			}
		} catch (Exception  e) {
			e.getMessage();
			try {
				readParamToTxt(null,"notifyUrl","record19_","银联快捷支付订单信息填写异常"+getErrorInfoFromException(e));
			} catch (UnsupportedEncodingException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			return false;
		}
		return true;
	}
	
}


import java.util.HashMap;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.google.gson.JsonObject;
import com.lvche.QiuBaoHaoConfigInfo.MyAppGrobleConfigInfo;

/**
 * 对字符串数组进行排序
 * 
 * @author William
 * @since 2018年4月25日10:33:57
 */
public class CardPayBySign {

	private static final Log _log = LogFactory.getLog(CardPayBySign.class);

	/**
	 * 对字符串数组进行排序
	 * 
	 * @param keys
	 * @return
	 */
	public static String[] getUrlParam(String[] keys) {

		for (int i = 0; i < keys.length - 1; i++) {
			for (int j = 0; j < keys.length - i - 1; j++) {
				String pre = keys[j];
				String next = keys[j + 1];
				if (isMoreThan(pre, next)) {
					String temp = pre;
					keys[j] = next;
					keys[j + 1] = temp;
				}
			}
		}
		return keys;
	}

	/**
	 * 比较两个字符串的大小,按字母的ASCII码比较
	 * 
	 * @param pre
	 * @param next
	 * @return
	 */
	private static boolean isMoreThan(String pre, String next) {
		if (null == pre || null == next || "".equals(pre) || "".equals(next)) {
			_log.error("字符串比较数据不能为空!");
			return false;
		}

		char[] c_pre = pre.toCharArray();
		char[] c_next = next.toCharArray();

		int minSize = Math.min(c_pre.length, c_next.length);

		for (int i = 0; i < minSize; i++) {
			if ((int) c_pre[i] > (int) c_next[i]) {
				return true;
			} else if ((int) c_pre[i] < (int) c_next[i]) {
				return false;
			}
		}
		if (c_pre.length > c_next.length) {
			return true;
		}

		return false;
	}

	public static void main(String[] args) {

		try {
			System.out.println("阿里巴巴支付宝RSA签名:" + AlipaySignature.rsaSign(CardPayBySign.getSignStringParam7013(),
					MyAppGrobleConfigInfo.qiubaohaoCardPayRSAPrivateKeyPKCS8Key, "UTF-8"));
		} catch (AlipayApiException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	/**
	 * 交易金额	amount	是	Decimal(18,2)	单位:分
		商户支付订单号	orderNo	是	String(32)	商户系统内部的支付订单号,32个字符内、可包含字母,数字,请确保在商户系统唯一
		支付渠道	channel	是	String(24)	支付使用的第三方支付渠道,见附件<支付渠道>

		订单支付时间	timePaid	是	String(32)	时间戳
		商户号	mchNo	是	String(32)	由平台分配的商户号
		商品描述	body	是	String(128)	商品或支付单简要描述
		附加数据	description	是	String(32)	描述
		商品的标题	subject	是	String(127)	商品的标题,该参数最长为 32 个 Unicode 字符
		扩展字段	extra	是	Array	特定渠道发起交易时需要的额外参数以及部分渠道支付成功返回的额外参数。见附件<扩展字段>

		版本	version	是	String(8)	版本号,默认2.0
		签名	sign	是	
	 * @return
	 */
//	public static String getSignStringParam(String type, int amount,String orderNo,String channel,String timePaid,
//			String BusenessNo,String goodsDesc,String extraDesc,String goodsSubject,String extra,String version) {
//
//		
//		
//		JsonObject jsonExtra = new JsonObject();
//		if (type.trim().equalsIgnoreCase("信用卡")) {
//			jsonExtra.addProperty("validDate", "");
//			jsonExtra.addProperty("sCode", "");
//		}
//		jsonExtra.addProperty("mobileNo", "13433886372");
//		jsonExtra.addProperty("bankCard", "6236272202000008539");
//		jsonExtra.addProperty("userId", "rm15058931168603888");
//		jsonExtra.addProperty("notifyUrl", "http://asda/m/minsheng_pay/weixinpay_notify.php");
//		jsonExtra.addProperty("callbackUrl", "http://asda/m/minsheng_pay/weixinpay_notify.php");
//
//		extra = extra.replace("/", "\\/");
//
//		HashMap<String, String> keyMap = new HashMap<String, String>();
//		keyMap.put("amount", amount + "");
//		keyMap.put("orderNo", orderNo);
//		keyMap.put("channel", channel);
//		keyMap.put("timePaid", timePaid);
//		keyMap.put("mchNo", BusenessNo);//自己管理
//		keyMap.put("body", goodsDesc);
//		keyMap.put("description", extraDesc);
//		keyMap.put("subject", goodsSubject);
//		keyMap.put("version", version);
//		keyMap.put("extra", extra);
//		// keyMap.put("sign", "100");
//
//		/*
//		 * 生成签名: 1:把请求数组先按数组键名排序,
//		 * 
//		 * 2:(如果数组参数值有数组的先转成json字符串)然后把数组参数用##链接起来,
//		 * 
//		 * 3:最后用私钥(rsa_private_key)生成签名sign
//		 */
//
//		String[] keys = getUrlParam(new String[] { "amount", "orderNo", "channel", "timePaid", "mchNo", "body",
//				"description", "subject", "version", "extra" });
//
//		StringBuilder sb = new StringBuilder();
//		for (String key : keys) {
//			sb.append(keyMap.get(key) + "##");
//		}
//
//		String sign = sb.toString().substring(0, sb.toString().lastIndexOf("##"));
//
//		System.out.println("sign签名:" + sign);
//		return sign;
//	}
	
    public static String getSignStringParam7013(Long... currMil) {
		
		
		// amount:100
		// orderNo:1146645644fdfsdf
		// channel:7017
		// timePaid:1523156284
		// mchNo:rm15058931168603
		// body:556646466
		// description:描述
		// subject:美的空调
		// version:2.0
		// extra[]:[mobileNo:13433886372,bankCard:6236272202000008539,userId
		// :rm15058931168603,notifyUrl:http://asda/m/minsheng_pay/weixinpay_notify.php,callbackUrl:http://asda/m/minsheng_pay/weixinpay_notify.php]
		// sign:hsPEG-SmkylQKJVEYrz1cH8UkkgbZo-XPk7dt_7SoRZCbpRI47r8L0JqZzTCkFTLvjsjC2WzzxWTIHUR5eut0vtsrwwbTtr7bjdBZrtFJvsw97lNDoI0Jsb73SrJk-8KqtDh-flSz8LUOn1A1GUFTrdoAUh3dRu5D3ewm1dcFkdpz3W-FbqOhMDZ3NW4I6wFT7gkPiZpZKLHiJ8o4JhSlOJALR144saUDLIqC4qa29MCUvpl0KkOhhk6DSe0maQ-UW63OFXUKRpDtMvXET7G5pSiKk2pOWeKTQY30Oiji8kz6HqUvohOOWC29Cqle18nzTVBWMkGefY2anmfjuhBH3EFMp6sIDHnp179V9BHG6Pd2QPNU5focZcOkmKm5GXbeTWdhn21cipwUYzNTXkvBBRkHm-b14p1ctXBwUiTYTjBz-dvuagt_qMprA-HfoYARM8ff2Cqxk5iMklGRjSzR3rCkuHEZsx65jRmE07FPzPnm_uPjnfIqanhI9urjW8g

		JsonObject jsonExtra = new JsonObject();
		jsonExtra.addProperty("storeOiType", "1");
		jsonExtra.addProperty("pay_id", "unionquickpay");
		jsonExtra.addProperty("notifyUrl", "http://120.78.87.172:8088/order/notifyUrl");
		jsonExtra.addProperty("callbackUrl", "http://120.78.87.172:8088/order/callbackUrl");

		String extraStr = jsonExtra.toString();
		extraStr = extraStr.replace("/", "\\/");

		HashMap<String, String> keyMap = new HashMap<String, String>();
		keyMap.put("amount", "10000");
		keyMap.put("channel", "7013");
		String currTime = currMil[0]+"";//"" + System.currentTimeMillis();
		keyMap.put("orderNo", "1146645644fdfsdf"+currTime);
		System.out.println(currTime);
		keyMap.put("timePaid", currTime);
		keyMap.put("mchNo", "rm15058931168603");
		keyMap.put("body", "556646466");
		keyMap.put("description", "描述");
		keyMap.put("subject", "美的空调");
		keyMap.put("version", "2.0");
		keyMap.put("extra", extraStr);
		// keyMap.put("sign", "100");

		/*
		 * 生成签名: 1:把请求数组先按数组键名排序,
		 * 
		 * 2:(如果数组参数值有数组的先转成json字符串)然后把数组参数用##链接起来,
		 * 
		 * 3:最后用私钥(rsa_private_key)生成签名sign
		 */

		String[] keys = getUrlParam(new String[] { "amount", "orderNo", "channel", "timePaid", "mchNo", "body",
				"description", "subject", "version", "extra" });

		StringBuilder sb = new StringBuilder();
		for (String key : keys) {
			/*
			 * 100##556646466##7017##描述##
			 * ["[mobileNo:13433886372,bankCard:6236272202000008539,userId :rm15058931168603,notifyUrl:http:\/\/asda\/m\/minsheng_pay\/weixinpay_notify.php,callbackUrl:http:\/\/asda\/m\/minsheng_pay\/weixinpay_notify.php]"
			 * ]##rm15058931168603##1146645644fdfsdf##美的空调##1523156284##2.0
			 */
			/*
			 * if (key.equals("extra")) sb.append("[\""+keyMap.get(key)+"\"]" +
			 * "##") ; else ;
			 */
			sb.append(keyMap.get(key) + "##");
		}

		String sign = sb.toString().substring(0, sb.toString().lastIndexOf("##"));

		System.out.println("sign签名:" + sign);
		return sign;
	}
    
    /**
     * Unicode转中文  
     * @param dataStr
     * @return
     */
    public static String decodeUnicode(final String dataStr) {     
       int start = 0;     
       int end = 0;     
       final StringBuffer buffer = new StringBuffer();     
       while (start > -1) {     
           end = dataStr.indexOf("\\u", start + 2);     
           String charStr = "";     
           if (end == -1) {     
               charStr = dataStr.substring(start + 2, dataStr.length());     
           } else {     
               charStr = dataStr.substring(start + 2, end);     
           }     
           char letter = (char) Integer.parseInt(charStr, 16); // 16进制parse整形字符串。     
           buffer.append(new Character(letter).toString());     
           start = end;     
       }     
       return buffer.toString();     
    } 
	
	
//	public static String getSignStringParam() {
//		
//		
//		// amount:100
//		// orderNo:1146645644fdfsdf
//		// channel:7017
//		// timePaid:1523156284
//		// mchNo:rm15058931168603
//		// body:556646466
//		// description:描述
//		// subject:美的空调
//		// version:2.0
//		// extra[]:[mobileNo:13433886372,bankCard:6236272202000008539,userId
//		// :rm15058931168603,notifyUrl:http://asda/m/minsheng_pay/weixinpay_notify.php,callbackUrl:http://asda/m/minsheng_pay/weixinpay_notify.php]
//		// sign:hsPEG-SmkylQKJVEYrz1cH8UkkgbZo-XPk7dt_7SoRZCbpRI47r8L0JqZzTCkFTLvjsjC2WzzxWTIHUR5eut0vtsrwwbTtr7bjdBZrtFJvsw97lNDoI0Jsb73SrJk-8KqtDh-flSz8LUOn1A1GUFTrdoAUh3dRu5D3ewm1dcFkdpz3W-FbqOhMDZ3NW4I6wFT7gkPiZpZKLHiJ8o4JhSlOJALR144saUDLIqC4qa29MCUvpl0KkOhhk6DSe0maQ-UW63OFXUKRpDtMvXET7G5pSiKk2pOWeKTQY30Oiji8kz6HqUvohOOWC29Cqle18nzTVBWMkGefY2anmfjuhBH3EFMp6sIDHnp179V9BHG6Pd2QPNU5focZcOkmKm5GXbeTWdhn21cipwUYzNTXkvBBRkHm-b14p1ctXBwUiTYTjBz-dvuagt_qMprA-HfoYARM8ff2Cqxk5iMklGRjSzR3rCkuHEZsx65jRmE07FPzPnm_uPjnfIqanhI9urjW8g
//
//		JsonObject jsonExtra = new JsonObject();
//		jsonExtra.addProperty("mobileNo", "13433886372");
//		jsonExtra.addProperty("bankCard", "6236272202000008539");
//		jsonExtra.addProperty("userId", "rm15058931168603888");
//		jsonExtra.addProperty("notifyUrl", "http://asda/m/minsheng_pay/weixinpay_notify.php");
//		jsonExtra.addProperty("callbackUrl", "http://asda/m/minsheng_pay/weixinpay_notify.php");
//
//		String extraStr = jsonExtra.toString();
//		extraStr = extraStr.replace("/", "\\/");
//
//		HashMap<String, String> keyMap = new HashMap<String, String>();
//		keyMap.put("amount", "1000");
//		keyMap.put("orderNo", "1146645644fdfsdf");
//		keyMap.put("channel", "7017");
//		String currTime = "" + System.currentTimeMillis();
//		System.out.println(currTime);
//		keyMap.put("timePaid", currTime);
//		keyMap.put("mchNo", "rm15058931168603");
//		keyMap.put("body", "556646466");
//		keyMap.put("description", "描述");
//		keyMap.put("subject", "美的空调");
//		keyMap.put("version", "2.0");
//		keyMap.put("extra", extraStr);
//		// keyMap.put("sign", "100");
//
//		/*
//		 * 生成签名: 1:把请求数组先按数组键名排序,
//		 * 
//		 * 2:(如果数组参数值有数组的先转成json字符串)然后把数组参数用##链接起来,
//		 * 
//		 * 3:最后用私钥(rsa_private_key)生成签名sign
//		 */
//
//		String[] keys = getUrlParam(new String[] { "amount", "orderNo", "channel", "timePaid", "mchNo", "body",
//				"description", "subject", "version", "extra" });
//
//		StringBuilder sb = new StringBuilder();
//		for (String key : keys) {
//			/*
//			 * 100##556646466##7017##描述##
//			 * ["[mobileNo:13433886372,bankCard:6236272202000008539,userId :rm15058931168603,notifyUrl:http:\/\/asda\/m\/minsheng_pay\/weixinpay_notify.php,callbackUrl:http:\/\/asda\/m\/minsheng_pay\/weixinpay_notify.php]"
//			 * ]##rm15058931168603##1146645644fdfsdf##美的空调##1523156284##2.0
//			 */
//			/*
//			 * if (key.equals("extra")) sb.append("[\""+keyMap.get(key)+"\"]" +
//			 * "##") ; else ;
//			 */
//			sb.append(keyMap.get(key) + "##");
//		}
//
//		String sign = sb.toString().substring(0, sb.toString().lastIndexOf("##"));
//
//		System.out.println("sign签名:" + sign);
//		return sign;
//	}

}




package cn.lvche.PocketScoreShopApi.cardpay;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

public class HttpClient4 {

    public static String doGet(String url) {
        CloseableHttpClient httpClient = null;
        CloseableHttpResponse response = null;
        String result = "";
        try {
            // 通过址默认配置创建一个httpClient实例
            httpClient = HttpClients.createDefault();
            // 创建httpGet远程连接实例
            HttpGet httpGet = new HttpGet(url);
            // 设置请求头信息,鉴权
            httpGet.setHeader("Authorization", "Bearer da3efcbf-0845-4fe3-8aba-ee040be542c0");
            // 设置配置请求参数
            RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(35000)// 连接主机服务超时时间
                    .setConnectionRequestTimeout(35000)// 请求超时时间
                    .setSocketTimeout(60000)// 数据读取超时时间
                    .build();
            // 为httpGet实例设置配置
            httpGet.setConfig(requestConfig);
            // 执行get请求得到返回对象
            response = httpClient.execute(httpGet);
            // 通过返回对象获取返回数据
            HttpEntity entity = response.getEntity();
            // 通过EntityUtils中的toString方法将结果转换为字符串
            result = EntityUtils.toString(entity);
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭资源
            if (null != response) {
                try {
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != httpClient) {
                try {
                    httpClient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return result;
    }

    public static String doPost(String url, Map<String, Object> paramMap) {
        CloseableHttpClient httpClient = null;
        CloseableHttpResponse httpResponse = null;
        String result = "";
        // 创建httpClient实例
        httpClient = HttpClients.createDefault();
        // 创建httpPost远程连接实例
        HttpPost httpPost = new HttpPost(url);
        // 配置请求参数实例
        RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(35000)// 设置连接主机服务超时时间
                .setConnectionRequestTimeout(35000)// 设置连接请求超时时间
                .setSocketTimeout(60000)// 设置读取数据连接超时时间
                .build();
        // 为httpPost实例设置配置
        httpPost.setConfig(requestConfig);
        // 设置请求头
        //httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded");
        httpPost.addHeader("Content-Type", "application/json;charset=utf-8");  
        // 封装post请求参数
        if (null != paramMap && paramMap.size() > 0) {
            List<NameValuePair> nvps = new ArrayList<NameValuePair>();
            // 通过map集成entrySet方法获取entity
            Set<Entry<String, Object>> entrySet = paramMap.entrySet();
            // 循环遍历,获取迭代器
            Iterator<Entry<String, Object>> iterator = entrySet.iterator();
            while (iterator.hasNext()) {
                Entry<String, Object> mapEntry = iterator.next();
                nvps.add(new BasicNameValuePair(mapEntry.getKey(), mapEntry.getValue().toString()));
            }

            // 为httpPost设置封装好的请求参数
            try {
                httpPost.setEntity(new UrlEncodedFormEntity(nvps, "UTF-8"));
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
        try {
            // httpClient对象执行post请求,并返回响应参数对象
            httpResponse = httpClient.execute(httpPost);
            // 从响应对象中获取响应内容
            HttpEntity entity = httpResponse.getEntity();
            result = EntityUtils.toString(entity);
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭资源
            if (null != httpResponse) {
                try {
                    httpResponse.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != httpClient) {
                try {
                    httpClient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return result;
    }
    
    /**
     * json提交参数
     * @param url
     * @param paramMap
     * @return
     */
    public static String doPost(String url,String jsonEntity) {
        CloseableHttpClient httpClient = null;
        CloseableHttpResponse httpResponse = null;
        String result = "";
        // 创建httpClient实例
        httpClient = HttpClients.createDefault();
        // 创建httpPost远程连接实例
        HttpPost httpPost = new HttpPost(url);
        // 配置请求参数实例
        RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(35000)// 设置连接主机服务超时时间
                .setConnectionRequestTimeout(35000)// 设置连接请求超时时间
                .setSocketTimeout(60000)// 设置读取数据连接超时时间
                .build();
        // 为httpPost实例设置配置
        httpPost.setConfig(requestConfig);
        // 设置请求头
        //httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded");
        httpPost.addHeader("Content-Type", "application/json;charset=utf-8");  
        // 封装post请求参数

        // 为httpPost设置封装好的请求参数
        try {
        	 StringEntity stringEntity=new StringEntity(jsonEntity.toString(),"utf-8");
            httpPost.setEntity(stringEntity);
        } catch (Exception e) {
            e.printStackTrace();
        }
        
        try {
            // httpClient对象执行post请求,并返回响应参数对象
            httpResponse = httpClient.execute(httpPost);
            // 从响应对象中获取响应内容
            HttpEntity entity = httpResponse.getEntity();
            result = EntityUtils.toString(entity);
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭资源
            if (null != httpResponse) {
                try {
                    httpResponse.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != httpClient) {
                try {
                    httpClient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return result;
    }
}