Android—基于微信开放平台v3SDK开发(微信支付填坑)

作者:奋斗者—cyf 时间:2023-05-20 09:04:02 

接触微信支付之前听说过这是一个坑,,,心里已经有了准备。。。我以为我没准跳坑出不来了,没有想到我填上了,调用成功之后我感觉公司所有的同事都是漂亮的,隔着北京的大雾霾我仿佛看见了太阳~~~好了,装逼结束。。。进入正题

开发准备:

1.在微信开放平台申请账号

2.成功后创建应用,就是填一些看似很官方很正经的资料了。。。(说审核7天左右,没有意外的情况下你的app第二天就审核成功了是不是很开心,有了appid,是不是就可以调用微   信支付了????-------想多了,真的)

3.微信支付是需要额外申请的:需要资料审核,账户验证,协议签署等步骤,(我记得,,资料审核要填写的东西好多,,,好多,,,账户验证就是你审核成功后微信会发送邮件到你   注册时登记的邮箱账号,其中含有随机金额用于账户验证,协议签署,略,太简单)一定要好好阅读你邮件的任何信息,因为有的细节错了,,,你可能填坑很久。。。。。。

正式开发阶段:

问题1:

调用官方的SDK发现只能成功的调起一次微信,再次支付的时候怎么也调用不起来了

解决:

似乎不是什么正经方法:在手机设置中管理应用程序,清除微信数据,缓存,,再来一遍,绝对可以调起来(当然还是只是一次。。。。)

继续:

我认为要用微信支付嘛,,就只看了调用支付接口的文档:Android—基于微信开放平台v3SDK开发(微信支付填坑)
后来发现需要的参数prepayid是怎么也找不到啊,,后来才发现这个prepayid是先调用”统一下单“这个接口时候温馨反过来的东西,但是官方的SDK中并没有统一下单的代码。坑吗???

所以要先看统一下单文档了

1.使用自己的APP调用的时候把官网down下来的SDK中WXPayEntryActivity拷贝到自己的项目,所在包的名字最后一定是.wxapi(我连包一起拷了。。。。)

2.在项目清单文件中填写:Android—基于微信开放平台v3SDK开发(微信支付填坑)

3.SDK中的AppRegister拷贝下来,,,里面换成你自己的appid,然后在项目清单中也注册一下。Android—基于微信开放平台v3SDK开发(微信支付填坑)
4.重点来了,,就是你APP要调微信支付的activity,我这还叫PayActivity

要调起微信支付页面,要在这个activity中,将你的app注册到微信Android—基于微信开放平台v3SDK开发(微信支付填坑)
 接下来先调用统一下单获取prepayid,参数,微信人家要xml格式的!我们就得发送xml格式的!Android—基于微信开放平台v3SDK开发(微信支付填坑)
好了调用的时候把这个方法的返回值当参数传,,等待微信返回success吧!。。

 我遇见的错误:签名错误

我的原因是大意了 ConfigUtil.NOTIFY_URL这个参数写的空字符串

还有是因为debug版运行的,没有打包运行

返回成功之后,可以调用支付接口了Android—基于微信开放平台v3SDK开发(微信支付填坑)

不要忘了这一步去跳转界面,,,,,
Android—基于微信开放平台v3SDK开发(微信支付填坑)
没有跳转到微信支付可能是你由运行的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;
 @Override
 protected 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() {

@Override
     public void onClick(View v) {
       GetPrepayIdTask getPrepayId = new GetPrepayIdTask();
       getPrepayId.execute();
     }
   });
   /**
    * 将该app注册到微信
    */
   check_pay_btn.setOnClickListener(new View.OnClickListener() {

@Override
     public 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\n" + sb.toString() + "\n\n");
   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;

@Override
   protected void onPreExecute() {
     dialog = ProgressDialog.show(PayActivity.this, getString(R.string.app_tip),
         getString(R.string.getting_prepayid));
   }

@Override
   protected void onPostExecute(Map<string, string=""> result) {
     if (dialog != null) {
       dialog.dismiss();
     }
     sb.append("prepay_id\n" + result.get("prepay_id") + "\n\n");

resultunifiedorder = result;

}

@Override
   protected void onCancelled() {
     super.onCancelled();
   }

@Override
   protected 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\n" + req.sign + "\n\n");
   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,>

里面没有的类,,,,呐:源码下载。自己下载一下拷贝一下。。。

参考文章:https://www.jb51.net/article/97712.htm

来源:http://www.cnblogs.com/yunfang/p/6078208.html

标签:微信支付v3,java
0
投稿

猜你喜欢

  • flutter实现底部不规则导航栏

    2023-03-03 04:33:08
  • Java利用钉钉机器人实现发送群消息

    2021-06-28 23:37:33
  • Java超详细讲解设计模式之一的单例模式

    2023-03-09 10:59:09
  • 使用Springboot 打jar包实现分离依赖lib和配置

    2023-01-29 18:35:29
  • 详解ThreadLocal为什么会内存溢出原理

    2023-11-09 18:45:26
  • C++普通函数指针与成员函数指针实例解析

    2022-09-29 10:19:36
  • C语言多功能动态通讯录实现示例

    2022-11-16 09:12:44
  • 深入Android SQLite 事务处理详解

    2023-07-17 08:32:17
  • Java开发环境jdk 1.8安装配置方法(Win7 64位系统/windows server 2008)

    2022-05-11 20:00:58
  • Android界面刷新的方法分享

    2022-06-20 15:20:52
  • C# 利用StringBuilder提升字符串拼接性能的小例子

    2022-06-02 02:21:13
  • C#实现合并多张图片为GIF动态图

    2022-12-13 04:16:35
  • spring cloud gateway跨域全局CORS配置方式

    2021-11-02 01:09:00
  • Java对象类型的判断详解

    2023-07-26 09:55:07
  • C#实现斐波那契数列的几种方法整理

    2023-09-02 05:05:58
  • java 中使用匿名类直接new接口详解及实例代码

    2021-08-13 22:26:12
  • 关于Spring Boot获取bean的3种方式

    2023-07-08 11:52:15
  • Android studio so库找不到问题解决办法

    2023-10-28 02:20:49
  • MyBatis通用的10种写法总结大全

    2022-08-01 12:04:02
  • Java面向对象之内部类案例讲解

    2021-09-16 13:28:19
  • asp之家 软件编程 m.aspxhome.com