پرش به مطلب اصلی

راهنمای پرداخت درون‌برنامه‌ای مایکت در Unity

Unity
پروژه نمونه

برای مشاهده نمونه کامل پرداخت درون‌برنامه‌ای مایکت در یونیتی، به پروژه نمونه رسمی در GitHub مراجعه کنید.

پلاگین Myket In-App Billing (IAB) Unity ابزار رسمی مایکت برای پیاده‌سازی پرداخت درون‌برنامه‌ای در بازی‌ها و برنامه‌های اندرویدی توسعه‌یافته با موتور بازی‌سازی یونیتی (Unity) است.

قابلیت‌ها​

  • محصولات مصرف‌شدنی و غیرمصرفی: پشتیبانی از خرید محصولات یک‌باره (مانند سکه، اعتبار، الماس یا ارتقای دائمی).
  • استعلام موجودی و بازیابی خریدها: استعلام خریدهای فعال کاربر و دریافت مشخصات کاتالوگ محصولات.
  • مدیریت مصرف تکی و گروهی: ارائه متدهای consumeProduct و consumeProducts جهت آزادسازی محصولات مصرفی.
  • معماری مبتنی بر رویداد: رویدادهای C# در کلاس IABEventManager برای دریافت ناهمگام نتایج.
  • پشتیبانی از قالب‌های Gradle یونیتی: مدیریت وابستگی‌ها از طریق مخزن رسمی Maven مایکت در settingsTemplate.gradle و launcherTemplate.gradle.
  • قوانین ProGuard و R8: جلوگیری از حذف کلاس‌های ارتباطی بومی در بیلد Release.

پیش‌نیازها​

  • ویرایشگر Unity: نسخه Unity 6 (6000.x) یا Unity 2022 LTS به همراه ماژول Android Build Support.
  • محیط توسعه جاوا (JDK): نسخه سازگار با Java 17.
  • دستگاه آزمایشی: دستگاه اندرویدی دارای آخرین نسخه برنامه مایکت نصب‌شده و حساب کاربری فعال.
  • حساب توسعه‌دهندگان مایکت:
    • ثبت برنامه با شناسه بسته (Package Name) منطبق با تنظیمات Player در یونیتی.
    • تعریف محصولات درون‌برنامه‌ای و SKUها.
    • دریافت کلید عمومی RSA پرداخت برنامه.

[!NOTE] ارتباط با سرویس پرداخت مایکت از طریق پروتکل IPC (AIDL) اندروید برقرار می‌شود؛ بنابراین برنامه بازارگاه مایکت باید روی دستگاه تست نصب و فعال باشد.

ساختار پوشه‌های پلاگین​

Assets/
├── MyketIAB/ # هسته اصلی پلاگین C# مایکت
│ ├── MyketIAB.cs # پل ارتباطی اصلی بومی به C#
│ ├── MyketIABEventManager.cs # مدیریت رویدادها (C# Actions)
│ ├── MyketPurchase.cs # مدل داده خرید
│ ├── MyketSkuInfo.cs # مدل داده اطلاعات محصول
│ ├── AbstractManager.cs # پل ارتباطی ارسال پیام بومی
│ ├── ActionExtensions.cs # متدهای کمکی اکشن‌ها
│ ├── SimpleJSON.cs # پارسر سبک JSON
│ └── Demo/ # صحنه و اسکریپت‌های نمونه
│ ├── IABTestScene.unity # صحنه تست تعاملی
│ ├── IABTestUI.cs # رابط گرافیکی تست
│ └── MyketIABEventListener.cs # نمونه لیسنر رویدادها
└── Plugins/
└── Android/ # پیکربندی‌های ساخت اندروید
├── AndroidManifest.xml # مانیفست اختصاصی اندروید
├── launcherTemplate.gradle # وابستگی‌های سطح برنامه
├── settingsTemplate.gradle # مخزن رسمی Maven مایکت
├── gradleTemplate.properties # مشخصات JVM گریدل
└── proguard-user.txt # قوانین R8 / ProGuard

