En

فصل ۴: خرید محصولات

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

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

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

خرید محصول

برای شروع عملیات خرید از برنامه خود، متدlaunchPurchaseFlow(Activity, String, int, OnIabPurchaseFinishedListener, String) را از نمونه IabHelper فراخوانی کنید. شما باید این فراخوانی را از thread اصلی Activity خود انجام دهید. توضیحی درباره متد launchPurchaseFlow در ادامه آمده:

  • اولین آرگومان Activity‌ای است که متد را صدا زده.
  • آرگومان دوم شناسه محصول (SKU نیز می‌نامیم) است. مطمئن شوید که شناسه محصول را می‌دهید نه نام محصول را. شما باید قبلاً این محصول را در پنل توسعه‌دهندگان مایکت تعریف کرده باشید، در غیر این صورت قابل شناسایی نخواهد بود.
  • آرگومان سوم مقدار یک «کد درخواست» است. این مقدار می‌تواند هر عدد صحیح مثبتی باشد. مایکت این کد درخواست را به همراه نتیجه خرید، به متد onActivityResult در Activity صدا زننده برمی‌گرداند.
  • آرگومان چهارم یک شنونده است که زمانی که عملیات خرید کامل شد آگاه می‌شود و پاسخ فرستاده شده از مایکت را بررسی می‌نماید.
  • پنجمین آرگومان رشته‌ای به نام «developer payload» است که شما می‌توانید با استفاده از آن اطلاعات تکمیلی درباره سفارش خود بفرستید (می‌تواند یک رشته خالی باشد). به طور معمول از این رشته به عنوان یک نشانه استفاده می‌شود که منحصرا این درخواست خرید را شناسایی می‌کند. اگر شما این رشته را مقداری دهی کنید، مایکت به همراه پاسخ خرید این رشته را نیز برمی‌گرداند. متعاقبا، هر زمان که کوئری در مورد این محصول بزنید، مایکت این رشته را به همراه سایر جزئیات محصول برمی‌گرداند.

توصیه مهم: بهتر است از یک رشته استفاده کنید که به برنامه شما کمک کند تا کاربری که خرید را انجام داده تعیین هویت کند، بدین صورت شما بعدا می‌توانید مطمئن شوید که این یک خرید معتبر توسط آن کابر باشد (در اینجا منظور از «کاربر» کاربر برنامه شماست نه کاربر مایکت، البته در صورتی که برنامه شما امکان ساختن حساب کاربری داشته باشد. برنامه شما به مشخصات کاربر مایکت دسترسی ندارد). برای محصولات قابل استفاده، شما می‌توانید یک رشته تصادفی تولید استفاده کنید، اما برای محصولات غیر قابل مصرف شما باید از یک رشته استفاده کنید که بتوانید کاربر را منحصرا شناسایی کنید.

مثال زیر نشان می‌دهد که شما چگونه می‌توانید یک درخواست خرید برای یک محصول با شناسه SKU_GAS بسازید، با استفاده از مقدار دلخواه 10001 برای کد درخواست، و یک رشته developer payload کد شده.


mHelper.launchPurchaseFlow (this, SKU_GAS, 10001, mPurchaseFinishedListener, "bGoa+V7g/yqDXvKRqq+JTFn4uQZbPiQJo4pf9RzJ");
					

اگر سفارش خرید موفقیت آمیز باشد، پاسخی که از مایکت آمده در یک شی Purchase ذخیره می‌شود و به شنونده (Listener) داده می‌شود.

