移动大脑-SpringMVc搭建RestFul后台服务(六)-微信支付(Android)

445 阅读17分钟
原文链接: blog.csdn.net

目录:

        移动大脑-SpringMVc搭建RestFul后台服务(一)-环境搭建

        移动大脑-SpringMVc搭建RestFul后台服务(二)-配置mysql数据库

        移动大脑-SpringMVc搭建RestFul后台服务(三)-RestFul接口编写(模拟用户注册登录)

        移动大脑-SpringMVc搭建RestFul后台服务(四)-添加Token过滤器

        移动大脑-SpringMVc搭建RestFul后台服务(五)-支付宝支付

         移动大脑-SpringMVc搭建RestFul后台服务(六)-微信支付(Android)

        

        在上一篇《移动大脑-SpringMVc搭建RestFul后台服务(五)-支付宝支付》博客中已经实现了支付宝支付,接下来我满再添加微信支付功能,这样支付功能基本就完整了,银联就不考虑了

        原来我写过一篇《Android微信支付爬坑》的博客,里面讲的就是完全从APP端发起的支付,有需要的可以看看。


先来张实例图:




        首先开始准备工作,在微信开发平台(https://open.weixin.qq.com/)申请自己的应用,并填写正确的包名和签名,审核通过后再申请微信支付功能,此时或得到商户账号,并在商户后台设置自己的32位key,以上都准备好后,并下载所需要的微信开发jar包(主要是生成签名和网络访问的工具类,可根据自己情况来改成自己的工具类),就可以开始微信的开发了。


        微信支付流程和支付宝其实也是一样的:APP请求服务端支付接口---->服务端生成本地订单---->服务端构造数据到微信端生成预支付订单---->服务端拿到预支付订单返回给APP---->APP拿到微信支付信息调起微信支付---->微信支付成功通过通知APP---->微信异步调用服务端支付验证接口---->服务端处理验证结果返回给微信,就完成了一次支付过程。


开始编码:

一、在PaySerVice中添加微信下单

  1. else if(payWay == 2)//微信支付  
  2.             {  
  3.                 SortedMap<String, String> parameters = new TreeMap<String, String>();  
  4.                 parameters.put("appid", WX_APPID);  
  5.                 parameters.put("body", orderBean.getSubject());  
  6.                 parameters.put("mch_id", WX_MCHID);  
  7.                 parameters.put("nonce_str", CommonUtils.genNonceStr());  
  8.                 parameters.put("notify_url""http://10.50.50.205:8080/pay/verifywxpayresult.do");  
  9.                 parameters.put("out_trade_no", orderBean.getOrderNo());  
  10.                 parameters.put("total_fee""50");  
  11.                 parameters.put("trade_type""APP");  
  12.                 parameters.put("spbill_create_ip""196.168.1.1");  
  13.                 parameters.put("sign", CommonUtils.createSign("UTF-8", parameters, WX_KEY)); //传入签名好的参数值  
  14.   
  15.                 StringBuilder xmlBuilder = new StringBuilder();  
  16.                 xmlBuilder.append("<xml>");  
  17.                 Set es = parameters.entrySet();//所有参与传参的参数按照accsii排序(升序)  
  18.                 Iterator it = es.iterator();  
  19.                 CommonUtils.createXml(it, xmlBuilder);  
  20.                 xmlBuilder.append("</xml>");  
  21.                 System.out.println(xmlBuilder.toString());  
  22.                 try {  
  23.                     String url = "https://api.mch.weixin.qq.com/pay/unifiedorder";  
  24.                     byte[] buf = Util.httpPost(url,  new String(xmlBuilder.toString().getBytes("UTF-8"), "ISO8859-1"));  
  25.                     String content = new String(buf);  
  26.                     System.out.println("content:" + content);  
  27.   
  28.                     Map<String, String> map = CommonUtils.xmlToMap(content);  
  29.                     String nonceStr = CommonUtils.genNonceStr();  
  30.                     String timeStamp = String.valueOf(CommonUtils.genTimeStamp());  
  31.   
  32.                     SortedMap<String, String> signparameters = new TreeMap<String, String>();  
  33.                     signparameters.put("appid", map.get( "appid"));  
  34.                     signparameters.put("partnerid", map.get( "mch_id"));  
  35.                     signparameters.put("prepayid", map.get( "prepay_id"));  
  36.                     signparameters.put("package" "Sign=WXPay");  
  37.                     signparameters.put("noncestr", nonceStr);  
  38.                     signparameters.put("timestamp", timeStamp);  
  39.   
  40.                     wxPayBean = new WxPayBean();  
  41.                     wxPayBean.setOrderId(order.getOrderNo());  
  42.                     wxPayBean.setAppid(map.get("appid"));  
  43.                     wxPayBean.setPartnerid(map.get("mch_id"));  
  44.                     wxPayBean.setPrepayid(map.get("prepay_id"));  
  45.                     wxPayBean.setNoncestr(nonceStr);  
  46.                     wxPayBean.setTimestamp(timeStamp);  
  47.                     wxPayBean.setPackageValue("Sign=WXPay");  
  48.                     wxPayBean.setSign(CommonUtils.createSign("UTF-8", signparameters, WX_KEY));  
  49.   
  50.                 } catch (Exception e) {  
  51.                     e.printStackTrace();  
  52.                 }  
  53.             }  
        else if(payWay == 2)//微信支付
                    {
                        SortedMap<String, String> parameters = new TreeMap<String, String>();
                        parameters.put("appid", WX_APPID);
                        parameters.put("body", orderBean.getSubject());
                        parameters.put("mch_id", WX_MCHID);
                        parameters.put("nonce_str", CommonUtils.genNonceStr());
                        parameters.put("notify_url", "http://10.50.50.205:8080/pay/verifywxpayresult.do");
                        parameters.put("out_trade_no", orderBean.getOrderNo());
                        parameters.put("total_fee", "50");
                        parameters.put("trade_type", "APP");
                        parameters.put("spbill_create_ip", "196.168.1.1");
                        parameters.put("sign", CommonUtils.createSign("UTF-8", parameters, WX_KEY));//传入签名好的参数值

                        StringBuilder xmlBuilder = new StringBuilder();
                        xmlBuilder.append("<xml>");
                        Set es = parameters.entrySet();//所有参与传参的参数按照accsii排序(升序)
                        Iterator it = es.iterator();
                        CommonUtils.createXml(it, xmlBuilder);
                        xmlBuilder.append("</xml>");
                        System.out.println(xmlBuilder.toString());
                        try {
                            String url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
                            byte[] buf = Util.httpPost(url, new String(xmlBuilder.toString().getBytes("UTF-8"), "ISO8859-1"));
                            String content = new String(buf);
                            System.out.println("content:" + content);

                            Map<String, String> map = CommonUtils.xmlToMap(content);
                            String nonceStr = CommonUtils.genNonceStr();
                            String timeStamp = String.valueOf(CommonUtils.genTimeStamp());

                            SortedMap<String, String> signparameters = new TreeMap<String, String>();
                            signparameters.put("appid", map.get("appid"));
                            signparameters.put("partnerid", map.get("mch_id"));
                            signparameters.put("prepayid", map.get("prepay_id"));
                            signparameters.put("package", "Sign=WXPay");
                            signparameters.put("noncestr", nonceStr);
                            signparameters.put("timestamp", timeStamp);

                            wxPayBean = new WxPayBean();
                            wxPayBean.setOrderId(order.getOrderNo());
                            wxPayBean.setAppid(map.get("appid"));
                            wxPayBean.setPartnerid(map.get("mch_id"));
                            wxPayBean.setPrepayid(map.get("prepay_id"));
                            wxPayBean.setNoncestr(nonceStr);
                            wxPayBean.setTimestamp(timeStamp);
                            wxPayBean.setPackageValue("Sign=WXPay");
                            wxPayBean.setSign(CommonUtils.createSign("UTF-8", signparameters, WX_KEY));

                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }

二、在PayAction中添加微信支付回调接口


  1. /** 
  2.      * 微信回调接口 
  3.      * @param request 
  4.      * @param resp 
  5.      * @return 
  6.      */  
  7.     @ResponseBody  
  8.     @RequestMapping(value="/verifywxpayresult.do", method=RequestMethod.POST)  
  9.     public String verifyWxPayRight(HttpServletRequest request, HttpServletResponse resp)  
  10.     {  
  11.         System.out.println("-----------------------------------come here wxpay--------------------------------");  
  12.         synchronized (wxlock) {  
  13.             System.out.println("-----------------------------------come here wxpay 2--------------------------------");  
  14.   
  15.             BufferedReader reader = null ;  
  16.   
  17.             try {  
  18.                 reader = request.getReader() ;  
  19.                 String line = "" ;  
  20.                 String xmlString = null ;  
  21.                 StringBuffer inputString = new StringBuffer() ;  
  22.   
  23.                 while( (line = reader.readLine()) != null ){  
  24.                     inputString.append(line) ;  
  25.                 }  
  26.   
  27.                 xmlString = inputString.toString() ;  
  28.                 request.getReader().close();  
  29.                 System.out.println("xmlString:" + xmlString);  
  30.                 Map<String, String> map = CommonUtils.xmlToMap(xmlString);  
  31.   
  32.                 System.out.println("result sign:" + map.get("sign"));  
  33.                 SortedMap<String, String> parameters = new TreeMap<String, String>();  
  34.                 parameters.put("appid", map.get("appid"));  
  35.                 parameters.put("bank_type", map.get("bank_type"));  
  36.                 parameters.put("cash_fee", map.get("cash_fee"));  
  37.                 parameters.put("fee_type", map.get("fee_type"));  
  38.                 parameters.put("is_subscribe", map.get("is_subscribe"));  
  39.                 parameters.put("mch_id", map.get("mch_id"));  
  40.                 parameters.put("nonce_str", map.get("nonce_str"));  
  41.                 parameters.put("openid", map.get("openid"));  
  42.                 parameters.put("out_trade_no", map.get("out_trade_no"));  
  43.                 parameters.put("result_code", map.get("result_code"));  
  44.                 parameters.put("return_code", map.get("return_code"));  
  45.                 parameters.put("time_end", map.get("time_end"));  
  46.                 parameters.put("total_fee", map.get("total_fee"));  
  47.                 parameters.put("trade_type", map.get("trade_type"));  
  48.                 parameters.put("transaction_id", map.get("transaction_id"));  
  49.   
  50.                 String resultSign = CommonUtils.createSign("UTF-8", parameters, PayService.WX_KEY);  
  51.                 System.out.println("create sign:" + resultSign);  
  52.                 if(map.get("sign").equals(resultSign))  
  53.                 {  
  54.                     if(payService.verifyWxPay(map).equals("success"))  
  55.                     {  
  56.                         SortedMap<String, String> result = new TreeMap<String, String>();  
  57.                         result.put("return_code" "SUCCESS");  
  58.                         return mapToXml(result);  
  59.                     }  
  60.                     SortedMap<String, String> result = new TreeMap<String, String>();  
  61.                     result.put("return_code""FAIL");  
  62.                     return mapToXml(result);  
  63.                 }  
  64.                 else  
  65.                 {  
  66.                     SortedMap<String, String> result = new TreeMap<String, String>();  
  67.                     result.put("return_code""FAIL");  
  68.                     return mapToXml(result);  
  69.                 }  
  70.   
  71.             } catch (IOException e) {  
  72.                 e.printStackTrace();  
  73.             }  
  74.         }  
  75.         SortedMap<String, String> result = new TreeMap<String, String>();  
  76.         result.put("return_code""FAIL");  
  77.         return mapToXml(result);  
  78.     }  
/**
     * 微信回调接口
     * @param request
     * @param resp
     * @return
     */
    @ResponseBody
    @RequestMapping(value="/verifywxpayresult.do", method=RequestMethod.POST)
    public String verifyWxPayRight(HttpServletRequest request, HttpServletResponse resp)
    {
        System.out.println("-----------------------------------come here wxpay--------------------------------");
        synchronized (wxlock) {
            System.out.println("-----------------------------------come here wxpay 2--------------------------------");

            BufferedReader reader = null ;

            try {
                reader = request.getReader() ;
                String line = "" ;
                String xmlString = null ;
                StringBuffer inputString = new StringBuffer() ;

                while( (line = reader.readLine()) != null ){
                    inputString.append(line) ;
                }

                xmlString = inputString.toString() ;
                request.getReader().close();
                System.out.println("xmlString:" + xmlString);
                Map<String, String> map = CommonUtils.xmlToMap(xmlString);

                System.out.println("result sign:" + map.get("sign"));
                SortedMap<String, String> parameters = new TreeMap<String, String>();
                parameters.put("appid", map.get("appid"));
                parameters.put("bank_type", map.get("bank_type"));
                parameters.put("cash_fee", map.get("cash_fee"));
                parameters.put("fee_type", map.get("fee_type"));
                parameters.put("is_subscribe", map.get("is_subscribe"));
                parameters.put("mch_id", map.get("mch_id"));
                parameters.put("nonce_str", map.get("nonce_str"));
                parameters.put("openid", map.get("openid"));
                parameters.put("out_trade_no", map.get("out_trade_no"));
                parameters.put("result_code", map.get("result_code"));
                parameters.put("return_code", map.get("return_code"));
                parameters.put("time_end", map.get("time_end"));
                parameters.put("total_fee", map.get("total_fee"));
                parameters.put("trade_type", map.get("trade_type"));
                parameters.put("transaction_id", map.get("transaction_id"));

                String resultSign = CommonUtils.createSign("UTF-8", parameters, PayService.WX_KEY);
                System.out.println("create sign:" + resultSign);
                if(map.get("sign").equals(resultSign))
                {
                    if(payService.verifyWxPay(map).equals("success"))
                    {
                        SortedMap<String, String> result = new TreeMap<String, String>();
                        result.put("return_code", "SUCCESS");
                        return mapToXml(result);
                    }
                    SortedMap<String, String> result = new TreeMap<String, String>();
                    result.put("return_code", "FAIL");
                    return mapToXml(result);
                }
                else
                {
                    SortedMap<String, String> result = new TreeMap<String, String>();
                    result.put("return_code", "FAIL");
                    return mapToXml(result);
                }

            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        SortedMap<String, String> result = new TreeMap<String, String>();
        result.put("return_code", "FAIL");
        return mapToXml(result);
    }


三、过滤器中添加支付白名单

  1. else if(uri.endsWith("pay/verifyalipayresult.do"))//支付宝回调接口  
  2.         {  
  3.             return true;  
  4.         }  
  5.         else if(uri.endsWith("pay/verifywxpayresult.do")) //微信回调接口  
  6.         {  
  7.             return true;  
  8.         }  
else if(uri.endsWith("pay/verifyalipayresult.do"))//支付宝回调接口
		{
			return true;
		}
		else if(uri.endsWith("pay/verifywxpayresult.do"))//微信回调接口
		{
			return true;
		}


主要代码就是这些,就能在服务端生成微信预支付订单,详细代码请参见文章末尾源代码,预支付订单实例如图:

服务端信息:


客户端信息:


客户端拿到预支付订单后就可以调起微信支付了:

调起微信支付代码:

  1. PayApi.getInstance().createOrder(MyApplication.getInstance().getUserBean().getId(), MyApplication.getInstance().getPhone(), "微信支付测试" "1"2"APP微信SDK支付"new HttpSubscriber<AliWxPayBean>( new SubscriberOnListener<AliWxPayBean>() {  
  2.                     @Override  
  3.                     public void onSucceed( final AliWxPayBean data) {  
  4.                         hideLoadDialog();  
  5.                         System.out.println("微信预支付订单信息:" + data.getPrepayid());  
  6.                         System.out.println("sign:" + data.getSign());  
  7.                         PayReq request = new PayReq();  
  8.                         request.appId = data.getAppid();  
  9.                         request.partnerId = data.getPartnerid();  
  10.                         request.prepayId = data.getPrepayid();  
  11.                         request.packageValue = data.getPackageValue();  
  12.                         request.nonceStr = data.getNoncestr();  
  13.                         request.timeStamp = data.getTimestamp();  
  14.                         request.sign = data.getSign();  
  15.                         WxFactory.getInstance().getWxApi(MainActivity.this).sendReq(request);  
  16.   
  17.                     }  
  18.   
  19.                     @Override  
  20.                     public void onError( int code, String msg) {  
  21.                         hideLoadDialog();  
  22.                         Toast.makeText(MainActivity.this, msg, Toast.LENGTH_LONG).show();  
  23.                     }  
  24.                 }, MainActivity.this));  
PayApi.getInstance().createOrder(MyApplication.getInstance().getUserBean().getId(), MyApplication.getInstance().getPhone(), "微信支付测试", "1", 2, "APP微信SDK支付", new HttpSubscriber<AliWxPayBean>(new SubscriberOnListener<AliWxPayBean>() {
                    @Override
                    public void onSucceed(final AliWxPayBean data) {
                        hideLoadDialog();
                        System.out.println("微信预支付订单信息:" + data.getPrepayid());
                        System.out.println("sign:" + data.getSign());
                        PayReq request = new PayReq();
                        request.appId = data.getAppid();
                        request.partnerId = data.getPartnerid();
                        request.prepayId = data.getPrepayid();
                        request.packageValue = data.getPackageValue();
                        request.nonceStr = data.getNoncestr();
                        request.timeStamp = data.getTimestamp();
                        request.sign = data.getSign();
                        WxFactory.getInstance().getWxApi(MainActivity.this).sendReq(request);

                    }

                    @Override
                    public void onError(int code, String msg) {
                        hideLoadDialog();
                        Toast.makeText(MainActivity.this, msg, Toast.LENGTH_LONG).show();
                    }
                }, MainActivity.this));


处理微信支付结果:

  1. package com.ywl5320.rxjavaretrofit.wxapi;  
  2.   
  3. import android.app.Activity;  
  4. import android.content.Intent;  
  5. import android.os.Bundle;  
  6. import android.widget.Toast;  
  7.   
  8. import com.tencent.mm.opensdk.constants.ConstantsAPI;  
  9. import com.tencent.mm.opensdk.modelbase.BaseReq;  
  10. import com.tencent.mm.opensdk.modelbase.BaseResp;  
  11. import com.tencent.mm.opensdk.openapi.IWXAPI;  
  12. import com.tencent.mm.opensdk.openapi.IWXAPIEventHandler;  
  13.   
  14. public class WXPayEntryActivity extends Activity implements IWXAPIEventHandler {  
  15.       
  16. private IWXAPI api;  
  17.       
  18.     @Override  
  19.     public void onCreate(Bundle savedInstanceState) {  
  20.         super.onCreate(savedInstanceState);  
  21. //      api = WXAPIFactory.createWXAPI(this, "", true);  
  22. //      api.registerApp("");  
  23.         api = WxFactory.getInstance().getWxApi(this);  
  24.         api.handleIntent(getIntent(), this);  
  25.     }  
  26.   
  27.     @Override  
  28.     protected void onNewIntent(Intent intent) {  
  29.         super.onNewIntent(intent);  
  30.         setIntent(intent);  
  31.         api.handleIntent(intent, this);  
  32.     }  
  33.   
  34.     @Override  
  35.     public void onReq(BaseReq req) {  
  36.           
  37.     }  
  38.   
  39.     @Override  
  40.     public void onResp(BaseResp resp) {  
  41.         if (resp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX) {  
  42.             if(resp.errCode == 0)  
  43.             {  
  44.                 Toast.makeText(this"支付成功", Toast.LENGTH_LONG).show();  
  45.             }  
  46.             else if(resp.errCode == -1)  
  47.             {  
  48.                 Toast.makeText(this"支付出错:" + resp.errStr, Toast.LENGTH_LONG).show();  
  49.             }  
  50.             else if(resp.errCode == -2)  
  51.             {  
  52.                 Toast.makeText(this"取消支付", Toast.LENGTH_LONG).show();  
  53.             }  
  54.         }  
  55.         finish();  
  56.     }  
  57. }  
package com.ywl5320.rxjavaretrofit.wxapi;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Toast;

import com.tencent.mm.opensdk.constants.ConstantsAPI;
import com.tencent.mm.opensdk.modelbase.BaseReq;
import com.tencent.mm.opensdk.modelbase.BaseResp;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.IWXAPIEventHandler;

public class WXPayEntryActivity extends Activity implements IWXAPIEventHandler {
	
private IWXAPI api;
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
//		api = WXAPIFactory.createWXAPI(this, "", true);
//		api.registerApp("");
		api = WxFactory.getInstance().getWxApi(this);
		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) {
		if (resp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX) {
			if(resp.errCode == 0)
			{
				Toast.makeText(this, "支付成功", Toast.LENGTH_LONG).show();
			}
			else if(resp.errCode == -1)
			{
				Toast.makeText(this, "支付出错:" + resp.errStr, Toast.LENGTH_LONG).show();
			}
			else if(resp.errCode == -2)
			{
				Toast.makeText(this, "取消支付", Toast.LENGTH_LONG).show();
			}
		}
		finish();
	}
}

服务端和客户端核心代码就是以上的全部,具体实例请参考源码:


源码下载 GitHub AppServiceRestFul

下一篇将添加增量更新功能。