JAVA实现微信支付V3

  1. 云栖社区>
  2. 博客>
  3. 正文

JAVA实现微信支付V3

dsn727455218 2018-07-04 16:43:24 浏览1209
展开阅读全文

喜欢的朋友可以关注下,粉丝也缺。


相信很多的码友在项目中都需要接入微信支付,虽说微信支付已成为一个普遍的现象,但是接入的过程中难免会遇到各种各样的坑,这一点支付宝的SDK就做的很好,已经完成的都知道了。

下面就开始我们的代码之旅,这里我将给大家提供两种支付一个是微信公众号支付,一个是APP微信支付。

一 微信公众号支付

流程:

1.获取用户openid

2.获取token,注意获取的token是有时效的而且接口是有获取上线,具体看微信API文档

3.拿商品信息(金额,名字等)去请求统一下单接口

4.统一下单接口获取预支付ID,后进行二次签名把参数返回给前端

5.前端JS中接收到参数调起支付

6.支付成功页面跳转以及回调处理

下面我们就来具体说说功能

GetOpenId:获取用户openid

public class GetOpenid extends HttpServlet {

	private static final Logger logger = Logger.getLogger(GetOpenid.class);
	
	@SuppressWarnings("unused")
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		request.setCharacterEncoding("UTF-8");
		response.setCharacterEncoding("UTF-8");
		response.setContentType("text/html;charset=UTF-8");
		HttpSession session = request.getSession();
		PreparedStatement pst=null;
		String username="";
		//获取code
		String appid=WeiXinUitls.appid;
		
		String code = request.getParameter("code");
		String rturl = request.getParameter("rturl");

		String appsecret = WeiXinUitls.appsecret;
		String grant_type = "authorization_code";
		String returnJSON = HttpTool.getToken(appid, appsecret, grant_type,code);
		JSONObject obj = JSONObject.fromObject(returnJSON);
		if(!(obj==null)){
			String openid = obj.get("openid").toString();
			String token = obj.get("access_token").toString();
			String retoken = obj.get("refresh_token").toString();
			//获取微信用户
			String getuserinfo = HttpTool.getuserinfo(token, openid);
			JSONObject fromObject = JSONObject.fromObject(getuserinfo);
			String stropenid = fromObject.get("openid").toString();
			session.setAttribute("openid", stropenid);
			String strnickname = fromObject.get("nickname").toString();
			String strcity = fromObject.get("city").toString();
			String strcountry = fromObject.get("country").toString();
			String strprovince = fromObject.get("province").toString();
			String strsex = fromObject.get("sex").toString();
		
		}
		
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}
	public static String RmFilter(String message){

		if ((message == null) || (message.equals(""))) {
	      message = "";
	    }
		message = message.replace("<",""); 
		message = message.replace(">",""); 
		message = message.replace("'","");
		message = message.replace("\"","");
		//message = message.replace("/","/");
		message = message.replace("%",""); 
		message = message.replace(";",""); 
		message = message.replace("(",""); 
		message = message.replace(")",""); 
		message = message.replace("&",""); 
		message = message.replace("+","_"); 
		return message;
	}

}

RefTicket:获取ticket

public class RefTicket extends TimerTask{

	private static ServletContext application = null;
	public RefTicket(ServletContext application){
		this.application = application;
	}
	
	public void run() {
		String jsapi_ticket = getTicket();
		if(!"".equalsIgnoreCase(jsapi_ticket)){
			this.application.setAttribute("jsapi_ticket", jsapi_ticket);
			System.out.println("jsapi_ticket:"+jsapi_ticket);
			System.out.println("jsapi_ticket--application:"+this.application.getAttribute("jsapi_ticket"));
		}
		
	}
	
	private static DefaultHttpClient httpclient;
	static {
		httpclient = new DefaultHttpClient();
		httpclient = (DefaultHttpClient) HttpClientConnectionManager
				.getSSLInstance(httpclient);
	}
	
