Developer ZoneRecipesAPI ReferenceChangelog
Developer Zone
These docs are for v3.2.6. Click to read the latest docs for v4.3.0.

3DS / Non-3DS payment

3D-Secure is authentication protocol for e-commerce transaction where card is not present on time of the purchase. Initially developed by VISA and known as Verified by VISA. 3D-Secure is adapted by all the major card schemes such as MasterCard, Amex, JCB and Discovery.

Here are 5 steps to make a successful credit card payment:


 
Merchant server implementation : Download


Step 1: Get payment token.

📘

Payment Token API

Please refer: Full sample code

Enable / Disable / Force 3DS

Set payment option

$request_3ds = CardSecureMode::YES;

Construct payment token request

$payment_token_request = new stdClass();
$payment_token_request->version = $api_version;
$payment_token_request->merchantID = $mid;
$payment_token_request->invoiceNo = $invoice_no;
$payment_token_request->desc = $desc;
$payment_token_request->amount = $amount;
$payment_token_request->currencyCode = $currency_code;
$payment_token_request->request3DS = $request_3ds;
$payment_token_request->nonceStr = $nonce_str;

Set payment token

String paymentToken = "roZG9I1hk/GYjNt+BYPYbxQtKElbZDs9M5cXuEbE+Z0QTr/yUcl1oG7t0AGoOJlBhzeyBtf5mQi1UqGbjC66E85S4m63CfV/awwNbbLbkxsvfgzn0KSv7JzH3gcs/OIL";
let paymentToken:String = "roZG9I1hk/GYjNt+BYPYbxQtKElbZDs9M5cXuEbE+Z0QTr/yUcl1oG7t0AGoOJlBhzeyBtf5mQi1UqGbjC66E85S4m63CfV/awwNbbLbkxsvfgzn0KSv7JzH3gcs/OIL"
NSString *paymentToken = @"roZG9I1hk/GYjNt+BYPYbxQtKElbZDs9M5cXuEbE+Z0QTr/yUcl1oG7t0AGoOJlBhzeyBtf5mQi1UqGbjC66E85S4m63CfV/awwNbbLbkxsvfgzn0KSv7JzH3gcs/OIL";

2C2P PGW SDK:

Step 2: Construct credit card request.

CreditCardPayment creditCardPayment = new CreditCardPaymentBuilder("4111111111111111")
                                         .setExpiryMonth(12)
                                         .setExpiryYear(2019)
                                         .setSecurityCode("123")
                                         .build();
let creditCardPayment:CreditCardPayment = CreditCardPaymentBuilder(pan: "4111111111111111")
                                             .expiryMonth(12)
                                             .expiryYear(2019)
                                             .securityCode("123")
                                             .build()
CreditCardPayment *creditCardPayment = [[[[[[CreditCardPaymentBuilder alloc]
                                                initWithPan:@"4111111111111111"]
                                                expiryMonth:12]
                                                expiryYear:2019]
                                                securityCode:@"123"]
                                                build];

Step 3: Construct transaction request.

TransactionRequest transactionRequest = new TransactionRequestBuilder(paymentToken)
                                           .withCreditCardPayment(creditCardPayment)
                                           .build();
let transactionRequest:TransactionRequest = TransactionRequestBuilder(paymentToken: paymentToken)
                                               .withCreditCardPayment(creditCardPayment)
                                               .build()
TransactionRequest *transactionRequest = [[[[TransactionRequestBuilder alloc]
                                                initWithPaymentToken:paymentToken]
                                                withCreditCardPayment:creditCardPayment]
                                                build];

Step 4: Execute payment request.

