Android编程实现的微信支付功能详解【附Demo源码下载】
本文实例讲述了android编程实现的微信支付功能。分享给大家供大家参考,具体如下:
最近公司弄ionic框架,项目中需要微信支付,无奈,把我调过去弄,期间也是几近崩溃,好在皇天不负有心人,在看别人的文档,终于是在项目中集成了微信支付,下面作为一个小白的我,想要把我的经验分享给大家,希望对大家有所帮助。
先给一个可用的demo吧(运行前先看txt文件)
demo代码点击此处本站下载。
这个demo是基于eclipse开发的,博主也在android studio开发过微信支付,原理都是一样的,大家把这个demo弄懂了,在as上面也是一样的。
(温馨提示:大家下载下来可能会出错,也有可能不会。下面给出出错的解决方法:1.进入项目中的weixinpay->build path->configure build path,移除那个报错的jar包。 2.会出现资源找不到的情况,这是因为你没有v7包,下载一个v7包,或者把出错的地方都删除,只是一个主题,删除了看起来不好看而已,当然,你也可以用你有的主题。 还有一个问题需要提出来,就是你可能按照里面的text操作的仍然调不起客户端,有可能是你没有安装微信客户端,因为我没有做判断。这个demo不会出现只能成功支付一次的情况,博主亲测有效。出现只能支付一次只能说明你的签名没有对应)
1. 去微信开放平台申请微信支付服务,绑定自己的应用这里具体不多讲,但是一定要申请完成,将会得到是三个参数
//appid 微信分配的公众账号id public static final string app_id = ""; //商户号 微信分配的公众账号id public static final string mch_id = ""; // api密钥,在商户平台设置 public static final string api_key= "";
**坑点提示:在微信开发平台设置包名和签名。这里的包名一定要和你自己的包名一样,就是manifest中的package,签名一定要和你用官方app生成的一样(https://open.weixin.qq.com/zh_cn/htmledition/res/dev/download/sdk/gen_signature_android.apk)。
微信会根据你的填写的包名,然后对你的keystore进行一种算法,生成你的签名。包名和签名一定要和微信开放平台的相同。不过这里需要注意的是,如果你发布的正式版本,需要用官方app重新生成签名,然后在开放平台重新设置sign,因为测试版本的keystore与正式版的keystore不一样。总之,就是你用的keystore生成的sign要和微信开放平台的时刻保持一致。**
2. 准备工作做好了,接下来就是开发了,先下载微信的jar包,导入。
微信支付分为三个步骤
① .生成prepayid
@override protected map<string, string> doinbackground(string... params) { // todo auto-generated method stub string url=string.format(params[0]); string entity=getproductargs(); log.e("simon",">>>>"+entity); byte[] buf=util.httppost(url, entity); string content = new string(buf); log.e("orion", "----"+content); map<string,string> xml=decodexml(content); return xml; }
② .生成签名参数
private void genpayreq() { req.appid = constants.app_id; req.partnerid = constants.mch_id; if (resultunifiedorder!=null) { req.prepayid = resultunifiedorder.get("prepay_id"); req.packagevalue = "prepay_id="+resultunifiedorder.get("prepay_id"); } else { toast.maketext(mainactivity.this, "prepayid为空", toast.length_short).show(); } req.noncestr = getnoncestr(); req.timestamp = string.valueof(gentimestamp()); list<namevaluepair> signparams = new linkedlist<namevaluepair>(); signparams.add(new basicnamevaluepair("appid", req.appid)); signparams.add(new basicnamevaluepair("noncestr", req.noncestr)); signparams.add(new basicnamevaluepair("package", req.packagevalue)); signparams.add(new basicnamevaluepair("partnerid", req.partnerid)); signparams.add(new basicnamevaluepair("prepayid", req.prepayid)); signparams.add(new basicnamevaluepair("timestamp", req.timestamp)); req.sign = genappsign(signparams); sb.append("sign\n"+req.sign+"\n\n"); textview.settext(sb.tostring()); log.e("simon", "----"+signparams.tostring()); }
③ .调起支付
/* * 调起微信支付 */ private void sendpayreq() { msgapi.registerapp(constants.app_id); msgapi.sendreq(req); log.i(">>>>>", req.partnerid); }
下面给出完整代码
package com.alpha.live; import java.io.stringreader; import java.util.hashmap; import java.util.linkedlist; import java.util.list; import java.util.map; import java.util.random; import org.apache.http.namevaluepair; import org.apache.http.message.basicnamevaluepair; import org.xmlpull.v1.xmlpullparser; import com.tencent.mm.sdk.modelpay.payreq; import com.tencent.mm.sdk.openapi.iwxapi; import com.tencent.mm.sdk.openapi.wxapifactory; import android.app.activity; import android.app.alertdialog; import android.app.progressdialog; import android.os.asynctask; import android.os.bundle; import android.util.log; import android.util.xml; import android.view.view; import android.view.view.onclicklistener; import android.widget.button; import android.widget.textview; import android.widget.toast; /** * created by simon on 2016/12/2. */ public class mainactivity extends activity implements onclicklistener { private button submitbutton; private button confirmbutton; private textview textview; private stringbuffer sb; private map<string,string> resultunifiedorder; private payreq req; private final iwxapi msgapi = wxapifactory.createwxapi(this, null); @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); submitbutton=(button) findviewbyid(r.id.bt_submit_order); confirmbutton=(button) findviewbyid(r.id.bt_corfirm); textview=(textview) findviewbyid(r.id.tv_prepay_id); submitbutton.setonclicklistener(this); confirmbutton.setonclicklistener(this); sb=new stringbuffer(); req=new payreq(); } @override public void onclick(view v) { // todo auto-generated method stub switch (v.getid()) { case r.id.bt_submit_order: string urlstring="https://api.mch.weixin.qq.com/pay/unifiedorder"; prepayidasynctask prepayidasynctask=new prepayidasynctask(); prepayidasynctask.execute(urlstring); //生成prepayid break; case r.id.bt_corfirm: genpayreq();//生成签名参数 sendpayreq();//调起支付 break; default: break; } } /* * 调起微信支付 */ private void sendpayreq() { msgapi.registerapp(constants.app_id); msgapi.sendreq(req); log.i(">>>>>", req.partnerid); } private long gentimestamp() { return system.currenttimemillis() / 1000; } private void genpayreq() { req.appid = constants.app_id; req.partnerid = constants.mch_id; if (resultunifiedorder!=null) { req.prepayid = resultunifiedorder.get("prepay_id"); req.packagevalue = "prepay_id="+resultunifiedorder.get("prepay_id"); } else { toast.maketext(mainactivity.this, "prepayid为空", toast.length_short).show(); } req.noncestr = getnoncestr(); req.timestamp = string.valueof(gentimestamp()); list<namevaluepair> signparams = new linkedlist<namevaluepair>(); signparams.add(new basicnamevaluepair("appid", req.appid)); signparams.add(new basicnamevaluepair("noncestr", req.noncestr)); signparams.add(new basicnamevaluepair("package", req.packagevalue)); signparams.add(new basicnamevaluepair("partnerid", req.partnerid)); signparams.add(new basicnamevaluepair("prepayid", req.prepayid)); signparams.add(new basicnamevaluepair("timestamp", req.timestamp)); req.sign = genappsign(signparams); sb.append("sign\n"+req.sign+"\n\n"); textview.settext(sb.tostring()); log.e("simon", "----"+signparams.tostring()); } private string genappsign(list<namevaluepair> params) { stringbuilder sb = new stringbuilder(); for (int i = 0; i < params.size(); i++) { sb.append(params.get(i).getname()); sb.append('='); sb.append(params.get(i).getvalue()); sb.append('&'); } sb.append("key="); sb.append(constants.api_key); this.sb.append("sign str\n"+sb.tostring()+"\n\n"); string appsign = md5.getmessagedigest(sb.tostring().getbytes()); log.e("simon","----"+appsign); return appsign; } private class prepayidasynctask extends asynctask<string,void, map<string, string>> { private progressdialog dialog; @override protected void onpreexecute() { // todo auto-generated method stub super.onpreexecute(); dialog = progressdialog.show(mainactivity.this, "提示", "正在提交订单"); } @override protected map<string, string> doinbackground(string... params) { // todo auto-generated method stub string url=string.format(params[0]); string entity=getproductargs(); log.e("simon",">>>>"+entity); byte[] buf=util.httppost(url, entity); string content = new string(buf); log.e("orion", "----"+content); map<string,string> xml=decodexml(content); return xml; } @override protected void onpostexecute(map<string, string> result) { // todo auto-generated method stub super.onpostexecute(result); if (dialog != null) { dialog.dismiss(); } sb.append("prepay_id\n"+result.get("prepay_id")+"\n\n"); textview.settext(sb.tostring()); resultunifiedorder=result; } } public map<string,string> decodexml(string content) { try { map<string, string> xml = new hashmap<string, string>(); xmlpullparser parser = xml.newpullparser(); parser.setinput(new stringreader(content)); int event = parser.geteventtype(); while (event != xmlpullparser.end_document) { string nodename=parser.getname(); switch (event) { case xmlpullparser.start_document: break; case xmlpullparser.start_tag: if("xml".equals(nodename)==false){ //实例化student对象 xml.put(nodename,parser.nexttext()); } break; case xmlpullparser.end_tag: break; } event = parser.next(); } return xml; } catch (exception e) { log.e("simon","----"+e.tostring()); } return null; } private string getproductargs() { // todo auto-generated method stub stringbuffer xml=new stringbuffer(); try { string noncestr=getnoncestr(); xml.append("<xml>"); list<namevaluepair> packageparams=new linkedlist<namevaluepair>(); packageparams.add(new basicnamevaluepair("appid",constants.app_id)); packageparams.add(new basicnamevaluepair("body", "app pay test")); packageparams.add(new basicnamevaluepair("mch_id", constants.mch_id)); packageparams.add(new basicnamevaluepair("nonce_str", noncestr)); packageparams.add(new basicnamevaluepair("notify_url", "https://www.baidu.com"));//写你们的回调地址 packageparams.add(new basicnamevaluepair("out_trade_no",genouttradno())); packageparams.add(new basicnamevaluepair("total_fee", "1")); packageparams.add(new basicnamevaluepair("trade_type", "app")); string sign=getpackagesign(packageparams); packageparams.add(new basicnamevaluepair("sign", sign)); string xmlstring=toxml(packageparams); return xmlstring; } catch (exception e) { // todo: handle exception return null; } } //生成订单号,测试用,在客户端生成 private string genouttradno() { random random = new random(); // return "dasgfsdg1234"; //订单号写死的话只能支付一次,第二次不能生成订单 return md5.getmessagedigest(string.valueof(random.nextint(10000)).getbytes()); } //生成随机号,防重发 private string getnoncestr() { // todo auto-generated method stub random random=new random(); return md5.getmessagedigest(string.valueof(random.nextint(10000)).getbytes()); } /** 生成签名 */ private string getpackagesign(list<namevaluepair> params) { stringbuilder sb = new stringbuilder(); for (int i = 0; i < params.size(); i++) { sb.append(params.get(i).getname()); sb.append('='); sb.append(params.get(i).getvalue()); sb.append('&'); } sb.append("key="); sb.append(constants.api_key); string packagesign = md5.getmessagedigest(sb.tostring().getbytes()).touppercase(); log.e("simon",">>>>"+packagesign); return packagesign; } /* * 转换成xml */ private string toxml(list<namevaluepair> params) { stringbuilder sb = new stringbuilder(); sb.append("<xml>"); for (int i = 0; i < params.size(); i++) { sb.append("<"+params.get(i).getname()+">"); sb.append(params.get(i).getvalue()); sb.append("</"+params.get(i).getname()+">"); } sb.append("</xml>"); log.e("simon",">>>>"+sb.tostring()); return sb.tostring(); } }
接下来就是有个支付结果的页面代码。是微信官方提供的一个类。你要在manifest注册这个类。这里需要注意的是,这个类必须放在wxapi包下,你自己新建一个包即可。
为了大家可以直接运行这个demo,我的微信加签都是在本地执行的,获取prepayid和加签都应该在服务端完成,还有最终的支付返回结果也是以服务端的为准。
*下面给出运行结果图*
大家下载demo然后把参数换了,弄下keystore,包名,签名。应该就可以用了。
更多关于android相关内容感兴趣的读者可查看本站专题:《android开发入门与进阶教程》、《android数据库操作技巧总结》、《android编程之activity操作技巧总结》、《android文件操作技巧汇总》、《android编程开发之sd卡操作方法汇总》、《android资源操作技巧汇总》、《android视图view技巧总结》及《android控件用法总结》
希望本文所述对大家android程序设计有所帮助。
上一篇: day1-双向链表
下一篇: 707. 设计双向链表
推荐阅读
-
微信小程序五子棋游戏的棋盘,重置,对弈实现方法【附demo源码下载】
-
微信小程序五子棋游戏的悔棋实现方法【附demo源码下载】
-
Android编程实现仿优酷圆盘旋转菜单效果的方法详解【附demo源码下载】
-
Android开发实现的简单计算器功能【附完整demo源码下载】
-
Android编程调用系统自带的拍照功能并返回JPG文件示例【附demo源码下载】
-
微信小程序实现动态改变view标签宽度和高度的方法【附demo源码下载】
-
微信小程序实现的涂鸦功能示例【附源码下载】
-
微信小程序实现点击按钮移动view标签的位置功能示例【附demo源码下载】
-
微信小程序实现点击按钮修改view标签背景颜色功能示例【附demo源码下载】
-
微信小程序实现点击按钮修改文字大小功能【附demo源码下载】