当前位置:首页 > 安卓源码 > VIP源码 > 安卓应用 >

Android开发微信app支付(android端+java后台)实例源码

时间:2018-01-27 11:57 来源:互联网 作者:源码搜藏 浏览: 收藏 挑错 推荐 打印

  • 源码类别:安卓应用
  • 源码大小:未知
  • 编码格式:gbk
  • 运行环境:Android studio
  • 官方网址:暂无
  • 下载权限:单独购买10金币
  • 欢迎加入QQ群讨论学习
  • Android学习交流
  • IDC/源码/项目-广告推荐
本文讲解使用微信支付接口完成在android开发的原生态app中完成微信支付功能, 文章具体讲解了前端android如何集成微信支付功能以及后台如何组装前端需要支付信息, 话不多话, 具体看文章内容吧

本实例项目运行条件:

开发环境: 【Android Studio】

1. 到微信开放平台注册帐号并且创建移动应用

   https://open.weixin.qq.com/cgi-bin/frame?t=home/app_tmpl&lang=zh_CN

blob.png

 

2. 获得移动应用的权限【微信支付】

   这个权限要求比较高,需要公司资质 并且 每年需要支付300元 才能开通 (这里不作讲解, 具体到官网上申请)

blob.png

 

3. 配置应用签名, 这个签名通过 android打包文件jks生成或者keystore生成    【如何生成jks文件】

   签名文件生成方法: 

   3.1  keytool -list -v -keystore jks文件(或者keystore文件)

   3.2 获取指纹证书md5值, 将md5中的冒号去掉, 大写换成小写   (详情)

   总结: 微信开放平台Android应用签名的本质便是我们签名文件jks(或者keystore)的MD5值

blob.png

4. 配置支付密钥, 【如何配置密钥】    【微信配置密钥官网】

  blob.png

 

5. 应用程序开发完成后,debug模式是无法完成支付的,应用程序必须由相应的jks签名之后生成的apk包安装在手机上才能进行分支付(微信会校验应用签名)

 

2. 支付流程讲解

2.1 android程序启动后如下第一张图, 点击【确认支付】

  2.1.1 android端向后台请求获得预支付信息

  2.1.2 后台根据微信官网平台上的 配置信息 加上 订单信息 生成预支付信息

  2.1.3 android端根据预支付信息 拉起微信支付页面进行支付(见下面第二张图)

 

blob.png              blob.png

 

3. 代码详解(Android端)

3.1 在android studio中引入 微信需要使用的jar包

    blob.png

 

3.2 在android工程对应的包名下面新建 包以及类, wxapi/WXPayEntryActivity

blob.png

 

在AndroidManifest.xml中引用 WXPayEntryActivity

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<application
    android:allowBackup="true"
    android:icon="@drawable/desk"
    android:label="@string/app_name"
    android:theme="@style/AppTheme">
    <activity
        android:name=".activity.MainActivity"
        android:screenOrientation="portrait"
        android:label="@string/app_name">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
         </intent-filter>
    </activity>
 
    <activity
        android:name=".wxapi.WXPayEntryActivity"
        android:screenOrientation="portrait"
        android:exported="true"
        android:launchMode="singleTop"/>
</application>

 

WXPayEntryActivity 代码详情(支付完成后,onResp会被调用,BaseResp.ErrCode.ERR_OK 表明支付成功)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
public class WXPayEntryActivity extends Activity implements IWXAPIEventHandler {
 
    private static final String TAG = "WXPayEntryActivity";
 
    private IWXAPI api;
 
 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
 
        Constant.wxApi.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.i(TAG, "onPayFinish, errCode = " + resp.errCode);
 
        String strPayResult = "";
        switch (resp.errCode) {
            case BaseResp.ErrCode.ERR_OK:
                Toast.makeText(this, "付款成功!", Toast.LENGTH_SHORT).show();
                break;
            case BaseResp.ErrCode.ERR_USER_CANCEL:
                //分享取消
                //Toast.makeText(this, "付款取消!", Toast.LENGTH_SHORT).show();
                //Constant.WEIXIN_PAY_STATUS = "PAY_CANCEL";
                break;
            case BaseResp.ErrCode.ERR_AUTH_DENIED:
                //分享拒绝
                //Toast.makeText(this, "付款拒绝!", Toast.LENGTH_SHORT).show();
                //Constant.WEIXIN_PAY_STATUS = "PAY_DENY";
                break;
        }
 
        //向之前页面返回支付结果信息
        /*Intent intent = new Intent();
        intent.putExtra("payResult", strPayResult);
        setResult(100, intent);*/
        finish();
    }
}

 

3.3 支付按钮的点击事件

    通过http协议向后台请求相应的预支付信息, 根据这些信息组装相应的信息来调用微信接口, 拉起微信支付界面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
