Woocommerce / WordPress Платежный шлюз BarclayCard - PullRequest
0 голосов
/ 27 апреля 2020

Я пытаюсь интегрировать BarclayCard с веб-сайтом WordPress. Проблема в том, что все происходит нормально / Просто на обратном URL-адресе (notify_url) перенаправление с BarclayCard на веб-сайт не выполняется, если я не использую URL-адрес пользовательской страницы в поле notify_url. Кроме того, мне нужно go войти на портал администрирования woocommerce, чтобы вручную отправить данные клиента. Статус заказа зависает на «ожидающий платеж», и мне нужно вручную проверить портал barclaycard, чтобы подтвердить платеж, а затем изменить статус платежа на «завершен» на портале администрирования woocommerce.

Проблема заключается в том, что результат оплаты перенаправляется обратно на сайт со страницы оплаты barclaycard. Подскажите, пожалуйста, что мне нужно сделать, чтобы результат платежа был правильно передан, а клиент перенаправлен на страницу подтверждения заказа woocommerce по умолчанию?

Вот код, который я использую:

if (!defined('ABSPATH')) {
    exit;
}

class RapidDive_WC_Gateway_Barclay extends WC_Payment_Gateway
{
    const TEST_URL = 'https://mdepayments.epdq.co.uk/ncol/test/orderstandard.asp';
    const LIVE_URL = 'https://payments.epdq.co.uk/ncol/prod/orderstandard.asp';

    public static $log_enabled = false;

    public static $log = false;
    protected $access_key;


    public function __construct()
    {
        $this->id = 'barclay';
        $this->method_title = __('Barclay ePDQ', 'woocommerce');
        $this->order_button_text = __('Proceed to Barcalay ePDQ', 'woocommerce');
        $this->method_description = __('Barclay ePDQ redirects customers to Barclay to enter their payment information.',
            'woocommerce');
        $this->supports = array(
            'products',
//            'refunds',
        );
        $this->icon = plugin_dir_url(__FILE__) . '../assets/barclaycard_logo.png';

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

        $this->title = $this->get_option('title');
        $this->title = ($this->title !== null && $this->title !== '') ? $this->title : __('Barclay ePDQ', 'woocommerce');
        $this->description = $this->get_option('description');
        $this->access_key = $this->get_option('access_key');
        $this->showLogo = $this->get_option('show_logo');

        $this->status = $this->get_option('status');
        $this->error_notice = $this->get_option('error_notice');
        $this->sha_in = $this->get_option('sha_in');
        $this->sha_out = $this->get_option('sha_out');
        $this->sha_method = $this->get_option('sha_method');
        $this->sha_method = ($this->sha_method != '') ? $this->sha_method : 0;

        $this->cat_url = woocommerce_get_page_id('shop');

        $this->aavscheck = $this->get_option('aavcheck');
        $this->cvccheck = $this->get_option('cvccheck');

        $this->payment_method = is_array($this->get_option('payment_method')) ? implode(';',
            $this->get_option('payment_method')) : '';
        $this->brand_cards = is_array($this->get_option('brand_cards')) ? implode(';',
            $this->get_option('brand_cards')) : '';
        $this->secure_3d = $this->get_option('secure_3d');
//        $this->method_list = $this->get_option('method_list');
        $this->method_list = is_array($this->get_option('method_list')) ? implode(';',
            $this->get_option('method_list')) : '';

        $this->com_plus = $this->get_option('com_plus');
        $this->param_plus = $this->get_option('param_plus');

        $this->param_var = $this->get_option('param_var');

        //Recommended for Direct Payments and Advanced Payments
        $this->operation = $this->get_option('operation');
        $this->api_user_id = $this->get_option('api_user_id');
        $this->api_user_pswd = $this->get_option('api_user_pswd');


        //Recommended for Direct Payments and Advanced Payments
        $this->operation = $this->get_option('operation');
        $this->api_user_id = $this->get_option('api_user_id');
        $this->api_user_pswd = $this->get_option('api_user_pswd');

        $this->notify_url = 'https://www.example.com/custom-page-url/';

        // templating
        $this->pp_format = $this->get_option('pp_format ');
        $this->TITLE = $this->get_option('TITLE');
        $this->BGCOLOR = $this->get_option('BGCOLOR');
        $this->TXTCOLOR = $this->get_option('TXTCOLOR');
        $this->TBLBGCOLOR = $this->get_option('TBLBGCOLOR');
        $this->TBLTXTCOLOR = $this->get_option('TBLTXTCOLOR');
        $this->BUTTONBGCOLOR = $this->get_option('BUTTONBGCOLOR');
        $this->BUTTONTXTCOLOR = $this->get_option('BUTTONTXTCOLOR');
        $this->FONTTYPE = $this->get_option('FONTTYPE');
        $this->LOGO = $this->get_option('LOGO');

        $this->add_payment_hooks();
    }

