feat(wp-plugin): expand IFNEX Bridge with wallet and transaction support

Extend the WordPress bridge plugin to provide seamless integration with
the backend wallet system. This update introduces user-specific
functionality via shortcodes and AJAX.

- feat(bridge): implement `IFNEX_User_Bridge` for Sanctum token management
- feat(bridge): add `[ifnex_wallet_balance]` shortcode for balance display
- feat(bridge): add `[ifnex_transactions]` shortcode for transaction history
- feat(bridge): implement AJAX handlers for real-time balance and transaction updates
- feat(bridge): add plugin-specific CSS assets and enqueueing logic
- docs: update project status with new bridge capabilities
- chore: add plugin testing utility and asset directory structure
This commit is contained in:
Kazem Alghasi 2026-08-08 03:49:46 +03:30
parent e1c4385a9c
commit b605b689fd
7 changed files with 894 additions and 0 deletions

View File

@ -261,6 +261,14 @@
- [x] تست‌های Unit/Feature برای Phase 2 (24 تست، 77 assertion) - [x] تست‌های Unit/Feature برای Phase 2 (24 تست، 77 assertion)
- [x] رفع باگ WalletController::balance() - [x] رفع باگ WalletController::balance()
- [x] حذف PaymentGatewayService قدیمی (استفاده نمی‌شد) - [x] حذف PaymentGatewayService قدیمی (استفاده نمی‌شد)
- [x] زیباسازی داشبورد و صفحه لاگین Filament
- [x] گسترش پلاگین IFNEX Bridge برای وردپرس:
- [x] ساخت `IFNEX_User_Bridge` برای مدیریت توکن Sanctum کاربران وردپرس
- [x] اضافه کردن شورت‌کد `[ifnex_wallet_balance]`
- [x] اضافه کردن شورت‌کد `[ifnex_transactions]`
- [x] اضافه کردن AJAX handlers برای کیف پول و تراکنش‌ها
- [x] ساخت استایل‌های CSS کامل برای تمام کامپوننت‌های پلاگین
- [x] ایجاد صفحه تست در وردپرس: http://localhost/ifnexwp/?page_id=16
--- ---
@ -530,6 +538,15 @@ IFNEX-Logistics/
- رفع باگ CHECK constraint در migration discount_codes (enum type: percent → percentage) - رفع باگ CHECK constraint در migration discount_codes (enum type: percent → percentage)
- رفع باگ Wallet::isFrozen() — مدیریت null برای مقدار پیش‌فرض - رفع باگ Wallet::isFrozen() — مدیریت null برای مقدار پیش‌فرض
- به‌روزرسانی STATUS.md با کارهای انجام‌شده Phase 2 - به‌روزرسانی STATUS.md با کارهای انجام‌شده Phase 2
- گسترش پلاگین IFNEX Bridge:
- ساخت `IFNEX_User_Bridge` برای مدیریت توکن Sanctum کاربران وردپرس
- اضافه کردن شورت‌کد `[ifnex_wallet_balance]` با نمایش موجودی کیف پول
- اضافه کردن شورت‌کد `[ifnex_transactions]` با لیست تراکنش‌های کاربر
- اضافه کردن AJAX handlers برای موجودی کیف پول و تراکنش‌ها
- ساخت استایل‌های CSS کامل برای تمام کامپوننت‌های پلاگین
- ایجاد صفحه تست در وردپرس: http://localhost/ifnexwp/?page_id=16
- رفع باگ صفحه لاگین Filament (MethodNotAllowed)
- حذف فایل‌های سفارشی لاگین و بازگشت به پیش‌فرض Filament

View File

