Handle PGW Payment Authentication

1. Handle PGW Payment Authentication Payment Flow

Refer to the sample code below for handling PGW payment authentications. This client callback will return a payment token, which merchants can to retrieve transaction details or manage transactions via API.

import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebSettings;
import android.webkit.WebView;
import androidx.fragment.app.Fragment;
import com.ccpp.pgw.sdk.android.callback.PGWWebViewClientCallback;
import com.ccpp.pgw.sdk.android.callback.PGWWebViewTransactionStatusCallback;
import com.ccpp.pgw.sdk.android.core.authenticate.PGWWebViewClient;
 
public class PGWWebViewFragment extends Fragment {
 
    private final String TAG = PGWWebViewFragment.class.getName();
    private static final String ARG_REDIRECT_URL = "ARG_REDIRECT_URL";
 
    private String mRedirectUrl;
 
    public PGWWebViewFragment() { }
 
    public static PGWWebViewFragment newInstance(String redirectUrl) {
 
        PGWWebViewFragment fragment = new PGWWebViewFragment();
        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) {
 
        //Step 5: Authentication handling for 3DS payment.
        WebView webview = new WebView(getActivity());
 
        //Optional
        webview.getSettings().setBuiltInZoomControls(true);
        webview.getSettings().setSupportZoom(true);
        webview.getSettings().setLoadWithOverviewMode(true);
        webview.getSettings().setUseWideViewPort(true);
        webview.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
 
        //Mandatory
        webview.getSettings().setJavaScriptEnabled(true);
        webview.getSettings().setDomStorageEnabled(true); //Some bank page required. eg: am bank
        webview.setWebViewClient(new PGWWebViewClient(mTransactionStatusCallback, mWebViewClientCallback));
 
        webview.loadUrl(mRedirectUrl);
 
        return webview;
    }
 
    /**
     * Reference : https://developer.2c2p.com/docs/api-sdk-transaction-status-inquiry
     */
    private final PGWWebViewTransactionStatusCallback mTransactionStatusCallback = new PGWWebViewTransactionStatusCallback() {
         
        @Override
        public void onInquiry(String paymentToken) {
 
            //Do Transaction Status Inquiry API and close this WebView.
        }
    };
 
    private final PGWWebViewClientCallback mWebViewClientCallback = new PGWWebViewClientCallback() {
 
        @Override
        public void shouldOverrideUrlLoading(String url) {
 
            Log.i(TAG, "PGWWebViewClientCallback shouldOverrideUrlLoading : " + url);
        }
 
        @Override
        public void onPageStarted(String url) {
 
            Log.i(TAG, "PGWWebViewClientCallback onPageStarted : " + url);
        }
 
        @Override
        public void onPageFinished(String url) {
 
            Log.i(TAG, "PGWWebViewClientCallback onPageFinished : " + url);
        }
    };
}
import android.annotation.SuppressLint
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.webkit.WebSettings
import android.webkit.WebView
import androidx.fragment.app.Fragment
import com.ccpp.pgw.sdk.android.callback.PGWWebViewClientCallback
import com.ccpp.pgw.sdk.android.callback.PGWWebViewTransactionStatusCallback
import com.ccpp.pgw.sdk.android.core.authenticate.PGWWebViewClient

class PGWWebViewFragment private constructor() : Fragment() {

    private lateinit var redirectUrl: String

