Install
This is the repository archive. It installs, but the folder name will carry the branch suffix and updates will not flow.
Install straight from GitHub with WP-CLI:
wp plugin install https://github.com/keyvansolha/ts-bnpl/archive/refs/heads/main.zipقیمتگذاری اقساطی ۴ قسطه و نمایش طرح خرید اعتباری دیجیپی در فروشگاه تهراناسپیکر.
English: Installment pricing and Digipay 4-month plan display for Tehran Speaker online store.
نیازمندیها / Requirements
- WordPress 6.5+
- PHP 7.4+
- WooCommerce 8.0+
- Amazing theme (optional, for tight integration)
نصب / Installation
- کپی کنید پوشهی
ts-bnplرا بهwp-content/plugins/ - فعال کنید افزونه از پیشخوان ووکامرس
- برای اعلام سازگاری با HPOS، هیچ کار اضافی لازم نیست
cp -r ts-bnpl /path/to/wp-content/plugins/
تنظیمات / Configuration
قیمتهای اقساطی
محصولات ← قیمتهای اقساطی (Products → Installment Prices)
- جدول همهی محصولات و متغیرهایی که قیمت اقساطی دارند
- ستونهای نمایش: نام، SKU، قیمت نقدی، قیمت اقساطی، اختلاف
- مرتبسازی بر حسب مبلغ اختلاف و درصد
- خروجی CSV برای تطبیق با سیستم حسابداری
- خلاصهی آماری: تعداد، میانگین تفاوت، و محدوده
نمایش در صفحهی محصول
محصولات ← قیمتهای اقساطی → قسمت "نمایش در صفحهی محصول"
چهار حالت نمایش:
1️⃣ حالت بازشونده (Accordion)
- تیزر کمرنگ: "امکان خرید ۴ قسطه این کالا از تهراناسپیکر"
- کلیک → جزئیات (مبلغ، لوگو، راهنما) همانجا باز میشود
- پیشفرض
2️⃣ حالت پنل راهنما (Modal)
- تیزر کمرنگ
- کلیک → پنل راهنما باز میشود
- جزئیات طرح بالای بخش "خرید اقساطی چگونه انجام میشود"
3️⃣ حالت صفحهی فرود (Landing)
- تیزر کمرنگ، اما این بار یک لینک است نه دکمه
- کلیک → کاربر به صفحهی کامل راهنمای خرید اعتباری میرود
- نیازمند انتخاب یک برگه در بخش «صفحهی فرود خرید اعتباری»
- اگر برگهای انتخاب نشده باشد، بهصورت خودکار به حالت بازشونده برمیگردد
4️⃣ حالت صفحهی فرود تصویری (Visual Landing — Experimental)
- روی همان برگهی انتخابی «صفحهی فرود خرید اعتباری» فعال میشود
- محتوا و تصاویر از مدیر اختصاصی محصولات ← لندینگ تصویری (آزمایشی) میآیند
- محتوای دستی برگه را در این حالت جایگزین میکند؛ Landing قدیمی همچنان محتوای دستی را حفظ و بدنهی خودش را به آن اضافه میکند
- اگر برگهی منتشرشدهای انتخاب نشده باشد، مثل Landing قدیمی به حالت بازشونده برمیگردد
تنظیم متن تیزر: فیلد "متن قابل کلیک"
- خالی = پیشفرض: "امکان خرید ۴ قسطه این کالا از تهراناسپیکر"
صفحهی فرود / Landing Page
یک برگهی معمولی وردپرس بسازید (مثلاً «خرید اعتباری») و آن را در محصولات ← قیمتهای اقساطی ← صفحهی فرود خرید اعتباری انتخاب کنید.
افزونه محتوای کامل را روی همان یک برگه میسازد. لازم نیست چیزی داخل برگه بنویسید — نه گوتنبرگ، نه المنتور، نه شورتکد، نه HTML.
چه چیزی رندر میشود
- هیرو و معرفی خرید اعتباری
- مراحل خرید در ۴ گام
- راهنمای تشخیص کالای واجد شرایط
- کاروسل «محصولاتی که قابلیت خرید اعتباری دارند»
- توضیح تفاوت مبلغ نهایی با قیمت نقدی
- پرسشهای پرتکرار
- فراخوان پایانی
هدر، فوتر، بردکرامپ و <h1> از خود قالب و عنوان برگه میآیند؛ افزونه فقط بدنه
را اضافه میکند و محتوای دستی خود برگه (اگر چیزی نوشته باشید) بالای آن حفظ
میشود.
قواعد مهم
- هیچ شناسهای هاردکد نیست. با عوض کردن برگه در تنظیمات، لندینگ جابهجا میشود.
- فقط همان یک برگه تغییر میکند. بقیهی صفحات دستنخورده میمانند.
- اگر برگهای انتخاب نشده باشد، هیچ صفحهای override نمیشود.
- محتوای لندینگ عمداً provider-neutral است: نه نام ارائهدهنده، نه تعداد قسط، نه نرخ، نه سقف اعتبار.
کاروسل کالاهای واجد شرایط
- منطق واجد شرایط بودن دقیقاً همان منطق صفحهی محصول است: متای
_bnpl_priceبا مقدار بزرگتر از صفر. سیستم موازی و شناسهی ثابت وجود ندارد. - کاملاً پویاست و هیچ برچسبی لازم ندارد. به محض اینکه قیمت اقساطی یک کالا ثبت شود در کاروسل میآید و به محض خالی شدنش حذف میشود. نه تگ، نه دسته، نه taxonomy، نه نگهداری دستی در پیشخوان.
- برای کالاهای متغیر، متا روی خودِ متغیر است و کارت والد نمایش داده میشود.
- کارتها همان
simple-card.phpقالب هستند؛ کارت اختصاصی BNPL ساخته نشده. - استایل کارت و کاروسل هم از خود قالب صف میشوند (
archiveModular.cssیا نسخهی موبایلش، بهعلاوهassets/scss/modules/product-carousel.css). قالب این فایلها را فقط در آرشیو و صفحههای page-builder لود میکند، پس افزونه همان هندلها را روی برگهی فرود صف میکند. هیچ استایل کارتی بازنویسی نشده. - ظرف کاروسل کلاس
products-carousel-panelقالب را دارد، چون CSS ماژول به همان اسکوپ شده و عرض اسلاید و اسکرول موبایل از آنجا میآید. - کارتهای محصول در بقیهی سایت (خانه، جستوجو، برند، آرشیو) هیچ تغییری نمیکنند؛ هیچ نشان یا برچسبی به آنها اضافه نمیشود.
- اسلایدر همان Swiper خود قالب است؛ کتابخانهی جدیدی اضافه نشده.
- روی موبایل اسکرول افقی با snap، مثل بقیهی کاروسلهای سایت.
- اگر کالای واجد شرایطی نباشد، یک پیام تمیز نمایش داده میشود و چیدمان نمیشکند.
فهرست کامل در آرشیو فروشگاه
دکمهی «مشاهده محصولات...» کاربر را به ?ts_bnpl=1 روی آرشیو فروشگاه میبرد و
همان صفحه فقط کالاهای واجد شرایط را نشان میدهد — با مرتبسازی، فیلترها،
صفحهبندی و کارتهای همیشگی خودش.
- قالب آرشیو را با
WC_Product_Queryخودش میسازد و هیچ هوکی ندارد، پس بهجای دست بردن در آن، فیلترwoocommerce_product_data_store_cpt_get_products_queryووکامرس گرفته میشود. فهرست، شمارش «X کالا» و بازهی قیمت با هم فیلتر میشوند. - از
post__inاستفاده میشود نهmeta_query، چون در کالاهای متغیر متای قیمت اقساطی روی خودِ متغیر است و کوئری روی والد پیدایش نمیکند. - صفحهبندی و مرتبسازی آرشیو از ایجکس میآیند و فرم را serialize میکنند، پس
پرچم به شکل یک ورودی پنهان در همان فرم هم قرار میگیرد
(
lib/Archive/template/sample/active-filters.phpدر قالب، پشتclass_exists). - بدون این پارامتر، آرشیو فروشگاه دقیقاً مثل همیشه کار میکند.
صفحهی فرود تصویری آزمایشی / Visual Landing
پس از انتخاب همان برگهی Landing، حالت Visual Landing (Experimental) / لندینگ تصویری (آزمایشی) را در محصولات ← قیمتهای اقساطی ← نمایش در صفحهی محصول انتخاب کنید. محتوای این نسخه از محصولات ← لندینگ تصویری (آزمایشی) مدیریت میشود و شش تب دارد: Top Banners، Hero، Providers، Eligibility، Conditions و Final CTA.
- بنرها قابل افزودن، حذف و مرتبسازیاند. یک بنر ثابت است؛ از دو بنر به بالا همان Swiper موجود سایت با دکمه و pagination فعال میشود.
- هر تصویر محتوایی source جداگانهی AVIF و WebP برای دسکتاپ و موبایل دارد. اولین بنر اولویت LCP میگیرد و بقیهی تصاویر lazy هستند.
- ارائهدهنده وقتی عمومی میشود که به یک درگاه اقساطی واقعی و ثبتشده وصل باشد، نمایش آن در مدیر لندینگ روشن باشد و خود درگاه ووکامرس نیز فعال و خارج از حالت تست باشد. در دسترسبودن برای سبد جاری در checkout بررسی میشود.
- کارت محصولات، منطق واجد شرایط بودن، FAQ، کاروسل و لوگوی متحرک از پیادهسازی موجود قالب/افزونه استفاده میشوند؛ نمونهی بخش Eligibility نیز همان تیزر واقعی صفحه محصول است و checkout و دادههای مالی مسیر جدا ندارند.
- breadcrumb، عنوان قالب و محتوای ویرایشگر فقط روی برگهی انتخابی و فقط در این mode پنهان/جایگزین میشوند.
- اندازهها، نسبتها، حجم فایل، safe area، نامگذاری و محل دقیق آپلود در راهنمای تحویل تصویر آمده است.
رابط کاربری / UI
صفحهی محصول / Product Page
قیمت نقدی همیشه CTA اصلی میماند.
خرید اعتباری یک گزینهی ثانویه و جمع:
- تا کاربر کلیک نکند، مبلغ قسط و نام دیجیپی دیده نمیشود
- موبایل و دسکتاپ با طراحی تطبیقی پشتیبانی میشوند
متغیرهای متحرک: با تعویض رنگ/ویژگی:
- مبلغ قسط بهروز میشود
- در حالت مودال، جزئیات در داخل پنل جایی دارد
تسویهحساب / Checkout
- درگاه دیجیپی وقتی فعال است، نمایش دارد
- انتخاب درگاه → مبالغ بازمحاسبه میشود
- کیف پول جزئی خودکار غیرفعال میشود تا تضاد مبالغ رخ ندهد
توسعه / Development
بازنویسی تنظیمات
برای override حالت یا متن تیزر در کد:
// تغییر حالت جهانی
add_filter( 'ts_bnpl_display_mode', function () {
return 'modal'; // accordion، modal، landing یا visual_landing
} );
// تغییر صفحهی فرود
add_filter( 'ts_bnpl_landing_page_id', function () {
return 123;
} );
// دستکاری فهرست کالاهای کاروسل
add_filter( 'ts_bnpl_eligible_product_ids', function ( $ids ) {
return $ids;
} );
// تغییر متن تیزر
add_filter( 'ts_bnpl_teaser_text', function () {
return 'خرید اقساطی دسترسپذیر است';
} );
قیمت اقساطی محصول
// دریافت
$teaser_html = TS_BNPL_Display::teaser_html( $total );
// در variation:
$variation['bnpl_html'] = TS_BNPL_Display::teaser_html( $total );
دادههای متادیتا
- محصول:
_bnpl_price(قیمت اقساطی) - سفارش:
_is_bnpl(آیا اقساط است) - سفارش:
_bnpl_months(تعداد اقساط، مثلاً ۴)
اختبار / Testing
لندینگ تصویری
php tests/mode-routing.test.php
php tests/legacy-landing-routing.test.php
php tests/visual-settings.test.php
php tests/responsive-media.test.php
php tests/providers.test.php
php tests/visual-admin.test.php
php tests/visual-render.test.php
node --test tests/*.test.mjs
صفحهی محصول
# متغیرهای متحرک و تیزرهای دو حالت
npm test -- tests/product-variation.test.mjs
تسویهحساب
# بازمحاسبه هنگام تعویض درگاه
npm test -- tests/checkout-experience.test.mjs
حقالاستفاده / License
تمام کد در این افزونه برای تهراناسپیکر اختصاصی است.
پشتیبانی / Support
برای مسائل یا بهبودهای پیشنهادی، درخواست pull یا issue را باز کنید.