PGWSDK.getInstance().proceedTransaction(transactionRequest, new TransactionResultCallback() {

      @Override
      public void onResponse(TransactionResultResponse response) {
            
         //For 3DS
         if(response.getResponseCode().equals(APIResponseCode.TRANSACTION_AUTHENTICATE)) {
          
            String redirectUrl = response.getRedirectUrl();
            openWebviewFragment(redirectUrl); //Open WebView for 3DS
         } else if(response.getResponseCode().equals(APIResponseCode.TRANSACTION_COMPLETED)) {
          
            //Inquiry payment result by using transaction id.
            String transactionID = response.getTransactionID();
         } else {
            //Get error response and display error
         }
      }

      @Override
      public void onFailure(Throwable error) {
         //Get error response and display error
      }
   });
PGWSDK.shared.proceedTransaction(transactionRequest: transactionRequest, 
                                    success: { (response:TransactionResultResponse) in
                                    
      //For 3DS
      if response.responseCode == APIResponseCode.TRANSACTION_AUTHENTICATE {
      
         let redirectUrl:String = response.redirectUrl!
         self.openWebViewController(redirectUrl) //Open WebView for 3DS
      } else if response.responseCode == APIResponseCode.TRANSACTION_COMPLETED {
      
         //Inquiry payment result by using transaction id.
         let transactionID:String = response.transactionID!
      } else {
         //Get error response and display error
      }
   }) { (error:NSError) in
      //Get error response and display error
   }
[[PGWSDK shared] proceedTransactionWithTransactionRequest:transactionRequest 
                    success:^(TransactionResultResponse * _Nonnull response) {
                      
      //For 3DS
      if ([response.responseCode isEqualToString:APIResponseCode.TRANSACTION_AUTHENTICATE]) {
        
         NSString *redirectUrl = response.redirectUrl;
         [self openWebViewController:redirectUrl]; //Open WebView for 3DS
      } else if ([response.responseCode isEqualToString:APIResponseCode.TRANSACTION_COMPLETED]) {
        
         //Inquiry payment result by using transaction id.
         NSString *transactionID = response.transactionID;
      } else {
         //Get error response and display error
      }
   } failure:^(NSError * _Nonnull error) {
      //Get error response and display error
   }];

Step 5: Authentication handling for 3DS payment.

Load authentication redirect URL.

public class WebViewFragment extends Fragment {
     
      //...
     
      @Override
      public View onCreateView(LayoutInflater inflater, 
                               ViewGroup container,
                               Bundle savedInstanceState) {

         WebView webview = new WebView(getActivity());
         webview.getSettings().setJavaScriptEnabled(true);
         webview.setWebViewClient(new PGWWebViewClient());
         webview.addJavascriptInterface(new PGWJavaScriptInterface(mTransactionResultCallback),
                                         PGWJavaScriptInterface.JAVASCRIPT_TRANSACTION_RESULT_KEY);
         webview.loadUrl(mRedirectUrl);

         return webview;
      }
   }
//For UIWebView implementation
   class UIWebViewController: UIViewController {
    
      //…
    
      override func viewDidLoad() {
         super.viewDidLoad()
        
         //Authentication handling for 3DS payment
         let requestUrl:URL = URL.init(string: self.redirectUrl!)!
         let request:URLRequest = URLRequest.init(url: requestUrl)
         
         self.webView = UIWebView(frame: UIScreen.main.bounds)
         self.webView.delegate = self.transactionResultCallback()
         self.webView.loadRequest(request)
         
         self.view.addSubview(self.webView)
      }
   }

   //For WKWebView implementation
   class WKWebViewController: UIViewController {
    
      //…
    
      override func viewDidLoad() {
         super.viewDidLoad()
         
         //Authentication handling for 3DS payment
         let requestUrl:URL = URL.init(string: self.redirectUrl!)!
         let request:URLRequest = URLRequest.init(url: requestUrl)
        
         let webConfiguration = WKWebViewConfiguration()
         self.webView = WKWebView(frame: UIScreen.main.bounds, configuration: webConfiguration)
         self.webView.navigationDelegate = self.transactionResultCallback()
         self.webView.load(request)
         
         self.view.addSubview(self.webView)
      }
   }
