android 微信支付
来源:互联网 发布:Mac照片循环播放软件 编辑:程序博客网 时间:2024/05/17 08:15
微信开放平台有demo和开发文档,但是对于我第一次写支付真的不够细致、具体好吗!
第一步先申请一个APPID,然后添加依赖包--》libammsdk.jar,以及WXPayEntryActivity类。类的路径为 包名.wxapi。下载的demo里都有这些内容。记得要在清单中注册
<activity android:name=".wxapi.WXPayEntryActivity" android:exported="true" android:launchMode="singleTop" />
使用微信支付前要将APP注册到微信
private IWXAPI msgApi;HashMap<String, String> content = new HashMap<String, String>();private boolean isPay = false;@Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 将该app注册到微信 msgApi = WXAPIFactory.createWXAPI(App.getInstance(), null);}
要使用到的一些方法(全是博主在网上找的,忘记出处了。)
/** * 获取本地IP的方法 */public String getLocalIpAddress() { try { for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) { NetworkInterface intf = en.nextElement(); for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements(); ) { InetAddress inetAddress = enumIpAddr.nextElement(); if (!inetAddress.isLoopbackAddress()) { return inetAddress.getHostAddress().toString(); } } } } catch (SocketException ex) { } return null;}/** * 获取WIFI的IP */private String getWifiIp() { //获取wifi服务 WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE); //判断wifi是否开启 if (!wifiManager.isWifiEnabled()) { wifiManager.setWifiEnabled(true); } WifiInfo wifiInfo = wifiManager.getConnectionInfo(); int ipAddress = wifiInfo.getIpAddress(); String ip = intToIp(ipAddress); return ip;}private String intToIp(int i) { return (i & 0xFF) + "." + ((i >> 8) & 0xFF) + "." + ((i >> 16) & 0xFF) + "." + (i >> 24 & 0xFF);}
/** * 生成随机字符串 */public static String genOutTradNo() { Random random = new Random(); return MD5.getMessageDigest(String.valueOf(random.nextInt(10000)).getBytes());}/** * 签名工具 */public static String genAppSign(Map<String, String> params) { Map<String, String> sortMap = new TreeMap<String, String>(params); StringBuilder sb = new StringBuilder(); for (Map.Entry<String, String> s : sortMap.entrySet()) { String k = s.getKey(); String v = s.getValue(); if ("".equals(v) || v == null) {// 过滤空值 continue; } sb.append(k).append("=").append(v).append("&"); } sb.append("key="); sb.append(App.API_KEY); String appSign = MD5.md5(sb.toString()).toUpperCase(); LogOut("=====AppSign=====", appSign); return appSign;}/* public static String md5(String string) { byte[] encodeBytes = null; try { encodeBytes = MessageDigest.getInstance("MD5").digest(string.getBytes("UTF-8")); } catch (NoSuchAlgorithmException neverHappened) { throw new RuntimeException(neverHappened); } catch (UnsupportedEncodingException neverHappened) { throw new RuntimeException(neverHappened); } return toHexString(encodeBytes); }*//** * 转换成xml */public static String toXml(Map<String, String> params) { StringBuilder sb = new StringBuilder(); sb.append("<xml>"); for (Map.Entry<String, String> s : params.entrySet()) { sb.append("<" + s.getKey() + ">"); sb.append(s.getValue()); sb.append("</" + s.getKey() + ">"); } sb.append("</xml>"); LogOut("=====xml=====", sb.toString()); return sb.toString();}/** * 解析xml */public static HashMap<String, String> decodeXml(String content) { try { HashMap<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) { LogOut("orion", e.toString()); } return null;}/*将字符串转为时间戳*/public static long getStringToDate(String time) { sf = new SimpleDateFormat("yyyy-MM-dd HH:mm"); Date date = new Date(); try{ date = sf.parse(time); } catch(ParseException e) { e.printStackTrace(); } return date.getTime();}public static long getTimeStr(){ return (getStringToDate(getCurrentDate())/1000);}
准备工作做好就可以开始写支付代码了,根据文档先是统一下单。因为要签名,所以先将除签名外的字段都添加到HashMap中。订单号是自己设置的,我是设置成了时间戳+10位随机数。这里尤其要注意的一点是notify_url,这是接收微信支付异步通知回调地址,通知url必须为直接可访问的url,不能携带参数。这个地址很重要,微信支付结果全部会返到这个地址,如果在APP端接收会出现一些意料之外的后果。所以,一定要在后台处理微信回调结果!一定要在后台处理!后台处理!重要的事情说三遍!地址让后台给你。
content.clear();// 每次使用前记得要清空String ip = getWifiIp();if ("".equals(ip)) { ip = getLocalIpAddress();}content.put("body", "等级提升");content.put("total_fee", 1 + "");// 微信以分为单位content.put("appid", App.API_ID);// 申请的应用IDcontent.put("mch_id", App.MCH_ID);// 商户号content.put("nonce_str", CommTools.genOutTradNo());// 随机字符串String orderNum = CommTools.getTimeStr() + CommTools.genOutTradNo().substring(0, 9);content.put("out_trade_no", orderNum);// 商户订单号content.put("spbill_create_ip", ip);content.put("notify_url", "http://www.weixin.qq.com/wxpay/pay.php");// 通知地址content.put("trade_type", "APP");
然后调用写好的签名工具生成签名,开放平台有签名算法,并且有校验签名是否正确的工具。将生成的签名也放入map中,然后转换成xml。
String sign = CommTools.genAppSign(content);content.put("sign", sign);String xml = CommTools.toXml(content);
我的项目用的xutils3.0,已经都封装好了,这里我就直接使用它的post方法,将xml添加进去,发送给微信给出的
URL地址:https://api.mch.weixin.qq.com/pay/unifiedorder
回调成功,使用decodeXml()解析微信返回的数据,获得prepayid,实例化一个map,存取数据生成签名,调起微信支付接口
String url = "https://api.mch.weixin.qq.com/pay/unifiedorder";requestParams = new RequestParams(url);requestParams.setBodyContent(xml);x.http().post(requestParams, new Callback.CommonCallback<String>() { @Override public void onSuccess(String result) { LogOut(result); Map<String, String> xml = CommTools.decodeXml(result); PayReq request = new PayReq(); HashMap<String, String> map = new HashMap<String, String>(); request.appId = App.API_ID; map.put("appid", App.API_ID); request.partnerId = xml.get("mch_id");// 商户号 map.put("partnerid", xml.get("mch_id")); request.prepayId = xml.get("prepay_id");// 预支付交易会话ID map.put("prepayid", xml.get("prepay_id")); request.packageValue = "Sign=WXPay";// 扩展字段 map.put("package", "Sign=WXPay"); request.nonceStr = xml.get("nonce_str"); map.put("noncestr", xml.get("nonce_str")); String time = CommTools.getTimeStr() + ""; request.timeStamp = time; map.put("timestamp", time); request.sign = CommTools.genAppSign(map); msgApi.registerApp(App.API_ID); msgApi.sendReq(request); isPay = true; } @Override public void onError(Throwable ex, boolean isOnCallback) { } @Override public void onCancelled(CancelledException cex) { } @Override public void onFinished() { }});
在WXPayEntryActivity类中获取返回值并保存在本地,setConfig()是我封装好的方法,你也可以使用SharedPreferences保存值,我的博客中有关于SharedPreferences的使用。最后记得finish()
public class WXPayEntryActivity extends Activity implements IWXAPIEventHandler { private IWXAPI api; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); api = WXAPIFactory.createWXAPI(this, App.API_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) { if (resp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX) { setConfig("resp", resp.errCode + "");// 将返回结果保存在本地 finish(); } }}
我写了个对话框用于显示微信支付结果,写在了onResume()方法中
@Overrideprotected void onResume() { super.onResume(); if (isPay) { LayoutInflater inflaterDl = LayoutInflater.from(this); FrameLayout layout = (FrameLayout) inflaterDl.inflate(R.layout.dialog_pay_result, null); //对话框 final Dialog dialog = new AlertDialog.Builder(ActivityMyPoints.this).create(); dialog.show(); dialog.getWindow().setContentView(layout); TextView message = (TextView) layout.findViewById(R.id.message); ImageView state = (ImageView) layout.findViewById(R.id.iv_pay_statu); switch (Integer.valueOf(getConfig("resp"))) { case 0: message.setText("支付成功"); state.setImageResource(R.drawable.pay_success); break; case -1: message.setText("支付失败"); state.setImageResource(R.drawable.pay_fail); break; case -2: message.setText("取消支付"); state.setImageResource(R.drawable.pay_fail); break; default: break; } // 确定按钮 Button btnOK = (Button) layout.findViewById(R.id.positiveButton); btnOK.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { initData();// 刷新界面 dialog.dismiss(); } }); isPay = false; } else { }}
感兴趣的可以参考我的界面
<?xml version="1.0" encoding="utf-8"?><FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@drawable/dialog_shape" android:clickable="true"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center" android:orientation="vertical"> <ImageView android:id="@+id/iv_pay_statu" android:layout_marginTop="20dp" android:layout_width="50dp" android:layout_height="50dp" android:scaleType="centerInside" android:layout_gravity="center_horizontal" android:src="@drawable/pay_success"/> <TextView android:id="@+id/message" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:layout_margin="10dp" android:text="支付成功" android:textColor="#333" android:textSize="20sp" /> <Button android:id="@+id/positiveButton" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="20dp" android:layout_marginRight="20dp" android:layout_marginBottom="10dp" android:layout_marginTop="20dp" android:background="#526CFD" android:text="确定" android:textColor="#fff" android:textSize="16sp" /> </LinearLayout></FrameLayout>
写完了!调试的时候一定要匹配应用签名,很多人直接运行会发现不能跳转到微信,那是因为app有一个debug签名和一个正式签名,一定要确保与开放平台填写的签名、包名保持一致。
获取应用签名的方法 获取应用签名
SharedPreferences存值 SharedPreferences轻量级存储
- android微信支付
- android微信支付
- Android 微信支付
- android微信支付
- android微信支付
- android微信支付
- Android 微信支付
- Android 微信支付
- android微信支付
- android 微信支付
- Android 微信支付
- android微信支付
- Android微信支付
- Android微信支付
- Android微信支付
- Android微信支付
- android微信支付
- Android微信支付
- 浅谈服务器性能测试的全生命周期——从测试、结果分析到优化策略
- Gson库和Android自带JSON解析对转义字符的处理存在不同
- 使用caffe fine-tune一个单标签图像分类模型
- C#59课的主要内容
- ActiveMQ使用教程
- android 微信支付
- RTTHREAD scons构建环境
- 浅析C语言中assert的用法
- 09上机练习3
- [iOS Swift3.0] SnapKit 使用注意点[转]
- linux驱动开发之pwm蜂鸣器
- java开发的时候在tomcat服务器中遇到的问题总结
- Oracle SQL性能优化
- Qt desiner 的继承写法