مثال زیر نشان می‌دهد که شما چگونه می‌توانید پاسخ دریافتی از مایکت را در شنونده (Listener) بررسی کنید، با توجه به اینکه آیا سفارش خرید با موفقیت به پایان رسیده است، و اینکه آیا کاربر «بنزین» یا «ارتقا ویژه» (Premium Upgrade) حساب کاربری خریده است. در این مثال، بنزین یک محصول درون‌برنامه‌ای است که می‌تواند چندین بار خریداری شود، بنابراین شما باید محصول خریده شده را مصرف کنید تا کاربر بتواند دوباره آن را بخرد. برای یادگیری نحوه مصرف محصول خریده شده بخش «مصرف یک محصول خریده شده» را در زیر ببینید. محصول «ارتقا ویژه» تنها یکبار قابل خرید است بنابراین شما نباید آن را مصرف کنید. کار خوبی‌ست که بلافاصله UI (رابط کاربری) را به روزرسانی کنید تا کاربران بتوانند محصولات خریداری شده خود را ببینند.


IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener = new IabHelper.OnIabPurchaseFinishedListener()  {
	public void onIabPurchaseFinished(IabResult result, Purchase purchase) {
			if (result.isFailure()) {
					Log.d(TAG, "Error purchasing: " + result);
					return;
			}
			else if (purchase.getSku().equals(SKU_GAS)) {
					// consume the gas and update the UI
			}
			else if (purchase.getSku().equals(SKU_PREMIUM)) {
					// give user access to premium content and update the UI
			}
	}
};
					

توصیه امنیتی: وقتی که شما پاسخ خرید را از مایکت دریافت می‌کنید، حتما امضای (Signature) داده‌های دریافتی، orderId و رشته developerPayload در شی Purchase را بررسی کنید، تا مطمئن شوید که همان مقادیر مورد انتظار شما هستند. باید کنترل کنید که orderId دارای یک مقدار منحصر به فرد که قبلا ندیده‌اید، و رشته developerPayload مطابق با همان چیزی‌ست که قبلاً با درخواست خرید فرستاده‌اید. حتی برای امنیت بیشتر می‌توانید این بررسی‌ها را به جای دستگاه کاربر روی سرور خودتان انجام دهید.

کوئری محصولات خریداری شده

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

برای دریافت خریدهای کاربر از برنامه خود، از نمونه IabHelper که دارید، متد queryInventoryAsync(QueryInventoryFinishedListener) را فراخوانی کنید. آرگومان QueryInventoryFinishedListener یک شنونده است که وقتی عملیات کوئری به پایان رسید مطلع می‌شود و پاسخ کوئری را بررسی می‌کند. صدا زدن این متد از thread اصلی برنامه مشکلی ندارد.


mHelper.queryInventoryAsync ( mGotInventoryListener ) ;
					

اگر کوئری موفقیت آمیز باشد، نتایج آن در یک شی Inventory ذخیره، و به شنونده داده می‌شود. سرویس خرید درون‌برنامه‌ای تنها خریدهای حساب کاربری‌ای را برمی‌گرداند که همان موقع در مایکت لاگین است. اگر هم هیچ کاربری لاگین نباشد کوئری ناموفق خواهد بود و مایکت در پاسخی که برمی‌گرداند این را اطلاع می‌دهد، در چنین حالتی بهتر است که برنامه شما به طریقی کاربر را مطلع سازد که در مایکت لاگین نکرده است.


IabHelper.QueryInventoryFinishedListener mGotInventoryListener = new IabHelper.QueryInventoryFinishedListener()  {
	   public void onQueryInventoryFinished(IabResult result, Inventory inventory) {
	        if (result.isFailure()) {        
	            // handle error here      
	        }      
	        else {
	            // does the user have the premium upgrade?
	            mIsPremium = inventory.hasPurchase(SKU_PREMIUM);
	            // update UI accordingly      
	        }   
	    } };
					

مصرف یک محصول خریده شده

