cloudpayments / CloudPayments_iOSCheckout

0 stars 0 forks source link

Реализация 3ds с WKWebView #3

Open yurybondar opened 4 years ago

yurybondar commented 4 years ago

Добрый день. Apple уже давно не пропускает приложения, которые используют UIWebView.

Но лично у меня возникла проблема с реализацией через WKWebView: если пытаться ловить редирект на TermUrl, то получаем пустое тело запроса (nil):

func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {

        print("navigationAction: \(navigationAction.request.url)")

        if let url = navigationAction.request.url, url.absoluteString.contains(completeUrl) {
            var response: String?
            if let aBody = navigationAction.request.httpBody {
                response = String(data: aBody, encoding: .ascii)
            }
            let responseDictionary = parse(response: response)

            print("respDic: \(responseDictionary)")
            //post3ds(transactionId: responseDictionary?["MD"] as! String, paRes: responseDictionary?["PaRes"] as! String)

            decisionHandler(.cancel)
            return
        }
        decisionHandler(.allow)
    }

Тем не менее, если разрешить webView переход по TermUrl (decisionHandler(.allow)), в Charlesproxy я вижу в POST параметрах PaRes и MD.

Может, у кого есть примеры реализации или какие-то идеи, как обойти это ограничение?

a-ignatov-cp commented 4 years ago

Добрый день! Сейчас готовится к выходу новая версия SDK и новый пример реализации проведения оплаты в приложении. С похожей проблемой мы столкнулись ранее в новых версиях Android, решили ее следующим образом: сделали страницу https://demo.cloudpayments.ru/WebFormPost/GetWebViewData которая возвращает параметры PaRes и MD в виде JSON объекта. Чтобы это сделать необходимо передать ее url в параметре term_url при открытии url 3ds формы банка, тогда после прохождения 3ds авторизации банк перенаправит вас на эту страницу отправив ей PaRes и MD которые вернуться вам в виде JSON объекта. Более подробно эту реализацию можно посмотреть здесь: https://github.com/cloudpayments/SDK-Android/blob/master/sdk/src/main/java/ru/cloudpayments/sdk/three_ds/ThreeDsDialogFragment.java

IlyaOstashkov commented 4 years ago

Вот реализация обработки 3DS с WKWebView

NSString * const CloudPaymentPostBackUrl = @"https://demo.cloudpayments.ru/WebFormPost/GetWebViewData";

- (void)webView:(WKWebView *)webView
didFinishNavigation:(WKNavigation *)navigation {
    NSURL *url = webView.URL;
    if (![url.absoluteString containsString:CloudPaymentPostBackUrl]) {
        return;
    }
    __weak typeof(self)weakSelf = self;
    [webView evaluateJavaScript:@"document.documentElement.outerHTML.toString()"
              completionHandler:^(NSString *_Nullable result,
                                  NSError * _Nullable error) {
        __strong typeof(weakSelf) strongSelf = weakSelf;
        [webView removeFromSuperview];
        if (!result.length || error) {
            [strongSelf fail3DSPayment];
            return;
        }
        HTMLDocument *home = [HTMLDocument documentWithString:result];
        NSString *jsonString = [home.bodyElement textContent];
        if (!jsonString.length) {
            return;
        }
        NSData *data = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
        if (!data) {
            return;
        }
        NSError *parsingError;
        NSDictionary *responseDictionary = [NSJSONSerialization JSONObjectWithData:data
                                                                           options:0
                                                                             error:&parsingError];
        if (parsingError) {
            NSLog(@"%@", parsingError.description);
            return;
        }
        NSString *paResString = responseDictionary[@"PaRes"];
        NSString *mdString = responseDictionary[@"MD"];
        [strongSelf complete3DSPaymentWithToken:paResString
                                withTransaction:mdString];
    }];
}