@ -0,0 +1,62 @@
<?php
// Test script for IFNEX Bridge plugin
// This creates a test page in WordPress with all shortcodes
require_once('wp-load.php');
// Check if user is logged in as admin
if (!is_user_logged_in() || !current_user_can('manage_options')) {
die('Admin access required');
}
// Create test page content
$page_content = '
<h1>تست پلاگین IFNEX Bridge</h1>
<h2>1. فرم رهگیری مرسوله</h2>
[ifnex_tracking_form title="رهگیری مرسوله IFNEX" placeholder="شماره بارنامه را وارد کنید" button_text="جستجو"]
<h2>2. موجودی کیف پول</h2>
[ifnex_wallet_balance show_details="yes"]
<h2>3. لیست تراکنش‌ها</h2>
[ifnex_transactions per_page="5" show_pagination="yes"]
<h2>4. وضعیت مستقیم مرسوله</h2>
[ifnex_tracking_status awb="980100010"]
';
// Check if test page already exists
$test_page = get_page_by_title('تست IFNEX Bridge', OBJECT, 'page');
if (!$test_page) {
// Create test page
$page_id = wp_insert_post(array(
'post_title' => 'تست IFNEX Bridge',
'post_content' => $page_content,
'post_status' => 'publish',
'post_type' => 'page',
'post_author' => 1,
));
if ($page_id) {
echo "✅ صفحه تست ایجاد شد: " . get_permalink($page_id) . "\n";
} else {
echo "❌ خطا در ایجاد صفحه تست\n";
}
} else {
// Update existing test page
$test_page->post_content = $page_content;
wp_update_post($test_page);
echo "✅ صفحه تست به‌روز شد: " . get_permalink($test_page->ID) . "\n";
}
echo "\n📋 اطلاعات اتصال:\n";
echo "API URL: " . get_option('ifnex_api_url', 'http://localhost:8000/api/v1') . "\n";
echo "API Key: " . (get_option('ifnex_api_key', '') ? 'تنظیم شده' : 'تنظیم نشده') . "\n";
echo "\n🔧 مراحل بعدی:\n";
echo "1. مطمئن شوید لاراول در حال اجرا است: cd 04_Laravel && php artisan serve\n";
echo "2. وارد صفحه تست شوید: http://localhost/ifnexwp/?page_id=" . ($test_page ? $test_page->ID : $page_id) . "\n";
echo "3. ابتدا وارد وردپرس شوید (admin / admin)\n";
echo "4. صفحه تست را باز کنید و عملکرد شورت‌کدها را بررسی کنید\n";

View File