	private String getTicket(){
		String token = (String) this.application.getAttribute("token");
		if("".equalsIgnoreCase(token) || null ==  token ){
			return "";
		}
		HttpGet get = HttpClientConnectionManager
				.getGetMethod("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+token+"&type=jsapi");
						
		HttpResponse response;
		try {
			response = httpclient.execute(get);
			String jsonStr = EntityUtils
					.toString(response.getEntity(), "utf-8");
			JSONObject demoJson = JSONObject.fromObject(jsonStr);
			return demoJson.getString("ticket");
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (JSONException e) {
			e.printStackTrace();
		}
		return "";
		
	}

}

RefToken:获取token

public class RefToken extends TimerTask{

	private  final static String appId = "wx842b838875cd9bd3";
	private final static String appSecret = "ce7948b66d04b5ae714c9d0e4bc6eba9";
	private static ServletContext application = null;
	public RefToken(ServletContext application){
		this.application = application;
	}
	
	public void run() {
		String token = getAccessToken(appId,appSecret);
		if(!"".equalsIgnoreCase(token)){
			this.application.setAttribute("token", token);
			System.out.println("token---init:"+token);
			 String ticket = getTicket();
			this.application.setAttribute("jsapi_ticket", ticket);
			System.out.println("ticket--init:"+ticket);
		}
	}
	
	private static DefaultHttpClient httpclient;
	static {
		httpclient = new DefaultHttpClient();
		httpclient = (DefaultHttpClient) HttpClientConnectionManager
				.getSSLInstance(httpclient);
	}
	
	private static String getAccessToken(String appid, String secret) {
		HttpGet get = HttpClientConnectionManager
				.getGetMethod("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="
						+ appid + "&secret=" + secret);
		HttpResponse response;
		try {
			response = httpclient.execute(get);
			String jsonStr = EntityUtils
					.toString(response.getEntity(), "utf-8");
			JSONObject demoJson = JSONObject.fromObject(jsonStr);
			return demoJson.getString("access_token");
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (JSONException e) {
			e.printStackTrace();
		}
		return "";
	}
	
	private String getTicket(){
		String token = (String) this.application.getAttribute("token");
		if("".equalsIgnoreCase(token) || null ==  token ){
			return "";
		}
		HttpGet get = HttpClientConnectionManager
				.getGetMethod("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+token+"&type=jsapi");
						
		HttpResponse response;
		try {
			response = httpclient.execute(get);
			String jsonStr = EntityUtils
					.toString(response.getEntity(), "utf-8");
			JSONObject demoJson = JSONObject.fromObject(jsonStr);
			return demoJson.getString("ticket");
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (JSONException e) {
			e.printStackTrace();
		}
		return "";
		
	}

}
GetSignature :
public class GetSignature extends HttpServlet {
	private static final long serialVersionUID = 1L;
	private static final Logger logger = Logger.getLogger(GetSignature.class);
    public GetSignature() {
        super();
    }


	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
	}

	
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		try{
			response.setCharacterEncoding("UTF-8");
			request.setCharacterEncoding("UTF-8");
			PrintWriter out = response.getWriter();
			//你的支付目录的Url,不需要转义,不包含#及其后面部分
			String url = request.getParameter("url");
			ServletContext application = this.getServletContext();
			String jsapi_ticket=String.valueOf(application.getAttribute("jsapi_ticket"));
			JSONObject obj = WeixinPay.getSignature(url, jsapi_ticket);
//			Map<String, String> sign = Sign.sign(jsapi_ticket,url);
			out.print(obj.toString());
			out.flush();
			out.close();
		}catch (Exception e) {
			logger.error(e.getMessage(), e);
			e.printStackTrace();
		}
		
	}

}

JS中初始化:

//支付初始化
		function initPay(openId){
			//获取当前页面URL
			var geturl=window.location.href.split('#')[0];
			var getencodeurl=encodeURIComponent(geturl);
			$.ajax({
				type : 'POST',
				url : "/GetSignature?url="+getencodeurl,
				contentType:"application/x-www-form-urlencoded", 
				success : function(response) {
					var params = eval("(" + response + ")");
					wx.config({
					 	debug: false,
						appId : params.appid, // 必填,公众号的唯一标识
						timestamp : params.timestamp, // 必填,生成签名的时间戳
						nonceStr : params.nonceStr,  // 必填,生成签名的随机串
						signature : params.signature,// 必填,签名,见附录1
						jsApiList : [ 'chooseWXPay']
					});
					wx.ready(function() {
						// config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
						$("#weixinpay").on('click', function(t) {
// 							var c_sname =getQueryString("c_sname");
							var paymoney=document.getElementById("money").value;//实际付款
							var phone=document.getElementById("phone").value;//手机号
							
							if(phone==null||phone==""){
								Dialog.alert("请填写手机号码!");
							}else{
								$("#weixinpay").unbind('click');
								$("#mcover").css("display","block"); 
// 								alert($("#payment").serialize());
								$.ajax({
									type : 'POST',
// 									url:"/topayServlet",
									url : "/topayServlet?openId="+openId+"&money="+paymoney+"&phone="+phone,
// 									data:$("#payment").serialize(),// 提交formid
// 									async: false,
									success : function(response) {
											var params = eval("(" + response + ")");
											$("#mcover").css("display","none");
											wx.chooseWXPay({
												appId : params.appId,
												timestamp :params.timeStamp, // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
												nonceStr  : params.nonceStr, // 支付签名随机串,不长于 32 位
												package : params.package, // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=***)
												signType :params.signType, 
												paySign : params.paySign, 
												success : function(res) {
	 												if(res.errMsg == "chooseWXPay:ok" ) {
		 												window.location.href="/3g/shareBusiness.jsp?sid="+sp+"&c_sname="+skf+"&phone="+phone;
								                        //支付成功
								                        $("#weixinpay").bind('click');
								                    }
												},
											 	cancel: function (res) { 
											 		window.location.href="/3g/shop_list.jsp";
											 		$("#weixinpay").bind('click');
											    },
											    fail:function(res){
											   		window.location.href="/3g/shop_list.jsp";
											   		$("#weixinpay").bind('click');
											    }
											});
									},
									error : function() {
// 										window.location.reload();
// 										alert("服务器异常,统一下单接口出错!");
									}
								})
							}
							
						});
					});
					// config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
// 					wx.error(function(res){
// 						alert('wx.error: '+JSON.stringify(res));
// 					});
				},
				error : function() {
// 					window.location.reload();
// 					Dialog.alert("服务器异常,支付初始化失败!");
				}
			})
	}

TopayServlet:统一下单接口

/**
 * 支付请求处理
 * @author dsn
 *
 */
public class TopayServlet extends HttpServlet {


	/**
	 * 
	 */
	private static final long serialVersionUID = 1359159929707330023L;
	private static final Logger logger = Logger.getLogger(TopayServlet.class);
	private String finalmoney=null;
	private String createOrderURL = "https://api.mch.weixin.qq.com/pay/unifiedorder";
	//商户相关资料 
	private	String appid = WeiXinUitls.appid;
	private	String appsecret = WeiXinUitls.appsecret;
	private	String partner = WeiXinUitls.partner;
	private	String partnerkey = WeiXinUitls.partnerkey;
	@SuppressWarnings("static-access")
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setCharacterEncoding("UTF-8");
		request.setCharacterEncoding("UTF-8");
		PrintWriter out = response.getWriter();
		//网页授权后获取传递的参数
		String openId = request.getParameter("openId"); 	
		String sid = request.getParameter("sssp"); //商户ID
		String money = request.getParameter("money");//实际付款
		String phone = request.getParameter("phone");//手机号
		
		String c_sname = new String(skf.getBytes("ISO-8859-1"), "utf-8");
		//拼接字符串
		String zong=sid+"*"+money+"*"+phone+"*"+jfdy;
		//金额转化为分为单位
		String money2 = TenpayUtil.getMoney(money);
		//获取openId后调用统一支付接口https://api.mch.weixin.qq.com/pay/unifiedorder
				String currTime = TenpayUtil.getCurrTime();
				//8位日期
				String strTime = currTime.substring(8, currTime.length());
				//四位随机数
				String strRandom = TenpayUtil.buildRandom(4) + "";
				//10位序列号,可以自行调整。
				String strReq = strTime + strRandom;
				//商户号
				String mch_id = partner;
				//子商户号  非必输
				//String sub_mch_id="";
				//设备号   非必输
				String device_info="WEB";
				//随机数 
				String nonce_str = strReq;
				//商品描述
				//String body = describe;
				//商品描述根据情况修改
				String body = c_sname;
				//附加数据
				String attach = zong;
				//商户订单号
				String out_trade_no = NonceString.generate();
				//int intMoney = Integer.parseInt(finalmoney);
				//总金额以分为单位,不带小数点
				//int total_fee = intMoney;
				//订单生成的机器 IP
				String spbill_create_ip = request.getRemoteAddr();
				//订 单 生 成 时 间   非必输
				String time_start =TenpayUtil.getStartTime();
				//订单失效时间      非必输
				String time_expire =TenpayUtil.getEndTime();;
				//商品标记   非必输
				String goods_tag = "WXG";
				//这里notify_url是 支付完成后微信发给该链接信息,可以判断会员是否支付成功,改变订单状态等。
				String notify_url ="http://www.yiquanmian.com/notifyServlet";
				String trade_type = "JSAPI";
				String openid = openId;
				//非必输
//				String product_id = "";
				SortedMap<String, String> packageParams = new TreeMap<String, String>();
				packageParams.put("appid", appid);  
				packageParams.put("mch_id", mch_id);  
				packageParams.put("nonce_str", nonce_str);  
				packageParams.put("body", body);  
				packageParams.put("attach", attach);  
				packageParams.put("out_trade_no", out_trade_no);  
				packageParams.put("total_fee", money2);  
				packageParams.put("spbill_create_ip", spbill_create_ip);
				packageParams.put("time_start", time_start); 
				packageParams.put("time_expire", time_expire); 
				packageParams.put("notify_url", notify_url);  
				packageParams.put("trade_type", trade_type);  
				packageParams.put("openid", openid);  
				RequestHandler reqHandler = new RequestHandler(request, response);
				reqHandler.init(appid, appsecret, partnerkey);
				String sign = reqHandler.createSign(packageParams);
				String xml="<xml>"+
						"<appid>"+appid+"</appid>"+
						"<mch_id>"+mch_id+"</mch_id>"+
						"<nonce_str>"+nonce_str+"</nonce_str>"+
						"<sign>"+sign+"</sign>"+
						"<body><![CDATA["+body+"]]></body>"+
						"<attach>"+attach+"</attach>"+
						"<out_trade_no>"+out_trade_no+"</out_trade_no>"+
						"<total_fee>"+money2+"</total_fee>"+
						"<spbill_create_ip>"+spbill_create_ip+"</spbill_create_ip>"+
						"<time_start>"+time_start+"</time_start>"+
						"<time_expire>"+time_expire+"</time_expire>"+
						"<notify_url>"+notify_url+"</notify_url>"+
						"<trade_type>"+trade_type+"</trade_type>"+
						"<openid>"+openid+"</openid>"+
						"</xml>";
				String allParameters = "";
				try {
					allParameters =  reqHandler.genPackage(packageParams);
				} catch (Exception e) {
					logger.error(e.getMessage(), e);
					e.printStackTrace();
				}
				String prepay_id="";
				try {
					prepay_id= new GetWxOrderno().getPayNo(createOrderURL, xml);
//					JSONObject xmls = p.getJSONObject("xml");
					if(prepay_id.equals("")){
						request.setAttribute("ErrorMsg", "统一支付接口获取预支付订单出错");
						response.sendRedirect("error.jsp");
					}
				} catch (Exception e1) {
					logger.error(e1.getMessage(), e1);
					e1.printStackTrace();
				}
				SortedMap<String, String> finalpackage = new TreeMap<String, String>();
				String appid2 = appid;
				String timestamp = Sha1Util.getTimeStamp();
				String nonceStr2 = nonce_str;
				String prepay_id2 = "prepay_id="+prepay_id;
				String packages = prepay_id2;
				finalpackage.put("appId", appid2);  
				finalpackage.put("timeStamp", timestamp);  
				finalpackage.put("nonceStr", nonceStr2);  
				finalpackage.put("package", packages);  
				finalpackage.put("signType", "MD5");
				String finalsign = reqHandler.createSign(finalpackage);
				finalpackage.put("paySign",finalsign);
				JSONObject jsonObject1 = JSONObject.fromObject(finalpackage);   
				out.print(jsonObject1);
				out.flush();
				out.close();
				 
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}

NotifyServlet:回调处理类

public class NotifyServlet extends HttpServlet {

	/**
	 * 
	 */
	private static final long serialVersionUID = 6743167121907086323L;
	private static final Logger logger = Logger.getLogger(NotifyServlet.class);
	private String resultXML;


	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
//		response.setContentType("text/html;charset=utf-8");
		HttpSession session = request.getSession();
		int i = 0;
		//
		String inputLine;
		String notityXml = "";
		String resXml = "";
		try {
			while ((inputLine = request.getReader().readLine()) != null) {
				notityXml += inputLine;
			}
			request.getReader().close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		try {
			Map m = GetWxOrderno.parseXmlToList2(notityXml);
			WxPayResult wpr = new WxPayResult();
			String appid = m.get("appid").toString();
			String bank_type = m.get("bank_type").toString();
			String attach = m.get("attach").toString();
			String cash_fee = m.get("cash_fee").toString();
			String fee_type = m.get("fee_type").toString();
			String is_subscribe = m.get("is_subscribe").toString();
			String mch_id = m.get("mch_id").toString();
			String nonce_str = m.get("nonce_str").toString();
			String openid = m.get("openid").toString();
			String out_trade_no = m.get("out_trade_no").toString();
			String result_code = m.get("result_code").toString();
			String return_code = m.get("return_code").toString();
			String sign = m.get("sign").toString();
			String time_end = m.get("time_end").toString();
			String times = time_end.substring(0, 4) + "-"
					+ time_end.substring(4, 6) + "-" + time_end.substring(6, 8)
					+ " " + time_end.substring(8, 10) + ":"
					+ time_end.substring(10, 12) + ":"
					+ time_end.substring(12, 14);
			Timestamp tstamp = Timestamp.valueOf(times);
			String total_fee = m.get("total_fee").toString();
			int totalint = Integer.parseInt(total_fee);
			double pasint = totalint * 0.01;
			String trade_type = m.get("trade_type").toString();
			String transaction_id = m.get("transaction_id").toString();
			
			if ("SUCCESS".equals(result_code)) {
				// 支付成功
				// 处理附加数据
				
				// 判断订单是否已经存在
				
				if (rs.next()) {
					if(transaction_id.equals(rs.getString("ddh"))){
						System.out.println("订单已经存在");
					}
				} else {
					
					
					
					// ----------------------------------------------------发送短信-------------------------------------------
					// 给用户发短信
					

					// 给商家发短信
					
					

				}
				resXml = "<xml>"
						+ "<return_code><![CDATA[SUCCESS]]></return_code>"
						+ "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
			} else {
				resXml = "<xml>"
						+ "<return_code><![CDATA[FAIL]]></return_code>"
						+ "<return_msg><![CDATA[false]]></return_msg>"
						+ "</xml> ";
			}

			BufferedOutputStream out = new BufferedOutputStream(
					response.getOutputStream());
			out.write(resXml.getBytes());
			out.flush();
			out.close();
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			e.printStackTrace();
		}

	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}
}

上面就是微信公众号的核心代码,需要源码的可以去我的地址下

https://download.csdn.net/download/dsn727455218/9325425

重点提示一下一定要在js的页面中引入微信的js文件不然会调不起支付的

<script type="text/javascript" charset="UTF-8"
src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>


二 APP支付

流程:

1.Android引入微信支付的SDK

2.拿商品信息请求统一下单接口

3.统一下单接口获取预支付ID,后进行二次签名把参数返回给前端

4.前端JS中接收到参数调起支付

5.支付成功页面跳转以及回调处理

具体骚操作:

首先在Constants.java中设置相关参数,具体请查看该文件注释,同时根据注释修改androidmanifest.xml文件

要保证: 包名和开放平台一致,签名和开放平台一致,并且再公众平台做设置,详情请阅读: http://pay.weixin.qq.com/wiki/doc/api/app.php?chapter=8_5,注意:此条仅仅适用于android,ios不受签名文件限制

要保证回调类WXPayEntryActivity.java文件必须位于包名的wxapi目录下,否则会导致无法回调的情况,注意:此条仅仅适用于android,ios有固定格式,请参考ios demo

上面是Android的注意事项

androidmanifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="你的项目包名"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="4" />

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    
    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        
        <activity
            android:name=".PayActivity"
            android:label="@string/app_name"
            android:exported="true"
            android:launchMode="singleTop">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            
            <intent-filter>
                <action android:name="android.intent.action.VIEW"/>
                <category android:name="android.intent.category.DEFAULT"/>
                <data android:scheme="你的开发者ID"/>
            </intent-filter>
        </activity>
        
        <activity
            android:name=".wxapi.WXPayEntryActivity"
            android:exported="true"
            android:launchMode="singleTop"/>
        

        <receiver
            android:name="net.sourceforge.simcpux.AppRegister">
            <intent-filter>
                <action android:name="com.tencent.mm.plugin.openapi.Intent.ACTION_REFRESH_WXAPP" />
            </intent-filter>
        </receiver>
        
    </application>

</manifest>
PayActivity:调起支付类
public class PayActivity extends Activity {

	private static final String TAG = "MicroMsg.SDKSample.PayActivity";

	PayReq req;
	final IWXAPI msgApi = WXAPIFactory.createWXAPI(this, null);
	TextView show;
	Map<String,String> resultunifiedorder;
	StringBuffer sb;
	
	private IWXAPI api; // IWXAPI 是第三方app和微信通信的openapi接口

	private Context context;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.pay);

        //微信appId
        api = WXAPIFactory.createWXAPI( this, Constants.APP_ID);
        api.registerApp(Constants.APP_ID);
        final Button appayBtn = (Button) findViewById(R.id.appay_btn);
        appayBtn.setOnClickListener(new View.OnClickListener() {
        	
            @Override
            public void onClick(View v) {
                String url = "http://192.168.0.104:8080/wx_pay/servlet/TopayServlet";

                Toast.makeText(PayActivity.this, "获取订单中...", Toast.LENGTH_SHORT).show();
                try{
                    byte[] buf = Util.httpGet(url);
                    if (buf != null && buf.length > 0) {
                        String content = new String(buf);
                        Log.e("get server pay params:",content);
                        JSONObject json = new JSONObject(content); 
                       
                        if(null != json && json.getString("returnstatus").equals("success") ){
                        	 String retmsg = json.getString("retmsg");
                             JSONObject json2 = new JSONObject(retmsg); 
                            PayReq req = new PayReq();
                            //req.appId = "wxf8b4f85f3a794e77";  // 测试用appId
                            Log.e("get appid  :",json2.getString("appid"));
                            Log.e("get partnerid  :",json2.getString("partnerid"));
                            Log.e("get prepayid  :",json2.getString("prepayid"));
                            Log.e("get noncestr  :",json2.getString("noncestr"));
                            Log.e("get timestamp  :",json2.getString("timestamp"));
                            Log.e("get package  :",json2.getString("package"));
                            Log.e("get sign  :",json2.getString("sign"));
                            //从服务器获取
                            req.appId           = json2.getString("appid");
                            req.partnerId       = json2.getString("partnerid");
                            req.prepayId        = json2.getString("prepayid");
                            req.nonceStr        = json2.getString("noncestr");
                            req.timeStamp       = json2.getString("timestamp");
                            req.packageValue    = json2.getString("package");
                            req.sign            = json2.getString("sign");
                            req.extData         = "app data"; // optional
                            Toast.makeText(PayActivity.this, "正常调起支付", Toast.LENGTH_SHORT).show();
                            // 在支付之前,如果应用没有注册到微信,应该先调用IWXMsg.registerApp将应用注册到微信
                            
                            api.sendReq(req);
                            Log.e("get api.sendReq(req)  :",api.sendReq(req)+"");
                        }else{
                            Log.d("PAY_GET", "返回错误"+json.getString("retmsg"));
                            Toast.makeText(PayActivity.this, "返回错误"+json.getString("retmsg"), Toast.LENGTH_SHORT).show();
                        }
                    }else{
                        Log.d("PAY_GET", "服务器请求错误");
                        Toast.makeText(PayActivity.this, "服务器请求错误", Toast.LENGTH_SHORT).show();
                    }
                }catch(Exception e){
                    Log.e("PAY_GET", "异常:"+e.getMessage());
                    Toast.makeText(PayActivity.this, "异常:"+e.getMessage(), Toast.LENGTH_SHORT).show();
                }
//                appayBtn.setEnabled(true);
            }
        });     
    }

WXPayEntryActivity:支付成功页面跳转类

public class WXPayEntryActivity extends Activity implements IWXAPIEventHandler{
	
	private static final String TAG = "MicroMsg.SDKSample.WXPayEntryActivity";
	
    private IWXAPI api;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.pay_result);
        //微信APP_ID
        api = WXAPIFactory.createWXAPI(this, Constants.APP_ID);
        api.handleIntent(getIntent(), this);
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        setIntent(intent);
        api.handleIntent(intent, this);
    }

