Android应用接入微信支付实现支付功能

Android应用接入微信支付实现支付功能

记得很早以前公司项目中添加过移动支付这一块, 包括 微信,支付宝,银联等第三方的整合。 但是后来懒于总结就没留下什么, 最近公司项目打算添加,所以打算简单总结一下,记上一笔以备将来使用。 毕竟第三方的支付SDK , 一般定下了以后三五年不会改变。 闲话少说,开干。 集成第三方SDK没什么难度,只要我们用心阅读文档和开发引导,集成起来再留点神,一切都不是问题。

申请准备材料

首先说一下,微信支付需要在开放平台进行注册,申请商户资质。不是公众平台,另外这两个平台却用了同一套账号体系也就是说,有一个邮箱你注册公众平台,开放平台就不行了。
先给个官网链接https://pay.weixin.qq.com/index.php.

申请商户的准备工作,需要申请商户资质的材料也不会特殊,大概都需要以下几种:

  • 单位营业执照彩色扫描件或数码照片
  • 对公银行账户(基本账户、一般账户均可)
  • 法定代表人的身份证彩色扫描件或数码照片
    若为代理人(即法人以外的公司代表)申请认证,需额外提供以下两项材料
  • 代理人的身份证彩色扫描件或数码照片
  • 委托书,委托书上必须盖有单位公章或财务专用章(合同专用章、业务专用章等无效)下载委托书模版
  • 开发者资质审核需要299元RMB/年.

申请过程按照微信官网提示进行操作即可,就不在赘述了。

SDK配置

集成过程很简单,现在一般都使用gradle看一下配置

//下面依赖根据业务需要,任选其一
dependencies {
   //包含统计功能
   compile 'com.tencent.mm.opensdk:wechat-sdk-android-with-mta:+'
   //不包含统计功能,不使用统计功能的话这个就足够使用了。
   compile 'com.tencent.mm.opensdk:wechat-sdk-android-without-mta:+'
}

如果还是用eclipse的话, 就记得把libammsdk.jar 放到libs目录中, 记得addToBuildPath

下边是权限配置

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

下边就看一下Manifest.xml 文档配置。

  <activity android:name=".wxapi.WXPayEntryActivity" 
     android:exported="true"
     android:launchMode="singleTop" />

这个文件就是支付完成之后微信通过Aidl回调传送结果的类,所以exported属性为true。 另外这个文件的放置目录一定要准确包名的路径和AndroidManifest.xml文件中WXPayEntryActivity配置一致 ,微信回调找不到class 就会checkargs出错,调不起微信。

接下来就看一下代码吧:
官网SDKDemo下载解压导入eclipse之后可以看到。一个很简单的调用过程。
检查当前的微信版本是否支持.发起req的时候一定要检测一下sdk是否支持.

扫描二维码关注公众号,回复: 2159114 查看本文章
    Button checkPayBtn = (Button) findViewById(R.id.check_pay_btn);
        checkPayBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                boolean isPaySupported = api.getWXAppSupportAPI() >= Build.PAY_SUPPORTED_SDK_INT;
                Toast.makeText(PayActivity.this, String.valueOf(isPaySupported), Toast.LENGTH_SHORT).show();
            }
        });

下边看一下发起支付请求的主调用方法

            try {
                Log.d("get server pay params:", content);
                JSONObject json = new JSONObject(content);
                if (null != json && !json.has("retcode")) {
                    PayReq req = new PayReq();
                    req.appId = Constants.APP_ID; 
                    req.prepayId = json.getString("prepayid");
                    req.nonceStr = json.getString("noncestr");
                    req.timeStamp = json.getString("timestamp");
                    req.packageValue = json.getString("package");
                    req.sign = json.getString("sign");
                    req.extData = "app data"; // optional
                     Toast.makeText(PayActivity.this, "正常调起支付", Toast.LENGTH_SHORT).show();
                     api.sendReq(req);
                } else {
                    Log.d("PAY_GET", "返回错误" + json.getString("retmsg"));
                    Toast.makeText(PayActivity.this, "返回错误" + json.getString("retmsg"), Toast.LENGTH_SHORT).show();
                }

            } catch (Exception e) {
                Log.e("PAY_GET", "异常:" + e.getMessage());
                Toast.makeText(PayActivity.this, "异常:" + e.getMessage(), Toast.LENGTH_SHORT).show();
            }

