iOS集積支付宝H 5支付ジャンプとコールバックを実現するソリューション
20171 ワード
iOS集積支付宝H 5支付ジャンプとコールバックを実現するソリューション
前言
最近、iOSクライアント内に支付宝と微信を統合できないApp決済SDK(アップルの監査検出SDKを防ぐため)が必要なので、H 5決済を使う.微信と支付宝のH 5決済ドキュメントは、App内でH 5決済ではなくApp決済を使うと言っているが、方法はいつもある.
この記事では、アリペイH 5の支払い方法をAppからアリペイにジャンプする方法と、アリペイからAppにジャンプする方法について説明しています.
iOS統合H 5微信決済によるジャンプとコールバックのソリューション
実現する効果は、App→アリペイ→支払い(成功失敗またはキャンセル)→App
事前準備
本プロジェクトはWKWebViewを使用し、前置き動作はバックエンドの仲間がすでに支付宝H 5の支付下のリンクを処理し、クライアントが下のリンクを受信した後の操作である.
単一リンクは、支付宝H 5の支付文書-パラメータ説明-共通パラメータで構成された
https://openapi.alipay.com/gateway.do
の先頭のリンクであり、構造リンクの操作はバックエンド処理に渡される.操作手順
1.URL Schemeを追加してアリペイをホワイトリストに入れる
URL Schemeを追加します.
xcodeproj
ファイルInfo
タブの一番下のURL Types
に設定します.このURL Schemeは微信決済とは異なり、商戸のバックグラウンドに記入しなければならない1級ドメイン名を検証するため、支付宝のこれは任意に設定することができる.支付宝のURL Scheme
alipay
とalipays
を項目のホワイトリストに記入します.xcodeproj
ファイルInfo
タブ内のCustom iOS Target Properties
のLSApplicationQueriesSchemes
に上記2つの文字列を追加し、LSApplicationQueriesSchemes
がなければ手動で追加を入力します.タイプは配列Arrayです.2.WKWebViewロードリンク
プロトコル
WKNavigationDelegate
およびWKUIDelegate
を追加します.WKWebViewを作成し、統合された単一リンクをロードします.
- (void)buildWKWebView {
WKWebView *webView = [[WKWebView alloc] initWithFrame:CGRectMake(0, NAV_HEIGHT, SCREEN_WIDTH, SCREEN_HEIGHT - NAV_HEIGHT)];
[self.view addSubview:webView];
webView.navigationDelegate = self;
webView.UIDelegate = self;
NSURL *payURL = [NSURL URLWithString:self.payString];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:payURL];
[webView loadRequest:request];
}
ここでself.payStringはバックグラウンドから届いた支付宝5支付統一注文リンクで、フォーマットは:
https://openapi.alipay.com/gateway.do?app_id=2015081808011180&biz_content={"body"%3A" "%2C"subject"%3A"10000 "%2C"out_trade_no"%3A"30677"%2C"total_amount"%3A"1.00"%2C"seller_id"%3A"2088721584425035"%2C"product_code"%3A"QUICK_WAP_PAY"%2C"goods_type"%3A"1"%2C"passback_params"%3A"20190322083556lkkzmwT2wi0bAaFL1W"%2C"store_id"%3A"company"%2C"timeout_express"%3A"3m"}&charset=UTF-8&format=JSON&method=alipay.trade.wap.pay¬ify_url=https%3A%2F%2Fsttv3-api.company.com%2FaliNotify&return_url=https%3A%2F%2Fwww.company.com&sign_type=RSA2×tamp=2019-03-22+20%3A35%3A56&version=1.0&sign=rmnKUOsZBYi%2BWzDELY%2B5ixnSFn0b0S38K0NR45SRZBAvmzr0qaXm7mnKaXm7OrvmnKUOsZRYiaJ2LNAaFL1K0hvJ3L3hZqH5HifNCIJ0hfTr1OkA5Lgyn1SCx74SrSWVfXdMXqiLurpN0Mj%2B2zs7vDee%2B8vxwzhRG3a5EaZbOHDQFN1%2OrvvVcdv%2F%2FBJCwISBhoXhBelvfZRYiaJ2LNAaFL1KdrJvjlo2lR%2BEzvda0ppMKFzjMLxRZBAvmzr0qNwxyTMfAuxjAT2%2BXAaF3hZqH5Hlo2lRiaJ2LNE
微信の支払いのように請求先を追加するのではなく、支付宝の簡単さが多く、直接アクセスすればいい.
3.代理方法でリンクをブロックし、アリペイをジャンプすることを実現する
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
if ([navigationAction.request.URL.scheme isEqualToString:@"alipay"]) {
// 1. ?
NSArray *urlBaseArr = [navigationAction.request.URL.absoluteString componentsSeparatedByString:@"?"];
NSString *urlBaseStr = urlBaseArr.firstObject;
NSString *urlNeedDecode = urlBaseArr.lastObject;
// 2. Str, URLDecode,
NSMutableString *afterDecodeStr = [NSMutableString stringWithString:[SmallTools decoderUrlEncodeStr:urlNeedDecode]];
// 3. Scheme Scheme
NSString *afterHandleStr = [afterDecodeStr stringByReplacingOccurrencesOfString:@"alipays" withString:@"alipayreturn.cutv.com"];
// 4. , ,
NSString *finalStr = [NSString stringWithFormat:@"%@?%@",urlBaseStr, [SmallTools urlEncodeStr:afterHandleStr]];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
// , APP( URL)
if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:finalStr]]) {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:finalStr]];
} else {
// ,
}
});
decisionHandler(WKNavigationActionPolicyCancel);
return;
}
decisionHandler(WKNavigationActionPolicyAllow);
}
ついでにURLのEncodeとDecodeの方法を添付します.
//urlEncode
+ (NSString *)urlEncodeStr:(NSString *)input {
NSString *charactersToEscape = @"?!@#$^&%*+,:;='\"`<>()[]{}/\\| ";
NSCharacterSet *allowedCharacters = [[NSCharacterSet characterSetWithCharactersInString:charactersToEscape] invertedSet];
NSString *upSign = [input stringByAddingPercentEncodingWithAllowedCharacters:allowedCharacters];
return upSign;
}
//urlEncode
+ (NSString *)decoderUrlEncodeStr: (NSString *) input {
NSMutableString *outputStr = [NSMutableString stringWithString:input];
[outputStr replaceOccurrencesOfString:@"+" withString:@"" options:NSLiteralSearch range:NSMakeRange(0,[outputStr length])];
return [outputStr stringByRemovingPercentEncoding];
}
4.AppDelegateでのジャンプ動作の受信
もちろん、AppDelegateでリターンアクションを受信する必要はありません.直接支払いインタフェースに戻って、後続のロジックを自分で操作することもできます.
以下にAppDelegateがリターン動作を受信した例を示す.
このうちアリペイコールのhostは固定safepayであり、微信が支払うhostは勝手に定義されている.
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options{
//safepay H5 host,
if ([url.host isEqualToString:@"wxpaycallback"] || [url.host isEqualToString:@"safepay"]) {
// , ,popView
UITabBarController *tabBarVC = (UITabBarController *)topRootViewController;
UINavigationController *navVC = tabBarVC.viewControllers[tabBarVC.selectedIndex];
[navVC popViewControllerAnimated:YES];
NSString *orderId = [[NSUserDefaults standardUserDefaults] objectForKey:@"PayOrderId"];
NSString *payFee = [[NSUserDefaults standardUserDefaults] objectForKey:@"PayFee"];
//
NSDictionary *resultDict = @{@"order_id":orderId, @"payFee":payFee};
[[NSNotificationCenter defaultCenter] postNotificationName:@"htmlPaymentNotification" object:self userInfo:resultDict];
}
}