接触微信支付之前听说过这是一个坑,,,心里已经有了准备。。。我以为我没准跳坑出不来了,没有想到我填上了,调用成功之后我感觉公司所有的同事都是漂亮的,隔着北京的大雾霾我仿佛看见了太阳~~~好了,装逼结束。。。进入正题
开发准备:
1.在微信开放平台申请账号
2.成功后创建应用,就是填一些看似很官方很正经的资料了。。。(说审核7天左右,没有意外的情况下你的app第二天就审核成功了是不是很开心,有了appid,是不是就可以调用微 信支付了????-------想多了,真的)
3.微信支付是需要额外申请的:需要资料审核,账户验证,协议签署等步骤,(我记得,,资料审核要填写的东西好多,,,好多,,,账户验证就是你审核成功后微信会发送邮件到你 注册时登记的邮箱账号,其中含有随机金额用于账户验证,协议签署,略,太简单)一定要好好阅读你邮件的任何信息,因为有的细节错了,,,你可能填坑很久。。。。。。
正式开发阶段:
问题1:调用官方的SDK发现只能成功的调起一次微信,再次支付的时候怎么也调用不起来了
解决:
似乎不是什么正经方法:在手机设置中管理应用程序,清除微信数据,缓存,,再来一遍,绝对可以调起来(当然还是只是一次。。。。)
继续:
我认为要用微信支付嘛,,就只看了调用支付接口的文档:

后来发现需要的参数prepayid是怎么也找不到啊,,后来才发现这个prepayid是先调用”统一下单“这个接口时候温馨反过来的东西,但是官方的SDK中并没有统一下单的代码。坑吗???
所以要先看统一下单文档了
1.使用自己的APP调用的时候把官网down下来的SDK中WXPayEntryActivity拷贝到自己的项目,所在包的名字最后一定是.wxapi(我连包一起拷了。。。。)
2.在项目清单文件中填写:

3.SDK中的AppRegister拷贝下来,,,里面换成你自己的appid,然后在项目清单中也注册一下。

4.重点来了,,就是你APP要调微信支付的activity,我这还叫PayActivity
要调起微信支付页面,要在这个activity中,将你的app注册到微信

接下来先调用统一下单获取prepayid,参数,微信人家要xml格式的!我们就得发送xml格式的!

好了调用的时候把这个方法的返回值当参数传,,等待微信返回success吧!。。
我遇见的错误:签名错误
我的原因是大意了 ConfigUtil.NOTIFY_URL这个参数写的空字符串
还有是因为debug版运行的,没有打包运行
返回成功之后,可以调用支付接口了

不要忘了这一步去跳转界面,,,,,