@OnClick(R.id.pay)
public void pay(){
    String orderNum = OrderInfo.generateOutTradeNo();
    payService
            .wpay(orderNum, totalPrice, address.getText().toString() + "-外卖订单")
            .subscribe(new Action1<WeiXinPrePay>() {
                @Override
                public void call(WeiXinPrePay payInfo) {
                    if (Constant.wxApi != null) {
                        PayReq req = new PayReq();
                        req.appId = payInfo.getAppId();// 微信开放平台审核通过的应用APPID
                        req.partnerId = payInfo.getMchId();// 微信支付分配的商户号
                        req.prepayId = payInfo.getPrepayId();// 预支付订单号,app服务器调用“统一下单”接口获取
                        req.nonceStr = payInfo.getNonceStr();// 随机字符串,不长于32位,服务器小哥会给咱生成
                        req.timeStamp = payInfo.getTimeStamp();// 时间戳,app服务器小哥给出
                        req.packageValue = "WXPay";// 固定值Sign=WXPay,可以直接写死,服务器返回的也是这个固定值
                        req.sign = payInfo.getPaySign();// 签名,服务器小哥给出,他会根据:                                                   om/wiki/doc/api/app/app.php?chapter=4_3指导得到这个
                        Constant.wxApi.sendReq(req);
                    }
                }
            }, new Action1<Throwable>() {
                @Override
                public void call(Throwable throwable) {
                    showToast(throwable.getMessage());
                }
            });
}

 

4 微信支付Java后台

4.1 后台代码结构图

    blob.png

 

4.2 微信配置信息 Config.properties

blob.png

 

4.3 方法wxpay用于生成预支付订单信息

    方法notifyWeiXinPay用于微信支付成功后的回调, 注意: 在手机端使用微信支付成功后,微信服务器会根据提供的回调地址进行回调, parameterMap.put("notify_url", wxnotify); (见下面代码) 

在局域网是无法进行回调的,必须将你的服务端放在公网上进行测试, 回调函数会被多次调用,如果第一次成功后,你可以将业务数据状态标志为已处理, 对于相同订单的其它回调就不需要再次处理了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
@Controller
@RequestMapping("/pay")
public class PayController {
    
    String timeMillis = String.valueOf(System.currentTimeMillis() / 1000);
    String randomString = PayCommonUtil.getRandomString(32);
    //支付成功后的回调函数
    public static String wxnotify = "http://gepanjiang.hk1.tunnelfrp.cc/WxPay/pay/notifyWeiXinPay.htm";
    