@ -0,0 +1,384 @@
/**
* IFNEX Bridge Styles
* استایل‌های پلاگین IFNEX Logistics Bridge
*/
/* Wallet Balance */
.ifnex-wallet-balance {
background: #f9fafb;
border: 1px solid #e5e7eb;
border-radius: 12px;
padding: 20px;
margin: 15px 0;
font-family: inherit;
direction: rtl;
text-align: right;
}
.ifnex-balance-main {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
padding-bottom: 10px;
border-bottom: 1px solid #e5e7eb;
}
.ifnex-balance-label {
font-size: 14px;
color: #6b7280;
font-weight: 500;
}
.ifnex-balance-amount {
font-size: 24px;
font-weight: 700;
color: #059669;
}
.ifnex-balance-details {
margin-top: 10px;
}
.ifnex-balance-details p {
margin: 5px 0;
font-size: 14px;
color: #374151;
}
.ifnex-balance-details strong {
color: #6b7280;
margin-left: 8px;
}
.ifnex-wallet-frozen {
color: #dc2626;
font-weight: 600;
margin-top: 10px;
padding: 8px 12px;
background: #fee2e2;
border-radius: 6px;
border-right: 3px solid #dc2626;
}
/* Transactions */
.ifnex-transactions {
margin: 15px 0;
font-family: inherit;
direction: rtl;
text-align: right;
}
.ifnex-transactions h3 {
font-size: 18px;
font-weight: 600;
color: #111827;
margin-bottom: 15px;
padding-bottom: 8px;
border-bottom: 2px solid #f59e0b;
}
.ifnex-transactions-list {
display: flex;
flex-direction: column;
gap: 12px;
}
.ifnex-transaction-item {
background: #ffffff;
border: 1px solid #e5e7eb;
border-radius: 10px;
padding: 16px;
transition: all 0.2s ease;
}
.ifnex-transaction-item:hover {
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
border-color: #f59e0b;
}
.ifnex-transaction-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 8px;
}
.ifnex-transaction-type {
display: inline-block;
padding: 4px 10px;
border-radius: 6px;
font-size: 12px;
font-weight: 500;
text-transform: uppercase;
background: #dbeafe;
color: #1e40af;
}
.ifnex-transaction-type.deposit {
background: #d1fae5;
color: #065f46;
}
.ifnex-transaction-type.withdrawal {
background: #fee2e2;
color: #991b1b;
}
.ifnex-transaction-type.order_payment {
background: #fef3c7;
color: #92400e;
}
.ifnex-transaction-type.refund {
background: #e0e7ff;
color: #3730a3;
}
.ifnex-transaction-amount {
font-size: 16px;
font-weight: 700;
font-family: 'Vazirmatn', 'IranYekan', sans-serif;
}
.ifnex-transaction-amount.positive {
color: #059669;
}
.ifnex-transaction-amount.negative {
color: #dc2626;
}
.ifnex-transaction-details {
margin-top: 8px;
}
.ifnex-transaction-description {
color: #4b5563;
font-size: 14px;
margin: 0 0 6px 0;
}
.ifnex-transaction-meta {
display: flex;
gap: 12px;
font-size: 12px;
color: #6b7280;
}
.ifnex-transaction-status {
display: inline-block;
padding: 2px 8px;
border-radius: 4px;
background: #f3f4f6;
color: #374151;
font-size: 11px;
}
.ifnex-transaction-status.completed {
background: #d1fae5;
color: #065f46;
}
.ifnex-transaction-status.pending {
background: #fef3c7;
color: #92400e;
}
.ifnex-transaction-status.failed {
background: #fee2e2;
color: #991b1b;
}
.ifnex-transaction-ref {
margin-top: 6px;
font-size: 12px;
color: #6b7280;
font-family: monospace;
}
/* Tracking Status */
.ifnex-tracking-container {
max-width: 700px;
margin: 20px auto;
padding: 24px;
background: #ffffff;
border: 1px solid #e5e7eb;
border-radius: 12px;
font-family: inherit;
direction: rtl;
text-align: right;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
}
.ifnex-tracking-container h2 {
font-size: 20px;
font-weight: 700;
color: #111827;
margin-bottom: 16px;
padding-bottom: 8px;
border-bottom: 2px solid #f59e0b;
}
.ifnex-tracking-form {
margin-bottom: 20px;
}
.ifnex-form-group {
display: flex;
gap: 10px;
}
.ifnex-form-group input {
flex: 1;
padding: 12px 16px;
border: 1px solid #d1d5db;
border-radius: 8px;
font-size: 15px;
font-family: inherit;
transition: border-color 0.2s ease;
}
.ifnex-form-group input:focus {
outline: none;
border-color: #f59e0b;
box-shadow: 0 0 0 3px rgba(245, 158, 11, 0.1);
}
.ifnex-form-group button {
padding: 12px 24px;
background: #f59e0b;
color: white;
border: none;
border-radius: 8px;
cursor: pointer;
font-size: 15px;
font-weight: 600;
font-family: inherit;
transition: all 0.2s ease;
}
.ifnex-form-group button:hover {
background: #d97706;
transform: translateY(-1px);
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
}
.ifnex-form-group button:disabled {
background: #9ca3af;
cursor: not-allowed;
transform: none;
box-shadow: none;
}
.ifnex-tracking-result {
margin-top: 20px;
padding: 20px;
background: #f9fafb;
border-radius: 8px;
border: 1px solid #e5e7eb;
}
.ifnex-error {
color: #dc2626;
font-weight: 500;
padding: 10px;
background: #fee2e2;
border-radius: 6px;
border-right: 3px solid #dc2626;
}
.ifnex-tracking-status h3 {
margin-top: 0;
font-size: 18px;
font-weight: 700;
color: #111827;
}
.ifnex-status-badge {
display: inline-block;
padding: 6px 14px;
background: #f59e0b;
color: white;
border-radius: 6px;
margin-bottom: 12px;
font-weight: 600;
font-size: 14px;
}
.ifnex-status-badge.delivered {
background: #059669;
}
.ifnex-status-badge.failed {
background: #dc2626;
}
.ifnex-status-badge.in_transit {
background: #2563eb;
}
.ifnex-tracking-details {
margin-top: 12px;
}
.ifnex-tracking-details p {
margin: 6px 0;
font-size: 14px;
color: #4b5563;
}
.ifnex-tracking-details strong {
color: #374151;
margin-left: 8px;
}
.ifnex-timeline {
margin-top: 20px;
padding-top: 15px;
border-top: 1px solid #e5e7eb;
}
.ifnex-timeline h4 {
font-size: 16px;
font-weight: 600;
color: #111827;
margin-bottom: 12px;
}
.ifnex-timeline ul {
list-style: none;
padding: 0;
margin: 0;
}
.ifnex-timeline li {
padding: 10px 12px;
border-bottom: 1px solid #f3f4f6;
display: flex;
gap: 10px;
align-items: flex-start;
font-size: 14px;
}
.ifnex-timeline li:last-child {
border-bottom: none;
}
.ifnex-timeline li strong {
color: #f59e0b;
font-weight: 600;
white-space: nowrap;
min-width: 100px;
}
.ifnex-timeline li span {
color: #4b5563;
flex: 1;
}
.ifnex-timeline li small {
color: #9ca3af;
font-size: 12px;
white-space: nowrap;
}