    /**
     * Initialise Gateway Settings Form Fields.
     */
    public function init_form_fields()
    {
        $this->form_fields = include('includes/settings-barclay.php');
    }

    /**
     *
     */
    private function add_payment_hooks()
    {
        add_action('woocommerce_update_options_payment_gateways_' . $this->id, array($this, 'process_admin_options'));
        add_action('woocommerce_receipt_barclay', array($this, 'receipt_page'));
        add_action('woocommerce_api_rapiddive_wc_gateway_barclay', array($this, 'check_barclay_response'));
    }

    /**
     * @param $message
     * @param string $level
     */
    public static function log($message, $level = 'info')
    {
        if (self::$log_enabled) {
            if (self::$log === null) {
                self::$log = wc_get_logger();
            }
            self::$log->log($level, $message, array('source' => 'barclay'));
        }
    }

    /**
     *
     */
    public function admin_options()
    {
        ?>
        <h2> <?php _e('Barclay Payment Gateway', 'woocommerce'); ?> </h2>
        <table class="form-table">
            <?php $this->generate_settings_html(); ?>
        </table> <?php
    }

    /**
     * @param int $order_id
     * @return array
     */
    public function process_payment($order_id)
    {
        $order = wc_get_order($order_id);
        return array(
            'result' => 'success',
            'redirect' => $order->get_checkout_payment_url(true)
        );
    }

    /**
     * @param $order
     */
    public function receipt_page($order)
    {
        echo '<p>' . __('Thank you for your order, please click the button below to pay with Barclay ePDQ.',
                'woocommerce') . '</p>';
        echo $this->generate_barclay_form($order);
    }

    /**
     * @param $order
     * @return string
     */
    public function generate_barclay_form($order)
    {
        $order = wc_get_order($order);
        $barclay_args = $this->get_barclay_fields($order);

        $shasign = '';
        $shasign_arg = array();

        ksort($barclay_args);
        foreach ($barclay_args as $key => $value) {
            if ($value == '') {
                continue;
            }
            $shasign_arg[] = $key . '=' . $value;
        }

        if ($this->sha_method == 0) {
            $shasign = sha1(implode($this->sha_in, $shasign_arg) . $this->sha_in);
        } elseif ($this->sha_method == 1) {
            $shasign = hash('sha256', implode($this->sha_in, $shasign_arg) . $this->sha_in);
        } elseif ($this->sha_method == 2) {
            $shasign = hash('sha512', implode($this->sha_in, $shasign_arg) . $this->sha_in);
        }

        $barclay_html_args = array();
        foreach ($barclay_args as $key => $value) {
            if ($value == '') {
                continue;
            }
            $barclay_html_args[] = '<input type="hidden" name="' . $key . '" value="' . $value . '"/>';
        }

        if (isset($this->status) && ($this->status == 'test' || $this->status == 'live')) {
            $url = $this->status == 'test' ? self::TEST_URL : self::LIVE_URL;

            return
                '<form action="' . esc_url($url) . '" method="post" id="epdq_payment_form">' .
                implode('', $barclay_html_args) .
                '<input type="hidden" name="SHASIGN" value="' . $shasign . '"/>' .
                '<input type="submit" class="button alt" id="submit_epdq_payment_form" value="' . __('Pay via Barclay ePDQ',
                    'woocommerce') . '" />' .
                '<a class="button cancel" href="' . esc_url($order->get_cancel_order_url()) . '">' . __('Cancel order &amp; restore cart',
                    'woocommerce') . '</a>' .
                '</form>';
        } else {
            return '<p class="error">' . $this->error_notice . '</p>';
        }
    }