在支付之前,如果应用没有注册到微信,应该先调用IWXMsg.registerApp将应用注册到微信:

    api = WXAPIFactory.createWXAPI(this, Constants.APP_ID);
    api.registerApp(Constants.APP_ID);

createWXAPI这个方法,有个参数checkSignature,是否要检查签名。前期调试很好使,上线时候记得关掉。

下边看一下支付完成之后的微信的回调

 public class WXPayEntryActivity extends Activity implements IWXAPIEventHandler {
    private static final String TAG = "MicroMsg.SDKSample.WXPayEntryActivity";
    private IWXAPI api;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.pay_result);
        api = WXAPIFactory.createWXAPI(this, Constants.APP_ID);
        api.handleIntent(getIntent(), this);
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        setIntent(intent);
        api.handleIntent(intent, this);
    }

    @Override
    public void onReq(BaseReq req) {
    }
    @Override
    public void onResp(BaseResp resp) {
        Log.d(TAG, "onPayFinish, errCode = " + resp.errCode);
        if (resp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX) {
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setTitle("R.string.app_tip");
            builder.setMessage(getString(R.string.pay_result_callback_msg, String.valueOf(resp.errCode)));
            builder.show();
        }
    }

}

这里有个方法可以根据onResp方法的BaseResp参数来判断支付结果。 errCode =0 就是没错,支付成功。 -2 用户取消支付, -1 支付出错。

  • 这里有个坑,我觉得有必要说一下,一般支付完毕之后可以告诉用户是否成功, 如果产品让添加一下支付的介面呢, 比如添加一下UI, 这时候就需要根据结果来初始化UI, 这里的声明周期方法 就是 onResp –> onNewIntent –> onCreate , 所以需要声明一个字段提前保存支付状态。然后再根据结果再onCreate中进行初始化UI元素,以及其他操作。

整体流程分析

说起流程分析最适合的就是弄个sequence, 看图
微信支付流程图
红色的主体是我们自己的APP的和Server 。
这里注意14步,支付验证授权,完成支付交易之后,这里触发的是一个并行的流程。
* 微信后台通知微信APP ,然后再回调我们的APP通知结果
* 微信后台异步通知我们的后台Server,我们Server再进行接收保存等处理。
另一个地方是对于支付的结果,我们自己可以查询自己Server之前保存的结果,也可以Server调用微信的后台API来查询支付结果,这里不再赘述。

注意事项

  • APPId一定要配置成自己的APPID,别忘改了。
  • 在SDK集成封装完成之后,一定要用正式签名来打包。否则就会出errorCode -1
  • WXPayEntryActivity这个类要放到wxapi的package下,并声明export=true ,这个一般复制demo的话也不容易出错。
  • 我们的支付结果一般认为使用sdk提供的onResp回调就行了,可是移动端毕竟有很多不可控因素,所以在一些特殊的场合(断网或者弱网,断电,kill进程,等等)还是依赖我们自己Server的回调确认比较好。

总结

说到官网API不得不说和支付宝的根本没法比,
首先就说Demo,支付宝提供的demo两种版本,eclipse & gradle。 微信sdkdemo 只放的有eclipse 代码已经很久没有维护了,网络请求还在主线程中写着。
再说支付结构来说,微信是使用aidl进程间通信来回调WXPayEntryActivity这个类,使用上限制比较多,比如包名,签名,类放置位置,甚至在调起微信的过程还得请求验签。 支付宝很简单,靠的是强大的RSA2加密算法把自己的SDK嵌入到了调用者的APP中,调用十分方便,整洁。

另附完整支付宝微信集成源码:https://github.com/samuelhehe/PayDemo

关于支付宝的集成看我的另一篇文章Android应用接入支付宝实现支付功能

猜你喜欢

转载自blog.csdn.net/shinnexi/article/details/79594416