شما می‌توانید از سرویس خرید درون‌برنامه‌ای برای پیگیری مالکیت محصولات خریداری شده در مایکت استفاده کنید. هنگامی که یک محصول توسط کاربر خریداری شد، مالک آن محصول تلقی می‌شود و تا زمانی که در همین وضعیت باشد، اجازه خرید دوباره محصول به وی داده نمی‌شود. شما باید یک درخواست مصرف برای آن محصول ارسال کنید تا مایکت اجازه خرید دوباره آن محصول را به کاربر بدهد. محصولات می‌توانند مصرف شدنی یا مصرف نشدنی باشند. تعریف مصرف کردن محصولات به عهده شما می‌باشد. به طور معمول، شما محصولاتی را مصرف می‌کنید که مزایای موقتی دارند و کاربران ممکن است بخواهند چندین بار آنها را بخرند (مثلا، پول در بازی یا چیزهایی که دوباره شارژ می‌شوند). همچنین بهتر است محصولاتی که یک بار خریده می‌شوند و اثر دائمی دارند را مصرف نشدنی تعریف کنید (مانند حساب کاربری ویژه).

این مسئولیت شماست که ارائه مزایای محصولات به کاربر را کنترل کنید. به عنوان مثال، اگر کاربر پول درون بازی (مثلا سکه طلا، الماس یا هر چیزی که در بازی تعریف شده است) بخرد، شما باید موجودی پول کاربر در بازی را به مقداری که خریداری کرده بروز رسانی کنید.

توصیه امنیتی: شما باید قبل از اینکه در برنامه مزایای محصولی را به کاربر ارائه دهید یک درخواست مصرف به مایکت بفرستید. قبل از ارائه محصول، اطمینان حاصل کنید که یک پاسخ مصرف موفقیت آمیز از مایکت دارید.

برای مصرف یک خرید، از نمونه IabHelper که دارید متد consumeAsync(Purchase, OnConsumeFinishedListener) را فراخوانی کنید. اولین آرگومان همان محصولی‌ست که قرار است مصرف شود. دومین آرگومان یک OnConsumeFinishedListener است که بعد از به پایان رسیدن عملیات مصرف محصول صدا زده می‌شود و پاسخ دریافتی از مایکت را بررسی می‌کند. صدا زدن این متد از thread اصلی مشکلی ندارد. در این مثال، یک فقره از محصول «بنزین» که کاربر در برنامه شما خریده است، مصرف می‌شود.


IabHelper.OnConsumeFinishedListener mConsumeFinishedListener = new IabHelper.OnConsumeFinishedListener() {
    public void onConsumeFinished(Purchase purchase, IabResult result) {
        if (result.isSuccess()) {
            // provision the in-app purchase to the user
            // (for example, credit 50 gold coins to player's character)
        }
        else {
            // handle error
        }
    }
};
					

چک کردن محصولات قابل مصرف در آغاز برنامه

این امر مهم است که محصولات قابل مصرف را زمانی که کاربر برنامه را باز می‌کند بررسی کنید. به طور معمول، شما اول برای محصولاتی که کاربر خریده به سرویس خرید درون‌برنامه‌ای کوئری می‌زنید (با استفاده از queryInventoryAsync)، سپس اشیا مصرف شدنی Purchase را از Inventory می‌گیرید. اگر برنامه شما فهمید که محصول مصرف کردنی‌ای وجود دارد که کاربر آن را خریده، باید بلافاصله یک درخواست مصرف به مایکت بفرستد و در صورت موفقیت آمیز بودن محصول را به کاربر ارائه دهد. می‌توانید به عنوان مثالی از پیاده‌سازی این چک کردن به برنامه نمونه TrivialDrive نگاهی بیندازید.

مهم:در صورتی که فرآیند چک کردن محصولات قابل مصرف (محصولات مصرف شدنی خریداری شده توسط کاربر) در آغاز برنامه، و سپس مصرف کردن آنها به درستی انجام نشود، ممکن است کاربر محصولی را بخرد و پول از حسابش کسر گردد، اما محصول (مانند الماس، جم، سکه، ...) را درون برنامه دریافت نکند.


مراجعه به فصل 5

کلیه حقوق متعلق به مایکت می باشد.