    public PayController() {
        System.out.println("MainController构造函数");
    }
    
    
    /**
     * @param totalAmount    支付金额
     * @param description    描述
     * @param request
     * @return
     */
    @RequestMapping(value = "/wxpay.htm", produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody    
    public Result wxpay(HttpServletRequest request) {
        Result result = new Result();
        Long userId = new Long(1);//baseController.getUserId();
       
        BigDecimal totalAmount = new BigDecimal(request.getParameter("totalPrice"));
        String trade_no = "";
        String description="";
        try {
            trade_no = new String(request.getParameter("orderNum").getBytes("ISO-8859-1"),"UTF-8");
            description = request.getParameter("description");
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        String openId = "";
        
        Map<String, String> map = weixinPrePay(trade_no,totalAmount,description,openId,request);  
        SortedMap<String, Object> finalpackage = new TreeMap<String, Object>();
        finalpackage.put("appId", ConfigManager.getInstance().getConfigItem("WXAppID")/*PayCommonUtil.APPID*/); 
        finalpackage.put("mchId", ConfigManager.getInstance().getConfigItem("MCH_ID"));
        Long time = (System.currentTimeMillis() / 1000);  
        finalpackage.put("timeStamp", time.toString());
        finalpackage.put("nonceStr", map.get("nonce_str"));
        finalpackage.put("prepayId", map.get("prepay_id"));
        finalpackage.put("package", "Sign=WXPay");
        finalpackage.put("signType", "MD5");
        String sign = PayCommonUtil.createSign("UTF-8", finalpackage);  
        finalpackage.put("paySign", sign);//官方文档上是sign,当前示例代码是paySign 可能以前的
        
        WeiXinPrePay prePay = new WeiXinPrePay();
        prePay.setAppId(ConfigManager.getInstance().getConfigItem("WXAppID"));
        prePay.setMchId(ConfigManager.getInstance().getConfigItem("MCH_ID"));
        prePay.setTimeStamp(time.toString());
        prePay.setNonceStr(map.get("nonce_str"));
        prePay.setPrepayId(map.get("prepay_id"));
        prePay.setSignType("MD5");
        prePay.setPaySign("paySign");
        result.setData(prePay);
        result.setStateCode(GeneralConstant.SUCCESS);
        result.setDesc("微信支付加载成功");
        
        return result;
    } 
 
    
    /**
     * 统一下单 
     * 应用场景:商户系统先调用该接口在微信支付服务后台生成预支付交易单,返回正确的预支付交易回话标识后再在APP里面调起支付。
     * @param trade_no
     * @param totalAmount
     * @param description
     * @param openid
     * @param sym
     * @param request
     * @return
     */
    @SuppressWarnings("unchecked")
    public Map<String, String> weixinPrePay(String trade_no,BigDecimal totalAmount,  
            String description, String openid, HttpServletRequest request) { 
        SortedMap<String, Object> parameterMap = new TreeMap<String, Object>();  
        parameterMap.put("appid", ConfigManager.getInstance().getConfigItem("WXAppID"));  //应用appid 
        parameterMap.put("mch_id", ConfigManager.getInstance().getConfigItem("MCH_ID")/*PayCommonUtil.MCH_ID*/);  //商户号
        //parameterMap.put("device_info", "WEB");
        parameterMap.put("nonce_str", randomString);  
        parameterMap.put("body", description);
        parameterMap.put("out_trade_no", trade_no);
        parameterMap.put("fee_type", "CNY");  
        System.out.println("jiner");  
        BigDecimal total = totalAmount.multiply(new BigDecimal(100));  //接口中参数支付金额单位为【分】,参数值不能带小数,所以乘以100
        java.text.DecimalFormat df=new java.text.DecimalFormat("0");  
        parameterMap.put("total_fee", df.format(total));  
        System.out.println("jiner2");  
        parameterMap.put("spbill_create_ip", PayCommonUtil.getRemoteHost(request));  
        parameterMap.put("notify_url", wxnotify);
        parameterMap.put("trade_type", "APP");//"JSAPI"
        //trade_type为JSAPI是 openid为必填项
        //parameterMap.put("openid", openid);
        System.out.println("");  
        String sign = PayCommonUtil.createSign("UTF-8", parameterMap); 
        System.out.println("jiner2");  
        parameterMap.put("sign", sign);  
        String requestXML = PayCommonUtil.getRequestXml(parameterMap);  
        System.out.println(requestXML);  
        String result = PayCommonUtil.httpsRequest(  
                "https://api.mch.weixin.qq.com/pay/unifiedorder", "POST",  
                requestXML);  
        System.out.println(result);  
        Map<String, String> map = null;  
        try {  
            map = PayCommonUtil.doXMLParse(result);  
        } catch (JDOMException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        } catch (IOException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        }  
        return map;        
    }
    
    
 
    /**
     * 此函数会被执行多次,如果支付状态已经修改为已支付,则下次再调的时候判断是否已经支付,如果已经支付了,则什么也执行
     * @param request
     * @param response
     * @return
     * @throws IOException
     * @throws JDOMException
     */
    @RequestMapping(value = "notifyWeiXinPay.htm", produces = MediaType.APPLICATION_JSON_VALUE)
   // @RequestDescription("支付回调地址")
    @ResponseBody
    public String notifyWeiXinPay(HttpServletRequest request, HttpServletResponse response) throws IOException, JDOMException {
        System.out.println("微信支付回调");
        InputStream inStream = request.getInputStream();
        ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len = 0;
        while ((len = inStream.read(buffer)) != -1) {
            outSteam.write(buffer, 0, len);
        }
        String resultxml = new String(outSteam.toByteArray(), "utf-8");
        Map<String, String> params = PayCommonUtil.doXMLParse(resultxml);
        outSteam.close();
        inStream.close();
        
        
        Map<String,String> return_data = new HashMap<String,String>();  
        if (!PayCommonUtil.isTenpaySign(params)) {
            // 支付失败
            return_data.put("return_code", "FAIL");  
            return_data.put("return_msg", "return_code不正确");
            return StringUtil.GetMapToXML(return_data);
        } else {
            System.out.println("===============付款成功==============");
            // ------------------------------
            // 处理业务开始
            // ------------------------------
            // 此处处理订单状态,结合自己的订单数据完成订单状态的更新
            // ------------------------------
 
            String total_fee = params.get("total_fee");
            double v = Double.valueOf(total_fee) / 100;
            String out_trade_no = String.valueOf(Long.parseLong(params.get("out_trade_no").split("O")[0]));
            Date accountTime = DateUtil.stringtoDate(params.get("time_end"), "yyyyMMddHHmmss");
            String ordertime = DateUtil.dateToString(new Date(), "yyyy-MM-dd HH:mm:ss");
            String totalAmount = String.valueOf(v);
            String appId = params.get("appid");
            String tradeNo = params.get("transaction_id");
        
            return_data.put("return_code", "SUCCESS");  
            return_data.put("return_msg", "OK");  
            return StringUtil.GetMapToXML(return_data);
        }
    }
 
}

本站资源仅限于学习研究,严禁从事商业或者非法活动!Android开发微信app支付(android端+java后台)实例源码转载请注明出处https://www.codesocang.com/appvip-yy/38394.html 源码搜藏网所有源码来自互联网转载与用户上传分享,如果侵犯了您的权益请与我们联系,我们将在24小时内删除!谢谢!

安卓应用下载排行

最新文章