HEX
Server: LiteSpeed
System: Linux daria.pws-dns.net 5.14.0-503.35.1.el9_5.x86_64 #1 SMP PREEMPT_DYNAMIC Fri Apr 4 05:23:43 EDT 2025 x86_64
User: madaktos (1097)
PHP: 8.2.31
Disabled: NONE
Upload Files
File: /home/madaktos/public_html/wp-content/plugins/azkivam-wc-gateway/gateway.php
<?php

class WC_Azkivam extends WC_Payment_Gateway {
	private $failed_message;
	private $success_message;

	public function __construct() {
		$this->id = "WC_Azkivam";
		$this->method_title = "ازکی ‌وام";
		$this->method_description = "تنظیمات درگاه پرداخت ازکی ‌وام برای ووکامرس";
		$this->icon = WCAZKIVAM_URL."/assets/logo.svg";
		$this->has_fields = false;

		$this->init_form_fields();
		$this->init_settings();

		$this->title = $this->settings["title"];
		$this->description = $this->settings["description"];

		$this->success_message = $this->settings["successMessage"];
		$this->failed_message = $this->settings["failedMessage"];

		add_action("woocommerce_update_options_payment_gateways_".$this->id, array($this, "process_admin_options"));
		add_action("woocommerce_receipt_".$this->id."", array($this, "start_payment"));
		add_action("woocommerce_api_".strtolower(get_class($this))."", array($this, "verify_payment"));
	}

	public function init_form_fields() {
		$this->form_fields = array(
			"enabled"        => array(
				"title"       => "فعالسازی / غیرفعالسازی",
				"type"        => "checkbox",
				"label"       => "فعالسازی درگاه ازکی وام",
				"description" => "برای فعالسازی درگاه پرداخت ازکی وام باید چک باکس را تیک بزنید",
				"default"     => "yes",
				"desc_tip"    => true,
			),
			"title"          => array(
				"title"       => "عنوان درگاه",
				"type"        => "text",
				"description" => "عنوان درگاه که در طی خرید به مشتری نمایش داده میشود",
				"default"     => "ازکی وام",
				"desc_tip"    => true,
			),
			"description"    => array(
				"title"       => "توضیحات درگاه",
				"type"        => "text",
				"desc_tip"    => true,
				"description" => "توضیحاتی که در طی عملیات پرداخت برای درگاه نمایش داده خواهد شد",
				"default"     => "پرداخت اعتباری از طریق درگاه ازکی وام"
			),
			"merchantId"     => array(
				"title"       => "کد فروشگاه (MerchantID)",
				"type"        => "text",
				"description" => "کد فروشگاه نزد ازکی وام",
				"default"     => "",
				"desc_tip"    => true
			),
			"apiKey"         => array(
				"title"       => "کد امنیتی فروشگاه (APIKey)",
				"type"        => "text",
				"description" => "کد امنیتی فروشگاه برای ارتباط با درگاه ازکی وام",
				"default"     => "",
				"desc_tip"    => true
			),
			"paymentUri"     => array(
				"title"       => "آدرس API ازکی وام",
				"type"        => "text",
				"description" => "آدرس API ازکی وام",
				"default"     => "https://api.azkivam.com",
				"desc_tip"    => true
			),
			// "ticketItemCurrency" => array(
			// 	"title"       => "ارز آیتم های تیکت",
			// 	"type"        => "select",
			// 	"description" => "این مورد با هماهنگی پشتیبانی ازکی وام و بر اساس نوع ارز ووکامرس شما و همچنین تعریف مرچنت شما در ازکی وام انتخاب شود.",
			// 	"options"     => [
			// 		"irt" => "تومان",
			// 		"irr" => "ریال"
			// 	],
			// ),
			"successMessage" => array(
				"title"       => "پیام پرداخت موفق",
				"type"        => "textarea",
				"description" => "متن پیامی که میخواهید بعد از پرداخت موفق به کاربر نمایش دهید را وارد نمایید. همچنین می توانید از شورت کد {transaction_id} برای نمایش کد رهگیری (توکن) ازکی وام استفاده نمایید.",
				"default"     => "با تشکر از شما. سفارش شما با موفقیت پرداخت شد.",
			),
			"failedMessage"  => array(
				"title"       => "پیام پرداخت ناموفق",
				"type"        => "textarea",
				"description" => "متن پیامی که میخواهید بعد از پرداخت ناموفق به کاربر نمایش دهید را وارد نمایید. همچنین می توانید از شورت کد {fault} برای نمایش دلیل خطای رخ داده استفاده نمایید. این دلیل خطا از سایت ازکی وام ارسال میگردد.",
				"default"     => "پرداخت شما ناموفق بوده است. لطفا مجددا تلاش نمایید یا در صورت بروز اشکال با مدیر سایت تماس بگیرید.",
			),
		);
	}

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