اجرای سریع پروژه نمونه​

پشتیبانی از اشتراک

وجود سناریوی اشتراک در کد نمونه به معنی پشتیبانی فعلی مایکت از اشتراک نیست. طبق مستندات فعلی، مایکت از محصولات اشتراکی پشتیبانی نمی‌کند؛ بنابراین بخش مربوط به اشتراک را برای محصول واقعی استفاده نکنید.

۱. کلون کردن مخزن گیت‌هاب:

git clone https://github.com/myketstore/billing-sample-unity.git

۲. باز کردن در Unity Hub:

  • وارد Unity Hub شوید.
  • روی Add -> Add project from disk کلیک کرده و پوشه ریشه پروژه را انتخاب کنید.
  • پروژه را با نسخه Unity 6 یا نسخه پشتیبانی‌شده باز کنید. ۳. تنظیم شناسه بسته (Package Name):
  • از منوی یونیتی به مسیر Edit > Project Settings > Player > برگه Android بروید.
  • در بخش Other Settings > Identification، مقدار Package Name را با شناسه ثبت‌شده در پنل مایکت هماهنگ کنید. ۴. تنظیم کلید عمومی و SKUها:
  • فایل Assets/MyketIAB/Demo/IABTestUI.cs را باز کنید.
  • کلید عمومی RSA و SKUهای محصولات خود را جایگزین کنید:
    var key = "YOUR_MYKET_PUBLIC_KEY";
    MyketIAB.init(key);

۵. بیلد و اجرا:

  • صحنه Assets/MyketIAB/Demo/IABTestScene.unity را باز کنید.
  • دستگاه اندرویدی را با کابل USB متصل کنید (با فعال بودن حالت Developer و USB Debugging).
  • از منوی File > Build Settings... پلتفرم را روی Android قرار داده و روی Build and Run کلیک کنید.

افزودن به پروژه موجود​

برای افزودن پرداخت مایکت به یک پروژه یونیتی موجود:

۱. انتقال فایل‌های پلاگین​

پوشه Assets/MyketIAB/ را از پروژه نمونه به پوشه Assets/ پروژه خود منتقل کنید.

۲. فعال‌سازی قالب‌های اختصاصی Gradle​

در یونیتی به مسیر Project Settings > Player > برگه Android > Publishing Settings رفته و گزینه‌های زیر را تیک بزنید:

  • Custom Launcher Gradle Template (یا Custom Main Gradle Template)
  • Custom Gradle Settings Template
  • Custom Proguard File

الف) افزودن مخزن Maven مایکت (settingsTemplate.gradle)​

آدرس https://maven.myket.ir را به Assets/Plugins/Android/settingsTemplate.gradle اضافه کنید:

dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS)
repositories {
google()
mavenCentral()
maven { url 'https://maven.myket.ir' }
flatDir {
dirs "${project(':unityLibrary').projectDir}/libs"
}
}
}

ب) افزودن وابستگی پرداخت بومی (launcherTemplate.gradle)​

در فایل Assets/Plugins/Android/launcherTemplate.gradle، وابستگی زیر را در بخش dependencies اضافه کنید:

dependencies {
implementation project(':unityLibrary')
implementation 'ir.myket:billing-unity:2.2'
}

همچنین در بلوک android از تنظیم سازگاری با Java 17 اطمینان حاصل کنید:

