首页 > 系统 > Android > 正文

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

2019-12-12 02:29:56
字体:
来源:转载
供稿:网友

本文实例讲述了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 微信分配的公众账号IDpublic static final String APP_ID = "";//商户号 微信分配的公众账号IDpublic 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

@Overrideprotected Map<String, String> 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<String,String> 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<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");    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<String,String> 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<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");    textView.setText(sb.toString());    Log.e("Simon", "----"+signParams.toString());  }  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.API_KEY);    this.sb.append("sign str/n"+sb.toString()+"/n/n");    String appSign = MD5.getMessageDigest(sb.toString().getBytes());    Log.e("Simon","----"+appSign);    return appSign;  }  private class PrePayIdAsyncTask extends AsyncTask<String,Void, Map<String, String>>  {    private ProgressDialog dialog;    @Override    protected void onPreExecute() {      // TODO Auto-generated method stub      super.onPreExecute();      dialog = ProgressDialog.show(MainActivity.this, "提示", "正在提交订单");    }    @Override    protected Map<String, String> 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<String,String> xml=decodeXml(content);      return xml;    }    @Override    protected void onPostExecute(Map<String, String> 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<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("Simon","----"+e.toString());    }    return null;  }  private String getProductArgs() {    // TODO Auto-generated method stub    StringBuffer xml=new StringBuffer();    try {      String nonceStr=getNonceStr();      xml.append("<xml>");      List<NameValuePair> packageParams=new LinkedList<NameValuePair>();      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<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.API_KEY);    String packageSign = MD5.getMessageDigest(sb.toString().getBytes()).toUpperCase();    Log.e("Simon",">>>>"+packageSign);    return packageSign;  }  /*   * 转换成xml   */  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("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程序设计有所帮助。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表