//For UIWebView implementation
   @implementation UIWebViewController

      - (void)viewDidLoad {
          [super viewDidLoad];

          //Authentication handling for 3DS payment
          NSURL *requestUrl = [[NSURL alloc] initWithString:self.redirectUrl];
          NSURLRequest *request = [[NSURLRequest alloc] initWithURL:requestUrl];
     
          self.webView = [[UIWebView alloc] initWithFrame: UIScreen.mainScreen.bounds];
          self.webView.delegate = [self transactionResultCallback];
          [self.webView loadRequest:request];
     
          [self.view addSubview:self.webView];
      }
   @end

   //For WKWebView implementation
   @implementation WKWebViewController

      - (void)viewDidLoad {
          [super viewDidLoad];
     
          //Authentication handling for 3DS payment
          NSURL *requestUrl = [[NSURL alloc] initWithString:self.redirectUrl];
          NSURLRequest *request = [[NSURLRequest alloc] initWithURL:requestUrl];
    
          WKWebViewConfiguration *webConfiguration = [[WKWebViewConfiguration alloc] init];
          self.webView = [[WKWebView alloc] initWithFrame:UIScreen.mainScreen.bounds 
                                            configuration:webConfiguration];
          self.webView.navigationDelegate = [self transactionResultCallback];
          [self.webView loadRequest:request];
     
          [self.view addSubview:self.webView];
      }
   @end

Get result transaction ID.

private TransactionResultCallback mTransactionResultCallback = new TransactionResultCallback() {

      @Override 
      public void onResponse(TransactionResultResponse response) { 

         if(response.getResponseCode().equals(APIResponseCode.TRANSACTION_COMPLETED)) {
              
            //Inquiry payment result by using transaction id.
            String transactionID = response.getTransactionID();
         } else {
            //Get error response and display error 
         } 
      } 

      @Override 
      public void onFailure(Throwable error) {
         //Get error response and display error 
      }
   };
//For UIWebView implementation   
   func transactionResultCallback() -> PGWUIWebViewDelegate {
        
      self.pgwWebViewDelegate = PGWUIWebViewDelegate(
                                success: { (response: TransactionResultResponse) in
                                          
         if response.responseCode == APIResponseCode.TRANSACTION_COMPLETED {
         
            //Inquiry payment result by using transaction id.
            let transactionID:String = response.transactionID!
         } else {
            //Get error response and display error
         }
      }, failure: { (error: NSError) in
         //Get error response and display error
      })
        
      return self.pgwWebViewDelegate
   }
    
   //For WKWebView implementation
   func transactionResultCallback() -> PGWWKWebViewDelegate {
        
      self.pgwWebViewDelegate = PGWWKWebViewDelegate(
                                success: { (response: TransactionResultResponse) in
                                
         if response.responseCode == APIResponseCode.TRANSACTION_COMPLETED {
         
            //Inquiry payment result by using transaction id.
            let transactionID:String = response.transactionID!
         } else {
            //Get error response and display error
         }
      }, failure: { (error: NSError) in
         //Get error response and display error
      })
        
      return self.pgwWebViewDelegate
   }
//For UIWebView implementation   
   - (PGWUIWebViewDelegate *)transactionResultCallback {
     
      self.pgwWebViewDelegate = [[PGWUIWebViewDelegate alloc] 
                                  initWithSuccess:^(TransactionResultResponse * _Nonnull response) {
        
         if ([response.responseCode isEqualToString:APIResponseCode.TRANSACTION_COMPLETED]) {
        
            //Inquiry payment result by using transaction id.
            NSString *transactionID = response.transactionID;
         } else {
            //Get error response and display error
         }
      } failure:^(NSError * _Nonnull error) {
         //Get error response and display error
      }];
    
      return self.pgwWebViewDelegate;
   }
    
   //For WKWebView implementation
   - (PGWWKWebViewDelegate *)transactionResultCallback {
     
      self.pgwWebViewDelegate = [[PGWWKWebViewDelegate alloc] 
                                  initWithSuccess:^(TransactionResultResponse * _Nonnull response) {
        
         if ([response.responseCode isEqualToString:APIResponseCode.TRANSACTION_COMPLETED]) {
        
            //Inquiry payment result by using transaction id.
            NSString *transactionID = response.transactionID;
         } else {
            //Get error response and display error
         }
      } failure:^(NSError * _Nonnull error) {
         //Get error response and display error
      }];
    
      return self.pgwWebViewDelegate;
   }