    companion object {

        private val TAG: String = PGWWebViewFragment::class.java.name
        private const val ARG_REDIRECT_URL: String = "ARG_REDIRECT_URL"

        fun newInstance(redirectUrl: String): PGWWebViewFragment {

            return PGWWebViewFragment().apply {

                this.arguments = Bundle().apply {

                    this.putString(ARG_REDIRECT_URL, redirectUrl)
                }
            }
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        this.redirectUrl = requireArguments().getString(ARG_REDIRECT_URL) ?: ""
    }

    @SuppressLint("SetJavaScriptEnabled")
    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
        
        //Step 5: Authentication handling for 3DS payment.
        val webview = WebView(requireActivity()).apply {

            //Optional
            this.settings.builtInZoomControls = true
            this.settings.setSupportZoom(true)
            this.settings.loadWithOverviewMode = true
            this.settings.useWideViewPort = true
            this.settings.cacheMode = WebSettings.LOAD_NO_CACHE

            //Mandatory
            this.settings.javaScriptEnabled = true
            this.settings.domStorageEnabled = true //Some bank page required. eg: am bank
            this.webViewClient = PGWWebViewClient(transactionStatusCallback, webViewClientCallback)
        }

        webview.loadUrl(this.redirectUrl)

        return webview
    }

    /**
     * Reference : https://developer.2c2p.com/docs/api-sdk-transaction-status-inquiry
     */
    private val transactionStatusCallback: PGWWebViewTransactionStatusCallback = object : PGWWebViewTransactionStatusCallback {

        override fun onInquiry(paymentToken: String) {

            //Do Transaction Status Inquiry API and close this WebView.
        }
    }

    private val webViewClientCallback: PGWWebViewClientCallback = object : PGWWebViewClientCallback {

        override fun shouldOverrideUrlLoading(url: String) {

            Log.i(TAG, "PGWWebViewClientCallback shouldOverrideUrlLoading : $url")
        }

        override fun onPageStarted(url: String) {

            Log.i(TAG, "PGWWebViewClientCallback onPageStarted : $url")
        }

        override fun onPageFinished(url: String) {

            Log.i(TAG, "PGWWebViewClientCallback onPageFinished : $url")
        }
    }
}
#import "WKWebViewController.h"
#import <WebKit/WebKit.h>
@import PGW;
 
@interface PGWWebViewController ()
 
@property (nonatomic, strong) WKWebView *webView;
@property (nonatomic, strong) PGWWebViewNavigationDelegate *pgwWebViewNavigationDelegate;
 
@end
 
@implementation PGWWebViewController
 
- (void)viewDidLoad {
    [super viewDidLoad];
     
    //Step 5: 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 pgwTransactionResultCallback];
    [self.webView loadRequest: request];
     
    [self.view addSubview: self.webView];
}
 
/*
 * Reference : https://developer.2c2p.com/docs/api-sdk-transaction-status-inquiry
 */
- (PGWWebViewNavigationDelegate *)pgwTransactionResultCallback {
     
    self.pgwWebViewNavigationDelegate = [[PGWWebViewNavigationDelegate alloc] initWithTransactionStatusCallback: ^(NSString * _Nonnull paymentToken) {
         
        //Do Transaction Status Inquiry API and close this WebView.
    }];
     
    [self.pgwWebViewNavigationDelegate navigationCallbackWithDidStartProvisionalNavigation: ^(NSString * _Nonnull url) {
         
        NSLog(@"PGWWebViewNavigationDelegate didStartProvisionalNavigation : %@", url);
    } decidePolicyForNavigationAction: ^(NSString * _Nonnull url) {
         
        NSLog(@"PGWWebViewNavigationDelegate didStartProvisionalNavigation : %@", url);
    } didFinishNavigation: ^(NSString * _Nonnull url) {
         
        NSLog(@"PGWWebViewNavigationDelegate didStartProvisionalNavigation : %@", url);
    }];
     
    return self.pgwWebViewNavigationDelegate;
}
 
@end
import Foundation
 
import UIKit
import WebKit
import PGW
 
class PGWWebViewController: UIViewController {
    
    var webView: WKWebView!
    var pgwWebViewNavigationDelegate: PGWWebViewNavigationDelegate!
    var redirectUrl: String?
     
