(Mobile terminal) Teach you to complete the App terminal - Alipay payment Android

The blog has been stopped for several months. During this time, due to the constant trivial matters in life, I couldn’t stop writing. The front-end time company gave me 2 months to complete a software similar to Ctrip. As the main force of the company, after experiencing a series of difficulties, I think the process of third-party payment should be recorded. Because it really sucks too much.

This article will upload most of the code to GitHub, of course, I hope to have a serious look at the payment process before that.

Apply

1. To apply for a developer account, https://b.alipay.com/signing/authorizedProductSet.htm?navKey=all&type=productSet#/productSet?_k=yb5nbu 
recommends that you use the special account provided by the company to apply, and refer to 
https after passing ://docs.open.alipay.com/204/105297/ 
to do it step by step.

access

Before that, people must read the flow chart carefully 
This picture comes from Alipay official website

Knowing the general process, we need to connect Alipay to the project.

develop

Add the declaration in the AndroidManifest.xml file of the merchant application project:

<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

and permission declaration:

<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

Add obfuscation rules

-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

Since payment is a time-consuming operation, the use of a new thread is necessary. 
First get the order from the background, then, asynchronously call up the payment program (because RxJava is so popular, so I used it in the project, it doesn't matter if you don't know RxJava, because this step can be completely replaced by 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

First make sure that after obtaining the prepaid order, create a PayTask object, which encapsulates the payment operation. Then pass the prepaid bill into its payV2() method,

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

This step is a time-consuming operation, and the following judgments are relatively simple.

Since the code is commented, you will understand it in seconds after reading the flowchart. The process I have here is that after placing an order, the background generates the order number, and when the mobile terminal clicks to pay, the background goes to Alipay to obtain the prepaid order, and then the mobile terminal receives the data and starts the payment. After payment, the result is judged according to the resultStatus. Of course, the actual payment results depend on subsequent data. 
After the payment is completed, the Alipay server will call notify_url in POST mode to transmit data. Therefore, after paying on the mobile terminal, you need to go to the server to check the authenticity of the data.

In actual development, it is recommended to write the data in the Demo provided by Alipay to see if it can work after getting the payment order in the background, and then write the logic in your own project.

附加:

If you use payment for the first time, remember that after the Alipay client shows that the payment is successful, you should call the interface of the background staff in the next operation to confirm whether the transaction is real. As mentioned earlier, the real payment result depends on the data of the server. After payment, the Alipay backend will push the payment result to the backend. At this time, the backend should record the payment result to facilitate front-end query. Yes, what needs to be done on the Android side is that simple, because most of the work is done on the server side. If you are interested in the server side, you can check my next blog.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326163698&siteId=291194637