Step 6: Get payment result.

📘

Payment Inquiry API

Please refer: Full sample code


Complete Code
Merchant Server:


Copy & Paste below source code and put this file in your Web Server.

<?php

//Import necessary classes
require "../utils/PaymentGatewayHelper.php";
require "../enum/APIEnvironment.php";
require "../model/SignatureError.php";

require "enum/CardSecureMode.php";
require "enum/PaymentChannel.php";

//Set API request enviroment
$api_env = APIEnvironment::SANDBOX . "/paymentToken"; 

//Request information 
$api_version = "10.01"; 
$nonce_str = uniqid('', true);  

//Merchant's account information
$mid = "JT01"; //Get MerchantID when opening account with 2C2P
$secret_key = "7jYcp4FxFdf0"; //Get SecretKey from 2C2P PGW dashboard

//Transaction information
$desc = "2 days 1 night hotel room"; 
$invoice_no = time(); 
$currency_code = "SGD"; 
$amount = "000000001000";

//Set payment options
$request_3ds = CardSecureMode::YES; //Set 3D Secure

//Build payment token request
$payment_token_request = new stdClass();
$payment_token_request->version = $api_version;
$payment_token_request->merchantID = $mid;
$payment_token_request->invoiceNo = $invoice_no;
$payment_token_request->desc = $desc;
$payment_token_request->amount = $amount;
$payment_token_request->currencyCode = $currency_code;
$payment_token_request->request3DS = $request_3ds;
$payment_token_request->nonceStr = $nonce_str;

//Important: Generate signature
$pgw_helper = new PaymentGatewayHelper(); 
$hashed_signature = $pgw_helper->generateSignature($payment_token_request, $secret_key); 
$payment_token_request->signature = $hashed_signature;

//Do Payment Token API request
$encoded_payment_token_response = $pgw_helper->requestAPI($api_env, $payment_token_request);

//Important: Verify response signature
$is_valid_signature = $pgw_helper->validateSignature($encoded_payment_token_response, $secret_key);
if($is_valid_signature) {
  
    //Valid signature, get payment result
    $payment_token_response = $pgw_helper->parseAPIResponse($encoded_payment_token_response);
    echo $payment_token = $payment_token_response->paymentToken;
} else {
    //Invalid signature, return error response
}

?>

2C2P PGW SDK:

Copy & Paste below source code into your application.

Proceed credit card payment.

String paymentToken = "roZG9I1hk/GYjNt+BYPYbxQtKElbZDs9M5cXuEbE+Z0QTr/yUcl1oG7t0AGoOJlBhzeyBtf5mQi1UqGbjC66E85S4m63CfV/awwNbbLbkxsvfgzn0KSv7JzH3gcs/OIL";

   //Construct credit card request
   CreditCardPayment creditCardPayment = new CreditCardPaymentBuilder("4111111111111111")
                                         .setExpiryMonth(12)
                                         .setExpiryYear(2019)
                                         .setSecurityCode("123")
                                         .build();

   //Construct transaction request
   TransactionRequest transactionRequest = new TransactionRequestBuilder(paymentToken)
                                           .withCreditCardPayment(creditCardPayment)
                                           .build();
   
   //Execute payment request
   PGWSDK.getInstance().proceedTransaction(transactionRequest, new TransactionResultCallback() {

      @Override
      public void onResponse(TransactionResultResponse response) {
            
         //For 3DS
         if(response.getResponseCode().equals(APIResponseCode.TRANSACTION_AUTHENTICATE)) {
          
            String redirectUrl = response.getRedirectUrl();
            openWebviewFragment(redirectUrl); //Open WebView for 3DS
         } else if(response.getResponseCode().equals(APIResponseCode.TRANSACTION_COMPLETED)) {
          
            //Inquiry payment result by using transaction id.
            String transactionID = response.getTransactionID();
         } else {
            //Get error response and display error
         }
      }

      @Override
      public void onFailure(Throwable error) {
         //Get error response and display error
      }
   });