		return array(
			"result"   => "success",
			"redirect" => $order->get_checkout_payment_url(true)
		);
	}

	public function start_payment($order_id) {
		global $woocommerce;
		$woocommerce->session->azkivam_order_id = $order_id;

		$order = new WC_Order($order_id);
		$currency = strtolower($order->get_currency());

		$form = '<form action="" method="POST" class="azkivam-checkout-form" id="azkivam-checkout-form">
						<input type="submit" name="azkivam_submit" class="button button-primary alt btn btn-primary" id="azkivam-payment-button" value="پرداخت"/>
						<a class="button cancel" href="'.$woocommerce->cart->get_checkout_url().'">بازگشت</a>
					 </form><br/>';
		echo $form;

		$ratio = 1;
		if ($currency == "irht")
			$ratio = 10000;
		else if ($currency == "irhr")
			$ratio = 1000;
		else if ($currency == "irt")
			$ratio = 10;

		$amount = (int)($order->get_total($currency)*$ratio);

		$callback_uri = add_query_arg("wc_order", $order_id, WC()->api_request_url("WC_Azkivam"));

		$mobile_number = $order->get_billing_phone() ? : "";
		
		if (empty($mobile_number)) //Emta Ehraz Plugin
			$mobile_number = get_post_meta($order->get_id(), "wp_emta_mobile", true);
		
		if (empty($mobile_number)) //Digits
			$mobile_number = get_user_meta($order->get_user_id(), "digits_phone", true);
		
		if (empty($mobile_number)) //Smartlogin
			$mobile_number = get_user_meta($order->get_user_id(), "smartlogin_mobile", true);

		if (empty($mobile_number)) //MihanPanel
			$mobile_number = get_user_meta($order->get_user_id(), "mw_user_phone", true);
		
		if (empty($mobile_number)) //User WC Phone
			$mobile_number = get_user_meta($order->get_user_id(), "billing_phone", true);

		if (str_starts_with($mobile_number, "+"))
			$mobile_number = substr($mobile_number, 1);
		if (str_starts_with($mobile_number, "98") && strlen($mobile_number) >= 12)
			$mobile_number = substr($mobile_number, 2);
		if (!str_starts_with($mobile_number, "0"))
			$mobile_number = "0".$mobile_number;
		$mobile_number = preg_match("/^09[0-9]{9}/i", $mobile_number) ? $mobile_number : "";
		
		$items = array();
		$line_type = [
			"line_item" => "محصول",
			"fee" => "فی",
			"shipping" => "حمل",
			"coupon" => "تخفیف",
			"tax" => "مالیات"
		];
		foreach ($order->get_items(array("line_item", "fee", "shipping", "coupon", "tax")) as $item) {
			$quantity = $item->is_type("line_item") ? $item->get_quantity() : 1;
			$total = $item->is_type("coupon") ? -$item->get_discount() : (($item->is_type("tax") ? $item->get_tax_total()+$item->get_shipping_tax_total() : $item->get_total())/$quantity);
			$name = $item->is_type("coupon") ? $line_type["coupon"] : $line_type[$item->get_type()].": ".$item->get_name();
			// $irr_amount = wc_format_decimal($total, wc_get_price_decimals()) * $ratio;
			$irr_amount = wc_format_decimal($total, wc_get_price_decimals());


			$items[] = array(
				"name"   => $name,
				"url"    => $item->is_type("line_item") ? get_permalink($item->get_product_id()) : home_url(),
				"count"  => $quantity,
				// "amount" => (int)($this->settings["ticketItemCurrency"] == "irr" ? $irr_amount : $irr_amount/10)
				"amount" => $irr_amount
			);
		}

		$provider_id = mt_rand(100000000, 999999999);
		$woocommerce->session->azkivam_provider_id = $provider_id;

		$result = $this->send_request("/payment/purchase", array(
			"amount"        => $amount,
			"redirect_uri"  => $callback_uri,
			"fallback_uri"  => $callback_uri,
			"provider_id"   => $provider_id,
			"mobile_number" => $mobile_number,
			"items"         => $items
		));

		$error_message = "";
		if ($result && $result->rsCode == 0) {
			wp_redirect($result->result->payment_uri);
			exit;
		} else {
			$error_message = isset($result->rsCode) ? $this->get_error_message($result->rsCode) : "تراکنش ناموفق بود.";
		}
		
		if (!empty($error_message)) {
			$order->add_order_note(sprintf("خطا در هنگام ارسال به ازکی وام : %s", $error_message));
			wc_add_notice(sprintf("در هنگام اتصال به ازکی وام خطای زیر رخ داده است : <br/>%s", $error_message), "error");
		}
	}

	public function verify_payment() {
		global $woocommerce;
		if (isset($_GET["wc_order"])) {
			$order_id = $_GET["wc_order"];
		} else {
			$order_id = $woocommerce->session->azkivam_order_id;
			unset($woocommerce->session->azkivam_order_id);
		}

		if ($order_id) {
			$order = new WC_Order($order_id);
			if ($order->status === "pending") {
				if ($_GET["status"] == "Done") {
					$ticket_id = $_GET["ticketId"];
					$result = $this->send_request("/payment/verify", array("ticket_id" => $ticket_id));
					$tr_id = $ticket_id;
					if ($result->rsCode == 0) {
						$status = "completed";
						$fault = "";
						$message = "";
					} else {
						$status = "failed";
						$fault = $result->rsCode;
						$message = $this->get_error_message($result->rsCode);
					}
				} else {
					$status = "failed";
					$fault = "";
					$message = "تراکنش انجام نشد.";
				}

				if ($status == "completed" && isset($tr_id)) {
					update_post_meta($order_id, "_transaction_id", $tr_id);
					$order->payment_complete($tr_id);
					$woocommerce->cart->empty_cart();

					$order->add_order_note(sprintf("پرداخت موفقیت آمیز بود.<br/> کد رهگیری: %s", $tr_id), 1);

					$notice = wpautop(wptexturize($this->success_message));
					$notice = str_replace("{transaction_id}", $tr_id, $notice);
					wc_add_notice($notice, "success");

					wp_redirect(add_query_arg("wc_status", "success", $this->get_return_url($order)));
					exit;
				}

				if ($tr_id)
					$tr_id = ("<br/>شناسه پرداخت: ".$tr_id);
				else
					$tr_id = "";

				$pr_id = $woocommerce->session->azkivam_provider_id;
				if ($pr_id)
					$pr_id = ("<br/>شناسه یکتای خرید: ".$pr_id);
				else
					$pr_id = "";

				$order->add_order_note(sprintf("خطا در هنگام بازگشت از بانک : %s %s %s", $message, $tr_id, $pr_id), 1);

				$notice = wpautop(wptexturize($this->failed_message));
				$notice = str_replace(array("{transaction_id}", "{fault}"), array($tr_id, $message), $notice);
				wc_add_notice($notice, "error");

				wp_redirect($woocommerce->cart->get_checkout_url());
				exit;
			} else {
				if( $order->get_date_paid() ) {
					$tr_id = get_post_meta($order_id, "_transaction_id", true);
					$notice = wpautop(wptexturize($this->success_message));
					$notice = str_replace("{transaction_id}", $tr_id, $notice);
					wc_add_notice($notice, "success");
					wp_redirect(add_query_arg("wc_status", "success", $this->get_return_url($order)));
				} else {
					wp_redirect(get_home_url());
				}
			}
			exit;
		}

		$fault = "شماره سفارش وجود ندارد.";
		$notice = wpautop(wptexturize($this->failed_message));
		$notice = str_replace("{fault}", $fault, $notice);
		wc_add_notice($notice, "error");

		wp_redirect($woocommerce->cart->get_checkout_url());
		exit;
	}

	public function signature($sub_url, $request_method, $api_key): string {
		$plain = $sub_url."#".time()."#".$request_method."#".$api_key;
		$key = hex2bin($api_key);
		$errRep = error_reporting(E_ERROR); //Suppres Empty IV OpenSSL Warning
		$digest = openssl_encrypt($plain, "AES-256-CBC", $key, OPENSSL_RAW_DATA);
		error_reporting($errRep); //Restore User Prev. Error Report Level
		return bin2hex($digest);
	}

	public function send_request($action, $data) {
		try {
			$api_key = $this->settings["apiKey"];
			$signature = $this->signature($action, "POST", $api_key);
			$merchant_id = $this->settings["merchantId"];
			$payment_uri = $this->settings["paymentUri"];
			$data["merchant_id"] = $merchant_id;
			$data_string = json_encode($data);

			$ch = curl_init();
			curl_setopt($ch, CURLOPT_URL, $payment_uri.$action);
			curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
			curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
			curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
			curl_setopt($ch, CURLOPT_HTTPHEADER, array(
				"Content-Type: application/json",
				"Signature: ".$signature,
				"MerchantId: ".$merchant_id,
				"Content-Length: ".strlen($data_string)
			));
			$result = curl_exec($ch);
			curl_close($ch);
			return json_decode($result);
		} catch (Exception $ex) {
			return false;
		}
	}

	public function get_error_message($rsCode): string {
		switch ($rsCode) {
			case 1:
				return "خطای داخلی اتفاق افتاده است.";
			case 12:
				return "فروشگاه فعال نیست.";
			case 13:
				return "شماره موبایل معتبر نیست.";
			case 20:
				return "شماره موبایل مشتری با ثبت نام شده در درگاه ازکی وام یکسان نیست.";
			case 21:
				return "اعتبار کافی نیست.";
			case 28:
				return "تراکنش قابل تأیید نیست.";
			case 44:
				return "شماره موبایل کاربری شما یافت نشد، با پشتیبانی در ارتباط باشید.";
			default:
				return "پرداخت ناموفق بود. کد: ".$rsCode;
		}
	}
}