This article only discusses that you have successfully implemented the client -> Alipay payment process, but you cannot return to your APP after payment. If your payment process is client ->Safari-> Alipay is beyond the scope of this article. IOS Alipay H5 payment is not under discussion. Download the official Demo of Alipay H5 Payment (Demo usage document)

How did I solve this problem

The first paragraph of this article is about how the landlord solved this problem, and the trouble encountered in the middle. Those of you in a hurry can go straight to the final solution.

Before we discuss this, let’s take a look at the official document:

Note: In the iOS system, the payment evoked by alipay App will not automatically return to the browser or merchant App. Users can manually cut back to the browser or merchant APP; Alipay H5 cashier will automatically jump back to the page specified by merchant return_url.

what? Did the authorities just tell us “GG”? The building Lord is unwilling, still want to try. Learning from the previous experience that iOS wechat H5 payment cannot return APP solution, let’s try the return_URL parameter first.

The difference between Alipay and wechat is that alipay’s return_URL does not need to be recorded (filled in) in the alipay management background, while wechat’s redirect_URL is required.

First try the webView intercept request mapi.alipay.com/gateway.do,…

In the second attempt, since it could not be tamper with, please fill it in when placing the order directly. I asked the students in the background to help change the return_URL parameter to URLEncode(A.company.com://) when placing the order, but it still failed. The background reminds me that the return_URL must start with HTTP/HTTPS, which is explained in the Alipay document.

Return_url to URLEncode(httpA.company.com://) and URLSchemes of APP to httpA.company.com. When I returned from alipay, I opened Safari, which showed the error page of our payment center. The return_url scheme failed completely!

Or just tell the product that Alipay can’t make the payment and then jump back to the APP, which is what alipay’s official documentation says anyway. I thought so, but I kept looking through alipay’s files, hoping to find some clues.

And all of a sudden I saw this,Transfer payment from mobile website to Native payment

schemeStrThe key word lit up my eyes.

Payment transfer from Mobile website to Native payment: Alipay means that we provide an SDK, after you answer it, you can easily realize the transition from H5 cashier (i.e. enter alipay account password to pay on the Web) to alipay APP cashier.

If you are a “proper “APP developer, you can solve your problem by now. According to the Alipay document to connect to the Alipay SDK, you can achieve H5 payment callback APP.

However, this is not what the owner of the building wants, because of the work needs, the owner of the building do not want to accept alipay SDK, afraid of being audited by Apple father sweep package ah. If your APP” should “use Apple Pay, even if you don’t use Alipay’s functionality but include alipay’s SDK, it may be rejected if the review is discovered.

Keep looking for solutions.

Download alipay Demo, try it can actually jump back to the APP. “In the iOS system, alipay APP will not automatically return to the browser or merchant APP after the payment is completed. Users can manually cut it back to the browser or merchant APP, but Alipay is reluctant to disclose it.

Although there is schemeStr parameter in SDK, SDK is a black box, you don’t know what it does in it.

/** * payment interface ** @param orderStr order information * @param schemeStr Calls the payment app registered in scheme * @param completionBlock in info.plist Payment result callback Block, For wap payment result callback (non-jump wallet payment) */ - (void)payOrder:(NSString *)orderStr fromScheme:(NSString *)schemeStr callback:(CompletionBlock)completionBlock;Copy the code

Trace back to the source, eventually open alipay APP will go

[UIApplication sharedApplication] openURL:]
Copy the code

I ran it through the Demo project. No. But I’m sure it’s in the SDK!

Whatever – Method Swizzling

#import <UIKit/UIKit.h> #import <objc/runtime.h> @implementation UIApplication (TrackTimer) + (void)load { static dispatch_once_t oneToken; dispatch_once(&oneToken, ^{ SEL mySelector = NSSelectorFromString(@"my_openURL:"); SEL orginalSelector = NSSelectorFromString(@"openURL:"); Method myMethod = class_getInstanceMethod([self class], mySelector); Method orginalMethod = class_getInstanceMethod([self class], orginalSelector); BOOL didAddMethod = class_addMethod([self class], orginalSelector, method_getImplementation(myMethod), method_getTypeEncoding(myMethod)); if (didAddMethod) { class_replaceMethod([self class], mySelector, method_getImplementation(orginalMethod), method_getTypeEncoding(orginalMethod)); } else { method_exchangeImplementations(myMethod, orginalMethod); }}); } - (void)my_openURL:(NSURL*)url { NSLog(@"%@",url); [self my_openURL:url]; }Copy the code

Print the result after URLDecode

alipaymatrixbwf0cml3://alipayclient/? {

“fromAppUrlScheme” : “alisdkdemo”, “requestType” : “SafePay”, “dataString” : “trade_no=”2018041921001001270586523089″&pay_phase_id=””&biz_type=”trade”&biz_sub_type=”TRADE”&app_name=”tb”&extern_toke n=”1fc77c67c70ef70d58e2bf7c513d91a5″&appenv=””&pay_channel_id=”alipay_sdk”&bizcontext=”{“av”:”1″,”sc”:”h5tonative”,”ty”: “Ios_lite”, “appkey” : “2014052600006128”, “sv” : “h.a. 3.5.3”, “an” : “com. Antfin. AliSDKDemo”}} “”

