File: /www/wwwroot/soqatland.com/wp-content/plugins/persian-woocommerce/include/class-gateways.php
<?php
use Automattic\WooCommerce\Internal\DataStores\Orders\OrdersTableDataStore;
use Automattic\WooCommerce\Utilities\OrderUtil;
defined( 'ABSPATH' ) || exit;
if ( ! class_exists( 'WC_Payment_Gateway' ) ) {
return;
}
include 'gateways/class-zibal.php';
include 'gateways/class-zibal-block.php';
if ( class_exists( 'Persian_Woocommerce_Gateways' ) ) {
return;
}
abstract class Persian_Woocommerce_Gateways extends WC_Payment_Gateway {
protected $order_id = 0;
private $verification_params;
const PREFIX = 'Woocommerce_Ir_Gateway_';
public static function register( $gateway ) {
add_filter( 'woocommerce_payment_gateways', function ( $methods ) use ( $gateway ) {
$methods[] = self::PREFIX . $gateway;
return $methods;
} );
}
protected function init( $gateway ) {
$Gateway_Class = get_class( $gateway );
if ( stripos( $Gateway_Class, self::PREFIX ) === false ) {
return false;
}
$gateway_class = strtolower( $Gateway_Class );
$gateway->id = str_ireplace( self::PREFIX, '', $gateway_class );
if ( method_exists( $gateway, 'init_form_fields' ) ) {
$gateway->init_form_fields();
} else {
$this->init_form_fields();
}
if ( method_exists( $gateway, 'init_settings' ) ) {
$gateway->init_settings();
} else {
$this->init_settings();
}
$gateway->has_fields = false;
$gateway->title = $gateway->settings['title'] ?: $gateway->method_title;
$gateway->description = $gateway->settings['description'];
$gateway->method_description = $gateway->method_description ?: sprintf( 'تنظیمات درگاه پرداخت %s برای افزونه فروشگاه ساز ووکامرس', $gateway->method_title );
if ( empty( $gateway->icon ) && class_exists( 'ReflectionClass' ) ) {
try {
$file = ( new ReflectionClass( $Gateway_Class ) )->getFileName();
$gateway->icon = trailingslashit( WP_PLUGIN_URL ) . plugin_basename( dirname( $file ) ) . '/assets/images/logo.png';
} catch ( Exception $e ) {
}
}
add_action( 'woocommerce_update_options_payment_gateways_' . $gateway->id,
[ $gateway, 'process_admin_options' ] );
add_action( 'woocommerce_receipt_' . $gateway->id,
[ $gateway, 'process_payment_request' ] );
add_action( 'woocommerce_api_' . $gateway_class,
[ $gateway, 'process_payment_verify' ] );
}
public function init_form_fields() {
$main = [
'enabled' => [
'title' => 'فعالسازی',
'type' => 'checkbox',
'label' => 'فعالسازی درگاه',
'description' => 'برای فعالسازی این درگاه پرداخت باید چک باکس را تیک بزنید',
'default' => 'yes',
'desc_tip' => true,
],
'title' => [
'title' => 'عنوان درگاه',
'type' => 'text',
'description' => 'عنوان این درگاه که در طی خرید به مشتری نمایش داده میشود',
'default' => $this->method_title,
'desc_tip' => true,
],
'description' => [
'title' => 'توضیحات درگاه',
'type' => 'text',
'desc_tip' => true,
'description' => 'توضیحاتی که در طی عملیات پرداخت برای این درگاه نمایش داده خواهد شد',
'default' => sprintf( 'پرداخت امن به وسیله کلیه کارت های عضو شتاب از طریق درگاه %s', $this->method_title ),
],
'direct_redirect' => [
'title' => 'هدایت مستقیم به درگاه',
'type' => 'checkbox',
'label' => 'در صورتی که قصد دارید کاربر مستقیما به درگاه هدایت شود و در صفحه پیشفاکتور گزینه پرداخت را کلیک نکند، این گزینه را فعال نمایید.',
'description' => 'به صورت پیشفرض (غیرفعال بودن این گزینه) خریدار قبل از هدایت به درگاه ابتدا شماره سفارش و قیمت نهایی را مشاهده میکند و سپس با زدن دکمه تایید به درگاه هدایت میشود.',
'default' => 'no',
'desc_tip' => true,
],
];
$fields = $this->fields();
$shortcodes = [];
foreach ( $this->fields_shortcodes() as $shortcode => $title ) {
$shortcode = '{' . trim( $shortcode, '\{\}' ) . '}';
$shortcodes[] = "$shortcode:$title";
}
$shortcodes = '<br>' . implode( ' - ', $shortcodes );
unset( $fields['shortcodes'] );
$messages = [
'completed_massage' => [
'title' => 'پیام پرداخت موفق',
'type' => 'textarea',
'description' => 'متن پیامی که میخواهید بعد از پرداخت موفق به کاربر نمایش دهید را وارد نمایید. همچنین می توانید از شورت کدهای زیر نیز استفاده نمایید.' . $shortcodes,
'default' => 'با تشکر از شما. سفارش شما با موفقیت پرداخت شد.',
],
'failed_massage' => [
'title' => 'پیام پرداخت ناموفق',
'type' => 'textarea',
'description' => 'متن پیامی که میخواهید بعد از پرداخت ناموفق به کاربر نمایش دهید را وارد نمایید. همچنین می توانید از شورت کد {fault} برای نمایش دلیل خطای رخ داده استفاده نمایید. این دلیل خطا از سایت درگاه ارسال میگردد.',
'default' => 'پرداخت شما ناموفق بوده است. لطفا مجددا تلاش نمایید یا در صورت بروز اشکال با مدیر سایت تماس بگیرید.',
],
'cancelled_massage' => [
'title' => 'پیام انصراف از پرداخت',
'type' => 'textarea',
'description' => 'متن پیامی که میخواهید بعد از انصراف کاربر از پرداخت نمایش دهید را وارد نمایید. این پیام بعد از بازگشت از بانک نمایش داده خواهد شد.',
'default' => 'پرداخت به دلیل انصراف شما ناتمام باقی ماند.',
],
];
$this->form_fields = array_merge( $main, $fields, $messages );
foreach ( array_merge( $main, $messages ) as $key => $value ) {
if ( isset( $fields[ $key ] ) ) {
$this->form_fields[ $key ] = $fields[ $key ];
}
}
$this->form_fields = array_filter( $this->form_fields );
}
public function process_payment( $order ) {
$order = $this->get_order( $order );
return [
'result' => 'success',
'redirect' => $order->get_checkout_payment_url( true ),
];
}
public function process_payment_request( $order_id ) {
$this->order_id = $order_id;
$this->session( 'set', 'order_id', $order_id );
$order = $this->get_order( $order_id );
$form = $this->option( 'direct_redirect' ) != '1';
if ( $form ) {
?>
<form action="" method="POST" class="pw-gateway-checkout-form"
id="pw-gateway-checkout-form-<?php echo esc_attr( $this->id ); ?>">
<input type="submit" name="pw-gateway-submit" class="pw-gateway-submit button alt" value="پرداخت"/>
<a class="pw-gateway-cancel button cancel"
href="<?php echo esc_url( $this->get_checkout_url() ); ?>">بازگشت</a>
</form><br/>
<?php
}
if ( ! $form || isset( $_POST['pw-gateway-submit'] ) ) {
$error = $this->request( $order );
$this->set_message( 'failed', $error, true, false );
$order->add_order_note( sprintf( 'در هنگام اتصال به درگاه %s خطای زیر رخ داده است.', $this->title ) . "<br>{$error}" );
}
}
public function process_payment_verify() {
$redirect = $this->get_checkout_url();
$order_id = ! empty( $_GET['wc_order'] ) ? intval( $_GET['wc_order'] ) : $this->session( 'get', 'order_id' );
if ( empty( $order_id ) ) {
$this->set_message( 'failed', 'شماره سفارش وجود ندارد.', true, $redirect );
}
$order = $this->get_order( $order_id );
if ( ! $this->needs_payment( $order ) ) {
$this->set_message( 'failed', 'وضعیت تراکنش قبلا مشخص شده است.', true, $redirect, true );
}
$this->order_id = $order_id;
$result = $this->verify( $order );
if ( ! is_array( $result ) ) {
$error = is_string( $result ) && strlen( $result ) > 5 ? $result : 'اطلاعات صحت سنجی تراکنش صحیح نیست.';
$this->set_message( 'failed', $error, true, $redirect, true );
}
$error = '';
$status = ! empty( $result['status'] ) ? $result['status'] : '';
$transaction_id = ! empty( $result['transaction_id'] ) ? $result['transaction_id'] : '';
if ( $status == 'completed' ) {
$redirect = $this->get_return_url( $order );
$order->payment_complete( $transaction_id );
$this->empty_cart();
$this->set_verification();
$shortcodes = $this->get_shortcodes_values();
$note = [ 'تراکنش موفق بود.' ];
foreach ( $this->fields_shortcodes() as $key => $value ) {
$key = trim( $key, '\{\}' );
$note[] = "$value : {$shortcodes[$key]}";
}
$order->add_order_note( implode( "<br>", $note ), 1 );
} elseif ( $status == 'cancelled' ) {
$order->add_order_note( 'تراکنش به بعلت انصراف کاربر ناتمام باقی ماند.', 1 );
} else {
$error = ! empty( $result['error'] ) ? $result['error'] : 'در حین پرداخت خطایی رخ داده است.';
$order->add_order_note( sprintf( 'در هنگام بازگشت از درگاه %s خطای زیر رخ داده است.', $this->title ) . "<br>{$error}", 1 );
}
$this->set_message( $status, $error, true, $redirect );
exit;
}
/*
* ---------------------------------------------------
* */
protected function order_id( $order ) {
if ( is_numeric( $order ) ) {
$order_id = $order;
} elseif ( method_exists( $order, 'get_id' ) ) {
$order_id = $order->get_id();
} elseif ( ! ( $order_id = absint( get_query_var( 'order-pay' ) ) ) ) {
$order_id = $order->id;
}
if ( ! empty( $order_id ) ) {
$this->order_id = $order_id;
}
return $order_id;
}
protected function get_order( $order = 0 ) {
if ( empty( $order ) ) {
$order = $this->order_id;
}
if ( empty( $order ) ) {
return (object) [];
}
if ( is_numeric( $order ) ) {
$this->order_id = $order;
$order = wc_get_order( $order );
}
return $order;
}
protected function get_order_props( $prop, $default = '' ) {
if ( empty( $this->order_id ) ) {
return '';
}
$order = $this->get_order();
$method = 'get_' . $prop;
if ( method_exists( $order, $method ) ) {
$prop = $order->$method();
} elseif ( ! empty( $order->{$prop} ) ) {
$prop = $order->{$prop};
} else {
$prop = '';
}
return ! empty( $prop ) ? $prop : $default;
}
protected function get_order_items( $product = false ) {
if ( empty( $this->order_id ) ) {
return [];
}
$order = $this->get_order();
$items = $order->get_items();
if ( $product ) {
$products = [];
foreach ( (array) $items as $item ) {
$products[] = $item['name'] . ' (' . $item['qty'] . ') ';
}
return implode( ' - ', $products );
}
return $items;
}
protected function get_order_mobile() {
$Mobile = $this->get_order_props( 'billing_phone' );
$Mobile = $this->get_order_props( 'billing_mobile', $Mobile );
$Mobile = str_ireplace( [ '۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹' ],
[ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' ], $Mobile ); //farsi
$Mobile = str_ireplace( [ '٠', '١', '٢', '٣', '٤', '٥', '٦', '٧', '٨', '٩' ],
[ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' ], $Mobile ); //arabi
$Mobile = preg_replace( '/\D/is', '', $Mobile );
$Mobile = ltrim( $Mobile, '0' );
$Mobile = substr( $Mobile, 0, 2 ) == '98' ? substr( $Mobile, 2 ) : $Mobile;
return '0' . $Mobile;
}
protected function get_currency() {
if ( empty( $this->order_id ) ) {
return '';
}
$order = $this->get_order();
$currency = method_exists( $order, 'get_currency' ) ? $order->get_currency() : $order->get_order_currency();
$irt = [ 'irt', 'toman', 'tomaan', 'iran toman', 'iranian toman', 'تومان', 'تومان ایران' ];
if ( in_array( strtolower( $currency ), $irt ) ) {
$currency = 'IRT';
}
$irr = [ 'irr', 'rial', 'iran rial', 'iranian rial', 'ریال', 'ریال ایران' ];
if ( in_array( strtolower( $currency ), $irr ) ) {
$currency = 'IRR';
}
return $currency;
}
protected function get_total( $to_currency = 'IRR' ) {
if ( empty( $this->order_id ) ) {
return 0;
}
$order = $this->get_order();
if ( method_exists( $order, 'get_total' ) ) {
$price = $order->get_total();
} else {
$price = intval( $order->order_total );
}
$currency = strtoupper( $this->get_currency() );
$to_currency = strtoupper( $to_currency );
if ( in_array( $currency, [ 'IRHR', 'IRHT' ] ) ) {
$currency = str_ireplace( 'H', '', $currency );
$price *= 1000;
}
if ( $currency == 'IRR' && $to_currency == 'IRT' ) {
$price /= 10;
}
if ( $currency == 'IRT' && $to_currency == 'IRR' ) {
$price *= 10;
}
return $price;
}
protected function needs_payment( $order = 0 ) {
if ( empty( $order ) && empty( $this->order_id ) ) {
return true;
}
$order = $this->get_order( $order );
if ( method_exists( $order, 'needs_payment' ) ) {
return $order->needs_payment();
}
if ( empty( $this->order_id ) && ! empty( $order ) ) {
$this->order_id = $this->order_id( $order );
}
return ! in_array( $this->get_order_props( 'status' ), [ 'completed', 'processing' ] );
}
protected function get_verify_url() {
return add_query_arg( 'wc_order', $this->order_id, WC()->api_request_url( get_class( $this ) ) );
}
protected function get_checkout_url() {
if ( function_exists( 'wc_get_checkout_url' ) ) {
return wc_get_checkout_url();
} else {
global $woocommerce;
return $woocommerce->cart->get_checkout_url();
}
}
protected function empty_cart() {
if ( function_exists( 'wc_empty_cart' ) ) {
wc_empty_cart();
} elseif ( function_exists( 'WC' ) && ! empty( WC()->cart ) && method_exists( WC()->cart, 'empty_cart' ) ) {
WC()->cart->empty_cart();
} else {
global $woocommerce;
$woocommerce->cart->empty_cart();
}
}
protected function fields_shortcodes( $fields = [] ) {
$fields = ! empty( $fields ) ? $fields : $this->fields();
return ! empty( $fields['shortcodes'] ) && is_array( $fields['shortcodes'] ) ? $fields['shortcodes'] : [];
}
protected function get_shortcodes_values(): array {
$shortcodes = [];
$order = $this->get_order();
foreach ( $this->fields_shortcodes() as $key => $value ) {
$clean_key = trim( $key, '\{\}' );
$getter = 'get_' . $clean_key;
if ( is_callable( [ $order, $getter ] ) ) {
$shortcodes[ $clean_key ] = $order->$getter();
} else {
$shortcodes[ $clean_key ] = $order->get_meta( '_' . $clean_key );
}
}
return $shortcodes;
}
protected function set_shortcodes( $shortcodes ) {
$fields_shortcodes = $this->fields_shortcodes();
$order = $this->get_order();
foreach ( $shortcodes as $key => $value ) {
if ( is_numeric( $key ) ) {
$key = $fields_shortcodes[ $key ];
}
if ( ! empty( $key ) && ! is_array( $key ) ) {
$key = trim( $key, '\{\}' );
$order->update_meta_data( '_' . $key, $value );
}
}
$order->save_meta_data();
}
protected function set_message( $status, $error = '', $notice = true, $redirect = false, $failed_note = false ) {
if ( ! in_array( $status, [ 'completed', 'cancelled', 'failed' ] ) ) {
$status = 'failed';
}
if ( ! empty( $error ) && $failed_note && ( $order = $this->get_order() ) && ! empty( $order ) ) {
$order->add_order_note( 'خطا: ' . $error, 1 );
}
$shortcodes = array_merge( $this->get_shortcodes_values(), [ '{fault}' => $error ] );
$message = $this->option( $status . '_massage' );
$find = array_map( function ( $value ) {
return '{' . trim( $value, '\{\}' ) . '}';
}, array_keys( $shortcodes ) );
$message = str_ireplace( $find, array_values( $shortcodes ), $message );
$message = wpautop( wptexturize( trim( $message ) ) );
if ( $notice ) {
wc_add_notice( $message, $status == 'completed' ? 'success' : 'error' );
}
if ( $redirect ) {
wp_redirect( $redirect );
exit;
}
return $message;
}
protected function check_verification( $params ) {
if ( function_exists( 'func_get_args' ) ) {
$args = func_get_args();
if ( count( $args ) > 1 ) {
$params = array_merge( array_values( $args ), $params );
$params = implode( '_', array_unique( $params ) );
}
}
if ( is_array( $params ) ) {
$params = implode( '_', $params );
}
$params = $this->id . '_' . $params;
global $wpdb;
if ( OrderUtil::custom_orders_table_usage_is_enabled() ) {
$table = esc_sql( OrdersTableDataStore::get_meta_table_name() );
$query = "SELECT * FROM {$table} WHERE meta_key='_verification_params' AND meta_value='%s'";
$check = $wpdb->get_row( $wpdb->prepare( $query, $params ) );
if ( ! empty( $check ) ) {
return $this->set_message( 'failed', 'این تراکنش قبلا یکبار وریفای شده بود.', true, $this->get_checkout_url(), true );
}
} else {
$table = esc_sql( $wpdb->postmeta );
$query = "SELECT * FROM {$table} WHERE meta_key='_verification_params' AND meta_value='%s'";
$check = $wpdb->get_row( $wpdb->prepare( $query, $params ) );
if ( ! empty( $check ) ) {
return $this->set_message( 'failed', 'این تراکنش قبلا یکبار وریفای شده بود.', true, $this->get_checkout_url(), true );
}
}
$this->verification_params = $params;
}
protected function set_verification() {
if ( ! empty( $this->verification_params ) ) {
$order = $this->get_order();
$order->update_meta_data( '_verification_params', $this->verification_params );
$order->save_meta_data();
}
}
/*
* Helpers
* */
protected function option( $name ) {
$option = '';
if ( method_exists( $this, 'get_option' ) ) {
$option = $this->get_option( $name );
} elseif ( ! empty( $this->settings[ $name ] ) ) {
$option = $this->settings[ $name ];
}
if ( in_array( strtolower( $option ), [ 'yes', 'on', 'true' ] ) ) {
$option = '1';
}
if ( in_array( strtolower( $option ), [ 'no', 'off', 'false' ] ) ) {
$option = false;
}
return $option;
}
protected function get( $name, $default = '' ) {
return ! empty( $_GET[ $name ] ) ? sanitize_text_field( $_GET[ $name ] ) : $default;
}
protected function post( $name, $default = '' ) {
return ! empty( $_POST[ $name ] ) ? sanitize_text_field( $_POST[ $name ] ) : $default;
}
protected function store_date( $key, $value ) {
$this->session( 'set', $key, $value );
$order = $this->get_order();
$order->update_meta_data( '_' . $this->id . '_' . $key, $value );
$order->save_meta_data();
}
protected function get_stored( $key ) {
$order = $this->get_order();
$value = $order->get_meta( '_' . $this->id . '_' . $key );
return ! empty( $value ) ? $value : $this->session( 'get', $key );
}
protected function session( $action, $name, $value = '' ) {
global $woocommerce;
$name = $this->id . '_' . $name;
$wc_session = function_exists( 'WC' ) && ! empty( WC()->session );
if ( $action == 'set' ) {
if ( $wc_session && method_exists( WC()->session, 'set' ) ) {
WC()->session->set( $name, $value );
} else {
$woocommerce->session->{$name} = $value;
}
} elseif ( $action == 'get' ) {
if ( $wc_session && method_exists( WC()->session, 'get' ) ) {
$value = WC()->session->get( $name );
unset( WC()->session->{$name} );
} else {
$value = $woocommerce->session->{$name};
unset( $woocommerce->session->{$name} );
}
return $value;
}
return '';
}
protected function redirect( $url ) {
if ( ! headers_sent() ) {
header( 'Location: ' . trim( $url ) );
} else {
?>
<script type='text/javascript'>
window.onload = function () {
top.location.href = '<?php echo esc_url( $url ); ?>';
};
</script>
<?php
}
exit;
}
protected function submit_form( $form ) {
$name = 'pw_gateway_name_' . $this->id;
$form = explode( '>', $form );
$form[0] = preg_replace( '/name=[\'\"].*?[\'\"]/i', '', $form[0] );
$form = implode( '>', $form );
$form = str_ireplace( "<form", "<form name=\"{$name}\"", $form );
echo 'در حال هدایت به درگاه ....';
if ( headers_sent() ) {
?>
<script type="text/javascript">
function PWformSubmit() {
document
.<?php echo esc_attr( $name ); ?>.
submit();
}
PWformSubmit();
document
.<?php echo esc_attr( $name ); ?>.
submit();
</script>
<?php
echo wp_kses( $form, [
'form' => [ 'id' => [], 'name' => [], 'class' => [], 'method' => [], 'action' => [] ],
'input' => [ 'id' => [], 'name' => [], 'class' => [], 'type' => [], 'value' => [] ],
] );
} else {
echo wp_kses( $form, [
'form' => [ 'id' => [], 'name' => [], 'class' => [], 'method' => [], 'action' => [] ],
'input' => [ 'id' => [], 'name' => [], 'class' => [], 'type' => [], 'value' => [] ],
] );
?>
<script type="text/javascript">
document
.<?php echo esc_attr( $name ); ?>.
submit();
</script>
<?php
}
die();
}
protected function nusoap() {
}
/*
* Abstract methods and must be override
* */
abstract protected function fields();
abstract protected function request( $order );
abstract protected function verify( $order );
}