(手机端)手把手教你完成App端-支付宝支付Android

博客停更了好几个月,这段时间由于生活上的琐事不断,静不下心来写,前端时间公司给了2个月完成一个类似携程的软件。而我作为公司的主力,在经历了一系列难题以后,我认为第三方支付的流程,应该做一下记录。因为它真的坑太多了。

本文将会把大多数代码上传至GitHub上,当然,我希望在这之前,认真的看一遍支付流程。

申请

1.申请开发者账号,https://b.alipay.com/signing/authorizedProductSet.htm?navKey=all&type=productSet#/productSet?_k=yb5nbu 
推荐各位使用公司提供的专号来申请,通过后参考 
https://docs.open.alipay.com/204/105297/ 
一步步完成操作。

接入

在此之前,一定要人认真的的看一遍流程图 
此图源于支付宝官网

知道了大概流程,我们需要接入支付宝到项目里。

开发

在商户应用工程的AndroidManifest.xml文件里面添加声明:

<activity
    android:name="com.alipay.sdk.app.H5PayActivity"
    android:configChanges="orientation|keyboardHidden|navigation|screenSize"
    android:exported="false"
    android:screenOrientation="behind"
    android:windowSoftInputMode="adjustResize|stateHidden" >
</activity>
 <activity
    android:name="com.alipay.sdk.app.H5AuthActivity"
    android:configChanges="orientation|keyboardHidden|navigation"
    android:exported="false"
    android:screenOrientation="behind"
    android:windowSoftInputMode="adjustResize|stateHidden" >
</activity>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

和权限声明:

<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" />
  • 1
  • 2
  • 3
  • 4
  • 5

添加混淆规则

-libraryjars libs/alipaySDK-20150602.jar

-keep class com.alipay.android.app.IAlixPay{*;}
-keep class com.alipay.android.app.IAlixPay$Stub{*;}
-keep class com.alipay.android.app.IRemoteServiceCallback{*;}
-keep class com.alipay.android.app.IRemoteServiceCallback$Stub{*;}
-keep class com.alipay.sdk.app.PayTask{ public *;}
-keep class com.alipay.sdk.app.AuthTask{ public *;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

由于支付是需要耗时的操作,因此使用新线程是必要的。 
首先从后台获取订单,接下来,异步调起支付程序(由于RxJava实在太流行了所以我用到了项目里,不懂RxJava的也不要紧,因为这一步完全可以用Handler替代。):

Observable.create(new Observable.OnSubscribe<Map<String, String>>()
            {

                @Override
                public void call(Subscriber<? super Map<String, String>> subscriber)
                {
                    PayTask alipay = new PayTask(mActivity);
                    if (orders.getAliPayOrderString() == null) //orders.getAliPayOrderString()是后台请求得到的预付单,这个是必要条件。后台如何生成请参照下一篇博客。
                    {
                        subscriber.onNext(null);
                        return;
                    }
                    String orderInfo = orders.getAliPayOrderString();

                    Map<String, String> result = alipay.payV2(orderInfo, true);
                    subscriber.onNext(result);
                    subscriber.onCompleted();
                }
            }).observeOn(AndroidSchedulers.mainThread())
                    .subscribeOn(Schedulers.io 

())
                    .subscribe(new Observer<Map<String, String>>()
                    {
                        @Override
                        public void onCompleted()
                        {
                        }

                        @Override
                        public void onError(Throwable e)
                        {
                        }

                        @Override
                        public void onNext(Map<String, String> stringStringMap)
                        {
                            if (stringStringMap == null)
                            {
                                Toast.error("返回数据异常!");
                                return;
                            }
                            PayResult payResult = new PayResult(stringStringMap);
                            /**
                             对于支付结果,请商户依赖服务端的异步通知结果。同步通知结果,仅作为支付结束的通知。
                             */
                            String resultInfo = payResult.getResult();// 同步返回需要验证的信息
                            String resultStatus = payResult.getResultStatus();
                            // 判断resultStatus 为9000则代表支付成功
                            if (TextUtils.equals(resultStatus, "9000"))
                            {
                                // 该笔订单是否真实支付成功,需要依赖服务端的异步通知。
                                startActivity(new Intent(mActivity, OrderResult.class).putExtra("status", order)); // 付款页面
                                finish();
                            } else
                            {
                                // 该笔订单真实的支付结果,需要依赖服务端的异步通知。
                                order = null;
                                startActivity(new Intent(mActivity, OrderResult.class).putExtra("resultStatus", resultInfo)); // 付款结果页面,在跳转到此页面后,像服务器端发起请求查看异步通知的支付结果,由于只是调用一个接口因此这里不做演示。
                                finish();
                            }
                        }
                    });
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63

首先确保获取了预付单以后,创建一个PayTask 对象,此对象封装了支付的操作。然后将预付单传入它的payV2()方法内,

    Map<String, String> result = alipay.payV2(orderInfo, true);

这一步就是耗时操作,下面的判断都比较简单了。

由于代码都加上了注释,看了流程图一定会秒懂。我这里的流程是,下单后后台生成下单号,再手机端点击支付的时候,后台去支付宝获取预付单,然后手机端收到数据后开始付款,付款后,根据resultStatus判断结果。当然,真是的支付结果依赖于后来的数据。 
支付宝服务器在支付完成后,会以POST方式调用notify_url传输数据。所以当手机端支付后,需要去服务端查看数据真实性。

在实际开发中,建议拿到后台支付单后,先将数据写死在支付宝提供的Demo中尝试是否能跑通,然后再将逻辑写在自己的项目中。

附加:

首次使用支付的要记得,接下来支付宝客户端显示支付成功后,应该在下一步操作中调用后台人员的接口来确认该笔交易是否真实,前面也有讲过,真实支付结果依赖于服务器的数据,手机在支付后支付宝后台会推送支付结果到后台,此时后台应该记录支付结果,以便于前端查询。没错,Android端需要做的,就是这么简单,因为大部分工作,都在服务器端来完成。对服务器端感兴趣的,可以查看我下一篇博客。

猜你喜欢

转载自blog.csdn.net/zhh1072773034/article/details/79852044