    /**
     * @param $order_id
     * @return array
     */
    public function get_barclay_fields($order_id)
    {

        $order = wc_get_order($order_id);

        // var_dump(get_class_methods($order));
        // exit;
        $barclay_args = array(
            'PSPID' => $this->access_key,
            'ORDERID' => $order->id,
            'AMOUNT' => $order->order_total * 100,
            'CURRENCY' => get_woocommerce_currency(),
            'LANGUAGE' => get_bloginfo('language'),
            'CN' => $order->billing_first_name . ' ' . $order->billing_last_name,
            'EMAIL' => $order->billing_email,
            'OWNERZIP' => $order->billing_postcode,
            'OWNERADDRESS' => $order->billing_address_1,
            'OWNERADDRESS2' => $order->billing_address_2,
            'OWNERCTY' => $order->billing_country,
            'OWNERTOWN' => $order->billing_city,
            'OWNERTELNO' => $order->billing_phone,

            'ACCEPTURL' => $this->notify_url,
            'DECLINEURL' => $this->notify_url,
            'EXCEPTIONURL' => $this->notify_url,
            // 'CANCELURL' => $this->notify_url,
            'CANCELURL' => esc_url_raw($order->get_cancel_order_url_raw()),
            'BACKURL' => '',
            'HOMEURL' => '',
            'CATALOGURL' => get_permalink($this->cat_url),

            //payment method
            'PM' => $this->payment_method,
            'BRAND' => $this->brand_cards,
            'WIN3DS' => $this->secure_3d,
            'PMLISTTYPE' => $this->method_list,

            //Redirection on payment result
            'COMPLUS' => $this->com_plus,
            'PARAMPLUS' => $this->param_plus,

            //POST payment url
            'PARAMVAR' => $this->param_var,

            //REcommended for direct payments
            'OPERATION' => $this->operation,
            'USERID' => $this->api_user_id,
            'PASWD' => $this->api_user_pswd
        );

        if ($this->pp_format == 'yes') {
            $barclay_args['TITLE'] = $this->TITLE;
            $barclay_args['BGCOLOR'] = $this->BGCOLOR;
            $barclay_args['TXTCOLOR'] = $this->TXTCOLOR;
            $barclay_args['TBLBGCOLOR'] = $this->TBLBGCOLOR;
            $barclay_args['TBLTXTCOLOR'] = $this->TBLTXTCOLOR;
            $barclay_args['BUTTONBGCOLOR'] = $this->BUTTONBGCOLOR;
            $barclay_args['BUTTONTXTCOLOR'] = $this->BUTTONTXTCOLOR;
            $barclay_args['FONTTYPE'] = $this->FONTTYPE;
            $barclay_args['LOGO'] = $this->LOGO;
        }
        return $barclay_args;
    }

    /**
     *
     */
    public function payment_fields()
    {
        if ($this->showLogo === 'yes') {
            echo '<img src="' . plugin_dir_url(__FILE__) . '../assets/epdq.gif"/>';
        }
        if ($description = $this->get_description()) {
            echo wpautop(wptexturize($description));
        }
    }

    /**
     *
     */
    function check_barclay_response()
    {
        ob_clean();
        header('HTTP/1.1 200 OK');

        $datacheck = array();
        $datacheck1 = array();

        foreach ($_REQUEST as $key => $value) {
            if ($value == "") {
                continue;
            }
            $datacheck[$key] = $value;
            $datacheck1[strtoupper($key)] = strtoupper($value);
        }

        $verify = $this->checkShaOut($datacheck);

        if ($verify) {
            $this->transaction_successfull($datacheck1);
        } else {
            wp_die('Transaction is unsuccessfull!');
        }
    }