没有跳转到微信支付可能是你由运行的debug版本,,,,没有打包。。。。。
下面是我的PayActivity完整代码:
package com.example.taijiapp.ui; import java.io.StringReader;import java.net.InetAddress;import java.net.NetworkInterface;import java.net.SocketException;import java.util.Enumeration;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.example.taijiapp.R;import com.example.taijiapp.util.Constants;import com.example.taijiapp.util.MD5;import com.example.taijiapp.util.T;import com.example.taijiapp.util.Util;import com.example.taijiapp.utils.ConfigUtil;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.ProgressDialog;import android.content.Context;import android.net.wifi.WifiInfo;import android.net.wifi.WifiManager;import android.os.AsyncTask;import android.os.Bundle;import android.util.Log;import android.util.Xml;import android.view.View;import android.widget.Button; public class PayActivity extends Activity {PayReq req;private IWXAPI msgApi;Map<string, string=""> resultunifiedorder;StringBuffer sb;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.pay);req = new PayReq();sb = new StringBuffer();msgApi = WXAPIFactory.createWXAPI(this, Constants.APP_ID);/** * 将app注册到微信 */boolean registerApp = msgApi.registerApp(Constants.APP_ID);T.show(this, "注册========"+registerApp+"");Button appayBtn = (Button) findViewById(R.id.appay_btn);Button check_pay_btn = (Button) findViewById(R.id.check_pay_btn);appayBtn.setOnClickListener(new View.OnClickListener() { @Overridepublic void onClick(View v) {GetPrepayIdTask getPrepayId = new GetPrepayIdTask();getPrepayId.execute();}});/** * 将该app注册到微信 */check_pay_btn.setOnClickListener(new View.OnClickListener() { @Overridepublic void onClick(View v) {genPayReq();sendPayReq(); }});// // 生成签名参数// Button appay_pre_btn = (Button) findViewById(R.id.appay_pre_btn);// appay_pre_btn.setOnClickListener(new View.OnClickListener() {//// @Override// public void onClick(View v) {// genPayReq();// }// });}/** * 生成签名 */ private String genPackageSign(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.KEY);Log.e("拼接=====", sb.toString());String packageSign = MD5.getMessageDigest(sb.toString().getBytes()).toUpperCase();Log.e("orion生成签名===", packageSign);return packageSign;} /** * 签名工具 不含商户密钥 -暂时不用 = * 编码格式 UTF-8 = * @return */public static String createSignNoKey(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("&");}String signStr = sb.toString();String subStr = signStr.substring(0, signStr.length() - 1);// 注意sign转为大写return MD5.getMessageDigest(subStr.getBytes()).toUpperCase();} 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.KEY); this.sb.append("sign str
" + sb.toString() + "
");String appSign = MD5.getMessageDigest(sb.toString().getBytes());Log.e("orion", appSign);return appSign;} 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("orion", sb.toString());return sb.toString();} private class GetPrepayIdTask extends AsyncTask<void, void,="" map<string,="" string="">> { private ProgressDialog dialog; @Overrideprotected void onPreExecute() {dialog = ProgressDialog.show(PayActivity.this, getString(R.string.app_tip),getString(R.string.getting_prepayid));} @Overrideprotected void onPostExecute(Map<string, string=""> result) {if (dialog != null) {dialog.dismiss();}sb.append("prepay_id
" + result.get("prepay_id") + "
"); resultunifiedorder = result; } @Overrideprotected void onCancelled() {super.onCancelled();} @Overrideprotected Map<string, string=""> doInBackground(Void... params) { String url = String.format("https://api.mch.weixin.qq.com/pay/unifiedorder");String entity = genProductArgs();Log.e("orion===发送过去", entity);byte[] buf = Util.httpPost(url, entity); String content = new String(buf);Log.e("orion", content);Map<string, string=""> xml = decodeXml(content); return xml;}} 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("orion", e.toString());}return null; }/** * 生成随机数 * @return */private String genNonceStr() {Random random = new Random();return MD5.getMessageDigest(String.valueOf(random.nextInt(10000)).getBytes());}/** * 时间戳 * @return */private long genTimeStamp() {return System.currentTimeMillis() / 1000;}/** * 随机数 * @return */private String genOutTradNo() {Random random = new Random();return MD5.getMessageDigest(String.valueOf(random.nextInt(10000)).getBytes());}/** * 获取设备的ip地址 * @return */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;} 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;}/** * 转化成Ip地址的格式 * @param i * @return */private String intToIp(int i) { return (i & 0xFF) + "." + ((i >> 8) & 0xFF) + "." + ((i >> 16) & 0xFF) + "." + (i >> 24 & 0xFF);} private String genProductArgs() {StringBuffer xml = new StringBuffer();String ip = getWifiIp();if (ip == "" && ip == "") {ip = getLocalIpAddress();}try {String nonceStr = genNonceStr();xml.append("");List<namevaluepair> packageParams = new LinkedList<namevaluepair>();packageParams.add(new BasicNameValuePair("appid", Constants.APP_ID));packageParams.add(new BasicNameValuePair("body", "APPtest"));packageParams.add(new BasicNameValuePair("mch_id", Constants.MCH_ID));packageParams.add(new BasicNameValuePair("nonce_str", nonceStr));packageParams.add(new BasicNameValuePair("notify_url", ConfigUtil.NOTIFY_URL));packageParams.add(new BasicNameValuePair("out_trade_no", genOutTradNo()));packageParams.add(new BasicNameValuePair("spbill_create_ip", ip));packageParams.add(new BasicNameValuePair("total_fee", "100"));packageParams.add(new BasicNameValuePair("trade_type", "APP"));String sign = genPackageSign(packageParams);packageParams.add(new BasicNameValuePair("sign", sign));String xmlstring = toXml(packageParams);return xmlstring;} catch (Exception e) {Log.e("TAG", "fail, ex = " + e.getMessage());return null;}} private void genPayReq() {req.appId = Constants.APP_ID;req.partnerId = Constants.MCH_ID;req.prepayId = resultunifiedorder.get("prepay_id");req.packageValue = "prepay_id=" + resultunifiedorder.get("prepay_id");req.nonceStr = genNonceStr();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
" + req.sign + "
");Log.e("orion==genPayReq===============", signParams.toString()); } private void sendPayReq() {boolean sendReq = msgApi.sendReq(req);T.show(this, "微信跳转====="+sendReq+"");} }</namevaluepair></namevaluepair></namevaluepair></namevaluepair></inetaddress></networkinterface></string,></string,></string,></string,></string,></string,></void,></namevaluepair></namevaluepair></namevaluepair></namevaluepair></string,>
里面没有的类,,,,呐:源码下载。自己下载一下拷贝一下。。。
参考文章:http://www.jb51.net/article/97712.htm
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。