feat: Complete WordPress customer portal
This commit is contained in:
parent
aa8fb17230
commit
bac2a7bb25
@ -211,4 +211,163 @@
|
||||
max-width: 500px; margin: 40px auto; text-align: center;
|
||||
background: #fff; padding: 40px; border-radius: var(--ifnex-radius);
|
||||
border: 1px solid var(--ifnex-border);
|
||||
}
|
||||
|
||||
/* ═══ Payment Page ═══ */
|
||||
.ifnex-payment-page { max-width: 700px; margin: 0 auto; padding: 20px 0; }
|
||||
.ifnex-payment-card {
|
||||
background: #fff; border-radius: var(--ifnex-radius);
|
||||
border: 1px solid var(--ifnex-border); padding: 32px;
|
||||
}
|
||||
.ifnex-payment-card h2 { margin-top: 0; color: var(--ifnex-dark); }
|
||||
|
||||
.ifnex-order-summary {
|
||||
background: var(--ifnex-light); border-radius: 8px;
|
||||
padding: 20px; margin-bottom: 24px;
|
||||
}
|
||||
.ifnex-summary-row {
|
||||
display: flex; justify-content: space-between; padding: 8px 0;
|
||||
border-bottom: 1px dashed var(--ifnex-border);
|
||||
}
|
||||
.ifnex-summary-row:last-child { border-bottom: none; }
|
||||
.ifnex-summary-row.total {
|
||||
font-size: 18px; font-weight: 700; color: var(--ifnex-primary-dark);
|
||||
padding-top: 12px; margin-top: 8px; border-top: 2px solid var(--ifnex-primary);
|
||||
}
|
||||
|
||||
.ifnex-payment-methods { display: grid; gap: 16px; }
|
||||
.ifnex-payment-option {
|
||||
border: 2px solid var(--ifnex-border); border-radius: 8px;
|
||||
padding: 20px; transition: all 0.2s;
|
||||
}
|
||||
.ifnex-payment-option:hover { border-color: var(--ifnex-primary); }
|
||||
.ifnex-payment-option.disabled { opacity: 0.5; pointer-events: none; }
|
||||
.ifnex-payment-option h3 { margin-top: 0; color: var(--ifnex-dark); }
|
||||
.ifnex-payment-option p { color: var(--ifnex-gray); margin: 8px 0 16px; }
|
||||
|
||||
.ifnex-warning {
|
||||
background: #fef3c7; color: #92400e; padding: 10px;
|
||||
border-radius: 6px; font-size: 13px; margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.ifnex-payment-footer {
|
||||
margin-top: 24px; padding-top: 20px;
|
||||
border-top: 1px solid var(--ifnex-border); text-align: center;
|
||||
}
|
||||
|
||||
/* ═══ Order Detail Page ═══ */
|
||||
.ifnex-order-detail { max-width: 900px; margin: 0 auto; padding: 20px 0; }
|
||||
|
||||
.ifnex-detail-header {
|
||||
display: flex; justify-content: space-between; align-items: center;
|
||||
margin-bottom: 20px; flex-wrap: wrap; gap: 12px;
|
||||
}
|
||||
.ifnex-detail-title { display: flex; align-items: center; gap: 12px; }
|
||||
.ifnex-detail-title h2 { margin: 0; color: var(--ifnex-dark); }
|
||||
.ifnex-awb-code {
|
||||
background: var(--ifnex-dark); color: #fff; padding: 6px 12px;
|
||||
border-radius: 6px; font-size: 14px; font-weight: 700;
|
||||
}
|
||||
.ifnex-badge-lg { padding: 8px 20px; font-size: 14px; }
|
||||
|
||||
.ifnex-detail-actions {
|
||||
display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 24px;
|
||||
padding: 16px; background: var(--ifnex-light); border-radius: 8px;
|
||||
}
|
||||
|
||||
.ifnex-detail-section {
|
||||
background: #fff; border: 1px solid var(--ifnex-border);
|
||||
border-radius: var(--ifnex-radius); padding: 24px; margin-bottom: 20px;
|
||||
}
|
||||
.ifnex-detail-section h3 {
|
||||
margin-top: 0; color: var(--ifnex-dark); padding-bottom: 12px;
|
||||
border-bottom: 1px solid var(--ifnex-border); margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.ifnex-route-detail {
|
||||
display: flex; align-items: center; gap: 20px; padding: 20px;
|
||||
}
|
||||
.ifnex-route-point {
|
||||
flex: 1; text-align: center; padding: 20px;
|
||||
background: var(--ifnex-light); border-radius: 8px;
|
||||
}
|
||||
.ifnex-point-label {
|
||||
font-size: 12px; color: var(--ifnex-gray); text-transform: uppercase;
|
||||
letter-spacing: 1px; margin-bottom: 8px;
|
||||
}
|
||||
.ifnex-point-country {
|
||||
font-size: 20px; font-weight: 700; color: var(--ifnex-dark);
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.ifnex-point-iso {
|
||||
font-size: 13px; color: var(--ifnex-gray); font-weight: 600;
|
||||
}
|
||||
.ifnex-route-line {
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
flex: 0.5;
|
||||
}
|
||||
.ifnex-plane-icon { font-size: 32px; }
|
||||
|
||||
.ifnex-info-grid {
|
||||
display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px;
|
||||
}
|
||||
.ifnex-info-item.full { grid-column: 1 / -1; }
|
||||
.ifnex-info-label {
|
||||
display: block; font-size: 12px; color: var(--ifnex-gray);
|
||||
text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 4px;
|
||||
}
|
||||
.ifnex-info-value { font-size: 15px; color: var(--ifnex-dark); font-weight: 500; }
|
||||
|
||||
.ifnex-price-breakdown { padding: 8px 0; }
|
||||
.ifnex-price-row {
|
||||
display: flex; justify-content: space-between; padding: 10px 0;
|
||||
border-bottom: 1px dashed var(--ifnex-border); font-size: 14px;
|
||||
}
|
||||
.ifnex-price-row:last-child { border-bottom: none; }
|
||||
.ifnex-price-row.total {
|
||||
font-size: 18px; font-weight: 800; color: var(--ifnex-primary-dark);
|
||||
padding-top: 16px; margin-top: 8px; border-top: 2px solid var(--ifnex-primary);
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.ifnex-text-success { color: var(--ifnex-success); font-weight: 600; }
|
||||
.ifnex-text-warning { color: var(--ifnex-warning); font-weight: 600; }
|
||||
|
||||
/* Timeline */
|
||||
.ifnex-timeline { position: relative; padding-right: 20px; }
|
||||
.ifnex-timeline::before {
|
||||
content: ''; position: absolute; right: 8px; top: 0; bottom: 0;
|
||||
width: 2px; background: var(--ifnex-border);
|
||||
}
|
||||
.ifnex-timeline-item {
|
||||
position: relative; padding-right: 32px; padding-bottom: 20px;
|
||||
}
|
||||
.ifnex-timeline-item:last-child { padding-bottom: 0; }
|
||||
.ifnex-timeline-dot {
|
||||
position: absolute; right: -20px; top: 4px;
|
||||
width: 16px; height: 16px; border-radius: 50%;
|
||||
background: var(--ifnex-primary); border: 3px solid #fff;
|
||||
box-shadow: 0 0 0 2px var(--ifnex-border);
|
||||
}
|
||||
.ifnex-timeline-content {
|
||||
background: var(--ifnex-light); padding: 12px 16px;
|
||||
border-radius: 8px; border-right: 3px solid var(--ifnex-primary);
|
||||
}
|
||||
.ifnex-timeline-header {
|
||||
display: flex; justify-content: space-between; flex-wrap: wrap;
|
||||
gap: 8px; margin-bottom: 4px;
|
||||
}
|
||||
.ifnex-timeline-date { font-size: 12px; color: var(--ifnex-gray); }
|
||||
.ifnex-timeline-location { font-size: 13px; color: var(--ifnex-gray); }
|
||||
.ifnex-empty-timeline { color: var(--ifnex-gray); font-style: italic; }
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.ifnex-route-detail { flex-direction: column; }
|
||||
.ifnex-route-line { transform: rotate(90deg); }
|
||||
.ifnex-info-grid { grid-template-columns: 1fr; }
|
||||
}
|
||||
|
||||
@media print {
|
||||
.ifnex-detail-actions { display: none !important; }
|
||||
.ifnex-order-detail { max-width: 100%; }
|
||||
}
|
||||
@ -39,11 +39,13 @@ function ifnex_settings_page_html() {
|
||||
if (isset($_POST['ifnex_api_url']) && check_admin_referer('ifnex_settings_save')) {
|
||||
update_option('ifnex_api_url', sanitize_url($_POST['ifnex_api_url']));
|
||||
update_option('ifnex_api_key', sanitize_text_field($_POST['ifnex_api_key']));
|
||||
update_option('ifnex_bridge_api_key', sanitize_text_field($_POST['ifnex_bridge_api_key'] ?? ''));
|
||||
echo '<div class="notice notice-success"><p>تنظیمات ذخیره شد.</p></div>';
|
||||
}
|
||||
|
||||
$api_url = get_option('ifnex_api_url', 'http://localhost:8000/api/v1');
|
||||
$api_key = get_option('ifnex_api_key', '');
|
||||
$bridge_api_key = get_option('ifnex_bridge_api_key', '');
|
||||
?>
|
||||
<div class="wrap">
|
||||
<h1>تنظیمات IFNEX Logistics Bridge</h1>
|
||||
@ -52,15 +54,36 @@ function ifnex_settings_page_html() {
|
||||
<table class="form-table">
|
||||
<tr>
|
||||
<th scope="row"><label for="ifnex_api_url">API URL</label></th>
|
||||
<td><input type="text" id="ifnex_api_url" name="ifnex_api_url" value="<?php echo esc_attr($api_url); ?>" class="regular-text" placeholder="http://localhost:8000/api/v1"></td>
|
||||
<td>
|
||||
<input type="text" id="ifnex_api_url" name="ifnex_api_url" value="<?php echo esc_attr($api_url); ?>" class="regular-text" placeholder="http://localhost:8000/api/v1">
|
||||
<p class="description">آدرس پایه API لاراول</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><label for="ifnex_api_key">API Key</label></th>
|
||||
<td><input type="text" id="ifnex_api_key" name="ifnex_api_key" value="<?php echo esc_attr($api_key); ?>" class="regular-text"></td>
|
||||
<th scope="row"><label for="ifnex_api_key">API Key (عمومی)</label></th>
|
||||
<td>
|
||||
<input type="text" id="ifnex_api_key" name="ifnex_api_key" value="<?php echo esc_attr($api_key); ?>" class="regular-text">
|
||||
<p class="description">برای APIهای عمومی مثل Tracking</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr style="background: #fff3cd;">
|
||||
<th scope="row"><label for="ifnex_bridge_api_key">🔐 Bridge API Key</label></th>
|
||||
<td>
|
||||
<input type="text" id="ifnex_bridge_api_key" name="ifnex_bridge_api_key" value="<?php echo esc_attr($bridge_api_key); ?>" class="regular-text">
|
||||
<p class="description"><strong>مهم:</strong> باید با مقدار <code>IFNEX_BRIDGE_API_KEY</code> در فایل <code>.env</code> لاراول یکسان باشد.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<?php submit_button('ذخیره تنظیمات'); ?>
|
||||
</form>
|
||||
|
||||
<hr>
|
||||
<h2>راهنمای راهاندازی</h2>
|
||||
<ol>
|
||||
<li>در فایل <code>.env</code> لاراول، خط <code>IFNEX_BRIDGE_API_KEY=your-secret-key</code> را تنظیم کنید</li>
|
||||
<li>همان مقدار را در فیلد "Bridge API Key" بالا وارد کنید</li>
|
||||
<li>کاربران وردپرس باید در لاراول با همان ایمیل موجود باشند (از <code>php artisan ifnex:sync-wp-users</code> استفاده کنید)</li>
|
||||
</ol>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
@ -393,7 +393,7 @@ function ifnex_orders_list_shortcode($atts) {
|
||||
</div>
|
||||
|
||||
<div class="ifnex-order-actions">
|
||||
<a href="<?php echo esc_url(home_url('/order-detail/' . $order['id'] . '/')); ?>"
|
||||
<a href="<?php echo esc_url(home_url('/order-detail/?order_id=' . $order['id'])); ?>"
|
||||
class="ifnex-btn ifnex-btn-sm ifnex-btn-info">
|
||||
👁️ جزئیات
|
||||
</a>
|
||||
@ -406,8 +406,8 @@ function ifnex_orders_list_shortcode($atts) {
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!$order['status']['is_paid']): ?>
|
||||
<a href="<?php echo esc_url(home_url('/payment/' . $order['id'] . '/')); ?>"
|
||||
class="ifnex-btn ifnex-btn-sm ifnex-btn-success">
|
||||
<a href="<?php echo esc_url(home_url('/order-payment/?order_id=' . $order['id'])); ?>"
|
||||
class="ifnex-btn ifnex-btn-sm ifnex-btn-success">
|
||||
💳 پرداخت
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
@ -604,4 +604,496 @@ function ifnex_order_form_shortcode($atts) {
|
||||
</div>
|
||||
<?php
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
// ══════════════════════════════════════════════════════════════
|
||||
// شورتکد صفحه پرداخت سفارش
|
||||
// ══════════════════════════════════════════════════════════════
|
||||
|
||||
add_shortcode('ifnex_order_payment', 'ifnex_order_payment_shortcode');
|
||||
|
||||
function ifnex_order_payment_shortcode($atts) {
|
||||
if (!is_user_logged_in()) {
|
||||
return '<p class="ifnex-error">برای پرداخت، باید وارد شوید.</p>';
|
||||
}
|
||||
|
||||
$atts = shortcode_atts(array('order_id' => ''), $atts);
|
||||
|
||||
// دریافت order_id از URL parameter
|
||||
$order_id = $atts['order_id'] ?: ($_GET['order_id'] ?? 0);
|
||||
|
||||
if (!$order_id) {
|
||||
return '<p class="ifnex-error">شناسه سفارش مشخص نشده است.</p>';
|
||||
}
|
||||
|
||||
$bridge = new IFNEX_User_Bridge();
|
||||
$user_id = get_current_user_id();
|
||||
|
||||
$order = $bridge->get_customer_order($user_id, $order_id);
|
||||
|
||||
if (is_wp_error($order)) {
|
||||
return '<p class="ifnex-error">' . esc_html($order->get_error_message()) . '</p>';
|
||||
}
|
||||
|
||||
$data = $order['data'];
|
||||
|
||||
// بررسی وضعیت
|
||||
if ($data['status']['value'] !== 'pending_payment') {
|
||||
return '<div class="ifnex-success-box">
|
||||
<h3>✅ این سفارش قبلاً پرداخت شده است</h3>
|
||||
<p>وضعیت: ' . esc_html($data['status']['label']) . '</p>
|
||||
<a href="' . esc_url(home_url('/my-orders/')) . '" class="ifnex-btn ifnex-btn-primary">بازگشت به سفارشات</a>
|
||||
</div>';
|
||||
}
|
||||
|
||||
$balance = $bridge->get_wallet_balance($user_id);
|
||||
$wallet_balance = is_wp_error($balance) ? 0 : ($balance['balance'] ?? 0);
|
||||
$can_pay_wallet = $wallet_balance >= $data['total_fee'];
|
||||
|
||||
ob_start();
|
||||
?>
|
||||
<div class="ifnex-payment-page">
|
||||
<div class="ifnex-payment-card">
|
||||
<h2>💳 پرداخت سفارش</h2>
|
||||
|
||||
<div class="ifnex-order-summary">
|
||||
<div class="ifnex-summary-row">
|
||||
<span>شماره پیگیری:</span>
|
||||
<strong><?php echo esc_html($data['awb_no']); ?></strong>
|
||||
</div>
|
||||
<div class="ifnex-summary-row">
|
||||
<span>مسیر:</span>
|
||||
<strong><?php echo esc_html($data['from_country']['name']); ?> → <?php echo esc_html($data['to_country']['name']); ?></strong>
|
||||
</div>
|
||||
<div class="ifnex-summary-row total">
|
||||
<span>مبلغ قابل پرداخت:</span>
|
||||
<strong><?php echo number_format($data['total_fee']); ?> ریال</strong>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ifnex-payment-methods">
|
||||
<!-- پرداخت از کیف پول -->
|
||||
<div class="ifnex-payment-option <?php echo $can_pay_wallet ? '' : 'disabled'; ?>">
|
||||
<h3>💰 پرداخت از کیف پول</h3>
|
||||
<p>موجودی فعلی: <strong><?php echo number_format($wallet_balance); ?> ریال</strong></p>
|
||||
<?php if ($can_pay_wallet): ?>
|
||||
<button class="ifnex-btn ifnex-btn-success ifnex-pay-wallet" data-order-id="<?php echo esc_attr($order_id); ?>">
|
||||
پرداخت فوری از کیف پول
|
||||
</button>
|
||||
<?php else: ?>
|
||||
<p class="ifnex-warning">⚠️ موجودی کافی نیست. لطفاً ابتدا کیف پول خود را شارژ کنید.</p>
|
||||
<a href="<?php echo esc_url(home_url('/wallet/')); ?>" class="ifnex-btn ifnex-btn-info">شارژ کیف پول</a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<!-- پرداخت از درگاه -->
|
||||
<div class="ifnex-payment-option">
|
||||
<h3>🏦 پرداخت از درگاه بانکی</h3>
|
||||
<p>انتقال به درگاه پرداخت امن (زرینپال)</p>
|
||||
<button class="ifnex-btn ifnex-btn-primary ifnex-pay-gateway" data-order-id="<?php echo esc_attr($order_id); ?>">
|
||||
انتقال به درگاه بانکی
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="ifnex-payment-message" style="display:none; margin-top:20px;"></div>
|
||||
|
||||
<div class="ifnex-payment-footer">
|
||||
<a href="<?php echo esc_url(home_url('/my-orders/')); ?>" class="ifnex-btn ifnex-btn-sm">
|
||||
← بازگشت به سفارشات
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
jQuery(document).ready(function($) {
|
||||
// پرداخت از کیف پول
|
||||
$('.ifnex-pay-wallet').on('click', function() {
|
||||
if (!confirm('آیا از پرداخت از کیف پول اطمینان دارید؟')) return;
|
||||
|
||||
var btn = $(this);
|
||||
var orderId = btn.data('order-id');
|
||||
|
||||
console.log('═══════════════════════════════════════');
|
||||
console.log('🚀 Starting wallet payment');
|
||||
console.log('Order ID:', orderId);
|
||||
console.log('AJAX URL:', ifnex_ajax.ajax_url);
|
||||
console.log('Nonce:', ifnex_ajax.nonce);
|
||||
console.log('═══════════════════════════════════════');
|
||||
|
||||
btn.prop('disabled', true).text('در حال پرداخت...');
|
||||
|
||||
$.ajax({
|
||||
url: ifnex_ajax.ajax_url,
|
||||
method: 'POST',
|
||||
data: {
|
||||
action: 'ifnex_pay_order_wallet',
|
||||
order_id: orderId,
|
||||
nonce: ifnex_ajax.nonce
|
||||
},
|
||||
beforeSend: function() {
|
||||
console.log('📤 Sending AJAX request...');
|
||||
},
|
||||
success: function(res) {
|
||||
console.log('📥 Response received:', res);
|
||||
console.log('Success:', res.success);
|
||||
console.log('Data:', res.data);
|
||||
|
||||
if (res.success) {
|
||||
console.log('✅ Payment successful!');
|
||||
console.log('New status:', res.data?.status?.value);
|
||||
console.log('Transaction ID:', res.data?.transaction_id);
|
||||
|
||||
$('#ifnex-payment-message')
|
||||
.removeClass('ifnex-error-box')
|
||||
.addClass('ifnex-success-box')
|
||||
.html('✅ پرداخت با موفقیت انجام شد! در حال انتقال...')
|
||||
.show();
|
||||
|
||||
setTimeout(function() {
|
||||
window.location.href = ifnex_ajax.orders_url + '?t=' + Date.now();
|
||||
}, 2000);
|
||||
} else {
|
||||
console.error('❌ Payment failed:', res.data);
|
||||
btn.prop('disabled', false).text('پرداخت فوری از کیف پول');
|
||||
$('#ifnex-payment-message')
|
||||
.addClass('ifnex-error-box')
|
||||
.text('خطا: ' + (res.data || 'نامشخص'))
|
||||
.show();
|
||||
}
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
console.error('═══════════════════════════════════════');
|
||||
console.error('❌ AJAX ERROR');
|
||||
console.error('Status:', status);
|
||||
console.error('Error:', error);
|
||||
console.error('Response Code:', xhr.status);
|
||||
console.error('Response Text:', xhr.responseText);
|
||||
console.error('═══════════════════════════════════════');
|
||||
|
||||
btn.prop('disabled', false).text('پرداخت فوری از کیف پول');
|
||||
$('#ifnex-payment-message')
|
||||
.addClass('ifnex-error-box')
|
||||
.html('خطا در ارتباط با سرور<br><small>' + error + '</small>')
|
||||
.show();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// پرداخت از درگاه
|
||||
$('.ifnex-pay-gateway').on('click', function() {
|
||||
var btn = $(this);
|
||||
var orderId = btn.data('order-id');
|
||||
|
||||
btn.prop('disabled', true).text('در حال اتصال به درگاه...');
|
||||
|
||||
$.ajax({
|
||||
url: ifnex_ajax.ajax_url,
|
||||
method: 'POST',
|
||||
data: {
|
||||
action: 'ifnex_pay_order_gateway',
|
||||
order_id: orderId,
|
||||
callback_url: window.location.href,
|
||||
nonce: ifnex_ajax.nonce
|
||||
},
|
||||
success: function(res) {
|
||||
if (res.success && res.data.payment_url) {
|
||||
window.location.href = res.data.payment_url;
|
||||
} else {
|
||||
btn.prop('disabled', false).text('انتقال به درگاه بانکی');
|
||||
$('#ifnex-payment-message')
|
||||
.addClass('ifnex-error-box')
|
||||
.text('خطا: ' + (res.data || 'خطا در اتصال به درگاه'))
|
||||
.show();
|
||||
}
|
||||
},
|
||||
error: function() {
|
||||
btn.prop('disabled', false).text('انتقال به درگاه بانکی');
|
||||
$('#ifnex-payment-message')
|
||||
.addClass('ifnex-error-box')
|
||||
.text('خطا در ارتباط با سرور')
|
||||
.show();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<?php
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
// ══════════════════════════════════════════════════════════════
|
||||
// شورتکد جزئیات سفارش
|
||||
// ══════════════════════════════════════════════════════════════
|
||||
|
||||
add_shortcode('ifnex_order_detail', 'ifnex_order_detail_shortcode');
|
||||
|
||||
function ifnex_order_detail_shortcode($atts) {
|
||||
if (!is_user_logged_in()) {
|
||||
return '<p class="ifnex-error">برای مشاهده جزئیات، باید وارد شوید.</p>';
|
||||
}
|
||||
|
||||
$atts = shortcode_atts(array('order_id' => ''), $atts);
|
||||
$order_id = $atts['order_id'] ?: ($_GET['order_id'] ?? 0);
|
||||
|
||||
// اگر از URL pretty استفاده شده (order-detail/14/)
|
||||
if (!$order_id && isset($_SERVER['REQUEST_URI'])) {
|
||||
if (preg_match('/order-detail\/(\d+)/', $_SERVER['REQUEST_URI'], $matches)) {
|
||||
$order_id = $matches[1];
|
||||
}
|
||||
}
|
||||
|
||||
if (!$order_id) {
|
||||
return '<p class="ifnex-error">شناسه سفارش مشخص نشده است.</p>';
|
||||
}
|
||||
|
||||
$bridge = new IFNEX_User_Bridge();
|
||||
$user_id = get_current_user_id();
|
||||
|
||||
$order = $bridge->get_customer_order($user_id, $order_id);
|
||||
|
||||
if (is_wp_error($order)) {
|
||||
return '<p class="ifnex-error">' . esc_html($order->get_error_message()) . '</p>';
|
||||
}
|
||||
|
||||
$data = $order['data'];
|
||||
$status = $data['status'];
|
||||
|
||||
ob_start();
|
||||
?>
|
||||
<div class="ifnex-order-detail">
|
||||
<!-- هدر با وضعیت -->
|
||||
<div class="ifnex-detail-header">
|
||||
<div class="ifnex-detail-title">
|
||||
<h2>📦 جزئیات سفارش</h2>
|
||||
<code class="ifnex-awb-code"><?php echo esc_html($data['awb_no']); ?></code>
|
||||
</div>
|
||||
<span class="ifnex-badge ifnex-badge-<?php echo esc_attr($status['color']); ?> ifnex-badge-lg">
|
||||
<?php echo esc_html($status['label']); ?>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- دکمههای عملیاتی -->
|
||||
<div class="ifnex-detail-actions">
|
||||
<a href="<?php echo esc_url(home_url('/my-orders/')); ?>" class="ifnex-btn ifnex-btn-sm">
|
||||
← بازگشت به سفارشات
|
||||
</a>
|
||||
|
||||
<?php if (!$status['is_paid']): ?>
|
||||
<a href="<?php echo esc_url(home_url('/order-payment/?order_id=' . $order_id)); ?>"
|
||||
class="ifnex-btn ifnex-btn-sm ifnex-btn-success">
|
||||
💳 پرداخت
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($status['can_cancel']): ?>
|
||||
<button class="ifnex-btn ifnex-btn-sm ifnex-btn-danger ifnex-cancel-order-detail"
|
||||
data-order-id="<?php echo esc_attr($order_id); ?>">
|
||||
❌ لغو سفارش
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
|
||||
<button onclick="window.print()" class="ifnex-btn ifnex-btn-sm ifnex-btn-info">
|
||||
🖨️ چاپ
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- مسیر ارسال -->
|
||||
<div class="ifnex-detail-section">
|
||||
<h3>🗺️ مسیر ارسال</h3>
|
||||
<div class="ifnex-route-detail">
|
||||
<div class="ifnex-route-point from">
|
||||
<div class="ifnex-point-label">از</div>
|
||||
<div class="ifnex-point-country">
|
||||
<?php echo esc_html($data['from_country']['name'] ?? '—'); ?>
|
||||
</div>
|
||||
<div class="ifnex-point-iso">
|
||||
<?php echo esc_html($data['from_country']['iso_code'] ?? ''); ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ifnex-route-line">
|
||||
<div class="ifnex-plane-icon">✈️</div>
|
||||
</div>
|
||||
<div class="ifnex-route-point to">
|
||||
<div class="ifnex-point-label">به</div>
|
||||
<div class="ifnex-point-country">
|
||||
<?php echo esc_html($data['to_country']['name'] ?? '—'); ?>
|
||||
</div>
|
||||
<div class="ifnex-point-iso">
|
||||
<?php echo esc_html($data['to_country']['iso_code'] ?? ''); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- اطلاعات مرسوله -->
|
||||
<div class="ifnex-detail-section">
|
||||
<h3>📦 اطلاعات مرسوله</h3>
|
||||
<div class="ifnex-info-grid">
|
||||
<div class="ifnex-info-item">
|
||||
<span class="ifnex-info-label">نوع سرویس</span>
|
||||
<span class="ifnex-info-value"><?php echo esc_html($data['type'] ?? '—'); ?></span>
|
||||
</div>
|
||||
<div class="ifnex-info-item">
|
||||
<span class="ifnex-info-label">جهت ارسال</span>
|
||||
<span class="ifnex-info-value">
|
||||
<?php echo ($data['direction'] ?? '') === 'export' ? 'صادرات' : 'واردات'; ?>
|
||||
</span>
|
||||
</div>
|
||||
<div class="ifnex-info-item">
|
||||
<span class="ifnex-info-label">وزن واقعی</span>
|
||||
<span class="ifnex-info-value"><?php echo esc_html($data['weight'] ?? '—'); ?> kg</span>
|
||||
</div>
|
||||
<div class="ifnex-info-item">
|
||||
<span class="ifnex-info-label">وزن قابل محاسبه</span>
|
||||
<span class="ifnex-info-value"><?php echo esc_html($data['chargeable_weight'] ?? '—'); ?> kg</span>
|
||||
</div>
|
||||
<div class="ifnex-info-item">
|
||||
<span class="ifnex-info-label">تاریخ ثبت</span>
|
||||
<span class="ifnex-info-value"><?php echo esc_html($data['created_at_jalali'] ?? '—'); ?></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- اطلاعات مالی -->
|
||||
<div class="ifnex-detail-section">
|
||||
<h3>💰 اطلاعات مالی</h3>
|
||||
<div class="ifnex-price-breakdown">
|
||||
<div class="ifnex-price-row">
|
||||
<span>مبلغ خالص (درهم):</span>
|
||||
<span><?php echo number_format($data['net_dirham'] ?? 0); ?> AED</span>
|
||||
</div>
|
||||
<div class="ifnex-price-row">
|
||||
<span>مبلغ خالص (ریال):</span>
|
||||
<span><?php echo number_format($data['net_rial'] ?? 0); ?> ریال</span>
|
||||
</div>
|
||||
<div class="ifnex-price-row total">
|
||||
<span>مبلغ کل:</span>
|
||||
<span><?php echo number_format($data['total_fee'] ?? 0); ?> ریال</span>
|
||||
</div>
|
||||
<div class="ifnex-price-row">
|
||||
<span>وضعیت پرداخت:</span>
|
||||
<span class="<?php echo $status['is_paid'] ? 'ifnex-text-success' : 'ifnex-text-warning'; ?>">
|
||||
<?php echo $status['is_paid'] ? '✅ پرداخت شده' : '⏳ در انتظار پرداخت'; ?>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- اطلاعات فرستنده -->
|
||||
<?php if (!empty($data['sender_name']) || !empty($data['sender_phone'])): ?>
|
||||
<div class="ifnex-detail-section">
|
||||
<h3>👤 اطلاعات فرستنده</h3>
|
||||
<div class="ifnex-info-grid">
|
||||
<div class="ifnex-info-item">
|
||||
<span class="ifnex-info-label">نام</span>
|
||||
<span class="ifnex-info-value"><?php echo esc_html($data['sender_name'] ?? '—'); ?></span>
|
||||
</div>
|
||||
<div class="ifnex-info-item">
|
||||
<span class="ifnex-info-label">تلفن</span>
|
||||
<span class="ifnex-info-value"><?php echo esc_html($data['sender_phone'] ?? '—'); ?></span>
|
||||
</div>
|
||||
<div class="ifnex-info-item full">
|
||||
<span class="ifnex-info-label">آدرس</span>
|
||||
<span class="ifnex-info-value"><?php echo esc_html($data['sender_address'] ?? '—'); ?></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- اطلاعات گیرنده -->
|
||||
<?php if (!empty($data['receiver_name']) || !empty($data['receiver_phone'])): ?>
|
||||
<div class="ifnex-detail-section">
|
||||
<h3>📮 اطلاعات گیرنده</h3>
|
||||
<div class="ifnex-info-grid">
|
||||
<div class="ifnex-info-item">
|
||||
<span class="ifnex-info-label">نام</span>
|
||||
<span class="ifnex-info-value"><?php echo esc_html($data['receiver_name'] ?? '—'); ?></span>
|
||||
</div>
|
||||
<div class="ifnex-info-item">
|
||||
<span class="ifnex-info-label">تلفن</span>
|
||||
<span class="ifnex-info-value"><?php echo esc_html($data['receiver_phone'] ?? '—'); ?></span>
|
||||
</div>
|
||||
<div class="ifnex-info-item full">
|
||||
<span class="ifnex-info-label">آدرس</span>
|
||||
<span class="ifnex-info-value"><?php echo esc_html($data['receiver_address'] ?? '—'); ?></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- Timeline رهگیری -->
|
||||
<?php if (!empty($data['tracking_events'])): ?>
|
||||
<div class="ifnex-detail-section">
|
||||
<h3>📍 تاریخچه رهگیری</h3>
|
||||
<div class="ifnex-timeline">
|
||||
<?php foreach ($data['tracking_events'] as $event): ?>
|
||||
<div class="ifnex-timeline-item">
|
||||
<div class="ifnex-timeline-dot"></div>
|
||||
<div class="ifnex-timeline-content">
|
||||
<div class="ifnex-timeline-header">
|
||||
<strong><?php echo esc_html($event['event_description'] ?? ''); ?></strong>
|
||||
<span class="ifnex-timeline-date">
|
||||
<?php echo esc_html($event['event_date'] ?? ''); ?>
|
||||
<?php if (!empty($event['event_time'])): ?>
|
||||
- <?php echo esc_html($event['event_time']); ?>
|
||||
<?php endif; ?>
|
||||
</span>
|
||||
</div>
|
||||
<?php if (!empty($event['location'])): ?>
|
||||
<div class="ifnex-timeline-location">
|
||||
📍 <?php echo esc_html($event['location']); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="ifnex-detail-section">
|
||||
<h3>📍 تاریخچه رهگیری</h3>
|
||||
<p class="ifnex-empty-timeline">هنوز رویدادی ثبت نشده است.</p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
jQuery(document).ready(function($) {
|
||||
$('.ifnex-cancel-order-detail').on('click', function() {
|
||||
if (!confirm('آیا از لغو این سفارش اطمینان دارید؟')) return;
|
||||
|
||||
var btn = $(this);
|
||||
var orderId = btn.data('order-id');
|
||||
|
||||
btn.prop('disabled', true).text('در حال لغو...');
|
||||
|
||||
$.ajax({
|
||||
url: ifnex_ajax.ajax_url,
|
||||
method: 'POST',
|
||||
data: {
|
||||
action: 'ifnex_cancel_order',
|
||||
order_id: orderId,
|
||||
nonce: ifnex_ajax.nonce
|
||||
},
|
||||
success: function(response) {
|
||||
if (response.success) {
|
||||
alert('سفارش با موفقیت لغو شد.');
|
||||
location.reload();
|
||||
} else {
|
||||
alert('خطا: ' + response.data);
|
||||
btn.prop('disabled', false).text('❌ لغو سفارش');
|
||||
}
|
||||
},
|
||||
error: function() {
|
||||
alert('خطا در ارتباط با سرور.');
|
||||
btn.prop('disabled', false).text('❌ لغو سفارش');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<?php
|
||||
return ob_get_clean();
|
||||
}
|
||||
@ -18,23 +18,30 @@ class IFNEX_User_Bridge {
|
||||
}
|
||||
|
||||
/**
|
||||
* دریافت توکن Sanctum برای کاربر وردپرس
|
||||
* دریافت توکن 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) {
|
||||
// دریافت اطلاعات کاربر وردپرس
|
||||
$wp_user = get_userdata($user_id);
|
||||
if (!$wp_user) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$token = $this->request_token($user->user_email, $this->generate_temp_password($user_id));
|
||||
|
||||
// درخواست توکن از Bridge endpoint (جدید)
|
||||
$token = $this->request_bridge_token(
|
||||
$user_id,
|
||||
$wp_user->user_email,
|
||||
$wp_user->display_name
|
||||
);
|
||||
|
||||
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')));
|
||||
@ -43,13 +50,18 @@ class IFNEX_User_Bridge {
|
||||
return $token;
|
||||
}
|
||||
|
||||
/**
|
||||
* درخواست توکن از لاراول
|
||||
/**
|
||||
* درخواست توکن از Bridge endpoint جدید
|
||||
* این روش نیازی به رمز عبور ندارد و از API Key مشترک استفاده میکند
|
||||
*/
|
||||
private function request_token($email, $password) {
|
||||
//$url = $this->api_url . '/sanctum/token';
|
||||
|
||||
$url = $this->api_url . '/auth/login';
|
||||
private function request_bridge_token($wp_user_id, $email, $name) {
|
||||
$url = $this->api_url . '/bridge/login';
|
||||
$bridge_key = get_option('ifnex_bridge_api_key', '');
|
||||
|
||||
if (empty($bridge_key)) {
|
||||
error_log('IFNEX: Bridge API Key is not configured in WordPress settings');
|
||||
return false;
|
||||
}
|
||||
|
||||
$args = array(
|
||||
'headers' => array(
|
||||
@ -57,8 +69,10 @@ class IFNEX_User_Bridge {
|
||||
'Accept' => 'application/json',
|
||||
),
|
||||
'body' => json_encode(array(
|
||||
'email' => $email,
|
||||
'password' => $password,
|
||||
'bridge_api_key' => $bridge_key,
|
||||
'wp_user_id' => $wp_user_id,
|
||||
'wp_user_email' => $email,
|
||||
'wp_user_name' => $name,
|
||||
'token_name' => 'wordpress-bridge-' . get_current_blog_id(),
|
||||
)),
|
||||
'timeout' => 30,
|
||||
@ -67,6 +81,7 @@ class IFNEX_User_Bridge {
|
||||
$response = wp_remote_post($url, $args);
|
||||
|
||||
if (is_wp_error($response)) {
|
||||
error_log('IFNEX Bridge Error: ' . $response->get_error_message());
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -77,35 +92,23 @@ class IFNEX_User_Bridge {
|
||||
return $data['token'];
|
||||
}
|
||||
|
||||
error_log('IFNEX Bridge Token Error: ' . ($data['message'] ?? 'Unknown error'));
|
||||
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 لاراول
|
||||
/**
|
||||
* ارسال درخواست احراز هویتشده به 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;
|
||||
|
||||
$method = strtoupper($method);
|
||||
|
||||
$args = array(
|
||||
'headers' => array(
|
||||
'Authorization' => 'Bearer ' . $token,
|
||||
@ -113,16 +116,16 @@ class IFNEX_User_Bridge {
|
||||
'Content-Type' => 'application/json',
|
||||
),
|
||||
'timeout' => 30,
|
||||
'method' => $method, // ✅ همیشه متد درخواستی استفاده شود
|
||||
);
|
||||
|
||||
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);
|
||||
}
|
||||
// ✅ اصلاح: بر اساس متد، data را اضافه کن
|
||||
if (in_array($method, ['POST', 'PUT', 'PATCH'])) {
|
||||
// حتی اگر data خالی باشد، body را خالی بفرست
|
||||
$args['body'] = json_encode($data ?: new \stdClass());
|
||||
} elseif ($method === 'GET' && !empty($data)) {
|
||||
// برای GET، data را به URL اضافه کن
|
||||
$url = add_query_arg($data, $url);
|
||||
}
|
||||
|
||||
$response = wp_remote_request($url, $args);
|
||||
@ -132,13 +135,22 @@ class IFNEX_User_Bridge {
|
||||
}
|
||||
|
||||
$body = wp_remote_retrieve_body($response);
|
||||
$code = wp_remote_retrieve_response_code($response);
|
||||
$data = json_decode($body, true);
|
||||
|
||||
if ($response['response']['code'] === 401) {
|
||||
// لاگ برای دیباگ
|
||||
error_log("IFNEX API [{$method}] {$endpoint} => Status: {$code}");
|
||||
|
||||
if ($code === 401) {
|
||||
$this->invalidate_token(get_current_user_id());
|
||||
return new WP_Error('token_expired', 'توکن منقضی شده است. لطفاً دوباره وارد شوید.');
|
||||
}
|
||||
|
||||
// اگر پاسخ JSON نیست
|
||||
if (!is_array($data)) {
|
||||
return new WP_Error('invalid_response', 'پاسخ نامعتبر از سرور: ' . substr($body, 0, 200));
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
@ -427,10 +439,12 @@ function ifnex_enqueue_order_assets() {
|
||||
global $post;
|
||||
if (!is_a($post, 'WP_Post')) return;
|
||||
|
||||
$has_order_shortcodes =
|
||||
has_shortcode($post->post_content, 'ifnex_orders_list') ||
|
||||
has_shortcode($post->post_content, 'ifnex_order_form') ||
|
||||
has_shortcode($post->post_content, 'ifnex_user_profile');
|
||||
$has_order_shortcodes =
|
||||
has_shortcode($post->post_content, 'ifnex_orders_list') ||
|
||||
has_shortcode($post->post_content, 'ifnex_order_form') ||
|
||||
has_shortcode($post->post_content, 'ifnex_user_profile') ||
|
||||
has_shortcode($post->post_content, 'ifnex_order_payment') ||
|
||||
has_shortcode($post->post_content, 'ifnex_order_detail');
|
||||
|
||||
if ($has_order_shortcodes) {
|
||||
// ✅ اصلاح: dirname(__FILE__) یک سطح بالاتر میرود
|
||||
@ -461,4 +475,76 @@ function ifnex_enqueue_order_assets() {
|
||||
'orders_url' => home_url('/my-orders/'),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
// ══════════════════════════════════════════════════════════════
|
||||
// AJAX Handlers برای پرداخت سفارش
|
||||
// ══════════════════════════════════════════════════════════════
|
||||
|
||||
add_action('wp_ajax_ifnex_pay_order_wallet', 'ifnex_pay_order_wallet_ajax');
|
||||
function ifnex_pay_order_wallet_ajax() {
|
||||
check_ajax_referer('ifnex_ajax_nonce', 'nonce');
|
||||
if (!is_user_logged_in()) wp_send_json_error('باید وارد شوید.');
|
||||
|
||||
$order_id = intval($_POST['order_id'] ?? 0);
|
||||
if (!$order_id) wp_send_json_error('شناسه سفارش نامعتبر است.');
|
||||
|
||||
$bridge = new IFNEX_User_Bridge();
|
||||
$result = $bridge->authenticated_request(
|
||||
get_current_user_id(),
|
||||
"/customer/orders/{$order_id}/pay-wallet",
|
||||
'POST'
|
||||
);
|
||||
|
||||
if (is_wp_error($result)) wp_send_json_error($result->get_error_message());
|
||||
if (isset($result['success']) && !$result['success']) {
|
||||
wp_send_json_error($result['message'] ?? 'خطا در پرداخت');
|
||||
}
|
||||
|
||||
wp_send_json_success($result);
|
||||
}
|
||||
|
||||
add_action('wp_ajax_ifnex_pay_order_gateway', 'ifnex_pay_order_gateway_ajax');
|
||||
function ifnex_pay_order_gateway_ajax() {
|
||||
check_ajax_referer('ifnex_ajax_nonce', 'nonce');
|
||||
if (!is_user_logged_in()) wp_send_json_error('باید وارد شوید.');
|
||||
|
||||
$order_id = intval($_POST['order_id'] ?? 0);
|
||||
$callback_url = sanitize_url($_POST['callback_url'] ?? '');
|
||||
|
||||
if (!$order_id) wp_send_json_error('شناسه سفارش نامعتبر است.');
|
||||
if (!$callback_url) wp_send_json_error('آدرس بازگشت نامعتبر است.');
|
||||
|
||||
$bridge = new IFNEX_User_Bridge();
|
||||
$result = $bridge->authenticated_request(
|
||||
get_current_user_id(),
|
||||
"/customer/orders/{$order_id}/pay-gateway",
|
||||
'POST',
|
||||
['frontend_callback' => $callback_url]
|
||||
);
|
||||
|
||||
if (is_wp_error($result)) wp_send_json_error($result->get_error_message());
|
||||
if (isset($result['success']) && !$result['success']) {
|
||||
wp_send_json_error($result['message'] ?? 'خطا در اتصال به درگاه');
|
||||
}
|
||||
|
||||
wp_send_json_success($result);
|
||||
}
|
||||
|
||||
// Enqueue برای صفحه پرداخت
|
||||
add_action('wp_enqueue_scripts', 'ifnex_enqueue_payment_assets');
|
||||
function ifnex_enqueue_payment_assets() {
|
||||
global $post;
|
||||
if (!is_a($post, 'WP_Post')) return;
|
||||
|
||||
if (has_shortcode($post->post_content, 'ifnex_order_payment')) {
|
||||
$plugin_url = plugin_dir_url(dirname(__FILE__));
|
||||
wp_enqueue_style('ifnex-orders-css', $plugin_url . 'assets/css/ifnex-orders.css', array(), '1.3.0');
|
||||
wp_enqueue_script('jquery');
|
||||
wp_localize_script('jquery', 'ifnex_ajax', array(
|
||||
'ajax_url' => admin_url('admin-ajax.php'),
|
||||
'nonce' => wp_create_nonce('ifnex_ajax_nonce'),
|
||||
'orders_url' => home_url('/my-orders/'),
|
||||
));
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user