let paymentToken:String = "roZG9I1hk/GYjNt+BYPYbxQtKElbZDs9M5cXuEbE+Z0QTr/yUcl1oG7t0AGoOJlBhzeyBtf5mQi1UqGbjC66E85S4m63CfV/awwNbbLbkxsvfgzn0KSv7JzH3gcs/OIL"

   //Construct credit card request
   let creditCardPayment:CreditCardPayment = CreditCardPaymentBuilder(pan: "4111111111111111")
                                             .expiryMonth(12)
                                             .expiryYear(2019)
                                             .securityCode("123")
                                             .build()

   //Construct transaction request
   let transactionRequest:TransactionRequest = TransactionRequestBuilder(paymentToken: paymentToken)
                                               .withCreditCardPayment(creditCardPayment)
                                               .build()
   
   //Execute payment request
   PGWSDK.shared.proceedTransaction(transactionRequest: transactionRequest, 
                                    success: { (response:TransactionResultResponse) in
                                    
      //For 3DS
      if response.responseCode == APIResponseCode.TRANSACTION_AUTHENTICATE {
      
         let redirectUrl:String = response.redirectUrl!
         self.openWebViewController(redirectUrl) //Open WebView for 3DS
      } else if response.responseCode == APIResponseCode.TRANSACTION_COMPLETED {
      
         //Inquiry payment result by using transaction id.
         let transactionID:String = response.transactionID!
      } else {
         //Get error response and display error
      }
   }) { (error:NSError) in
      //Get error response and display error
   }
NSString *paymentToken = @"roZG9I1hk/GYjNt+BYPYbxQtKElbZDs9M5cXuEbE+Z0QTr/yUcl1oG7t0AGoOJlBhzeyBtf5mQi1UqGbjC66E85S4m63CfV/awwNbbLbkxsvfgzn0KSv7JzH3gcs/OIL";

   //Construct credit card request
   CreditCardPayment *creditCardPayment = [[[[[[CreditCardPaymentBuilder alloc]
                                                initWithPan:@"4111111111111111"]
                                                expiryMonth:12]
                                                expiryYear:2019]
                                                securityCode:@"123"]
                                                build];

   //Construct transaction request
   TransactionRequest *transactionRequest = [[[[TransactionRequestBuilder alloc]
                                                initWithPaymentToken:paymentToken]
                                                withCreditCardPayment:creditCardPayment]
                                                build];

   //Execute payment request
   [[PGWSDK shared] proceedTransactionWithTransactionRequest:transactionRequest 
                    success:^(TransactionResultResponse * _Nonnull response) {
                      
      //For 3DS
      if ([response.responseCode isEqualToString:APIResponseCode.TRANSACTION_AUTHENTICATE]) {
        
         NSString *redirectUrl = response.redirectUrl;
         [self openWebViewController:redirectUrl]; //Open WebView for 3DS
      } else if ([response.responseCode isEqualToString:APIResponseCode.TRANSACTION_COMPLETED]) {
        
         //Inquiry payment result by using transaction id.
         NSString *transactionID = response.transactionID;
      } else {
         //Get error response and display error
      }
   } failure:^(NSError * _Nonnull error) {
      //Get error response and display error
   }];

 
