当前位置:   article > 正文

Android端接入微信支付的详细流程_android微信支付流程

android微信支付流程

随着微信支付的越来越普及,现在几乎所有的app都会接入微信的支付API,我当前也遇到了这个问题,查了 微信的网页介绍,但还是走了很多弯路,所以把我的经验分享出来,防止网友再走弯路。

我会参照微信的api介绍,加上微信给的demo一步一步来说。

微信支付接入介绍参见:https://pay.weixin.qq.com/wiki/doc/api/app.php?chapter=8_5


1、后台设置

商户在微信开放平台申请开发应用后,微信开放平台会生成APP的唯一标识APPID。由于需要保证支付安全,需要在开放平台绑定商户应用包名和应用签名,设置好后才能正常发起支付。设置界面在【开放平台】中的栏目【管理中心 / 修改应用 / 修改开发信息】里面,如图8.8红框内所示。

修改开发信息

图8.8

应用包名:是在APP项目配置文件AndroidManifest.xml中声明的package值,例如DEMO中的package="net.sourceforge.simcpux"。

应用签名:根据项目的应用包名和编译使用的keystore,可由签名工具生成一个32位的md5串,在调试的手机上安装签名工具后,运行可生成应用签名串,如图8.9所示,绿色串即应用签名。签名工具下载地址https://open.weixin.qq.com/zh_CN/htmledition/res/dev/download/sdk/Gen_Signature_Android.apk

修改开发信息

图8.9

这一步就是用来验证APP合法性的,做APP的人应该都知道,简单配置一下就可以啦。



2、注册APPID

商户APP工程中引入微信JAR包,调用API前,需要先向微信注册您的APPID,代码如下:

API调用前,需要先向微信注册您的APP,代码如下:

final IWXAPI msgApi = WXAPIFactory.createWXAPI(context, null);

// 将该app注册到微信

msgApi.registerApp("wxd930ea5d5a258f4f");


还要在Manifest文件中加入你的APPID

  1. <span style="color:#222222;"><activity
  2. android:name=".PayActivity"
  3. android:label="@string/app_name"
  4. android:exported="true"
  5. android:launchMode="singleTop">
  6. <intent-filter>
  7. <action android:name="android.intent.action.MAIN" />
  8. <category android:name="android.intent.category.LAUNCHER" />
  9. </intent-filter>
  10. <intent-filter>
  11. <action android:name="android.intent.action.VIEW"/>
  12. <category android:name="android.intent.category.DEFAULT"/>
  13. </span><span style="color:#ff0000;"><data android:scheme="wxf2f565574a968187"/></span><span style="color:#222222;">
  14. </intent-filter>
  15. </activity></span>



