Receive and display response notifications from gateway on wordpress

I have a plugin built to integrate a payment gateway into wordpress woocommerce.
Its working ok but when the response comes from the gateway I don’t know how to get and
display it within wordpress. Here is the plugin code:

    function sb_gtpay_init() {
    if (!class_exists('WC_Payment_Gateway')) {
        return;
    }

    class WC_GTPay extends WC_Payment_Gateway { 

        public function __construct() { 
            global $woocommerce;

            $this->id       = 'gtpay';
            $this -> icon  =  plugins_url( 'GTPay.png' , __FILE__ );
            $this->has_fields   = false;
            $this->liveurl      = 'https://ibank.gtbank.com/GTPay/Tranx.aspx';
            $this->method_title     = __( 'GTPay', 'woocommerce' );

            // Load the form fields.
            $this->init_form_fields();

            // Load the settings.
            $this->init_settings();

            // Define user set variables
            $this->title        = $this->settings['title'];
            $this->description  = $this->settings['description'];
            $this->marchant_id  = $this->settings['marchant_id'];   
            $this->hash_key     = $this->settings['hash_key'];  
            $this->thanks_message   = $this->settings['thanks_message'];    
            $this->error_message    = $this->settings['error_message']; 
            $this->feedback_message = '';
            $this->response_codes   = $this->get_response_codes();

            // Actions
            add_action( 'init', array(&$this, 'check_ipn_response') );
            add_action('valid-gtpay-ipn-request', array(&$this, 'successful_request') );
            add_action('woocommerce_receipt_gtpay', array(&$this, 'receipt_page'));
            //add_action('woocommerce_update_options_payment_gateways', array(&$this, 'process_admin_options'));

            //add_action('woocommerce_thankyou_' . $this->id, array(&$this, 'thankyou_page'));


            // Actions
            if ( version_compare( WOOCOMMERCE_VERSION, '2.0', '<' ) ) {
                // Pre 2.0
                add_action('woocommerce_update_options_payment_gateways', array(&$this, 'process_admin_options'));
            } else {
                // 2.0
                add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ) );
            }           

            //Filters
            add_filter('woocommerce_currencies', array($this, 'add_ngn_currency'));
            add_filter('woocommerce_currency_symbol', array($this, 'add_ngn_currency_symbol'), 10, 2);

            if ( !$this->is_valid_for_use() ) $this->enabled = false;

        }

        function add_ngn_currency($currencies) {
             $currencies['NGN'] = __( 'Nigerian Naira (NGN)', 'woocommerce' );
             return $currencies;
        }

        function add_ngn_currency_symbol($currency_symbol, $currency) {
            switch( $currency ) {
                case 'NGN':
                    $currency_symbol = '₦';
                    break;
            }

            return $currency_symbol;
        }    

        function is_valid_for_use() {
            $return = true;

            if (!in_array(get_option('woocommerce_currency'), array('NGN'))) {
                $return = false;
            }

            return $return;
        }

        function admin_options() {

            echo '<h3>' . __('GTPay', 'woocommerce') . '</h3>';
            echo '<p>' . __('GTPay works by sending the user to secured GTBank portal to enter their payment information.', 'woocommerce') . '</p>';
            echo '<table class="form-table">';

            if ( $this->is_valid_for_use() ) {
                $this->generate_settings_html();
            } else {
                echo '<div class="inline error"><p><strong>' . __( 'Gateway Disabled', 'woocommerce' ) . '</strong>: ' . __( 'GTPay does not support your store currency.', 'woocommerce' ) . '</p></div>';
            }

            echo '</table>';

        }

           function init_form_fields() {
            $this->form_fields = array(
                'enabled' => array(
                                'title' => __( 'Enable/Disable', 'woocommerce' ), 
                                'type' => 'checkbox', 
                                'label' => __( 'Enable GTPay', 'woocommerce' ), 
                                'default' => 'yes'
                            ), 
                'title' => array(
                                'title' => __( 'Title', 'woocommerce' ), 
                                'type' => 'text', 
                                'description' => __( 'This controls the title which the user sees during checkout.', 'woocommerce' ), 
                                'default' => __( 'GTPay', 'woocommerce' )
                            ),
                'description' => array(
                                'title' => __( 'Description', 'woocommerce' ), 
                                'type' => 'textarea', 
                                'description' => __( 'This controls the description which the user sees during checkout.', 'woocommerce' ), 
                                'default' => __("Pay via GTPay;", 'woocommerce')
                            ),
                'thanks_message' => array(
                                'title' => __( 'Thanks message', 'woocommerce' ), 
                                'type' => 'textarea', 
                                'description' => __( 'The message to show on a successful payment', 'woocommerce' ), 
                                'default' => __("Thank you. Your order has been received", 'woocommerce')
                            ),
                'error_message' => array(
                                'title' => __( 'Failure message', 'woocommerce' ), 
                                'type' => 'textarea', 
                                'description' => __( 'The message to show when a payment has failed', 'woocommerce' ), 
                                'default' => __("Sorry. There was a problem with your order", 'woocommerce')
                            ),
                'marchant_id' => array(
                                'title' => __( 'Marchant ID', 'woocommerce' ), 
                                'type' => 'text', 
                                'description' => __( 'This is the GTPay-wide unique identifier of merchant, assigned by GTPay and communicated to merchant by GTBank.', 'woocommerce' ), 
                                'default' => ''
                            ),
                'hash_key' => array(
                                'title' => __( 'Hash Key', 'woocommerce' ), 
                                'type' => 'text', 
                                'description' => __( 'Hash Key is a hash which would have been given to you when you opened your account with GTPay', 'woocommerce' ), 
                                'default' => ''
                            )
            );

        }

        function payment_fields() {
            if ($this->description) {
            echo wpautop(wptexturize($this->description));
            }
        }

        function get_gtpay_args( $order ) {
            global $woocommerce;

            $order_id = wp_rand(1, 9999977);
            $redirect_url = $this->get_return_url($order);
            $order_total = round(((number_format($order->get_order_total() + $order->get_order_discount(), 2, '.', ''))*100),0);
            $hash_string = $order_id . $order_total  . $redirect_url . $this->hash_key;
            $hash = hash('sha512', $hash_string);

            $gtpay_args = array(
                'gtpay_mert_id'             => $this->marchant_id,
                'gtpay_tranx_id'            => $order_id,
                'gtpay_tranx_amt'           => $order_total,
                'gtpay_tranx_curr'          => 566,
                'gtpay_tranx_memo'                       =>"Mobow",

                'gtpay_tranx_hash'          => $hash,


                'gtpay_tranx_noti_url'          => $redirect_url,
                'gtpay_cust_id'         => $order_id . wp_rand(1, 999999),
                'gtpay_cust_name'           => trim($order->billing_first_name . ' ' . $order->billing_last_name)


            );

            if (isset($order->user_id)) {
                $gtpay_args['gtpay_cust_id'] = $order->user_id;
            }

            $gtpay_args = apply_filters('woocommerce_gtpay_args', $gtpay_args);

            return $gtpay_args;
        }

        function generate_gtpay_form( $order_id ) {
            global $woocommerce;

            $order = new WC_Order( $order_id );
            $gtpay_args = $this->get_gtpay_args( $order );
            $gtpay_args_array = array();

            $gtpay_adr = $this->liveurl;

            foreach ($gtpay_args as $key => $value) {
                $gtpay_args_array[] = '<input type="hidden" name="' . esc_attr($key) . '" value="' . esc_attr($value) . '" />';
            }


            $woocommerce->add_inline_js('
                jQuery("body").block({ 
                    message: "<img src="'.esc_url( $woocommerce->plugin_url() ).'/assets/images/ajax-loader.gif" alt="Redirecting..." style="float:left; margin-right: 10px;" />'.__('Thank you for your order. We are now redirecting you to GTPay to make payment.', 'woocommerce').'", 
                    overlayCSS: { 
                        background: "#fff", 
                        opacity: 0.6 
                    },
                    css: { 
                        padding:        20, 
                        textAlign:      "center", 
                        color:          "#555", 
                        border:         "3px solid #aaa", 
                        backgroundColor:"#fff", 
                        cursor:         "wait",
                        lineHeight: "32px"
                    } 
                });
                jQuery("#submit_gtpay_payment_form").click();
            ');

            $form = '<form action="'.esc_url( $gtpay_adr ).'" method="post" id="gtpay_payment_form">
                    ' . implode('', $gtpay_args_array) . '
                    <input type="submit" class="button-alt" id="submit_gtpay_payment_form" value="'.__('Pay via GTPay', 'woocommerce').'" /> <a class="button cancel" href="'.esc_url( $order->get_cancel_order_url() ).'">'.__('Cancel order &amp; restore cart', 'woocommerce').'</a>
                </form>';
                echo $form; exit;

            return $form;
        }

        function generate_gtpay_try_again_form( $order_id ) {
            global $woocommerce;

            $order = new WC_Order( $order_id );
            $gtpay_args = $this->get_gtpay_args( $order );
            $gtpay_args_array = array();

            $gtpay_adr = $this->liveurl;

            foreach ($gtpay_args as $key => $value) {
                $gtpay_args_array[] = '<input type="hidden" name="' . esc_attr($key) . '" value="' . esc_attr($value) . '" />';
            }

            $form = '<form action="'.esc_url( $gtpay_adr ).'" method="post" id="gtpay_payment_form">
                    ' . implode('', $gtpay_args_array) . '
                    <input type="submit" class="button-alt" id="submit_gtpay_payment_form" value="'.__('Try Again', 'woocommerce').'" />
                </form>';

            return $form;
        }

        function successful_request( $posted ) {
            global $woocommerce;
            print_r($_GET); exit;
            $order_ref = $posted['gtpay_tranx_id'];
            $order = new WC_Order( (int) $order_ref );



            //fool the thanks page into working?
            $_GET['key'] = $order->order_key;
            $_GET['order'] - $order->id;

            if ($this->get_transaction_status($order_ref)) {
                // Check order not already completed
                if ($order->status == 'completed') :
                     return false;
                endif;

                // Payment completed
                $order->add_order_note( __('IPN payment completed', 'woocommerce') );
                $order->payment_complete();
                $woocommerce->cart->empty_cart();

                foreach ($_GET as $k=>$v) {
                    update_post_meta((int)$order_ref, $k, $v);
                }

                update_post_meta( (int) $order_ref, 'Payment Method', 'GTPay');

                $this->feedback_message = $this->thanks_message;
            } else {
                $error_code = '';
                if (@$_GET['resp']) {
                    $error_code = $this->response_codes[$_GET['resp']];
                }

                $try_again = $this->generate_gtpay_try_again_form($this->parse_txn_ref_order_id($order_ref));

                $order->add_order_note(__('Payment Failed - ' . $error_code, 'woocommerce'));
                $order->update_status('failed');

                $woocommerce->add_error('Transaction Failed: ' . $error_code . ' ' . $try_again); // Transaction Failed Notice on Checkout

                $this->feedback_message = $this->failed_message . $error_code . ' ' . $try_again;

            }
        }

        function thankyou_page() {
            echo wpautop($this->feedback_message);
        }

        public function get_response_codes() {
            return array(
                '00'=>'Approved by Financial Institution'
                ,'01'=>'Refer to Financial Institution'
                ,'02'=>'Refer to Financial Institution, Special Condition'
                ,'03'=>'Invalid Merchant'
                ,'04'=>'Pick-up card'
                ,'05'=>'Do Not Honor'
                ,'06'=>'Error'
                ,'07'=>'Pick-Up Card, Special Condition'
                ,'08'=>'Honor with Identification'
                ,'09'=>'Request in Progress'
                ,'10'=>'Approved by Financial Institution, Partial'
                ,'11'=>'Approved by Financial Institution, VIP'
                ,'12'=>'Invalid Transaction'
                ,'13'=>'Invalid Amount'
                ,'14'=>'Invalid Card Number'
                ,'15'=>'No Such Financial Institution'
                ,'16'=>'Approved by Financial Institution, Update Track 3'
                ,'17'=>'Customer Cancellation'
                ,'18'=>'Customer Dispute'
                ,'19'=>'Re-enter Transaction'
                ,'20'=>'Invalid Response from Financial Institution'
                ,'21'=>'No Action Taken by Financial Institution'
                ,'22'=>'Suspected Malfunction'
                ,'23'=>'Unacceptable Transaction Fee'
                ,'24'=>'File Update not Supported'
                ,'25'=>'Unable to Locate Record'
                ,'26'=>'Duplicate Record'
                ,'27'=>'File Update Field Edit Error'
                ,'28'=>'File Update File Locked'
                ,'29'=>'File Update Failed'
                ,'30'=>'Format Error'
                ,'31'=>'Bank Not Supported'
                ,'32'=>'Completed Partially by Financial Institution'
                ,'33'=>'Expired Card, Pick-Up'
                ,'34'=>'Suspected Fraud, Pick-Up'
                ,'35'=>'Contact Acquirer, Pick-Up'
                ,'36'=>'Restricted Card, Pick-Up'
                ,'37'=>'Call Acquirer Security, Pick-Up'
                ,'38'=>'PIN Tries Exceeded, Pick-Up'
                ,'39'=>'No Credit Account'
                ,'40'=>'Function not Supported'
                ,'41'=>'Lost Card, Pick-Up'
                ,'42'=>'No Universal Account'
                ,'43'=>'Stolen Card, Pick-Up'
                ,'44'=>'No Investment Account'
                ,'51'=>'Insufficient Funds'
                ,'52'=>'No Check Account'
                ,'53'=>'No Savings Account'
                ,'54'=>'Expired Card'
                ,'55'=>'Incorrect PIN'
                ,'56'=>'No Card Record'
                ,'57'=>'Transaction not permitted to Cardholder'
                ,'58'=>'Transaction not permitted on Terminal'
                ,'59'=>'Suspected Fraud'
                ,'60'=>'Contact Acquirer'
                ,'61'=>'Exceeds Withdrawal Limit'
                ,'62'=>'Restricted Card'
                ,'63'=>'Security Violation'
                ,'64'=>'Original Amount Incorrect'
                ,'65'=>'Exceeds withdrawal frequency'
                ,'66'=>'Call Acquirer Security'
                ,'67'=>'Hard Capture'
                ,'68'=>'Response Received Too Late'
                ,'75'=>'PIN tries exceeded'
                ,'76'=>'Reserved for Future Postilion Use'
                ,'77'=>'Intervene, Bank Approval Required'
                ,'78'=>'Intervene, Bank Approval Required for Partial Amount'
                ,'90'=>'Cut-off in Progress'
                ,'91'=>'Issuer or Switch Inoperative'
                ,'92'=>'Routing Error'
                ,'93'=>'Violation of law'
                ,'94'=>'Duplicate Transaction'
                ,'95'=>'Reconcile Error'
                ,'96'=>'System Malfunction'
                ,'98'=>'Exceeds Cash Limit'
                ,'A0'=>'Unexpected error'
                ,'A4'=>'Transaction not permitted to card holder, via channels'
                ,'Z0'=>'Transaction Status Unconfirmed'
                ,'Z1'=>'Transaction Error'
                ,'Z2'=>'Bank account error'
                ,'Z3'=>'Bank collections account error'
                ,'Z4'=>'Interface Integration Error'
                ,'Z5'=>'Duplicate Reference Error'
                ,'Z6'=>'Incomplete Transaction'
                ,'Z7'=>'Transaction Split Pre-processing Error'
                ,'Z8'=>'Invalid Card Number, via channels'
                ,'Z9'=>'Transaction not permitted to card holder, via channels'
            );
        }   

        function gtpay_thanks() {

            echo $this->response_codes(urldecode($_GET['desc']));



            if ($GET['desc'] != '00') {
                $this->generate_gtpay_form($_POST['txnref']);
            }
        }

        function parse_txn_ref_order_id($txnref) {
            $txnref = htmlentities($txnref);
            $txn_details = explode('_', $txnref);
            $marchant_id = $txn_details[1];
            $order_id = $txn_details[0];

            return $order_id;
        }   

        function process_payment( $order_id ) {
            $order = new WC_Order( $order_id );

            return array(
                'result' => 'success',
                'redirect' => add_query_arg('order', $order->id, add_query_arg('key', $order->order_key, get_permalink(woocommerce_get_page_id('pay'))))
            );
        }

        function receipt_page( $order ) {
            echo '<p>'.__('Thank you for your order, please click the button below to pay with GTPay.', 'woocommerce').'</p>';

            echo $this->generate_gtpay_form( $order );
        }

        function check_ipn_response() {
            if (isset($_POST['retRef'])) {
                @ob_clean();

                $_POST = stripslashes_deep($_POST);

                header('HTTP/1.1 200 OK');
                do_action("valid-gtpay-ipn-request", $_POST);
            }
        }

        function get_transaction_status($txnref) { 
            $return = false;
            $txnref = htmlentities($txnref);
            $txn_details = explode('a', $txnref);
            $marchant_id = $txn_details[1];
            //$hash_string = $marchant_id . $txnref . $this->hash_key;
            //$hash = hash('sha512', $hash_string);

            $endpoint = "https://ibank.gtbank.com/GTPay/Tranx.aspx";

            $endpoint .= '?mertid=' . $marchant_id . '&amount=' . $order_total . '&tranxid=' . $order_id . '&hash='.$hash;

            set_time_limit(0);

            $ch = curl_init($endpoint);

            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_FOLLOWLOCATION ,1);
            curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
            curl_setopt($ch, CURLOPT_CONNECTTIMEOUT ,120);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER ,false);
            curl_setopt($ch, CURLOPT_TIMEOUT, 120);

            $output = curl_exec($ch);
            $last_url = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL);

            curl_close($ch);

            if ($last_url) {
                if ($url = parse_url($last_url)) {
                    if ($pairs = explode('&', $url['query'])) {
                    print_r($pairs); exit;
                        foreach ($pairs as $i=>$pair) {
                            $kv = explode('=', $pair);

                            $_GET[$kv[0]] = $kv[1];
                            $_REQUEST[$kv[0]] = $kv[1];

                            if ($kv[0] == 'resp') {
                                if ($kv[1] == '00') {
                                    $return = true;
                                }
                            }
                        }
                    }
                }
            }

            return $return;
        }   

    }

    /**
     * Add the gateway to WooCommerce
     **/
    function add_gtpay_gateway( $methods ) {
        $methods[] = 'WC_GTPay'; return $methods;
    }

    add_filter('woocommerce_payment_gateways', 'add_gtpay_gateway' );
}


add_filter('plugins_loaded', 'sb_gtpay_init' );

?>

You can test out the website here.

Related posts

Leave a Reply

1 comment

  1. Take a look at the default PayPal gateway. In the constructor there are 2 things being set up. First the notify URL that you will give to PayPal. This is where PayPal will send its IPN stuff.

    $this->notify_url         = WC()->api_request_url( 'WC_Gateway_Paypal' );
    

    If you track down the api_request_url() you find that if you are using permalinks your notify URL looks like : www.mysite.com/wc-api/wc_gateway_paypal or if not using permalinks your URL would be: www.mysite.com?wc-api=wc_gateway_paypal.

    Then the constructor continues to attach a callback to the action hook that will be fired when your site receives a notification sent to the above URL.

    // Payment listener/API hook
    add_action( 'woocommerce_api_wc_gateway_paypal', array( $this, 'check_ipn_response' ) );
    

    So when PayPal sends a response back the check_ipn_response() method handles it.

    Keep in mind that this is just my best understanding based on reading the code. I’ve not actually tried using the API yet, even though I really want to.