android {
compileOptions {
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
// ...
}

و در بخش defaultConfig مشخصه‌های سرویس پرداخت را ثبت کنید:

defaultConfig {
manifestPlaceholders += [
marketApplicationId: "ir.mservices.market",
marketBindAddress: "ir.mservices.market.InAppBillingService.BIND",
marketPermission: "ir.mservices.market.BILLING"
]
}

۳. تنظیم قوانین ProGuard / R8​

برای جلوگیری از حذف کلاس‌های پل بومی در بیلد Release، مطمئن شوید قوانین زیر در فایل Assets/Plugins/Android/proguard-user.txt وجود دارند:

-keep class ir.myket.billingclient.** { *; }
-keep interface ir.myket.billingclient.** { *; }
-keep class com.android.vending.billing.** { *; }
-keep interface com.android.vending.billing.** { *; }

راهنمای کدنویسی و متدهای API​

۱. مقداردهی اولیه (init)​

در ابتدای چرخه حیات بازی (مثلاً در Awake یا Start)، سرویس پرداخت را با کلید عمومی Base64 مایکت مقداردهی کنید:

using MyketPlugin;

string myketPublicKey = "YOUR_MYKET_PUBLIC_KEY";
MyketIAB.init(myketPublicKey);

۲. مدیریت رویدادها (Event Handling)​

ارتباط با سرویس مایکت غیرهم‌زمان است. برای دریافت پاسخ‌ها به رویدادهای IABEventManager متصل شوید. ثبت رویدادها را در OnEnable و حذف ثبت آن‌ها را در OnDisable انجام دهید:

using System.Collections.Generic;
using UnityEngine;
using MyketPlugin;

public class BillingManager : MonoBehaviour
{
void OnEnable()
{
IABEventManager.billingSupportedEvent += OnBillingSupported;
IABEventManager.billingNotSupportedEvent += OnBillingNotSupported;
IABEventManager.queryInventorySucceededEvent += OnQueryInventorySucceeded;
IABEventManager.queryInventoryFailedEvent += OnQueryInventoryFailed;
IABEventManager.purchaseSucceededEvent += OnPurchaseSucceeded;
IABEventManager.purchaseFailedEvent += OnPurchaseFailed;
IABEventManager.consumePurchaseSucceededEvent += OnConsumeSucceeded;
IABEventManager.consumePurchaseFailedEvent += OnConsumeFailed;
}

void OnDisable()
{
IABEventManager.billingSupportedEvent -= OnBillingSupported;
IABEventManager.billingNotSupportedEvent -= OnBillingNotSupported;
IABEventManager.queryInventorySucceededEvent -= OnQueryInventorySucceeded;
IABEventManager.queryInventoryFailedEvent -= OnQueryInventoryFailed;
IABEventManager.purchaseSucceededEvent -= OnPurchaseSucceeded;
IABEventManager.purchaseFailedEvent -= OnPurchaseFailed;
IABEventManager.consumePurchaseSucceededEvent -= OnConsumeSucceeded;
IABEventManager.consumePurchaseFailedEvent -= OnConsumeFailed;
}

void OnBillingSupported()
{
Debug.Log("اتصال به سرویس پرداخت مایکت برقرار شد.");
// اکنون می‌توانید استعلام موجودی یا خرید را آغاز کنید
}

void OnBillingNotSupported(string error)
{
Debug.LogError("سرویس پرداخت مایکت پشتیبانی نمی‌شود: " + error);
}

void OnPurchaseSucceeded(MyketPurchase purchase)
{
Debug.Log($"خرید موفق برای محصول: {purchase.ProductId}، توکن: {purchase.PurchaseToken}");

// اگر محصول مصرف‌شدنی است (سکه، الماس، بنزین):
if (purchase.ProductId == "gem_pack_100")
{
MyketIAB.consumeProduct(purchase.ProductId);
}
else
{
// محصول ماندگار / غیرمصرفی (ارتقای ویژه)
UnlockFeature();
}
}

void OnPurchaseFailed(string error)
{
Debug.LogError("خطا در خرید محصول: " + error);
}

void OnConsumeSucceeded(MyketPurchase purchase)
{
Debug.Log($"محصول با موفقیت مصرف شد: {purchase.ProductId}");
// اعطای الماس یا سکه به بازیکن
}

void OnConsumeFailed(string error)
{
Debug.LogError("خطا در مصرف محصول: " + error);
}

void OnQueryInventorySucceeded(List<MyketPurchase> purchases, List<MyketSkuInfo> skus)
{
Debug.Log("اطلاعات موجودی با موفقیت دریافت شد.");
// بازیابی خریدهای مصرفی معلق قبلی و محصولات غیرمصرفی
}

void OnQueryInventoryFailed(string error)
{
Debug.LogError("خطا در دریافت موجودی: " + error);
}
}

۳. استعلام موجودی و محصولات (queryInventory)​

برای دریافت مشخصات محصولات (عنوان، قیمت محلی، توضیحات) و خریدهای فعال کاربر:

// استعلام هم‌زمان اطلاعات SKU و وضعیت خریدهای کاربر
string[] productIds = new string[] { "gem_pack_100", "monthly_pass" };
MyketIAB.queryInventory(productIds);

// یا استعلام فقط مشخصات محصولات
MyketIAB.querySkuDetails(productIds);

// یا استعلام فقط خریدهای فعال کاربر
MyketIAB.queryPurchases();

۴. شروع فرآیند خرید (purchaseProduct)​

جهت نمایش دیالوگ درگاه پرداخت مایکت:

// خرید ساده
MyketIAB.purchaseProduct("gem_pack_100");

// خرید همراه با Developer Payload برای رهگیری و اعتبارسنجی امنیتی
MyketIAB.purchaseProduct("gem_pack_100", "unique_user_payload_123");
نکته

توجه کنید که مقدار طول رشته‌ی developerPayload نمی‌تواند بیش‌تر از ۸۰۰ کاراکتر باشد.

۵. مصرف محصولات خریداری‌شده (consumeProduct)​

محصولات مصرف‌شدنی (مانند سکه، انرژی، بسته‌ها) باید مصرف شوند تا کاربر امکان خرید مجدد آن‌ها را داشته باشد:

// مصرف یک محصول مشخص با شناسه SKU
MyketIAB.consumeProduct("gem_pack_100");

// مصرف هم‌زمان چند محصول به‌صورت گروهی
MyketIAB.consumeProducts(new string[] { "gem_pack_100", "gem_pack_200" });
اخطار مهم

محصولات غیرمصرفی (Non-consumable مانند حذف تبلیغات یا باز کردن مراحل دائمی) را هرگز مصرف نکنید. مصرف کالا آن را از لیست خریدهای فعال حساب کاربر در مایکت حذف می‌کند.

لاگ‌گیری و عیب‌یابی (Debugging & Troubleshooting)​

فعال‌سازی لاگ‌های جزئی​

در زمان توسعه و دیباگ می‌توانید لاگ‌های کامل ارتباط با سرویس مایکت را فعال کنید:

#if DEVELOPMENT_BUILD || UNITY_EDITOR
MyketIAB.enableLogging(true);
#endif
هشدار

لاگ‌های با جزئیات بالا، اطلاعات حساس پرداخت را در Logcat اندروید چاپ می‌کنند. پیش از ساخت نسخه نهایی Release، متد enableLogging(false) را قرار دهید.

رفع اشکالات متداول​

مشکلعلتراهکار
اجرای رویداد billingNotSupportedEventبرنامه مایکت روی دستگاه نصب نیست.آخرین نسخه برنامه مایکت را روی دستگاه تست اندروید نصب کرده و وارد حساب کاربری شوید.
خطای "Item Unavailable"شناسه SKU ثبت نشده یا برنامه در پنل مایکت فعال نیست.تطابق دقیق SKUها با پنل توسعه‌دهندگان مایکت و ثبت بودن Package Name برنامه را بررسی کنید.
خطای Signature verification failedکلید عمومی اشتباه است.مطمئن شوید کلید عمومی ارسالی به MyketIAB.init() دقیقاً با کلید پنل توسعه‌دهندگان مایکت مطابقت دارد.
کرش یا ClassNotFoundException در بیلد Releaseحذف کلاس‌های بومی توسط R8/ProGuard.مطمئن شوید قوانین فایل Assets/Plugins/Android/proguard-user.txt در تنظیمات ProGuard فعال هستند.
خطای بیلد گریدل: ir.myket:billing-unity not foundمخزن Maven تعریف نشده است.مطمئن شوید maven { url 'https://maven.myket.ir' } در settingsTemplate.gradle قرار دارد.