    override func viewDidLoad() {
        super.viewDidLoad()
 
        //Step 5: Authentication handling for 3DS payment.
        let requestUrl: URL = URL.init(string: self.redirectUrl!)!
        let request: URLRequest = URLRequest.init(url: requestUrl)
         
        let preferences = WKPreferences()
        preferences.javaScriptEnabled = true
         
        let webConfiguration = WKWebViewConfiguration()
        webConfiguration.preferences = preferences
         
        self.webView = WKWebView(frame: UIScreen.main.bounds, configuration: webConfiguration)
        self.webView.navigationDelegate = self.pgwTransactionResultCallback()
        self.webView.load(request)
         
        self.view.addSubview(self.webView)
    }
     
    /*
     * Reference : https://developer.2c2p.com/docs/api-sdk-transaction-status-inquiry
     */
    private func pgwTransactionResultCallback() -> PGWWebViewNavigationDelegate {
         
        self.pgwWebViewNavigationDelegate = PGWWebViewNavigationDelegate({ (paymentToken: String) in
 
            //Do Transaction Status Inquiry API and close this WebView.
        })
         
        self.pgwWebViewNavigationDelegate.navigationCallback(didStartProvisionalNavigation: { (url: String) in
 
             print("PGWWebViewNavigationDelegate didStartProvisionalNavigation : \(url)")
        }, decidePolicyForNavigationAction: { (url: String) in
 
            print("PGWWebViewNavigationDelegate decidePolicyForNavigationAction : \(url)")
        }, didFinishNavigation: { (url: String) in
 
            print("PGWWebViewNavigationDelegate didFinishNavigation : \(url)")
        })
         
        return self.pgwWebViewNavigationDelegate
    }
}
import 'package:flutter/material.dart';
import 'package:pgw_sdk/core/pgw_webview_navigation_delegate.dart';
import 'package:webview_flutter/webview_flutter.dart';
 
class PGWWebViewScreen extends StatelessWidget {
 
  final String redirectUrl;
 
  const PGWWebViewScreen({super.key, required this.redirectUrl});
 
  // Reference : https://developer.2c2p.com/docs/api-sdk-transaction-status-inquiry
  WebViewController _webViewController() {
 
    return WebViewController()
      ..setJavaScriptMode(JavaScriptMode.unrestricted)
      ..setNavigationDelegate(PGWNavigationDelegate(
          // onNavigationRequest: (NavigationRequest request) {
          //   return NavigationDecision.navigate;
          // },
          onHttpAuthRequest: (HttpAuthRequest request) { },
          onProgress: (int progress) { },
          onPageStarted: (String url) { },
          onPageFinished: (String url) { },
          onWebResourceError: (WebResourceError error) { },
          onUrlChange: (UrlChange change) { },
          onInquiry: (String paymentToken) {
 
            //Do Transaction Status Inquiry API and close this WebView.
          }
        )
      )
      ..loadRequest(Uri.parse(redirectUrl));
  }
 
  @override
  Widget build(BuildContext context) {
 
    return Scaffold(
      appBar: AppBar(
        title: const Text('PGWWebViewScreen')
      ),
      body: WebViewWidget(
        controller: _webViewController()
      )
    );
  }
}
import React from 'react';
import WebView from 'react-native-webview';
import { PGWWebViewNavigation } from '@2c2p/pgw-sdk-react-native';

export class PGWWebViewScreen extends React.Component<{redirectUrl: string}> {
  
  constructor(props: {
    redirectUrl: string;
  }) {
    super(props);
  }

  render(): React.ReactNode {

    return (
      <WebView 
          source={{uri: this.props.redirectUrl}}
          javaScriptEnabled={true}
          domStorageEnabled={true}
          onNavigationStateChange={(event: any) => {
 
            // Reference : https://developer.2c2p.com/docs/api-sdk-transaction-status-inquiry
            PGWWebViewNavigation.inquiry(event.url ?? '', (paymentToken: string) => {

              if(paymentToken) {

                //Do Transaction Status Inquiry API and close this WebView.
              }
            });
          }}
        />
    );
  }
}

2. Initiate Transaction Status Inquiry

To retrieve transaction details and status, merchants must initiate the Transaction Status Inquiry API. Refer to the sample code below.

📘

Transaction Status Inquiry API

Refer to: Transaction Status Inquiry API