热门标签 | HotTags
当前位置:  开发笔记 > 前端 > 正文

Android编程实现的微信支付功能详解【附Demo源码下载】

这篇文章主要介绍了Android编程实现的微信支付功能,结合实例形式详细分析了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 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 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 signParams = new LinkedList();
    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 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 signParams = new LinkedList();
    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 params) {
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i >
  {
    private ProgressDialog dialog;
    @Override
    protected void onPreExecute() {
      // TODO Auto-generated method stub
      super.onPreExecute();
      dialog = ProgressDialog.show(MainActivity.this, "提示", "正在提交订单");
    }
    @Override
    protected Map 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 xml=decodeXml(content);
      return xml;
    }
    @Override
    protected void onPostExecute(Map 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 decodeXml(String content) {
    try {
      Map xml = new HashMap();
      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("");
      List packageParams=new LinkedList();
      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 params) {
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i >>>"+packageSign);
    return packageSign;
  }
  /*
   * 转换成xml
   */
  private String toXml(List params) {
    StringBuilder sb = new StringBuilder();
    sb.append("");
    for (int i = 0; i ");
      sb.append(params.get(i).getValue());
      sb.append("");
    }
    sb.append("");
    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程序设计有所帮助。


推荐阅读
  • 解决JAX-WS动态客户端工厂弃用问题并迁移到XFire
    在处理Java项目中的JAR包冲突时,我们遇到了JaxWsDynamicClientFactory被弃用的问题,并成功将其迁移到org.codehaus.xfire.client。本文详细介绍了这一过程及解决方案。 ... [详细]
  • 嵌入式开发环境搭建与文件传输指南
    本文详细介绍了如何为嵌入式应用开发搭建必要的软硬件环境,并提供了通过串口和网线两种方式将文件传输到开发板的具体步骤。适合Linux开发初学者参考。 ... [详细]
  • 程序员如何优雅应对35岁职业转型?这里有深度解析
    本文探讨了程序员在职业生涯中如何通过不断学习和技能提升,优雅地应对35岁左右的职业转型挑战。我们将深入分析当前热门技术趋势,并提供实用的学习路径。 ... [详细]
  • 本文详细介绍了如何正确安装Java EE SDK,并解决在安装过程中可能遇到的问题,特别是关于servlet代码在Apache Tomcat 10中无法运行的情况。 ... [详细]
  • 本文详细介绍如何在IntelliJ IDEA 14中打包Android应用APK文件,并提供查询SHA1值的具体步骤。 ... [详细]
  • 基于KVM的SRIOV直通配置及性能测试
    SRIOV介绍、VF直通配置,以及包转发率性能测试小慢哥的原创文章,欢迎转载目录?1.SRIOV介绍?2.环境说明?3.开启SRIOV?4.生成VF?5.VF ... [详细]
  • 本文探讨了在通过 API 端点调用时,使用猫鼬(Mongoose)的 findOne 方法总是返回 null 的问题,并提供了详细的解决方案和建议。 ... [详细]
  • 创建项目:Visual Studio Online 入门指南
    本文介绍如何使用微软的 Visual Studio Online(VSO)创建和管理开发项目。作为一款基于云计算的开发平台,VSO 提供了丰富的工具和服务,简化了项目的配置和部署流程。 ... [详细]
  • 本文详细介绍了网络存储技术的基本概念、分类及应用场景。通过分析直连式存储(DAS)、网络附加存储(NAS)和存储区域网络(SAN)的特点,帮助读者理解不同存储方式的优势与局限性。 ... [详细]
  • Struts与Spring框架的集成指南
    本文详细介绍了如何将Struts和Spring两个流行的Java Web开发框架进行整合,涵盖从环境配置到代码实现的具体步骤。 ... [详细]
  • 本文作者分享了在阿里巴巴获得实习offer的经历,包括五轮面试的详细内容和经验总结。其中四轮为技术面试,一轮为HR面试,涵盖了大量的Java技术和项目实践经验。 ... [详细]
  • 深入理解ExtJS:从入门到精通
    本文详细介绍了ExtJS的功能及其在大型企业前端开发中的应用。通过实例和详细的文件结构解析,帮助初学者快速掌握ExtJS的核心概念,并提供实用技巧和最佳实践。 ... [详细]
  • 本文详细介绍如何使用 Python 集成微信支付的三种主要方式:Native 支付、APP 支付和 JSAPI 支付。每种方式适用于不同的应用场景,如 PC 网站、移动端应用和公众号内支付等。 ... [详细]
  • 本文详细介绍了如何在Python3环境中配置Appium1.4.6,并指导如何连接模拟器进行自动化测试。通过本文,您将了解从环境搭建到模拟器连接的完整流程。 ... [详细]
  • 本文介绍了Java语言开发的远程教学系统,包括源代码、MySQL数据库配置以及相关文档,适用于计算机专业的毕业设计。系统支持远程调试,采用B/S架构,适合现代教育需求。 ... [详细]
author-avatar
永恆極光_822
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有