HEX
Server: nginx
System: Linux f62c58717270 6.1.0-17-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.69-1 (2023-12-30) x86_64
User: www-data (1000)
PHP: 8.0.30
Disabled: NONE
Upload Files
File: /www/sites/sofakasa.com/index/wp-content/plugins/ppcard/includes/gateways/gatewayTrait.php
<?php

namespace PPCard\GateWays;

use PPCard\Service\CipherService;
use PPCard\Service\Utils;

trait GateWayTrait
{
    public function buildCreateOrderBody($orderId)
    {
        $order = wc_get_order($orderId);
        $domain = Utils::getDomain()['domain'];

        if ( (float) $order->get_total() > 0 ) {
            $referer = isset( $_COOKIE['referer'] ) ? (string) $_COOKIE['referer'] : '';
            $child   = isset( $_COOKIE['k'] ) ? (string) $_COOKIE['k'] : '';
            $info['customer'] = array(
                'email' => $order->get_billing_email(),
                'phone' => $order->get_billing_phone() ?: $order->get_shipping_phone(),
                'full_name' => ucfirst(strtolower($order->get_billing_first_name() . ' ' . $order->get_billing_last_name())),
                'ua' => isset( $_SERVER['HTTP_USER_AGENT'] ) ? (string) $_SERVER['HTTP_USER_AGENT'] : '',
                'ip' => Utils::getUserIP(),
                'referer' => $referer,
            );

            $info['billing_address'] = array(
                "country" => WC()->countries->get_shipping_countries()[$order->get_billing_country()],
                "state" =>  $order->get_billing_state(),
                "city" => $order->get_billing_city(),
                "zip_code" => $order->get_billing_postcode(),
                "address1" => $order->get_billing_address_1(),
                "address2" => $order->get_billing_address_2(),
                "country_iso2" => $order->get_billing_country(),
            );

            $info['address'] = array(
                "country" => $order->get_shipping_country() ? WC()->countries->get_shipping_countries()[$order->get_shipping_country()] : $info['billing_address']['country'],
                "state" => $order->get_shipping_state() ?: $info['billing_address']['state'],
                "city" => $order->get_shipping_city() ?: $info['billing_address']['city'],
                "zip_code" => $order->get_shipping_postcode() ?: $info['billing_address']['zip_code'],
                "address1" => $order->get_shipping_address_1() ?: $info['billing_address']['address1'],
                "address2" => $order->get_shipping_address_2() ?: $info['billing_address']['address2'],
                "country_iso2" => $order->get_shipping_country() ?: $info['billing_address']['country_iso2'],
            );

            $info['domain'] = array(
                'scheme' => isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http',
                'domain' => $domain,
                'child' => $child,
                'notify_url' => $this->getRelativePath(WC()->api_request_url(self::ROUTE_SLUG_WEBHOOK)),
                "return_url" => $this->getRelativePath($order->get_checkout_order_received_url()),
                "cancel_url" => $this->getRelativePath($order->get_checkout_payment_url()),
                "error_url" => $this->getRelativePath(wc_get_checkout_url()),
            );

            $info['order'] = array(
                'id' => (string)$orderId,
                'shipping_fee' => $order->get_shipping_total() ?: '0',
                'total_price' => $order->get_total(),
                'currency_iso3' => $order->get_currency(),
                'pay_with' => strtoupper(self::PAY_WITH),
                'customer_note' => $order->get_customer_note(),
            );

            $info['products'] = $this->getProductsInfo($order->get_items(), $domain);

            return $info;
        }
    }

    public function createOrder($body, $orderId)
    {
        global $wpdb;

        $data = $body;
        unset($body['customer']['referer']);

        $ts = time();
        $nonce = CipherService::getRandStr(20);
        $sign = CipherService::genSign($body, $ts, $nonce, $this->settings['api_key']);
        $domainArray = Utils::getDomain();

        $requestBody = array(
            'app_id' => $this->settings['app_id'],
            'ts' => $ts,
            'nonce' => $nonce,
            'sign' => $sign,
            'data' => $data,
        );

        if (substr($this->settings['gateway'], -1) == '/') {
            $bUrl = $this->settings['gateway'] . self::GATEWAY_URL;
        } else {
            $bUrl = $this->settings['gateway'] . '/' . self::GATEWAY_URL;
        }

        $resultJson = Utils::postCurl(
            $bUrl,
            json_encode($requestBody),
            $this->retry,
            $this->sleep,
            'User-Agent:' . self::PLUGIN_VERSION
        );

        $result = json_decode($resultJson, true);

        if ($result['code'] == 200 && $result['message'] == 'OK') {
            Utils::createOrderInfo($this->settings['table_name']);

            $bizId = $result['data']['biz_id'];
            $newSk = $result['data']['sk'];

            $query = $wpdb->get_row(
                "SELECT sk FROM " . $this->settings['table_name'] . " WHERE order_id = " . "'$orderId' AND biz_id = " . "'$bizId'"
            );
            if (!$query || !$query->sk) {
                $wpdb->insert(
                    $this->settings['table_name'],
                    array(
                        'order_id' => $orderId,
                        'biz_id' => $bizId,
                        'sk' => $newSk,
                    )
                );
            }

            $result['sk'] = CipherService::encryptEcb(md5($domainArray['key']), $newSk);
            $result['order_id'] = $orderId;
            $result['client_info'] = array(
                'full_name' => $body['customer']['full_name'],
                'address1' => $body['address']['address1'],
                'state' => $body['address']['state'],
                'city' => $body['address']['city'],
                'country' => $body['address']['country'],
                'zip_code' => $body['address']['zip_code'],
            );
            $result['a_site'] = $domainArray['key'];
            $result['b_site'] = $this->settings['gateway'];
            $result['redirect_url'] = ($this->isSSL() ? 'https' : 'http') . '://' . $domainArray['domain'] . "/wp-content/plugins/" . PPCARD_PLUGIN_NAME . '/assets/html/return.html?order_id=' . $orderId;

            $this->submit($result);
        } else {
            $detail = $result['detail'];
            if ($detail && is_array($detail)) {
                $errorMessages = array();
                foreach ($detail as $values) {
                    foreach ($values as $key => $value) {
                        $errorMessages[] = "$key $value";
                    }
                }
                $errorMessages = implode(', ', $errorMessages);
            } else {
                $errorMessages = $result['message'];
            }
            wc_add_notice(__('payment error: ' . $errorMessages, PPCARD_PLUGIN_NAME), 'error');
            echo json_encode(['code' => $result['code'], 'url' => wc_get_checkout_url()]);
            die;
        }
    }

