微信支付开发踩坑记录

2016-08-25  本文已影响0人  T_涛_T

在做微信支付时,虽然网上已经有了很多的文档和介绍,但是自己做了一遍还是遇到了很多坑,现在记录下来。

首先说一下大概的核心代码:

1、在微信开放平台下载了jar包后导入项目,建议顺便下载官方文档参考。虽然微信的开发文档有点坑,但有总比没有强。

2、按照开发文档,做好相关配置。下面正式开始自己的代码。

2.1、调用统一下单接口,该接口返回的是一个prepayId值。一般这一步都是由公司后台去进行,但有些公司可能需要自己写,现在写一下。

首先准备几个方法。

//获取上网ip地址:

public static String getLocalIpAddress(Context context){

try{// 获取wifi服务

WifiManager wifiManager = (WifiManager) context

.getSystemService(Context.WIFI_SERVICE);

if (!wifiManager.isWifiEnabled()){

//不能使用wifi

return getLocalIpAddress();

}else{WifiInfo wifiInfo = wifiManager.getConnectionInfo();

int i = wifiInfo.getIpAddress();

return int2ip(i);}

} catch (Exception ex){

return " 获取IP出错!!!!请保证是WIFI,或者请重新打开网络!\n" + ex.getMessage();}

}

public static String getLocalIpAddress() {      try {          for (Enumerationen = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {              NetworkInterface intf = en.nextElement();              for (EnumerationenumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {

InetAddress inetAddress = enumIpAddr.nextElement();

if (!inetAddress.isLoopbackAddress() && inetAddress instanceof Inet4Address) {

//if (!inetAddress.isLoopbackAddress() && inetAddress instanceof Inet6Address) {

return inetAddress.getHostAddress().toString();

}

}

}

} catch (Exception e) {

}

return "";

}

这些代码是我在网上找到的,wifi的可以准确获取,但gps的貌似有时候会出问题,有知道的可以指点一下。

//生成随机数,需要md5加密:

private String genNonceStr()

{

Random random = new Random();

String md5 = "";

try

{

md5 = MD5Util.md5Encode(String.valueOf(random.nextInt(10000)));

} catch (Exception e)

{

// TODO Auto-generated catch block

e.printStackTrace();

}

return md5;

}

/***

* MD5加密 生成32位md5码

* @param 待加密字符串

* @return 返回32位md5码

*/

public static String md5Encode(String inStr) throws Exception {

MessageDigest md5 = null;

try {

md5 = MessageDigest.getInstance("MD5");

} catch (Exception e) {

System.out.println(e.toString());

e.printStackTrace();

return "";

}

byte[] byteArray = inStr.getBytes("UTF-8");

byte[] md5Bytes = md5.digest(byteArray);

StringBuffer hexValue = new StringBuffer();

for (int i = 0; i < md5Bytes.length; i++) {

int val = ((int) md5Bytes[i]) & 0xff;

if (val < 16) {

hexValue.append("0");

}

hexValue.append(Integer.toHexString(val));

}

return hexValue.toString();

}

/** * 获取签名 * @param params * @return */private String genAppSign(Listparams)

{

StringBuilder sb = new StringBuilder();

for (int i = 0; i < params.size(); i++)

{

sb.append(((BasicNameValuePair) params.get(i)).getName());

sb.append('=');

sb.append(((BasicNameValuePair) params.get(i)).getValue());

sb.append('&');

}

sb.append("key=");

sb.append(Config.WXMY);

String appSign = "";

try

{

appSign = MD5Util.md5Encode(sb.toString()).toUpperCase(Locale.CHINESE);

} catch (Exception e)

{

// TODO Auto-generated catch block

e.printStackTrace();

}

return appSign;

}

在获得后台返回的商品订单号后,开启线程去提交参数。

new Thread(){

public void run(){

try{

int factPaymoney = (int) (rechargeAmount* 100);//微信单位是分

String ip =  NetworkUtils.getLocalIpAddress(PayActivity.this);//获取ip地址

String radom32=genNonceStr();//生成随机数

List<BasicNameValuePair>signParams = new LinkedList<BasicNameValuePair>();

//下面的参数你可以看官方文档查看意思,然后填入你自己的数据

signParams.add(new BasicNameValuePair("appid", Config.WXAPPID));

signParams.add(new BasicNameValuePair("body", reChargeName));

signParams.add(new BasicNameValuePair("mch_id", Config.MCHID));//

signParams.add(new BasicNameValuePair("nonce_str",radom32 ));

signParams.add(new BasicNameValuePair("notify_url",""));

signParams.add(new BasicNameValuePair("out_trade_no", paymentID));

signParams.add(new BasicNameValuePair("spbill_create_ip", ip));

signParams.add(new BasicNameValuePair("total_fee", 1+""));

signParams.add(new BasicNameValuePair("trade_type", "APP"));

StringBuilder xml = new StringBuilder();

xml.append("<xml>");

xml.append("<appid>" + Config.WXAPPID+ "</appid>");

xml.append("<body>"+reChargeName+"</body>");

xml.append("<mch_id>" + Config.MCHID+ "</mch_id>");

xml.append("<nonce_str>" +radom32+ "</nonce_str>");

xml.append("<notify_url>" + "自己的通知地址"+ "</notify_url>");

xml.append("<out_trade_no>" + paymentID+ "</out_trade_no>");

xml.append("<sign>"+ genAppSign(signParams)+"</sign>");

xml.append("<spbill_create_ip>"+ip+"</spbill_create_ip>");

xml.append("<total_fee>"+填入金额+"</total_fee>");

xml.append("<trade_type>APP</trade_type>");

xml.append("</xml>");

Stringxmls= new String(xml.toString().getBytes(), "UTF-8");

byte[] xmlbyte = xmls.getBytes("UTF-8");

URL url = new URL("https://api.mch.weixin.qq.com/pay/unifiedorder");//微信统一下单接口

HttpURLConnection conn = (HttpURLConnection) url.openConnection();

conn.setDoOutput(true);

conn.setConnectTimeout(5000);

conn.setRequestMethod("POST");

conn.setRequestProperty("Content-Type","text/xml;charset=UTF-8");//此处需要设置你的编码格式,我用的utf-8,不然中文会乱码

conn.setRequestProperty("Content-Length",

String.valueOf(xmlbyte.length));

conn.getOutputStream().write(xmlbyte);

if (conn.getResponseCode() == 200){InputStream is = conn.getInputStream();// 获取返回数据

// 使用输出流来输出字符(可选)

ByteArrayOutputStream out = new ByteArrayOutputStream();

byte[] buf = new byte[1024];

int len;while ((len = is.read(buf)) != -1){out.write(buf, 0, len);}

String string = out.toString("UTF-8");

Message msg= new Message();

msg.what=1;

msg.obj=string;handler.sendMessage(msg);out.close();}

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

};}.start();

@SuppressLint("HandlerLeak")

private Handler handler = new Handler(){

public void handleMessage(Message msg) {

switch (msg.what) {

case 1:

try{

String prepar_id=msg.obj.toString();

int start=prepar_id.indexOf("prepay_id");

int end =prepar_id.indexOf("]]></prepay_id>");

prepar_id=prepar_id.substring(start+19, end);//此处获得我们需要的prepar_id字段

sendPayReq(prepar_id);//最后再次进行传参,发起支付

} catch (Exception e)

{

}

break;

}

};

};

2.2 发起支付

/**

* 调用微信支付页面

*/

private void sendPayReq(String prepayId)

{

api.registerApp(Config.WXAPPID);//此处踩过坑,以为写了appregister注册后不用在注册,事实是需要,所以不知道那个appregister有什么作用

genPayReq(prepayId);

api.sendReq(req);//此处成功后,会回调微信支付结果页面WXPayEntryActivity,这个在官方文档里有

}

/** * 生成签名参数 * @param prepayId  */

private void  genPayReq(String prepayId){

req.appId = Config.WXAPPID;// appid

req.partnerId = Config.MCHID;// 商户号

req.prepayId = prepayId;// 预支付交易会话ID

req.packageValue = "Sign=WXPay";// 扩展字段,固定的

req.nonceStr = genNonceStr();// 随机字符串

req.timeStamp = String.valueOf(genTimeStamp());// 时间戳

List<BasicNameValuePair> signParams = newLinkedList<BasicNameValuePair>();

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);//再次签名

}

/**

* 时间戳

*

* @return

*/

private long genTimeStamp()

{

return System.currentTimeMillis() / 1000;

}

以上就是微信支付开发的基本步骤了,记录一下,以备以后再用。

上一篇下一篇

猜你喜欢

热点阅读