    @Override
    public void onReq(BaseReq req) {
    }

    @Override
    public void onResp(BaseResp resp) {
        Log.d(TAG, "onPayFinish, errCode = " + resp.errCode);
        String msg = "";
        if (resp.errCode == 0) {
            msg = "支付成功";
        } else if (resp.errCode == -1) {
            msg = "已取消支付";
        } else if (resp.errCode == -2) {
            msg = "支付失败";
        }
        Toast.makeText(WXPayEntryActivity.this, resp.errCode+"------"+msg, Toast.LENGTH_SHORT).show();
        finish();
    }
}
PrepayId:统一下单接口
/**
 * Servlet implementation class prepayid
 */
public class PrepayId extends HttpServlet {
    private static final long serialVersionUID = 1L;
    // key设置路径:微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->密钥设置

    //TODO
    private static String KEY = "你的商户平台key";

    /**
     * Default constructor.
     */
    public PrepayId() {}

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
     *      response)
     */
    @SuppressWarnings("rawtypes")
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String url = "https://api.mch.weixin.qq.com/pay/unifiedorder";

        SortedMap<String, String> map = new TreeMap<String, String>();
        //TODO 你的appid
        map.put("appid", "");
        //TODO 你的商户id
        map.put("mch_id", "");
        map.put("nonce_str", String.valueOf(System.currentTimeMillis()));
        map.put("body", "lidongliang");
        map.put("out_trade_no", String.valueOf(System.currentTimeMillis()));
        map.put("total_fee", "1");
        map.put("spbill_create_ip", "192.168.0.105");
        map.put("notify_url", "你的回调地址");
        map.put("trade_type", "APP");
        String sign = createSign(map);
        map.put("sign", sign);

        // 生成XMl
        Set set = map.entrySet();
        Iterator it = set.iterator();
        StringBuffer sb = new StringBuffer();
        sb.append("<xml>");
        while (it.hasNext()) {
            Map.Entry entry = (Map.Entry) it.next();
            String key = (String) entry.getKey();
            String value = (String) entry.getValue();
            sb.append("<" + key + "><![CDATA[");
            sb.append(value);
            sb.append("]]></" + key + ">");
        }
        sb.append("</xml>");

        try {
            System.out.println("111111111" + sb.toString());
            String postData = NetUtil.doPost(url, sb.toString());
            System.out.println("222222222" + postData.toString());
            SortedMap<String, String> test = new TreeMap<String, String>();
            JSONObject json = XML.toJSONObject(postData).getJSONObject("xml");

            test.put("appid", json.getString("appid"));
            test.put("partnerid", json.getString("mch_id"));
            test.put("prepayid", json.getString("prepay_id"));
            test.put("package", "Sign=WXPay");
            test.put("noncestr", String.valueOf(System.currentTimeMillis()));
            test.put("timestamp", String.valueOf(System.currentTimeMillis() / 1000));
            test.put("sign", createSign(test));

            response.getWriter().append(new JSONObject(test).toString());
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
     *      response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {}

    /**
     * 微信支付签名算法sign
     * 
     * @param characterEncoding
     * @param parameters
     * @return
     */
    @SuppressWarnings("rawtypes")
    public static String createSign(SortedMap<String, String> parameters) {
        StringBuffer sb = new StringBuffer();
        // 所有参与传参的参数按照accsii排序(升序)
        Set es = parameters.entrySet();
        Iterator it = es.iterator();
        while (it.hasNext()) {
            Map.Entry entry = (Map.Entry) it.next();
            String k = (String) entry.getKey();
            Object v = entry.getValue();
            if (null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) {
                sb.append(k + "=" + v + "&");
            }
        }
        sb.append("key=" + KEY);
        System.out.println("字符串拼接后是:" + sb.toString());
        String sign = MD5Util.MD5Encode(sb.toString(), "UTF-8").toUpperCase();
        System.out.println("sign:" + sign);
        return sign;
    }
}
NotifyHandle:支付回调类