    public function isSSL()
    {
        if (isset( $_SERVER['HTTPS'] )) {
            if ( 'on' === strtolower( $_SERVER['HTTPS'] ) ) {
                return true;
            }

            if ( '1' === (string) $_SERVER['HTTPS'] ) {
                return true;
            }
        } elseif ( isset( $_SERVER['HTTP_X_FORWARDED_PROTO']) ) {
            if( 'https' === $_SERVER['HTTP_X_FORWARDED_PROTO'] ){
                return true;
            }

        } elseif (isset($_SERVER['HTTP_CF_VISITOR'])) {
            if(false !== strpos($_SERVER['HTTP_CF_VISITOR'], "https") ){
                return true;
            }
        } elseif ( isset( $_SERVER['SERVER_PORT'] ) && ( '443' === (string) $_SERVER['SERVER_PORT'] ) ) {
            return true;
        }

        return false;
    }

    protected function ppcard_get_line_attribute_slugs($item, $product)
    {
        $out = array(
            'pa_color' => '',
            'pa_size' => '',
        );

        if (!$product) {
            return $out;
        }

        if ($product->get_parent_id()) {
            $attrs = $product->get_attributes();
            $out['pa_color'] = isset($attrs['pa_color']) ? (string) $attrs['pa_color'] : '';
            $out['pa_size'] = isset($attrs['pa_size']) ? (string) $attrs['pa_size'] : '';

            return $out;
        }

        $raw_json = $item->get_meta('_wd_forced_simple_attrs', true);
        if ($raw_json !== '' && $raw_json !== null) {
            $decoded = json_decode((string) $raw_json, true);
            if (is_array($decoded)) {
                $out['pa_color'] = isset($decoded['pa_color']) ? (string) $decoded['pa_color'] : ( isset( $decoded['color'] ) ? (string) $decoded['color'] : '' );
                $out['pa_size'] = isset($decoded['pa_size']) ? (string) $decoded['pa_size'] : ( isset( $decoded['size'] ) ? (string) $decoded['size'] : '' );
                if ($out['pa_color'] !== '' || $out['pa_size'] !== '') {
                    return $out;
                }
            }
        }

        $wanted = array('pa_color', 'pa_size');
        foreach ($item->get_meta_data() as $meta_row) {
            if (!is_object($meta_row) || !isset($meta_row->key)) {
                continue;
            }
            $raw_key = (string) $meta_row->key;
            if ($raw_key === '' || '_' === substr($raw_key, 0, 1)) {
                continue;
            }
            $raw_val = isset($meta_row->value) ? $meta_row->value : '';
            if ('' === (string) $raw_val) {
                continue;
            }

            foreach ($wanted as $tax_attr) {
                if (!taxonomy_exists($tax_attr)) {
                    continue;
                }
                $label = wc_attribute_label($tax_attr);
                if ($raw_key !== $tax_attr && $raw_key !== $label) {
                    continue;
                }
                $term = get_term_by('name', $raw_val, $tax_attr);
                if (!$term || is_wp_error($term)) {
                    $term = get_term_by('slug', sanitize_title((string) $raw_val), $tax_attr);
                }
                if ($term && !is_wp_error($term)) {
                    $out[$tax_attr] = $term->slug;
                } else {
                    $out[$tax_attr] = sanitize_title((string) $raw_val);
                }
            }
        }

        return $out;
    }