Authentication handling for 3DS payment on (Fragment / Activity / UIViewController).

public class WebViewFragment extends Fragment {

      private static final String ARG_REDIRECT_URL = "ARG_REDIRECT_URL";

      private String mRedirectUrl;

      public WebViewFragment() { }

      public static WebViewFragment newInstance(String redirectUrl) {

         WebViewFragment fragment = new WebViewFragment();
         Bundle args = new Bundle();
         args.putString(ARG_REDIRECT_URL, redirectUrl);
         fragment.setArguments(args);

         return fragment;
      }

      @Override
      public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);

         if(getArguments() != null) {
            mRedirectUrl = getArguments().getString(ARG_REDIRECT_URL);
         }
      }

      @Override
      public View onCreateView(LayoutInflater inflater, 
                               ViewGroup container,
                               Bundle savedInstanceState) {

         //Authentication handling for 3DS payment
         WebView webview = new WebView(getActivity());
         webview.getSettings().setJavaScriptEnabled(true);
         webview.setWebViewClient(new PGWWebViewClient());
         webview.addJavascriptInterface(new PGWJavaScriptInterface(mTransactionResultCallback),
                                         PGWJavaScriptInterface.JAVASCRIPT_TRANSACTION_RESULT_KEY);
         webview.loadUrl(mRedirectUrl);

         return webview;
      }

      private TransactionResultCallback mTransactionResultCallback = new TransactionResultCallback() {

         @Override
         public void onResponse(TransactionResultResponse response) {

           if(response.getResponseCode().equals(APIResponseCode.TRANSACTION_COMPLETED)) {

               String transactionID = response.getTransactionID();
            } else {
               //Get error response and display error
            }
         }

         @Override
         public void onFailure(Throwable error) {
            //Get error response and display error
         }
      };
   }
//For UIWebView implementation
   class UIWebViewController: UIViewController {
    
      var webView: UIWebView!
      var pgwWebViewDelegate:PGWUIWebViewDelegate!
      var redirectUrl:String?
    
      override func viewDidLoad() {
         super.viewDidLoad()
        
         //Authentication handling for 3DS payment
         let requestUrl:URL = URL.init(string: self.redirectUrl!)!
         let request:URLRequest = URLRequest.init(url: requestUrl)
         
         self.webView = UIWebView(frame: UIScreen.main.bounds)
         self.webView.delegate = self.transactionResultCallback()
         self.webView.loadRequest(request)
         
         self.view.addSubview(self.webView)
      }
    
      func transactionResultCallback() -> PGWUIWebViewDelegate {
        
         self.pgwWebViewDelegate = PGWUIWebViewDelegate(
                                success: { (response: TransactionResultResponse) in
                                          
            if response.responseCode == APIResponseCode.TRANSACTION_COMPLETED {
         
               //Inquiry payment result by using transaction id.
               let transactionID:String = response.transactionID!
            } else {
               //Get error response and display error
            }
         }, failure: { (error: NSError) in
            //Get error response and display error
         })
        
         return self.pgwWebViewDelegate
      }
   }
   
   //For WKWebView implementation
   class WKWebViewController: UIViewController {
   
      var webView:WKWebView!
      var pgwWebViewDelegate:PGWWKWebViewDelegate!
      var redirectUrl:String?
    
      override func viewDidLoad() {
         super.viewDidLoad()
         
         //Authentication handling for 3DS payment
         let requestUrl:URL = URL.init(string: self.redirectUrl!)!
         let request:URLRequest = URLRequest.init(url: requestUrl)
        
         let webConfiguration = WKWebViewConfiguration()
         self.webView = WKWebView(frame: UIScreen.main.bounds, configuration: webConfiguration)
         self.webView.navigationDelegate = self.transactionResultCallback()
         self.webView.load(request)
         
         self.view.addSubview(self.webView)
      }
    
      func transactionResultCallback() -> PGWWKWebViewDelegate {
        
         self.pgwWebViewDelegate = PGWWKWebViewDelegate(
                                success: { (response: TransactionResultResponse) in
                                
            if response.responseCode == APIResponseCode.TRANSACTION_COMPLETED {
         
               //Inquiry payment result by using transaction id.
               let transactionID:String = response.transactionID!
            } else {
               //Get error response and display error
            }
         }, failure: { (error: NSError) in
            //Get error response and display error
         })
        
         return self.pgwWebViewDelegate
      }
   }