    /**
     * @param $datacheck
     * @return bool
     */
    protected function checkShaOut($datacheck)
    {
        $shaout = $this->sha_out;

        $origsig = $datacheck['SHASIGN'];

        unset($datacheck['SHASIGN']);
        unset($datacheck['wc-api']);

        uksort($datacheck, 'strcasecmp');
        $shasign = "";

        $shasig = null;
        foreach ($datacheck as $key => $value) {
            $shasig .= trim(strtoupper($key)) . '=' . utf8_encode(trim($value)) . $shaout;
        }

        $shasig = strtoupper(hash('sha1', $shasig));

        if ($shasig == $origsig) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * @param $args
     */
    function transaction_successfull($args)
    {
        global $woocommerce;

        extract($args);
        $order = new WC_Order($ORDERID);

        $accepted = array(4, 5, 9, 41, 51, 91);
        $status = $STATUS;
        $ncerror = $NCERROR;

        $dienote = '<p>Transection result is uncertain.<p>';
        $dienote .= '<p>Status Code: ' . $STATUS . ' - ' . $this->get_barclay_status_code($status) . '';
        $dienote .= '<br>Error Code: ' . $NCERROR . ' - ' . $this->get_barclay_ncerror($ncerror) . '</p>';
        $died = '';
        $died .= $dienote;
        $died .= '<p>Your order is cancelled and your cart is emptied.';
        $died .= '<br>Go to your <a href="' . get_permalink(get_option('woocommerce_myaccount_page_id')) . '">account</a> to process your order again or ';
        $died .= 'go to <a href="' . home_url() . '">homepage</a></p>';

        if (in_array($STATUS, $accepted)) {

            if (!empty($args['ORDERID'])) {
                $note = 'Order ID: ' . $ORDERID . '.<br>';
            } //    order id
            if (!empty($args['AMOUNT'])) {
                $note .= 'Amount: ' . $AMOUNT . '.<br>';
            } //    amount
            if (!empty($args['CURRENCY'])) {
                $note .= 'Order currency: ' . $CURRENCY . '.<br>';
            } //    order currency
            if (!empty($args['PM'])) {
                $note .= 'Payment Method: ' . $PM . '.<br>';
            } //    payment method
            if (!empty($args['ACCEPTANCE'])) {
                $note .= 'Acceptance code returned by acquirer: ' . $ACCEPTANCE . '.<br>';
            }    // acceptance
            if (!empty($args['STATUS'])) {
                $note .= 'Transaction status : ' . $STATUS . '.<br>';
            } //    status code
            if (!empty($args['CARDNO'])) {
                $note .= 'Masked card number : ' . $CARDNO . '.<br>';
            } //    catd no
            if (!empty($args['PAYID'])) {
                $note .= 'Payment reference in EPDQ system: ' . $PAYID . '.<br>';
            } //    pay id
            if (!empty($args['NCERROR'])) {
                $note .= 'Error Code: ' . $NCERROR . '.<br>';
            } //    ncerror
            if (!empty($args['BRAND'])) {
                $note .= 'Card brand (EPDQ system derives this from the card number) : ' . $BRAND . '.<br>';
            } //    brand
            if (!empty($args['ED'])) {
                $note .= 'Payer\'s card expiry date : ' . $ED . '.<br>';
            } //    expiry date
            if (!empty($args['TRXDATE'])) {
                $note .= 'Transaction Date: ' . $TRXDATE . '.<br>';
            } //    date
            if (!empty($args['CN'])) {
                $note .= 'Cardholder/customer name: ' . $CN . '.<br>';
            } //    payer's name
            if (!empty($args['IP'])) {
                $note .= 'Customer\'s IP: ' . $IP . '.<br>';
            } //    payer's ip


            if (!empty($args['AAVADDRESS'])) {
                $note .= 'AAV result for the address: ' . $AAVADDRESS . ' . <br>';
            } //    aav address
            if (!empty($args['AAVCHECK'])) {
                $note .= 'Result of the automatic address verification: ' . $AAVCHECK . ' . <br>';
            } //    aav check
            if (!empty($args['AAVZIP'])) {
                $note .= 'AAV result for the zip code: ' . $AAVZIP . ' . <br>';
            } // aav zip
            if (!empty($args['BIN'])) {
                $note .= 'First 6 digits of credit card number: ' . $BIN . ' . <br>';
            } // bin
            if (!empty($args['CCCTY'])) {
                $note .= 'Country where the card was issued: ' . $CCCTY . ' . <br>';
            }
            if (!empty($args['COMPLUS'])) {
                $note .= 'Custom value passed: ' . $COMPLUS . ' . <br>';
            }

            if (!empty($args['CVCCHECK'])) {
                $note .= 'Result of the card verification code check: ' . $CVCCHECK . ' . <br>';
            }
            if (!empty($args['ECI'])) {
                $note .= 'Electronic Commerce Indicator: ' . $ECI . ' . <br>';
            }
            if (!empty($args['FXAMOUNT'])) {
                $note .= 'FXAMOUNT: ' . $FXAMOUNT . ' . <br>';
            }
            if (!empty($args['FXCURRENCY'])) {
                $note .= 'FXCURRENCY: ' . $FXCURRENCY . ' . <br>';
            }
            if (!empty($args['IPCTY'])) {
                $note .= 'Originating country of the IP address: ' . $IPCTY . ' . <br>';
            }
            if (!empty($args['SUBBRAND'])) {
                $note .= 'SUBBRAND: ' . $SUBBRAND . ' . <br>';
            }
            if (!empty($args['VC'])) {
                $note .= 'Virtual Card type: ' . $SUBBRAND . ' . <br>';
            }


            $woocommerce->cart->empty_cart();

            if (in_array($STATUS, array(4, 5, 9))) {
                $note = 'Barclay ePDQ transaction is confirmed.<br>';
                $note .= $note;
                $order->add_order_note($note);
                $order->payment_complete();
            }

            if (in_array($STATUS, array(41, 51, 91))) {
                $note = 'Barclay ePDQ transaction is awaiting for confirmation.<br>';
                $note .= $note;
                $order->update_status('on-hold', $note);
            }

        } elseif ($STATUS == 2 || $STATUS == 93) {
            $dienote .= '<br>Order is failed.';
            $order->update_status('failed', $dienote);
            $woocommerce->cart->empty_cart();
        } elseif ($STATUS == 52 || $STATUS == 92) {
            $dienote .= '<br>Order is failed.';
            $order->update_status('failed', $dienote);
            $woocommerce->cart->empty_cart();
        } elseif ($STATUS == 1) {
            $dienote .= '<br>Order is cancelled.';
            $order->update_status('cancelled', $dienote);
            $woocommerce->cart->empty_cart();
        } else {
            $dienote .= '<br>Order is failed.';
            $order->update_status('failed', $dienote);
            $woocommerce->cart->empty_cart();
        }

        wp_redirect($this->get_return_url($order));
        exit;
    }

    /**
     * @param $code
     * @return mixed|string|void
     */
    function get_barclay_status_code($code)
    {
        if ($code == '') {
            return;
        }
        $codes = array(
            0 => 'Incomplete or invalid',
            1 => 'Cancelled by client',
            2 => 'Authorisation refused',
            4 => 'Order stored',
            40 => 'Stored waiting external result',
            41 => 'Waiting client payment',
            5 => 'Authorised',
            51 => 'Authorisation waiting',
            52 => 'Authorisation not known',
            55 => 'Standby',
            56 => 'OK with scheduled payments',
            57 => 'Not OK with scheduled payments',
            59 => 'Author. to get manually',
            6 => 'Authorised and canceled',
            61 => 'Author. deletion waiting',
            62 => 'Author. deletion uncertain',
            63 => 'Author. deletion refused',
            64 => 'Authorised and cancelled',
            7 => 'Payment deleted',
            71 => 'Payment deletion pending',
            72 => 'Payment deletion uncertain',
            73 => 'Payment deletion refused',
            74 => 'Payment deleted (not accepted)',
            75 => 'Deletion processed by merchant',
            8 => 'Refund',
            81 => 'Refund pending',
            82 => 'Refund uncertain',
            83 => 'Refund refused',
            84 => 'Payment declined by the acquirer (will be debited)',
            85 => 'Refund processed by merchant',
            9 => 'Payment requested',
            91 => 'Payment processing',
            92 => 'Payment uncertain',
            93 => 'Payment refused',
            94 => 'Refund declined by the acquirer',
            95 => 'Payment processed by merchant',
            96 => 'Refund reversed',
            97 => 'Being processed - intermediate technical status',
            98 => 'Being processed - intermediate technical status',
            99 => 'Being processed - intermediate technical status'
        );
        if (isset($codes[$code])) {
            return $codes[$code];
        } else {
            return 'Unknown';
        }
    }

    /**
     * @param $code
     * @return mixed|string|void
     */
    function get_barclay_ncerror($code)
    {
        if ($code == '') {
            return;
        }

....
...
...

Спасибо.

...