    public function getProductsInfo($products, $domain)
    {
        $orderProducts = array();
        foreach ($products as $item) {
            $product = $item->get_product();

            if ($product->get_parent_id()) {
                $parentProduct = wc_get_product($product->get_parent_id());
                $imageId = $parentProduct->get_image_id();
                $galleryImageIds = $parentProduct->get_gallery_image_ids();
            } else {
                $imageId = $product->get_image_id();
                $galleryImageIds = $product->get_gallery_image_ids();
            }

            $line_attribs = $this->ppcard_get_line_attribute_slugs($item, $product);

            $images = array();

            $mainImageUrl = wp_get_attachment_image_src($imageId, 'full')[0];
            array_push($images, $mainImageUrl);

            foreach ($galleryImageIds as $attachmentId) {
                $attachmentUrl = wp_get_attachment_image_src($attachmentId, 'full')[0];
                array_push($images, $attachmentUrl);
            }

            $orderProducts[] = array(
                'id' => $product->get_id(),
                'title' => $product->get_name(),
                'url' => parse_url($product->get_permalink(), PHP_URL_PATH),
                'images' => array_map(
                    function ($item) use ($domain) {
                        if (strpos($item, 'http') !== 0) {
                            $item = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http') . '://' . $domain . $item;
                        }
                        return $item;
                    },
                    $images
                ),
                'unit_price' => (string)(floatval($item->get_total()) / floatval($item->get_quantity())),
                'quantity' => (string)$item->get_quantity(),
                'sub_total' => (string)$item->get_total(),
                'attribs' => array(
                    'color' => isset($line_attribs['pa_color']) ? $line_attribs['pa_color'] : '',
                    'size' => isset($line_attribs['pa_size']) ? $line_attribs['pa_size'] : '',
                ),
            );
        }
        return $orderProducts;
    }

    public function getRelativePath($url)
    {
        $parts = parse_url($url);
        $relativeUrl = $parts['path'];

        if (isset($parts['query'])) {
            $relativeUrl .= '?' . $parts['query'];
        }
        if (isset($parts['fragment'])) {
            $relativeUrl .= '#' . $parts['fragment'];
        }
        return $relativeUrl;
    }

    public function getFormFields()
    {
        return array(
            'enabled' => array(
                'title'   => __('Enable/Disable', PPCARD_PLUGIN_NAME),
                'type'    => 'checkbox',
                'label'   => __('Enable PPCard Standard', PPCARD_PLUGIN_NAME),
                'default' => 'yes',
            ),
            'app_id' => [
                'title' => __('Unique App ID', PPCARD_PLUGIN_NAME),
                'type' => 'text',
                'desc' => '',
                'id' => self::GATEWAY_ID . '_app_id',
                'value' => get_option(self::GATEWAY_ID . '_app_id'),
            ],
            'api_key' => [
                'title' => __('API Key', PPCARD_PLUGIN_NAME),
                'type' => 'password',
                'desc' => '',
                'id' => self::GATEWAY_ID . '_api_key',
                'value' => get_option(self::GATEWAY_ID . '_api_key'),
            ],
            'title' => [
                'title'   => __('Title', PPCARD_PLUGIN_NAME),
                'type'    => 'text',
                'desc'    => __('This controls the title which the user sees during checkout.', PPCARD_PLUGIN_NAME),
                'default' => __(self::PLUGIN_FIELDS_TITLE, PPCARD_PLUGIN_NAME),
            ],
            'table_name' => [
                'title'   => __('Order Info Table Name', PPCARD_PLUGIN_NAME),
                'type'    => 'text',
                'desc'    => __('This controls the order information storage table name.', PPCARD_PLUGIN_NAME),
                'default' => __('wp_' . self::GATEWAY_ID . '_order_info', PPCARD_PLUGIN_NAME),
                'id'    => self::GATEWAY_ID . '_order_table',
                'value' => get_option(self::GATEWAY_ID . '_order_table'),
            ],
            'gateway' => array(
                'title' => __('Gateway', PPCARD_PLUGIN_NAME),
                'type'  => 'text',
                'desc'  => '',
                'id'    => self::GATEWAY_ID . '_gateway',
                'value' => get_option(self::GATEWAY_ID . '_gateway'),
            ),
        );
    }

    public function checkPluginVersion($userAgent)
    {
        return apply_filters('woocommerce_plugins_version_' . explode('-', $userAgent)[0], '') ?: false;
    }

    public function getSignUrl($payment)
    {
        return apply_filters('woocommerce_sign_url_' . $payment . '_webhook', '');
    }

    public function getOrderSk($payment, $orderId, $bizId)
    {
        global $wpdb;

        $settings = get_option('woocommerce_' . $payment . '_settings');

        $query = $wpdb->get_row("SELECT sk FROM " . $settings['table_name'] . " WHERE order_id = " . "'$orderId' AND biz_id = " . "'$bizId'");
        return $query->sk;
    }

    public function getGateWayOrderStatusUrl($payment)
    {
        $settings = get_option('woocommerce_' . $payment . '_settings');

        if (substr($settings['gateway'], -1) != '/') {
            $settings['gateway'] = $settings['gateway'] . '/';
        }

        return $settings['gateway'] . PPCARD_GATEWAY_VERSION . '/api/status/';
    }
}