//For UIWebView implementation
   @interface UIWebViewController : UIViewController
   @property (nonatomic, copy) NSString *redirectUrl;
   @end

   @interface UIWebViewController ()
   @property (nonatomic, strong) UIWebView *webView;
   @property (nonatomic, strong) PGWUIWebViewDelegate *pgwWebViewDelegate;
   @end

   @implementation UIWebViewController

      - (void)viewDidLoad {
          [super viewDidLoad];

          //Authentication handling for 3DS payment
          NSURL *requestUrl = [[NSURL alloc] initWithString:self.redirectUrl];
          NSURLRequest *request = [[NSURLRequest alloc] initWithURL:requestUrl];
     
          self.webView = [[UIWebView alloc] initWithFrame: UIScreen.mainScreen.bounds];
          self.webView.delegate = [self transactionResultCallback];
          [self.webView loadRequest:request];
     
          [self.view addSubview:self.webView];
      }

      - (PGWUIWebViewDelegate *)transactionResultCallback {
     
         self.pgwWebViewDelegate = [[PGWUIWebViewDelegate alloc] 
                                    initWithSuccess:^(TransactionResultResponse * _Nonnull response) {
        
            if ([response.responseCode isEqualToString:APIResponseCode.TRANSACTION_COMPLETED]) {
        
               //Inquiry payment result by using transaction id.
               NSString *transactionID = response.transactionID;
            } else {
               //Get error response and display error
            }
         } failure:^(NSError * _Nonnull error) {
            //Get error response and display error
         }];
    
         return self.pgwWebViewDelegate;
      }
   @end
   
   //For WKWebView implementation
   @interface WKWebViewController : UIViewController
   @property (nonatomic, copy) NSString *redirectUrl;
   @end

   @interface WKWebViewController ()
   @property (nonatomic, strong) WKWebView *webView;
   @property (nonatomic, strong) PGWWKWebViewDelegate *pgwWebViewDelegate;
   @end

   @implementation WKWebViewController

      - (void)viewDidLoad {
          [super viewDidLoad];
     
          //Authentication handling for 3DS payment
          NSURL *requestUrl = [[NSURL alloc] initWithString:self.redirectUrl];
          NSURLRequest *request = [[NSURLRequest alloc] initWithURL:requestUrl];
    
          WKWebViewConfiguration *webConfiguration = [[WKWebViewConfiguration alloc] init];
          self.webView = [[WKWebView alloc] initWithFrame:UIScreen.mainScreen.bounds 
                                            configuration:webConfiguration];
          self.webView.navigationDelegate = [self transactionResultCallback];
          [self.webView loadRequest:request];
     
          [self.view addSubview:self.webView];
      }

      - (PGWWKWebViewDelegate *)transactionResultCallback {
     
         self.pgwWebViewDelegate = [[PGWWKWebViewDelegate alloc] 
                                    initWithSuccess:^(TransactionResultResponse * _Nonnull response) {
        
            if ([response.responseCode isEqualToString:APIResponseCode.TRANSACTION_COMPLETED]) {
        
               //Inquiry payment result by using transaction id.
               NSString *transactionID = response.transactionID;
            } else {
               //Get error response and display error
            }
         } failure:^(NSError * _Nonnull error) {
            //Get error response and display error
         }];
    
         return self.pgwWebViewDelegate;
      }
   @end

Next: Advance payment options