# payplug/3.1.0/src/Controller/PayplugGenericGateway.php

PayPlug for WooCommerce (Official), version 3.1.0. 550 lines.

- Page: https://pluginprobe.com/plugins/payplug/3.1.0/code/src/Controller/PayplugGenericGateway.php
- Raw: https://pluginprobe.com/plugins/payplug/3.1.0/raw/src/Controller/PayplugGenericGateway.php
- Modified: 2026-09-25T08:27:34+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/payplug/3.1.0/code/src/Controller/PayplugGenericGateway.php#L10-L20`.

```php
<?php

namespace Payplug\PayplugWoocommerce\Controller;

use Payplug\Exception\HttpException;
use Payplug\Payplug;
use Payplug\PayplugWoocommerce\Gateway\PayplugAddressData;
use Payplug\PayplugWoocommerce\Gateway\PayplugGateway;
use Payplug\PayplugWoocommerce\Interfaces\PayplugGatewayBuilder;
use Payplug\PayplugWoocommerce\PayplugWoocommerceHelper;
use Payplug\Resource\Payment as PaymentResource;
use Payplug\Resource\Refund as RefundResource;

class PayplugGenericGateway extends PayplugGateway implements PayplugGatewayBuilder
{
    /**
     * @var string
     */
    public $image;

    /**
     * @var array
     */
    protected $allowed_country_codes;

    public function __construct()
    {
        parent::__construct();
        add_action('woocommerce_after_order_itemmeta', [$this, 'hide_wc_refund_button'], 10, 3);
    }

    /**
     * Generic code to fetch payment gateway specific image
     *
     * @return string
     */
    public function get_icon()
    {

        //get object $image
        $icons = apply_filters('payplug_payment_icons', [
            'payplug' => sprintf('<img src="%s" alt="%s" class="payplug-payment-icon" />', esc_url(PAYPLUG_GATEWAY_PLUGIN_URL . '/assets/images/checkout/' . $this->image), $this->id . ' Icon'),
        ]);

        $icons_str = '';
        foreach ($icons as $icon) {
            $icons_str .= $icon;
        }

        return $icons_str;
    }

    /**
     * @return void
     */
    public function display_notice(): void
    {
        $error_message = 'payplug_' . $this->id . '_unauthorized_message'; ?>
		<div class="notice notice-error is-dismissible">
			<p><?php echo __($error_message, 'payplug'); ?></p>
		</div>
		<?php
    }

    public function checkGateway()
    {
        //check if module is enabled
        if (!isset($this->settings['enabled']) || !$this->settings['enabled']) {
            return false;
        }

        // todo: delete this usage to avoid call to getAccount resource each checkout loading
        $account = PayplugWoocommerceHelper::generic_get_account_data_from_options($this->id);
        $options = PayplugWoocommerceHelper::get_payplug_options();

        if (!$this->check_api_gateway_enable($account)) {
            return false;
        }

        if (!isset($options['payment_methods']) || empty($options['payment_methods'])) {
            return false;
        }

        if (!$options['payment_methods']['configuration'][$this->id]['active']) {
            return false;
        }

        $is_order_pay = is_wc_endpoint_url('order-pay');
        $country_code_billing = null;
        if (!is_admin() && (!PayplugWoocommerceHelper::is_checkout_block() || $is_order_pay)) {
            if (empty(WC()->cart) && !is_admin() && !$is_order_pay) {
                return false;
            }

            //for backend orders
            if (!empty(get_query_var('order-pay'))) {
                $order = wc_get_order((int) get_query_var('order-pay'));
                $items = $order->get_items();
                $country_code_billing = $order->get_billing_country();
                // Skip cart population for subscription renewals: WC Subscriptions manages the cart
                // itself and adding items here would cause a double entry in the order summary.
                $is_renewal = function_exists('wcs_order_contains_renewal') && wcs_order_contains_renewal($order);
                if (!$is_renewal) {
                    if (is_null(WC()->cart)) {
                        wc_load_cart();
                    }
                    $this->order_items_to_cart(WC()->cart, $items);
                }
            }

            $source_before_fallback = $country_code_billing;
            if (empty($country_code_billing)) {
                $country_code_billing = method_exists(WC()->customer, 'get_billing_country') ? WC()->customer->get_billing_country() : null;
            }

            $permission_result = $this->check_billing_country_permissions($account, $country_code_billing);

            if (!$permission_result) {
                return false;
            }
        }

        return true;
    }

    /**
     * check if payment is enable and customer has permissions
     *
     * @param $account
     *
     * @return bool
     */
    protected function check_api_gateway_enable($account)
    {
        if (
            isset($account['payment_methods']) &&
            empty($account['payment_methods'][$this->id]) &&
            !$account['payment_methods'][$this->id]['enabled']
        ) {
            return false;
        }

        return true;
    }

    /**
     * Check if billing country can use this payment method
     *
     * @param $account
     * @param $billing_code
     *
     * @return bool
     */
    public function check_billing_country_permissions($account, $billing_code)
    {
        if (!isset($account['payment_methods'][$this->id]['allowed_countries'])) {
            return true;
        }

        $this->allowed_country_codes = $account['payment_methods'][$this->id]['allowed_countries'];

        if (is_array($this->allowed_country_codes)) {
            if (in_array('ALL', $this->allowed_country_codes) || empty($this->allowed_country_codes)) {
                return true;
            }

            //check if country is allowed
            if (in_array($billing_code, $this->allowed_country_codes)) {
                return true;
            } else {
                return false;
            }
        }

        return false;
    }

    /**
     * if payment was generated by an intend, we shouldn't generate another one and try to pay it, this would generate duplications
     *
     * @param $order
     *
     * @throws \Exception
     *
     * @return array|null
     */
    private function process_standard_intent_payment($order)
    {
        $embedded_mode = $this->settings['payment_methods']['configuration']['payplug']['embedded_mode'];

        // This can run from AJAX endpoints whose own request URL never carries the order-pay
        // query var, so is_wc_endpoint_url() alone can't detect that context here: fall back
        // to the order_key/order_pay_key sent by the order-pay AJAX flows.
        $is_order_pay = $this->is_order_pay_request($order);

        if (!$is_order_pay &&
            empty($_POST['payplug_non_blocks']) &&
            PayplugWoocommerceHelper::is_checkout_block() &&
            (
                ($this->id === 'payplug' && in_array($embedded_mode, ['integrated', 'popup'])) ||
                ($this->id === 'american_express' && 'popup' == $embedded_mode)
            ) &&
            !empty($order->get_transaction_id())) {
            $order_id = PayplugWoocommerceHelper::is_pre_30() ? $order->id : $order->get_id();

            try {
                $payment = $this->payplug_api->payment_retrieve($order->get_transaction_id());
                if (ob_get_length() > 0) {
                    ob_clean();
                }

                // Save transaction id for the order
                PayplugWoocommerceHelper::is_pre_30()
                    ? update_post_meta($order_id, '_transaction_id', $payment->id)
                    : $order->set_transaction_id($payment->id);

                if (is_callable([$order, 'save'])) {
                    $order->save();
                }

                /**
                 * Fires once a payment has been created.
                 *
                 * @param int $order_id Order ID
                 * @param PaymentResource $payment Payment resource
                 */
                \do_action('payplug_gateway_payment_created', $order_id, $payment);

                $metadata = PayplugWoocommerceHelper::extract_transaction_metadata($payment);
                PayplugWoocommerceHelper::save_transaction_metadata($order, $metadata);

                PayplugGateway::log(sprintf('Payment intent created for order #%s', $order_id));

                $return_url = esc_url_raw($order->get_checkout_order_received_url());

                $result = [
                    'payment_id' => $payment->id,
                    'result' => 'success',
                    'redirect' => !empty($payment->hosted_payment->payment_url) ? $payment->hosted_payment->payment_url : $return_url,
                    'cancel' => !empty($payment->hosted_payment->cancel_url) ? $payment->hosted_payment->cancel_url : null,
                ];

                // wp_send_json_success() calls die(), which is only safe for the classic
                // wc-ajax request this was written for: the Store API checkout flow (used by
                // the checkout block) calls process_payment() through the REST framework,
                // and killing the process mid-request there produces a broken response.
                if (wp_doing_ajax()) {
                    wp_send_json_success($result);
                }

                return $result;
            } catch (HttpException $e) {
                PayplugGateway::log(sprintf('Error while processing order #%s : %s', $order_id, wc_print_r($e->getErrorObject(), true)), 'error');
                throw new \Exception(__('Payment processing failed. Please retry.', 'payplug'));
            } catch (\Exception $e) {
                PayplugGateway::log(sprintf('Error while processing order #%s : %s', $order_id, $e->getMessage()), 'error');
                throw new \Exception(__('Payment processing failed. Please retry.', 'payplug'));
            }
        }

        return null;
    }

    public function process_standard_payment($order, $amount, $customer_id)
    {
        $intent = $this->process_standard_intent_payment($order);
        if (!empty($intent)) {
            return $intent;
        }

        $order_id = PayplugWoocommerceHelper::is_pre_30() ? $order->id : $order->get_id();

        try {

            //if there's no auth to process payment
            if (!$this->checkGateway()) {
                throw new \Exception(__('Payment processing failed. Please retry.', 'payplug'));
            }

            $address_data = PayplugAddressData::from_order($order);
            $return_url = esc_url_raw($order->get_checkout_order_received_url());

            if (!(substr($return_url, 0, 4) === 'http')) {
                $return_url = get_site_url() . $return_url;
            }
            $payment_data = [
                'amount' => $amount,
                'currency' => get_woocommerce_currency(),
                'payment_method' => $this->id,
                'billing' => $address_data->get_billing(),
                'shipping' => $address_data->get_shipping(),
                'hosted_payment' => [
                    'return_url' => $return_url,
                    'cancel_url' => esc_url_raw($order->get_cancel_order_url_raw()),
                ],
                'notification_url' => esc_url_raw(WC()->api_request_url('PayplugGateway')),
                'metadata' => [
                    'order_id' => $order_id,
                    'customer_id' => ((int) $customer_id > 0) ? $customer_id : 'guest',
                    'domain' => $this->limit_length(esc_url_raw(home_url()), 500),
                ],
                'save_card' => false,
                'force_3ds' => false,
            ];
            if (!empty($payment_data['billing']['landline_phone_number'])) {
                $payment_data['billing']['mobile_phone_number'] = $payment_data['billing']['landline_phone_number'];
            }

            if (PayplugWoocommerceHelper::is_checkout_block() && is_checkout()) {
                $payment_data['metadata']['woocommerce_block'] = 'CHECKOUT';
            } elseif (PayplugWoocommerceHelper::is_cart_block() && is_cart()) {
                $payment_data['metadata']['woocommerce_block'] = 'CART';
            }
            /**
             * Filter the payment data before it's used
             *
             * @param array $payment_data
             * @param int $order_id
             * @param array $customer_details
             * @param PayplugAddressData $address_data
             */
            $payment_data = apply_filters('payplug_gateway_payment_data', $payment_data, $order_id, [], $address_data);
            $payment = $this->payplug_api->payment_create($payment_data);

            // Save transaction id for the order
            PayplugWoocommerceHelper::is_pre_30()
                ? update_post_meta($order_id, '_transaction_id', $payment->id)
                : $order->set_transaction_id($payment->id);

            $order->set_payment_method($this->id);
            $order->set_payment_method_title($this->method_title);

            if (is_callable([$order, 'save'])) {
                $order->save();
            }

            /**
             * Fires once a payment has been created.
             *
             * @param int $order_id Order ID
             * @param PaymentResource $payment Payment resource
             */
            \do_action('payplug_gateway_payment_created', $order_id, $payment);

            $metadata = PayplugWoocommerceHelper::extract_transaction_metadata($payment);
            PayplugWoocommerceHelper::save_transaction_metadata($order, $metadata);

            PayplugGateway::log(sprintf('Payment creation complete for order #%s', $order_id));

            return [
                'result' => 'success',
                'redirect' => $payment->hosted_payment->payment_url,
                'cancel' => $payment->hosted_payment->cancel_url,
            ];
        } catch (HttpException $e) {
            PayplugGateway::log(sprintf('Error while processing order #%s : %s', $order_id, wc_print_r($e->getErrorObject(), true)), 'error');
            throw new \Exception(__('Payment processing failed. Please retry.', 'payplug'));
        } catch (\Exception $e) {
            PayplugGateway::log(sprintf('Error while processing order #%s : %s', $order_id, $e->getMessage()), 'error');
            throw new \Exception(__('Payment processing failed. Please retry.', 'payplug'));
        }
    }

    /**
     * Process refund for an order paid with PayPlug gateway.
     *
     * @param int $order_id
     * @param null $amount
     * @param string $reason
     *
     * @return bool|\WP_Error
     */
    public function process_refund($order_id, $amount = null, $reason = '')
    {
        PayplugGateway::log(sprintf('Processing refund for order #%s', $order_id));

        if (!$this->user_logged_in()) {
            PayplugGateway::log(__('You must be logged in with your PayPlug account.', 'payplug'), 'error');

            return new \WP_Error('process_refund_error', __('You must be logged in with your PayPlug account.', 'payplug'));
        }

        $order = wc_get_order($order_id);
        if (!$order instanceof \WC_Order) {
            PayplugGateway::log(sprintf('The order #%s does not exist.', $order_id), 'error');

            return new \WP_Error('process_refund_error', sprintf(__('The order %s does not exist.', 'payplug'), $order_id));
        }

        if ($order->get_status() === 'cancelled') {
            PayplugGateway::log(sprintf('The order #%s cannot be refund.', $order_id), 'error');

            return new \WP_Error('process_refund_error', sprintf(__('The order %s cannot be refund.', 'payplug'), $order_id));
        }

        $transaction_id = PayplugWoocommerceHelper::is_pre_30() ? get_post_meta($order_id, '_transaction_id', true) : $order->get_transaction_id();
        if (empty($transaction_id)) {
            PayplugGateway::log(sprintf('The order #%s does not have PayPlug transaction ID associated with it.', $order_id), 'error');

            return new \WP_Error('process_refund_error', __('No PayPlug transaction was found for this order. The refund could not be processed.', 'payplug'));
        }

        /**
         * PPRO gateways feature!
         */
        if (isset($this->enable_refund) && $this->enable_refund === false) {
            PayplugGateway::log(__('payplug_refund_disabled_error', 'payplug'), 'error');

            return new \WP_Error('process_refund_error', __('payplug_refund_disabled_error', 'payplug'));
        }

        $customer_id = PayplugWoocommerceHelper::is_pre_30() ? $order->customer_user : $order->get_customer_id();
        $data = [
            'metadata' => [
                'order_id' => $order_id,
                'customer_id' => ((int) $customer_id > 0) ? $customer_id : 'guest',
                'refund_from' => 'woocommerce',
            ],
        ];

        if (!is_null($amount)) {
            $data['amount'] = PayplugWoocommerceHelper::get_payplug_amount($amount);
        }

        if (!empty($reason)) {
            $data['metadata']['reason'] = $reason;
        }

        /**
         * Filter the refund data before it's used.
         *
         * @param array $data
         * @param int $order_id
         * @param string $transaction_id
         */
        $data = apply_filters('payplug_gateway_refund_data', $data, $order_id, $transaction_id);

        try {
            $refund = $this->payplug_api->refund_create($transaction_id, $data);

            if ($refund->object === 'error') {
                PayplugGateway::log(__('payplug_ppro_flag_error', 'payplug'), 'error');

                return new \WP_Error('process_refund_error', __('payplug_ppro_flag_error', 'payplug'));
            }

            /**
             * Fires once a refund has been created.
             *
             * @param int $order_id Order ID
             * @param RefundResource $refund Refund resource
             * @param string $transaction_id Transaction id
             */
            \do_action('payplug_gateway_refund_created', $order_id, $refund, $transaction_id);

            $refund_meta_key = sprintf('_pr_%s', wc_clean($refund->id));
            if (PayplugWoocommerceHelper::is_pre_30()) {
                update_post_meta($order_id, $refund_meta_key, $refund->id);
            } else {
                $order->add_meta_data($refund_meta_key, $refund->id, true);
                $order->save();
            }

            $note = sprintf(__('Refund %s : Refunded %s', 'payplug'), wc_clean($refund->id), wc_price(((int) $refund->amount) / 100));
            if (!empty($refund->metadata['reason'])) {
                $note .= sprintf(' (%s)', esc_html($refund->metadata['reason']));
            }
            $order->add_order_note($note);

            try {
                $payment = $this->payplug_api->payment_retrieve($transaction_id);
                $metadata = PayplugWoocommerceHelper::extract_transaction_metadata($payment);
                PayplugWoocommerceHelper::save_transaction_metadata($order, $metadata);
            } catch (\Exception $e) {
            }

            PayplugGateway::log('Refund process complete for the order.');

            return true;
        } catch (HttpException $e) {
            PayplugGateway::log(sprintf('Refund request error for the order %s from PayPlug API : %s', $order_id, wc_print_r($e->getErrorObject(), true)), 'error');

            return new \WP_Error('process_refund_error', __('The transaction could not be refunded. Please try again.', 'payplug'));
        } catch (\Exception $e) {
            PayplugGateway::log(sprintf('Refund request error for the order %s : %s', $order_id, wc_clean($e->getMessage())), 'error');

            return new \WP_Error('process_refund_error', __('The transaction could not be refunded. Please try again.', 'payplug'));
        }
    }

    /**
     * Avoid usage of button refund on the BO
     *
     * @param int $item_id
     * @param \WC_Order_Item|null $item
     * @param mixed $product
     *
     * @return false|void
     */
    public function hide_wc_refund_button($item_id, $item = null, $product = null)
    {
        if (!$item instanceof \WC_Order_Item) {
            return false;
        }

        $order = $item->get_order();
        if (!$order instanceof \WC_Order) {
            return false;
        }

        if ($order->get_payment_method() === $this->id && isset($this->enable_refund) && $this->enable_refund === false) {
            ?>
			<script>
				jQuery(function () {
					jQuery('.refund-items').attr("disabled", true);
				});
			</script>
			<?php
        }
    }

    /**
     * refund not possible for PPRO payments
     *
     * @return void
     */
    public function refund_not_available($order): void
    {
        if ($this->id === $order->get_payment_method() && isset($this->enable_refund) && $this->enable_refund === false) {
            echo "<p style='color: red;'>" . __('payplug_refund_disabled_error', 'payplug') . '</p>';
        }
    }

    /**
     * Empty the cart and add all order_items
     *
     * @param $cart
     * @param $items
     *
     * @return void
     */
    private function order_items_to_cart($cart, $items): void
    {
        $cart->empty_cart();
        foreach ($items as $item) {
            $cart->add_to_cart($item->get_product_id(), $item->get_quantity(), $item->get_variation_id());
        }
    }
}

```