代码里体现在

  1. <span style="color:#222222;">package com.weixin.paydemo;
  2. public class PayActivity extends Activity {
  3. private static final String TAG = "MicroMsg.SDKSample.PayActivity";
  4. PayReq req;
  5. </span><span style="color:#ff0000;">final IWXAPI msgApi = WXAPIFactory.createWXAPI(this, null);</span><span style="color:#222222;">
  6. TextView show;
  7. Map<String,String> resultunifiedorder;
  8. StringBuffer sb;
  9. @Override
  10. protected void onCreate(Bundle savedInstanceState) {
  11. super.onCreate(savedInstanceState);
  12. setContentView(R.layout.pay);
  13. show =(TextView)findViewById(R.id.editText_prepay_id);
  14. req = new PayReq();
  15. sb=new StringBuffer();
  16. </span><span style="color:#ff0000;">msgApi.registerApp(Constants.APP_ID);</span><span style="color:#222222;">
  17. //生成prepay_id
  18. Button payBtn = (Button) findViewById(R.id.unifiedorder_btn);
  19. payBtn.setOnClickListener(new View.OnClickListener() {
  20. @Override
  21. public void onClick(View v) {
  22. GetPrepayIdTask getPrepayId = new GetPrepayIdTask();
  23. getPrepayId.execute();
  24. }
  25. });
  26. Button appayBtn = (Button) findViewById(R.id.appay_btn);
  27. appayBtn.setOnClickListener(new View.OnClickListener() {
  28. @Override
  29. public void onClick(View v) {
  30. sendPayReq();
  31. }
  32. });
  33. //生成签名参数
  34. Button appay_pre_btn = (Button) findViewById(R.id.appay_pre_btn);
  35. appay_pre_btn.setOnClickListener(new View.OnClickListener() {
  36. @Override
  37. public void onClick(View v) {
  38. genPayReq();
  39. }
  40. });
  41. String packageSign = MD5.getMessageDigest(sb.toString().getBytes()).toUpperCase();
  42. }
  43. </span>


3. 调用支付

商户服务器生成支付订单,先调用统一下单API(详见第7节)生成预付单,获取到prepay_id后将参数再次签名传输给APP发起支付。以下是调起微信支付的关键代码:

IWXAPI api;

PayReq request = new PayReq();

request.appId = "wxd930ea5d5a258f4f";

request.partnerId = "1900000109";

request.prepayId= "1101000000140415649af9fc314aa427",;

request.packageValue = "Sign=WXPay";

request.nonceStr= "1101000000140429eb40476f8896f4c9";

request.timeStamp= "1398746574";

request.sign= "7FFECB600D7157C5AA49810D2D8F28BC2811827B";

api.sendReq(req);

注意:该sign生成字段名列表见调起支付API

代码Demo

  1. private void sendPayReq() {
  2. msgApi.registerApp(Constants.APP_ID);
  3. msgApi.sendReq(req);
  4. }
这个req包含参数,参数生成方法如下

  1. private void genPayReq() {
  2. <span style="color:#ff0000;">req.appId = Constants.APP_ID;
  3. req.partnerId = Constants.MCH_ID;
  4. req.prepayId = resultunifiedorder.get("prepay_id");
  5. req.packageValue = "Sign=WXPay";
  6. req.nonceStr = genNonceStr();
  7. req.timeStamp = String.valueOf(genTimeStamp());</span>
  8. List<NameValuePair> signParams = new LinkedList<NameValuePair>();
  9. signParams.add(new BasicNameValuePair("appid", req.appId));
  10. signParams.add(new BasicNameValuePair("noncestr", req.nonceStr));
  11. signParams.add(new BasicNameValuePair("package", req.packageValue));
  12. signParams.add(new BasicNameValuePair("partnerid", req.partnerId));
  13. signParams.add(new BasicNameValuePair("prepayid", req.prepayId));
  14. signParams.add(new BasicNameValuePair("timestamp", req.timeStamp));
  15. req.sign = genAppSign(signParams);
  16. sb.append("sign\n"+req.sign+"\n\n");
  17. show.setText(sb.toString());
  18. Log.e("orion", signParams.toString());
  19. }
签名生成方式如下:

  1. private String genAppSign(List<NameValuePair> params) {
  2. StringBuilder sb = new StringBuilder();
  3. for (int i = 0; i < params.size(); i++) {
  4. sb.append(params.get(i).getName());
  5. sb.append('=');
  6. sb.append(params.get(i).getValue());
  7. sb.append('&');
  8. }
  9. sb.append("key=");
  10. sb.append(Constants.API_KEY);
  11. this.sb.append("sign str\n"+sb.toString()+"\n\n");
  12. String appSign = MD5.getMessageDigest(sb.toString().getBytes()).toUpperCase();
  13. Log.e("orion",appSign);
  14. return appSign;
  15. }


同时,微信支付之前其实是要先生成订单的,生成订单的代码如下

  1. private class GetPrepayIdTask extends AsyncTask<Void, Void, Map<String,String>> {
  2. private ProgressDialog dialog;
  3. @Override
  4. protected void onPreExecute() {
  5. dialog = ProgressDialog.show(PayActivity.this, getString(R.string.app_tip), getString(R.string.getting_prepayid));
  6. }
  7. @Override
  8. protected void onPostExecute(Map<String,String> result) {
  9. if (dialog != null) {
  10. dialog.dismiss();
  11. }
  12. sb.append("prepay_id\n"+result.get("prepay_id")+"\n\n");
  13. show.setText(sb.toString());
  14. resultunifiedorder=result;
  15. }
  16. @Override
  17. protected void onCancelled() {
  18. super.onCancelled();
  19. }
  20. @Override
  21. protected Map<String,String> doInBackground(Void... params) {
  22. String url = String.format("https://api.mch.weixin.qq.com/pay/unifiedorder");
  23. String entity = genProductArgs();
  24. Log.e("orion",entity);
  25. byte[] buf = Util.httpPost(url, entity);
  26. String content = new String(buf);
  27. Log.e("orion", content);
  28. Map<String,String> xml=decodeXml(content);
  29. return xml;
  30. }
  31. }

4,这样应该就能调起微信支付了,还有最重要的一步是,接收微信的返回结果,微信定义了一个入口,你需要在你自己的应用程序中定义这个入口,微信在支付完成后会回调这个入口的方法,代码如下:


AndroidManifest文件中先定义

  1. <activity
  2. android:name="com.weixin.paydemo.wxapi.WXPayEntryActivity"
  3. android:exported="true"
  4. android:launchMode="singleTop"/>
  5. <receiver
  6. android:name="net.sourceforge.simcpux.AppRegister">
  7. <intent-filter>
  8. <action android:name="com.tencent.mm.plugin.openapi.Intent.ACTION_REFRESH_WXAPP" />
  9. </intent-filter>
  10. </receiver>

  1. public class WXPayEntryActivity extends Activity<span style="color:#ff0000;"> implements IWXAPIEventHandler{</span>
  2. private static final String TAG = "MicroMsg.SDKSample.WXPayEntryActivity";
  3. private IWXAPI api;
  4. @Override
  5. public void onCreate(Bundle savedInstanceState) {
  6. super.onCreate(savedInstanceState);
  7. setContentView(R.layout.pay_result);
  8. api = WXAPIFactory.createWXAPI(this, Constants.APP_ID);
  9. api.handleIntent(getIntent(), this);
  10. }
  11. @Override
  12. protected void onNewIntent(Intent intent) {
  13. super.onNewIntent(intent);
  14. setIntent(intent);
  15. api.handleIntent(intent, this);
  16. }
  17. @Override
  18. public void onReq(BaseReq req) {
  19. }
  20. <span style="color:#ff0000;">@Override
  21. public void onResp(BaseResp resp) {
  22. Log.d(TAG, "onPayFinish, errCode = " + resp.errCode);
  23. if (resp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX) {
  24. AlertDialog.Builder builder = new AlertDialog.Builder(this);
  25. builder.setTitle(R.string.app_tip);
  26. builder.setMessage(getString(R.string.pay_result_callback_msg, resp.errStr +";code=" + String.valueOf(resp.errCode)));
  27. builder.show();
  28. }
  29. }</span>
  30. }


onResp就是支付完成之后回调的方法。


OK,一套完整的微信支付方法就完成了。

之前有网友问,一个APP里面可以有两个微信的APPID吗,也就是可以付款到两个微信账户吗,从代码来看好像是不可以的,因为首先应用程序会注册到一个APPID上,我认为微信会在sendREq的时候验证APPID和应用程序的对应性,但后来我发现其实可以,因为微信并没有这样做,也就是说在第二步注册APPID,你按照正常流程注册完之后,在第三步发送req的时候,你可以使用任意的APPID,想付款到那个账号就发送哪个APPID,是不是很爽,值得注意的是第三步中的req的APPID需要和prepayid里的APPID对应起来。


这样虽然用起来比较方便,但我总觉得可能不安全,也就是说微信之前做了那么多的验证工作,在关键的一步却没有验证,是不是很可笑。虽然还没有想到问题在哪里,再让我考虑下。


OK,到这里就结束了。有问题可以评论


声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/空白诗007/article/detail/989125
推荐阅读
相关标签
  

闽ICP备14008679号