View File

@ -12,9 +12,23 @@ if ( ! defined( 'ABSPATH' ) ) {
// لود کردن فایل‌های پلاگین // لود کردن فایل‌های پلاگین
require_once plugin_dir_path( __FILE__ ) . 'includes/api-client.php'; require_once plugin_dir_path( __FILE__ ) . 'includes/api-client.php';
require_once plugin_dir_path( __FILE__ ) . 'includes/user-bridge.php';
require_once plugin_dir_path( __FILE__ ) . 'includes/shortcodes.php'; require_once plugin_dir_path( __FILE__ ) . 'includes/shortcodes.php';
require_once plugin_dir_path( __FILE__ ) . 'includes/tracking-form.php'; require_once plugin_dir_path( __FILE__ ) . 'includes/tracking-form.php';
// لود کردن استایل‌های پلاگین
add_action('wp_enqueue_scripts', 'ifnex_enqueue_scripts');
function ifnex_enqueue_scripts() {
global $post;
if (is_a($post, 'WP_Post') &&
(has_shortcode($post->post_content, 'ifnex_tracking_form') ||
has_shortcode($post->post_content, 'ifnex_wallet_balance') ||
has_shortcode($post->post_content, 'ifnex_transactions') ||
has_shortcode($post->post_content, 'ifnex_tracking_status'))) {
wp_enqueue_style('ifnex-bridge-css', plugin_dir_url(__FILE__) . 'assets/css/ifnex-bridge.css', array(), '1.0.0');
}
}
// اضافه کردن لینک به منوی پیشخوان وردپرس // اضافه کردن لینک به منوی پیشخوان وردپرس
add_action( 'admin_menu', 'ifnex_plugin_setup_menu' ); add_action( 'admin_menu', 'ifnex_plugin_setup_menu' );
function ifnex_plugin_setup_menu() { function ifnex_plugin_setup_menu() {

View File

@ -86,3 +86,106 @@ function ifnex_tracking_status_shortcode($atts) {
<?php <?php
return ob_get_clean(); return ob_get_clean();
} }
// شورت‌کد موجودی کیف پول
add_shortcode('ifnex_wallet_balance', 'ifnex_wallet_balance_shortcode');
function ifnex_wallet_balance_shortcode($atts) {
if (!is_user_logged_in()) {
return '<p class="ifnex-error">برای مشاهده موجودی باید وارد شوید.</p>';
}
$atts = shortcode_atts(array(
'show_details' => 'no',
), $atts);
$bridge = new IFNEX_User_Bridge();
$balance = $bridge->get_wallet_balance(get_current_user_id());
if (is_wp_error($balance)) {
return '<p class="ifnex-error">' . esc_html($balance->get_error_message()) . '</p>';
}
ob_start();
?>
<div class="ifnex-wallet-balance">
<div class="ifnex-balance-main">
<span class="ifnex-balance-label">موجودی کیف پول:</span>
<span class="ifnex-balance-amount"><?php echo number_format($balance['balance']); ?> ریال</span>
</div>
<?php if ($atts['show_details'] === 'yes'): ?>
<div class="ifnex-balance-details">
<p><strong>مجموع واریزی:</strong> <?php echo number_format($balance['total_deposited']); ?> ریال</p>
<p><strong>مجموع برداشت:</strong> <?php echo number_format($balance['total_withdrawn']); ?> ریال</p>
<?php if ($balance['is_frozen']): ?>
<p class="ifnex-wallet-frozen">⚠️ کیف پول شما مسدود است.</p>
<?php endif; ?>
</div>
<?php endif; ?>
</div>
<?php
return ob_get_clean();
}
// شورت‌کد لیست تراکنش‌ها
add_shortcode('ifnex_transactions', 'ifnex_transactions_shortcode');
function ifnex_transactions_shortcode($atts) {
if (!is_user_logged_in()) {
return '<p class="ifnex-error">برای مشاهده تراکنش‌ها باید وارد شوید.</p>';
}
$atts = shortcode_atts(array(
'per_page' => 10,
'show_pagination' => 'no',
), $atts);
$bridge = new IFNEX_User_Bridge();
$transactions = $bridge->get_transactions(get_current_user_id(), intval($atts['per_page']));
if (is_wp_error($transactions)) {
return '<p class="ifnex-error">' . esc_html($transactions->get_error_message()) . '</p>';
}
if (empty($transactions['transactions'])) {
return '<p>هنوز تراکنشی ثبت نشده است.</p>';
}
ob_start();
?>
<div class="ifnex-transactions">
<h3>تاریخچه تراکنش‌ها</h3>
<div class="ifnex-transactions-list">
<?php foreach ($transactions['transactions'] as $transaction): ?>
<div class="ifnex-transaction-item">
<div class="ifnex-transaction-header">
<span class="ifnex-transaction-type <?php echo esc_attr($transaction['type']); ?>">
<?php echo esc_html($transaction['type']); ?>
</span>
<span class="ifnex-transaction-amount <?php echo $transaction['amount'] >= 0 ? 'positive' : 'negative'; ?>">
<?php echo $transaction['amount'] >= 0 ? '+' : ''; ?>
<?php echo number_format($transaction['amount']); ?> ریال
</span>
</div>
<div class="ifnex-transaction-details">
<p class="ifnex-transaction-description"><?php echo esc_html($transaction['description']); ?></p>
<div class="ifnex-transaction-meta">
<span class="ifnex-transaction-status"><?php echo esc_html($transaction['status']); ?></span>
<span class="ifnex-transaction-date"><?php echo esc_html($transaction['created_at_jalali']); ?></span>
</div>
<?php if (!empty($transaction['reference_id'])): ?>
<p class="ifnex-transaction-ref">کد پیگیری: <?php echo esc_html($transaction['reference_id']); ?></p>
<?php endif; ?>
</div>
</div>
<?php endforeach; ?>
</div>
<?php if ($atts['show_pagination'] === 'yes' && $transactions['last_page'] > 1): ?>
<div class="ifnex-pagination">
<!-- Pagination can be added here -->
</div>
<?php endif; ?>
</div>
<?php
return ob_get_clean();
}

View File

@ -204,3 +204,96 @@ function ifnex_track_shipment_ajax() {
wp_send_json(array('success' => true, 'html' => $html)); wp_send_json(array('success' => true, 'html' => $html));
} }
// AJAX Handler: موجودی کیف پول
add_action('wp_ajax_ifnex_get_wallet_balance', 'ifnex_get_wallet_balance_ajax');
add_action('wp_ajax_nopriv_ifnex_get_wallet_balance', 'ifnex_get_wallet_balance_ajax');
function ifnex_get_wallet_balance_ajax() {
if (!is_user_logged_in()) {
wp_send_json(array('success' => false, 'message' => 'برای مشاهده موجودی باید وارد شوید.'));
return;
}
$bridge = new IFNEX_User_Bridge();
$balance = $bridge->get_wallet_balance(get_current_user_id());
if (is_wp_error($balance)) {
wp_send_json(array('success' => false, 'message' => $balance->get_error_message()));
return;
}
wp_send_json(array(
'success' => true,
'balance' => $balance['balance'],
'formatted_balance' => number_format($balance['balance']) . ' ریال',
'total_deposited' => number_format($balance['total_deposited']) . ' ریال',
'total_withdrawn' => number_format($balance['total_withdrawn']) . ' ریال',
'is_frozen' => $balance['is_frozen'],
));
}
// AJAX Handler: لیست تراکنش‌ها
add_action('wp_ajax_ifnex_get_transactions', 'ifnex_get_transactions_ajax');
add_action('wp_ajax_nopriv_ifnex_get_transactions', 'ifnex_get_transactions_ajax');
function ifnex_get_transactions_ajax() {
if (!is_user_logged_in()) {
wp_send_json(array('success' => false, 'message' => 'برای مشاهده تراکنش‌ها باید وارد شوید.'));
return;
}
$per_page = isset($_POST['per_page']) ? intval($_POST['per_page']) : 10;
$bridge = new IFNEX_User_Bridge();
$transactions = $bridge->get_transactions(get_current_user_id(), $per_page);
if (is_wp_error($transactions)) {
wp_send_json(array('success' => false, 'message' => $transactions->get_error_message()));
return;
}
// ساخت HTML لیست تراکنش‌ها
if (empty($transactions['transactions'])) {
wp_send_json(array(
'success' => true,
'html' => '<p>هنوز تراکنشی ثبت نشده است.</p>',
));
return;
}
ob_start();
?>
<div class="ifnex-transactions-list">
<?php foreach ($transactions['transactions'] as $transaction): ?>
<div class="ifnex-transaction-item">
<div class="ifnex-transaction-header">
<span class="ifnex-transaction-type">
<?php echo esc_html($transaction['type']); ?>
</span>
<span class="ifnex-transaction-amount <?php echo $transaction['amount'] >= 0 ? 'positive' : 'negative'; ?>">
<?php echo $transaction['amount'] >= 0 ? '+' : ''; ?>
<?php echo number_format($transaction['amount']); ?> ریال
</span>
</div>
<div class="ifnex-transaction-details">
<p class="ifnex-transaction-description"><?php echo esc_html($transaction['description']); ?></p>
<div class="ifnex-transaction-meta">
<span class="ifnex-transaction-status"><?php echo esc_html($transaction['status']); ?></span>
<span class="ifnex-transaction-date"><?php echo esc_html($transaction['created_at_jalali']); ?></span>
</div>
<?php if (!empty($transaction['reference_id'])): ?>
<p class="ifnex-transaction-ref">کد پیگیری: <?php echo esc_html($transaction['reference_id']); ?></p>
<?php endif; ?>
</div>
</div>
<?php endforeach; ?>
</div>
<?php
$html = ob_get_clean();
wp_send_json(array(
'success' => true,
'html' => $html,
));
}

View File

@ -0,0 +1,221 @@
<?php
/**
* IFNEX User Bridge
* مدیریت ارتباط کاربران وردپرس با لاراول
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
class IFNEX_User_Bridge {
private $api_url;
private $api_key;
public function __construct() {
$this->api_url = rtrim(get_option('ifnex_api_url', 'http://localhost:8000/api/v1'), '/');
$this->api_key = get_option('ifnex_api_key', '');
}
/**
* دریافت توکن Sanctum برای کاربر وردپرس
*/
public function get_user_token($user_id) {
$token = get_user_meta($user_id, 'ifnex_laravel_token', true);
$token_expiry = get_user_meta($user_id, 'ifnex_laravel_token_expiry', true);
if ($token && $token_expiry && strtotime($token_expiry) > time()) {
return $token;
}
$user = get_userdata($user_id);
if (!$user) {
return false;
}
$token = $this->request_token($user->user_email, $this->generate_temp_password($user_id));
if ($token) {
update_user_meta($user_id, 'ifnex_laravel_token', $token);
update_user_meta($user_id, 'ifnex_laravel_token_expiry', date('Y-m-d H:i:s', strtotime('+30 days')));
}
return $token;
}
/**
* درخواست توکن از لاراول
*/
private function request_token($email, $password) {
$url = $this->api_url . '/sanctum/token';
$args = array(
'headers' => array(
'Content-Type' => 'application/json',
'Accept' => 'application/json',
),
'body' => json_encode(array(
'email' => $email,
'password' => $password,
'token_name' => 'wordpress-bridge-' . get_current_blog_id(),
)),
'timeout' => 30,
);
$response = wp_remote_post($url, $args);
if (is_wp_error($response)) {
return false;
}
$body = wp_remote_retrieve_body($response);
$data = json_decode($body, true);
if (isset($data['token'])) {
return $data['token'];
}
return false;
}
/**
* تولید رمز عبور موقت برای کاربر وردپرس
*/
private function generate_temp_password($user_id) {
$temp_pass = get_user_meta($user_id, 'ifnex_temp_password', true);
if (!$temp_pass) {
$temp_pass = wp_generate_password(32, true, true);
update_user_meta($user_id, 'ifnex_temp_password', $temp_pass);
}
return $temp_pass;
}
/**
* ارسال درخواست احراز هویت به API لاراول
*/
public function authenticated_request($user_id, $endpoint, $method = 'GET', $data = array()) {
$token = $this->get_user_token($user_id);
if (!$token) {
return new WP_Error('no_token', 'توکن احراز هویت یافت نشد.');
}
$url = $this->api_url . $endpoint;
$args = array(
'headers' => array(
'Authorization' => 'Bearer ' . $token,
'Accept' => 'application/json',
'Content-Type' => 'application/json',
),
'timeout' => 30,
);
if ($method === 'POST' && !empty($data)) {
$args['body'] = json_encode($data);
$args['method'] = 'POST';
} else {
$args['method'] = 'GET';
if (!empty($data)) {
$url = add_query_arg($data, $url);
}
}
$response = wp_remote_request($url, $args);
if (is_wp_error($response)) {
return $response;
}
$body = wp_remote_retrieve_body($response);
$data = json_decode($body, true);
if ($response['response']['code'] === 401) {
$this->invalidate_token(get_current_user_id());
return new WP_Error('token_expired', 'توکن منقضی شده است. لطفاً دوباره وارد شوید.');
}
return $data;
}
/**
* باطل کردن توکن
*/
public function invalidate_token($user_id) {
delete_user_meta($user_id, 'ifnex_laravel_token');
delete_user_meta($user_id, 'ifnex_laravel_token_expiry');
}
/**
* دریافت موجودی کیف پول کاربر
*/
public function get_wallet_balance($user_id) {
$result = $this->authenticated_request($user_id, '/wallet/balance');
if (is_wp_error($result)) {
return $result;
}
return array(
'balance' => $result['balance'] ?? 0,
'total_deposited' => $result['total_deposited'] ?? 0,
'total_withdrawn' => $result['total_withdrawn'] ?? 0,
'is_frozen' => $result['is_frozen'] ?? false,
);
}
/**
* دریافت تراکنش‌های کاربر
*/
public function get_transactions($user_id, $per_page = 15) {
$result = $this->authenticated_request($user_id, '/wallet/transactions', 'GET', array(
'per_page' => $per_page,
));
if (is_wp_error($result)) {
return $result;
}
return $result;
}
/**
* رهگیری مرسوله
*/
public function track_shipment($awb_no) {
if (empty($this->api_key)) {
return new WP_Error('no_api_key', 'API Key تنظیم نشده است.');
}
$url = $this->api_url . '/track/' . urlencode($awb_no);
$args = array(
'headers' => array(
'Authorization' => 'Bearer ' . $this->api_key,
'Accept' => 'application/json',
),
'timeout' => 30,
);
$response = wp_remote_get($url, $args);
if (is_wp_error($response)) {
return $response;
}
$body = wp_remote_retrieve_body($response);
$data = json_decode($body, true);
if ($response['response']['code'] === 404) {
return new WP_Error('not_found', 'مرسوله‌ای با این کد پیدا نشد.');
}
if ($response['response']['code'] !== 200) {
return new WP_Error('api_error', 'خطا در ارتباط با API: ' . ($data['message'] ?? 'Unknown error'));
}
return $data;
}
}