@Controller
@RequestMapping("notifyhandle")
public class NotifyHandle extends BaseAction{
	@Resource
	private ServiceSinggleService ssService;
	@Resource
	private ElutionRecordService edService;
	@Resource
	private AppUserService appuserService;
	@Resource
	private MsgJpushService mjService;
	private static final Logger logger = Logger.getLogger(NotifyHandle.class);
	@ResponseBody
	@RequestMapping(value="/notify")
	public String notify(ServiceSinggle ssinggle,ElutionRecord record,MsgJpush msgjpush,AppUser appuser,HttpServletRequest request,HttpSession session,HttpServletResponse response){
		String inputLine;
		String notityXml = "";
		String resXml = "";
		try {
			while ((inputLine = request.getReader().readLine()) != null) {
				notityXml += inputLine;
			}
			request.getReader().close();
			Map m = GetWxOrderno.parseXmlToList2(notityXml);
			String result_code = m.get("result_code").toString();
			if("SUCCESS".equals(result_code)){
				//查询是否存在订单
				String attach = m.get("attach").toString();
				String out_trade_no = m.get("out_trade_no").toString();
				String time_end = m.get("time_end").toString();
				String total_fee = m.get("total_fee").toString();
				int totalint = Integer.parseInt(total_fee);
				//订单更新 继续你的逻辑操作
			} else {
				resXml = "<xml>"
						+ "<return_code><![CDATA[FAIL]]></return_code>"
						+ "<return_msg><![CDATA[false]]></return_msg>"
						+ "</xml> ";
			}
			BufferedOutputStream out = new BufferedOutputStream(
					response.getOutputStream());
			out.write(resXml.getBytes());
			out.flush();
			out.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return "";
	}
}

APP的微信支付就是这么的简单:上面我贴的核心代码,一些工具类没有贴出来需要demo可以去下面地址下载

https://download.csdn.net/download/dsn727455218/10304062

如果遇到签名错误,缺少参数,返回-1,等错误请参考我的另一篇文章:微信支付遇到的几个问题

https://blog.csdn.net/dsn727455218/article/details/70139320

看着是不是很简单,完美的解决。

到这里已经完成了微信支付功能,如有需要可以加我Q群【308742428】大家一起讨论技术。

后面会不定时为大家更新文章,敬请期待。

喜欢的朋友可以关注下,粉丝也缺。


网友评论

登录后评论
0/500
评论
dsn727455218
+ 关注