Why is there a little bit of garbled alipayMatrixbwf0cml3 in front of it? I don’t care. FromAppUrlScheme, isn’t that a surprise?

Does pay treasure H5 pay to have this parameter? WebView will eventually have an Alipay :// request, block it, see the parameters

alipay://alipayclient/? {“dataString”:”h5_route_token=”xxxxxxxxxxxxx”&is_h5_route=”true””,”requestType”:”SafePay”,”fromAppUrlScheme”:”alipays”}

There is also the fromAppUrlScheme parameter, and the default is alipay APP URLScheme: AliPays. By comparison, the schemeStr parameter passed in the SDK corresponds to the fromAppUrlScheme field in Alipay ://. When alipay:// is opened, fromAppUrlScheme is passed in, and when the payment is finished, it will jump to the corresponding APP.

Finally, the building Lord verified afore-mentioned speculation in his project. Summary?

Final solution

Plan a

Connect the SDK provided by Alipay, and pass the schemeStr parameter into your APP’s URLScheme. The specific mobile website payment is transferred to Native payment

Scheme 2

Do not need to connect SDK, do not need to add Alipay white list. Ideas: WebView intercepts Alipay :// AlipayClient request, appends or modifies fromAppUrlScheme to your own URLScheme value, and generates a new NSURL. Open with [[UIApplication sharedApplication] openURL:]. How do you do that? The intercepted Alipay ://alipayclient/ request is processed with json parameter URLEncode (only json parameter encoding, alipay://alipayclient/ is not encoded). The request we rewrote also needs URLEncode encoding. The easiest way to do this is to replace the string “alipays” with your URLSchemes (let’s say “your_url_schemes”, not your_url_schemes://) as shown below. Alipays, do not write this field directly in the code, need to be confused, otherwise apple audit risk being rejected.

Alipay ://alipayclient/? %7B%22requestType%22%3A%22SafePay%22%2C%22fromAppUrlScheme%22%3A%22alipays%22%2C%22dataString%22%3A%22h5_route_token%3D% 5C%221233456%5C%22% 26is_H5_route %3D%5C% 22True %5C%22%22%7D 标 题 : alipay://alipayclient/? %7B%22requestType%22%3A%22SafePay%22%2C%22fromAppUrlScheme%22%3A%22your_url_schemes%22%2C%22dataString%22%3A%22h5_route_ token%3D%5C%221233456%5C%22%26is_h5_route%3D%5C%22true%5C%22%22%7DCopy the code

Q&A

1. Jump to Safari instead of returning to app after payment

Reason: URLSheme in your Xcode configuration is not written or written incorrectly, which is inconsistent with fromAppUrlScheme in alipay request parameters. Solution: Add or modify URLSheme in Xcode configuration to ensure that it is consistent with fromAppUrlScheme in Alipay :// AlipayClient request parameter.

Alipay: // Alipayclient **

Reason: your app may not directly communicate with Alipay in the client, but in the middle of a jump to the web page, by your background (or front) to tune up Alipay. So you can’t intercept the request. The mode I mentioned in this article is based on “client > Alipay” mode, whereas yours is “client >Safari > Alipay” mode, which cannot be returned to the app as described in this article. Solution: Plan 1, modify your payment mode to “client -> Alipay”, I’m afraid this change is a bit big, the workload is mainly in your background. Scheme 2: Without changing the mode, colleagues in the background (or the front end) are required to solve this problem. The principle is similar to this paper. Find a parameter similar to fromAppUrlScheme in the parameters of communication between the background and Alipay, and then change this parameter into your APP’s URLScheme. As for the specific how to deal with the landlord did not do research, if you have a good method, can share.

3. After the payment is completed, it stays on the Alipay results page, showing “continue to pay” and “completed”, and cannot return to the game **

Cause: After web initiates payment, the Web page will try to activate the Alipay client. Regardless of whether the alipay client is activated or not, the current page will be redirected to the Alipay result page, that is, the “Continue payment, Completed” page. So when you return from the Alipay client you will see this page. Solution: my approach is to create another webViewController page as the checkout, the checkout page initiates the payment, and then closes the checkout page. In this way, the original game page will not be affected, and the Alipay client will directly return to the game page. As for the payment result, the client cannot directly know the success or failure. If you need to pop up a window indicating that the user has successfully recharged, the game side needs to check the payment result in the background by itself.

[[UIApplication sharedApplication] openURL:newRequest.URL];
[self dismissViewControllerAnimated:NO completion:nil];
Copy the code

If you found this article helpful, please give it a thumbs up. If you have any questions you can follow my public number I leave a message. Please indicate the source of reprint, thank you!