آموزش های این وب سایت به صورت رایگان در دسترس است. اطلاعات بیشتر
بروز خطا
   [message]
اشتراک در سوال
رای ها
[dataList]

آموزش پرداخت درون برنامه ای بازار ، صفر تا صد

مجتبی یگانه  9 سال پیش  3 سال پیش
+223 0

:: مستندات بازار به روز شده است ! ، ممکن است بخش هایی از این آموزش با مستندات جدید تطابق نداشته باشد ! ، بازار همچنین REST API اش رو در مستندات اش اضافه کرده ، که برای برسی و تایید صحت پرداخت از سرور ، استفاده میشه :) 


تغییرات آموزش جدید !

  1. آموزش بروز و کامل شد 
  2. توضیحات بیشتری در مورد مصرف خرید اضافه شد
  3. سوالات دوستان ویرایش شد و پاسخ در خود سوال اضافه شد.
  4. تاپیک تمیز شد و پرسش و پاسخ های غیر مرتبط و تکراری حذف شد

توصیه میکنم با کلیک روی علامت زنگوله در این تاپیک مشترک بشید تا از تغییرات اش مطلع بشید


احتمالا شما هم قبول دارید که مستند سازی بازار در مورد پرداخت درون برنامه ای بسیار ضعیف هست و طبق مکاتبه ای که من با بازار داشتم خودشون هم این رو قبول دارند !

بله حق با شماست، ما در حال حاضر مشغول آماده‌سازی سند راهنمای پرداخت درون‌برنامه‌ای برای محیط‌های غیربومی هستیم، با اتمام این پروژه، اسناد را بازبینی خواهیم کرد."

پس تصمیم گرفتم اطلاعات ام رو با شما به اشتراک بزارم :)

+3 0
خسته نباشی ،عالیه کاش اموزش استفاده ازش رو هم می زاشتی (9 سال پیش)
0 0
ــــمشترکـــــ (9 سال پیش)
+1 0
دستت درد نکنه مجتبی جان خیلی نیازش داشتم . (9 سال پیش)
0 0
خیلیم عالی...مشترک (9 سال پیش)
+2 0
خسته نباشید (9 سال پیش)
+1 0
سوالات ما حذف شد ولی پاسخی داده نشد! (9 سال پیش)
+1 0
حاج حسینی جان من یادم نمیاد سوالت چی بود ! ، میشه دوباره بپرسی ؟ (9 سال پیش)
0 0
اساتید گرام ، این کتابخونه رو نمیشه ویرایش کرد برای استفاده در سیستم بازار؟ لینک (9 سال پیش)
0 0
بازار توضیحات جدیدی به مستندات اش اضافه کرد ! ، لینک (9 سال پیش)
0 0
تشکر از شما دوست عزیز (9 سال پیش)
0 0
مجتبی جان این پرداخت های چند حالته کدش چیه؟ مثلا برای فلان کار ۵۰۰ تومن برای فلان کار ۱۰۰۰ تومن مثل پرداخت های سکه ای برنامه هایی مثل آفتابه یا مشابه اون . (9 سال پیش)
+3 0
کدش هیچ فرق خاصی نداره ! ، فرق اش اون sku یا شناسه ی محصولی هست که شما به بازار میدید ، میتونید بگید اگه باتن 1 بود شناسه بشه 1 و... ، و موقع بازکشت هم باید بگید if(purchase.getSku().equals(mysku))z یه کاری رو انجام بده ، یعنی کلا چند شرط اضافه میشه (9 سال پیش)
0 0
اگر برنامه قبلا منتشر شده باشه ,بصورت رایگان یا پولی, میشه به حالت پرداخت درون برنامه ای تبدیلش کرد؟ (9 سال پیش)
+1 0
در مورد پولی به رایگان مطمئن نیستم ولی احتمال زیاد بشه ، در مورد رایگان به درون پرداخت هم میشه و مشکلی نداره ! (9 سال پیش)
0 0
با سلام جناب A.L.U عزیز. جا داره بخاطر این آموزش کامل و جامع شما تشکر کنم. بالاخره بعد از چند روز درگیری با کدهای متفاوت در انجمن های مختلف و همچنین داکیومنت های افتضاح بازار تونستم با راهنمایی های شما دوست عزیز به نتیجه برسم. موفق باشید (9 سال پیش)
+2 0
90 درصد برنامه های درون برنامه ای بازار قابل هک شدن و دور زدن هستند که با اضافه کردن چند تکه کد کوچک میتوان از این امر جلوگیری کرد . (9 سال پیش)
0 0
سلام.می تونید اون تیکه کد هارو و نحوه قرار دادنش تو کد رو توضیح بدید (9 سال پیش)
0 0
سلام بجه ها میتونم از صفحه pdf بگیرم و بدم به دوستم ؟ (9 سال پیش)
+1 0
آقا طاهر اون چند خط کد چی هست؟ (9 سال پیش)
0 0
سلام به دوستان عزیز من خیلی گشتم ولی نتونستم جوابمو پیدا کنم.و اون هم اینکه ، فایده کلید rsa چیه؟ آخه با دستکاری کلید باز هم پرداخت انجام می شود و محصول در تراکنش های ما ثبت میشود . فقط نمیشود ریستور گرفت!! حالا اگر کسی این کلید رو هک کنه بازم نباید اتفاقی بیفته. (8 سال پیش)
+2 0
ظاهرا ممکنه کلید rsa اصلی رو با rsa خودشون جایگزین کنن و هرکی برنامه رو خرید درون برنامه کنه بره به حساب مربوط به rsa خودشون. (7 سال پیش)
0 0
با سلام و تبریک عید خدمت دوستان من همه کد ها رو دنبال کردم ولی یه مشکل دارم عبور از صفحه اسپلش گاهی وقتا تا 3 دیقه هم طول میکشه تا بره از بازار گزارش بگیره و برگرده ولی اگه به نت وصل نباشه همون یه ثانیه که توی Thread گذاشتم طول میکشه تا وارد بشیم... چیکار کنم که وقتی کاربر به اینترنت وصله این همه طول نکشه؟ (7 سال پیش)
 برای این سوال 36 پاسخ وجود دارد.
پاسخ به سوال 
مجتبی یگانه  9 سال پیش
+29 0

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

  1. محتوای قابل مصرف (تمام شدنی – مثل خربد سوخت برای خودرو)
  2. محتوای غیر قابل مصرف (تمام نشدنی – مثل ارتقا به کاربر ویژه )

گام اول ، آماده سازی محیط توسعه !

ما در طول این پروژه از پکیج هایی که بازار در اختیارمون قرار داده استفاده میکنیم ، چون در سورس کد این پکیچ ها override وجود نداره و در محیط توسعه ی ما وجود override اجباری هست و نبودش خطایی رو ایجاد میکنه که باعث میشه برنامه اجرا نشه باید برای حل این مشکل به این سوال  مراجعه کنید

بهترین کار ، استفاده تنظیم رویwarning  هست ، چرا که ignore دیگه چیزی به ما نشون نمیده و این به دلایلی که استاد ذکر کردند خوب نیست !

بعد از انجام این کار ، دیگه مشکلی با فایل هایی که میخوایم وارد پروژه کنیم نداریم
این فایل  رو دانلود کنید ، در پوشه ی Src پروژه تون از حالت فشرده خارج کنید ، ساختار پوشه ی Src شما باید به این شکل باشه

(ir پکیچ خودم هست ، ممکنه برای شما متفاوت باشه)

خوب حالا وارد محیط ایکلیپس بشید ، در قسمتی که پروژه ها رو میبینید ، ( workspace - package)  راست کلیک و Refresh کنید ، ساختار پوشه ی Src باید به این شکل باشه (ir.negano.wallpapaer پکیچ کد های خودم هست ، مال شما اسمش فرق داره ، مهم نیست )

می بینید که دیگه اروری نیست (اگ باشه ، ارور های ساده و قابل حل هست ، یا هشدار که مهم نیست !)

0 0
سلام این بکیج اول رو از کجا باس بیارم (9 سال پیش)
0 0
سلام این بکیج اول رو از کجا باس بیارم وبه درد چی میخوره (9 سال پیش)
0 0
چگونه بعد از این که خرید انجام شد toast شود که موفقیت آمیز بوده یا نه؟ میدونم ظاهرا با این متغیر onIabPurchaseFinished این کار انجام میشه ولی چه جوریش رو نمیدونم. (8 سال پیش)
0 0
سلام و تشکر از آقای یگانه، آقا مجتبی خواهشا این لینک و این سوال رو نگاه کنید، برای من این خطا رخ میده. تمام جوابها رو گشتم در این تاپیک و دیگر تاپیکها، ولی راه حل درستی پیدا نکردم.https://answers.uncox.com/c/116178 . تشکر (3 سال پیش)
پاسخ به سوال 
مجتبی یگانه  9 سال پیش
+23 0

گام بعد کدنویسی !

فعلا طبق  مستندات ، غیر قابل استناد بازار میریم جلو ! 

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

<uses-permission android:name="com.farsitel.bazaar.permission.PAY_THROUGH_BAZAAR" />

پروژه را اجرا کنید ، اگه مشکلی نداشت ، وارد بازار بشید ، همین APK که تا اینجا بدست اومده رو آپلود کنید ، بعد آپلود متوجه میشید که این یکی با بقیه یه فرقایی داره !

البته نیازی به اضافه کردن پکیچ ها هم نبود ! ، یعنی وقتی مجوز درون پرداخت در Manifest باشه ، این قسمت فعال میشه پس اگه مشکل آپلود دارید میتونید اول یه برنامه ی جدید و فقط با مجوز اینترنت و بازار آپلود کنید (کم حجم تر میشه ! )

وارد می شید ، در قسمت محصولات ، محصول جدید ایجاد کنید ، خود بازار هم توضیح داده ، اما بازم میگم ، شناسهٔ کالا رو هرچی دوست دارید بزارید ، مثلا من میزارم "wallpaper2"  - اگه مشکلی داشتید مستندات بازار برای مدیریت محصولات رو بخونید ( لینک )

حالا که محصول رو ساختید ، به 2 تا چیز نیاز دارید

  1. شناسه محصول
  2. کلید RSA

کلید RSA برنامه تون رو میتونید در قسمت ، برنامه های فروشنده > کلید RSA دریافت کنید ، یک رشته ی عجیب و طولانی

خوب به قول وردپرس "بزن بریم !"

0 0
ممنون (9 سال پیش)
+1 0
ممنون مجتبی جان بعضی جاهاش گنگ بود تا اینجاش که پدر مون در اومده . (9 سال پیش)
0 0
"کد شده بر اساس الگوریتم Base64" جون؟!؟ درسته که تو آخرین مرحله بایت‌های کلید RSA توسط Base64 انکد می‌شن، ولی این جملتون واقعن توهین به ریاضی‌داناییه که روی این الگوریتم کار کردن! (9 سال پیش)
0 0
من این حروف رو از روی نام متغییر ( base64 Encoded PublicKey ) و شباهت اش به رشته های base64 و تابعی که برای دیکد اش نوشته شده، حدس زدم ، اگر شما جزء اون ریاضی دان ها هستید ازتون عذر میخوام و لطفا توضیح بیشتری بدید که از گمراهی در بیایم و متن توهین آمیز رو اصلاح کنم :) (9 سال پیش)
0 0
خوب اگه یه بار اون رشته‌ی به‌دست‌اومده رو سعی کنید base64 دیکد کنید متوجه منظورم می‌شید. در واقع یه سری بایت به دست می‌آد که برای این‌که بشه اینا رو به شکل رشته در آورد باید یا یه متد دیگه تولید کرد، یا هم این که از base64 استفاده کرد که توی تبدیل بایت به رشته جاهای زیادی ازش استفاده می‌شه. من خودم توی ساخت RSA دخیل نبودم (!) ولی اون ریاضی‌دانای مذکور روش ساختشو این‌طوری قرار دادن: لینک (9 سال پیش)
+1 0
مثل این‌که Regex لینک‌ها توی سایت با لینکای فارسی مشکل داره؛ لینکو می‌تونید از این‌جا دنبال کنید لینک (9 سال پیش)
0 0
خیلی ممنون از اطلاع رسانی - تا حدودی با این روش آشنایی داشتم (RSA) اما اسمش رو نمیدنستم و اشتباه ام از اینجا نشعت گرفته - من اینطور متوجه شدم : جدا از کد گذاری RSA که به صورت public / Private Key انجام میشه ، یک بار هم کلیک عمومی RSA ما Encode میشه ( با Base64 ) و مقدار RSA ای که Encode شده به ما داه میشه ، این کد در زمان اجرا Decode میشه و در واقع Public Key اصلی که بازار برای تبادل اطلاعات اون رو می پذیره Run Time ساخته میشه - امیدوارم درست متوجه شده باشم. (9 سال پیش)
+1 0
دیگه این مجوز اینترنت چه صیغه ایه نمیدونم lol .... در خود مجوز بازار ، مجوز دسترسی به اینترنت وجود داره .... اگه خواستی مطمئن بشی بگو چند تا برنامه با پرداخت درون برنامه ای هم بهت نشون بدم که مجوز اینترنت ندارند و درست کار میکنند (9 سال پیش)
+1 0
حق با حامد بود ، بدون مجوز اینترنت هم مشکلی نداشت ، آموزش اصلاح شد :) (9 سال پیش)
0 0
توی این مرحله برنامه ام توی کافه بازار آپلود کنم؟ هنوز که کده های پایین ننوشتیم؟ چرا الان این کار میکنیم؟ (8 سال پیش)
پاسخ به سوال 
مجتبی یگانه  9 سال پیش
+21 0

اکتیویتی ای می خواین کاربر رو از اون به بازار منتقل کنید رو بسازید ! 
بازار میگیه این 5 فیلد  رو به اکتیوتی اضافه کنید ، من میگم هرکدوم چیه !

// تگی که هر انقاقی بیفته با اون لاگ چاپ میکنه
static final String TAG = "";

// شناسه ی محصول 
// For me : "wallpaper2" as I told !
// بلـــــــــــــه فک کردی فقط خودت انگلیسی بلدی ! static final String SKU_PREMIUM = ""; // آیا کاربر ویژه هست ؟
// بیشتر هدفشون استفاده ازش در آخر کاره که اگه درست انجام شد
// true بشه boolean mIsPremium = false; // این مقدار تاثیری در خروجی نداره ، خود بازار هم نمی دونه چیه ! static final int RC_REQUEST =0 ; IabHelper mHelper;

برای استفاده از سرویس بازار ، ما باید اون رو Prepare کنیم ، برای انجام این آماده سازی ، بازار کد نا مشخصی نوشته بود که همین باعث کرش می شد !

چرا می گم کد نامشخص بود ! 

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

راهکار من چی بود ؟

ما 2 بار نیاز داریم درخواست آماده سازی بدیم ، یه بار موقع شروع برنامه که باید وضعیت  prefrences ها رو  بروز کنه ، یه بار هم تو صفحه پرداخت که باید سرویس رو برای پرداخت آماده کنه ، من تابع زیر رو تو کلاس G نوشتم

public static boolean prepareBazaarInAppBilling(final boolean requireUpdatePrefrences,
final QueryInventoryFinishedListener mGotInventoryListener) { try { mHelper = new IabHelper(G.context, base64EncodedPublicKey); Log.d(TAG, "Starting setup."); IabHelper.OnIabSetupFinishedListener listener =
new IabHelper.OnIabSetupFinishedListener() { @Override public void onIabSetupFinished(IabResult result) { Log.d(TAG, "Setup finished."); if ( !result.isSuccess()) { Log.d(TAG, "Problem setting up In-app Billing: " + result); } if (requireUpdatePrefrences && mGotInventoryListener != null) { mHelper.queryInventoryAsync(mGotInventoryListener); } } }; mHelper.startSetup(listener); return true; } catch (Exception e) { e.printStackTrace(); return false; } }

چون این تابع به همون کلید و RSA و اینها نیاز داره من اونها رو تو کلاس G تعریف کردم ، پس ما به بازار کاری نداریم که میگه تو oncreate اکتیویتی پرداخت تعریف کنید

حالا من این تابع رو یه بار تو صفحه ی splash برنامه فراخوانی میکنم ، که تا splash رو نشون بده ، بازار هم آمار رو به ما بده پس تو اکتیویتی اسپلش اینجوری کد میزنم

QueryInventoryFinishedListener mGotInventoryListener = new IabHelper.QueryInventoryFinishedListener() {

	@Override
	public void onQueryInventoryFinished(IabResult result, Inventory inventory) {
		if ( !result.isFailure()) {
			boolean state = inventory.hasPurchase(G.SKU_PREMIUM);
			Log.i(G.TAG, "Bazaar say isPremiumUser is : " + state);
			G.setPremiumState(state);
		}
		goToNextActivity();
	}
};
G.prepareBazaarInAppBilling(true, mGotInventoryListener);

بهش میگم true , mGotInventoryListener  یعنی بله نیاز دارم آماده سازی کنی و و و ...> وضعیت رو از بازار بگیری.

وقتی کارش تمو شد ، لیسنری که بهش دادم رو صدا میزنه ، منم گفتم اگه موفق به دریافت شده بودی ، تابع setPremiumState رو صدا بزن و بهش بگو مقدار رو بزار مقداری که بازار میگه (یعنی به بازار میگه آقا کاربر ویژه است یا نه ؟ میگه True یا False)
تابع setPremiumState  هم میره تو Prefrence ها جواب بازار رو ثبت میکنه ، یعنی اگه کاربر مقدار ها رو دستی تغییر بده ، بازم موقع شروع اگه به نت وصل باشه ، وضعیت واقعی ایش رو از بازار میگیریم !

حالا در onCreate در اکتیویتی پرداخت کافی هست بگیم

G.prepareBazaarInAppBilling(false, null);

یعنی نرو سرور رو چک کن ، چون لزومی نداره ، یه بار اول برنامه چک کردیم ، اگه کاربر اینجا بلافاصله روی پرداخت کلیک کنه ، مشکلی پیش نمیاد و میره واسه پرداخت.

+2 0
ممنون بازار خیلیییییی داغون توضیح داده واقعا ممنون از A.L.U (9 سال پیش)
0 0
ببخشید splash کجا میشه؟ و goNextActiviyi از کجا به کجا میره؟ (9 سال پیش)
+1 0
فهمیدم :دی (9 سال پیش)
+1 0
اسپلش به صفحه ی نمایش لوگو برنامه میگن ، شما میتونید این اکتیویتی رو طوری بنویسید که تا وقتی بازار پاسخ رو نداده ، اسپلش بسته نشه ! ، در برنامه ای که قرار دادم هم دقیقا همین اتفاق می افته ، اما یه نکته ! ، ممکنه این پاسخ خیلی سریع بیاد ، یا اصلا کاربر به اینترنت وصل نباشه و این برسی انجام نشه ، پس من در برنامه ای که گذاشتم ، Thread رو یک ثانیه Sleep میکنم که حداقل یک ثانیه اسپلش نمایش داده بشه :) (9 سال پیش)
0 0
سلام مجتبی این خط رو String base64EncodedPublicKey = ""; از اول متد mGotInventoryListener جا انداختی. (9 سال پیش)
0 0
سلام آقا مجتبی، دو تا سوال : آیا برای پرداخت یک اکتیویتی جدا درست کنم؟ اونوقت مثلا فرض کنید نرم افزار 100 مرحله داره که درون یک اکتیویتی اجرا می شن من می خوام 10 مرحله آزاد باشه بعدش پرداخت انجام بشه کی باید صفحه پرداخت رو صدا بزنم؟ (9 سال پیش)
+1 0
سلام :) ، شما همیشه یک متغییر G.isPremium دارید که اگر true باشه یعنی کاربر ویژه هست ، بنابراین در 10 امین مرحله که در واقع مرز برنامه ی شماست ، میگید اگه ویژه بود (G.isPremium==true) اجازه ی نمایش مرحله ی بعد رو بده در غیر اینصورت ، دیالوگی رو باز کن ، به کاربر بگو ویژه نیستید ، اگر تائید کرد وارد اکتیویتی پرداخت بشید ، بله اکتیویتی پرداخت نیاز هست ، البته میشه در سایر اکتیویتی ها هم انجام داد ، اما کدتون ، کد تمیزی از آب در نمیاد ! ، چون یه سری دستورات کلیشه ای همیشه مزاحم شماست ، در ضمن اگر چند محصول در برنامه ارائه بدید ، این سورس کد پیچیده تر میشه که ترکیب اش با قسمت های دیگه کار درستی به نظر نمیاد ! (9 سال پیش)
0 0
سلام. و از تاپیک خوبی که درست کردید و از صبر حوصله تون ممنونم. سؤال داشتم: من تعریف تابع setPremiumState را پیدا نمی کنم. یعنی خودم باید بنویسمش؟ میشه کمک کنید لطفا؟ (9 سال پیش)
0 0
ظاهرا پایین تر جواب اون سؤال را داده بودید. فهمیدم که خودم باید getPremiumState و setPremiumState را در کلاس G بنویسم. اولی راحته؛ اما دومی نه؛ چطوری setPremiumState را بنویسم؟ (9 سال پیش)
0 0
آقا جواب خودم را در خواب (!) پیدا کردم. ما مقدار مورد نظرمان با از طریق آرگومان تابع برایش می فرستیم. خودش قرار نیست چیزی را پیدا کند. (9 سال پیش)
0 0
آقایان؛ یک سؤال دیگه: من متد setPremiumState را نوشتم. اما درباره static بودن متغیر هام به مشکل برخوردم. کدی که نوشتم اینه: public static void setPremiumState(boolean state) { SharedPreferences settings = getSharedPreferences("MYPREFS", 0); SharedPreferences.Editor editor = settings.edit(); editor.putBoolean("IS_PREMIUM", state); editor.commit(); } ولی به getSharedPreference اشاره می کنه و این ارور رو میگیره: Cannot make a static reference to the non-static method getSharedPreferences(String, int) from the type ContextWrapper چطور میشه این مشکل را برطرف کرد؟ پیشاپیش ممنون از پاسخی که خواهی داد... (9 سال پیش)
+1 0
سلام ، از SharedPreferences استفاده کنید ، استاد آموزش دادند ، من نمی تونم تکرارش کنم ، ضمنا درج کامنت به این شکل اصلا کار صحیحی نیست ، هم سورس کد واضح نیست و هم نظم تاپیک به هم خورد ! ، می تونستید در سوال دیگه ای مطرح کنید یا در همین تاپیک به عنوان پاسخ درج کنید (9 سال پیش)
0 0
بله. تشکر. (9 سال پیش)
0 0
A.L.U عزیز. همونطوری که خودتون گفتید ممکنه در ابتدای اجرای برنامه کاربر به اینترنت وصل نباشه که برنامه بخواد بازار رو چک کنه. در این حالت باید چیکار کنیم؟ (9 سال پیش)
+1 0
از وضعیت ذخیره شده استفاده کنید :) ، هرچند ممکنه کاربر بیاد و true کنه و فعال بشه ! ، اما به جاش یه کار دیگه کنید ، مثلا برای فعال بگید مقدار بشه sgdshgdu برای غیر فعال بشه ifyujtyhgrfed حالا دیگه تغییر دستی سخت میشه :) (9 سال پیش)
0 0
اقا یک سوال ؟ مگه بولین نیست؟! پس تو خود بولین یک استرینگ djgsdgfh برای فغال و یک mkjnhn برای غیر فعال تعریف کنیم، درسته ؟ (9 سال پیش)
+2 0
عزیزم شنونده باید عاقل باشه ! ، من یه مثال زدم ، وقتی شما بخواین این کار رو انجام بدید ، باید مقدار رو با عنوانی مثل paymentState و به صورت String ذخیره کنید ، و در شروع برنامه این مقدار رو بخونید و پردازش کنید و با یک شرط ساده بگید اگر x بود isPremuim بشه True و اگر y بود بشه False ، منطقی به نظر میاد ! (9 سال پیش)
پاسخ به سوال 
مجتبی یگانه  9 سال پیش
+16 0

باید یک سری listener برای عملیات تعریف کنیم که از رویداد ها آگاه بشیم ، که بازار  ( گوگل پلی دیگه ، بازار فقط کپی کرده ) به این شکل تعریف کرده بهتون میگم چی کار کرده ! (اما فعلا استفاده نکنید ، نمونه ی من هم ببینید )

 QueryInventoryFinishedListener mGotInventoryListener = new QueryInventoryFinishedListener() {
    public void onQueryInventoryFinished(IabResult result, Inventory inventory) {
        Log.d(TAG, "Query inventory finished.");
        if (result.isFailure()) {
            Log.d(TAG, "Failed to query inventory: " + result);
            return;
        }
        else {
            Log.d(TAG, "Query inventory was successful.");
            // does the user have the premium upgrade?
            mIsPremium = inventory.hasPurchase(SKU_PREMIUM);

            // update UI accordingly

            Log.d(TAG, "User is " + (mIsPremium ? "PREMIUM" : "NOT PREMIUM"));
        }

        Log.d(TAG, "Initial inventory query finished; enabling main UI.");
    }
};

OnIabPurchaseFinishedListener mPurchaseFinishedListener = new OnIabPurchaseFinishedListener() {
    public void onIabPurchaseFinished(IabResult result, Purchase purchase) {
        if (result.isFailure()) {
            Log.d(TAG, "Error purchasing: " + result);
            return;
        }
        else if (purchase.getSku().equals(SKU_PREMIUM)) {
            // give user access to premium content and update the UI
        }
    }
};
0 0
آیا استفاده از mGotInventoryListener نیازمند زمان خاصی هستش. من هرکار میکنم در log من mIsPremium را false نشون میده (8 سال پیش)
0 0
Alireza@ : من هم همین مشکل رو دارم . ولی وقتی data کافه بازار رو پاک میکنم درست میشه . یه دیتابیسه به نام purchases.db که inventory ها از اون خونده میشه اما مشکلی که وجود داره اینه که بعد هر پرداخت اپدیت نمیشه و mIsPremium همیشه false میمونه تا موقعی که data پاک بشه و دوباره از سرور بازار خونده بشه (8 سال پیش)
0 0
@Blaster: بالاخره یکی یه جواب داد به ما بعد از ۳ هفته. آقا دستت درد نکنه. ولی خوب آیا راه حلی وجود داره براش؟ آیا به صورت دوره ای چک میشه؟ (8 سال پیش)
+1 0
این مشکل از خود کافه بازاره و اونا باید حلش کنن دست ما نیست . من بهشون 5-6 تا ایمیل زدم تازه قبول کردن مشکل از برنامه خودشونه و گفتن به زودی بررسی میکنیم . (8 سال پیش)
پاسخ به سوال 
مجتبی یگانه  9 سال پیش
+19 0

ما مثل بازار نیومدیم تو صفحه ی پرداخت وضعیت سرور رو برسی کنیم و خیلی حرفه ای تر در شروع برنامه برسی میکنیم پس به mGotInventoryListener در اکتیویتی پرداخت نیازی نیست و در اسپلش ازش استفاده کردیم  !

لیسنر onIabPurchaseFinished که واسه تموم شدن پرداخت هست ، یعنی کلا وقتی از بازار برگشت این لیستر فراخوانی میشه که من اون سوئیج بی روح (تو ورژن قبلی آموزش ) رو با دو تا توست ساده عوض کردم !

OnIabPurchaseFinishedListener mPurchaseFinishedListener = new OnIabPurchaseFinishedListener() {

  @Override
  public void onIabPurchaseFinished(IabResult result, Purchase purchase) {
	  // نتیجه یک فییلور / خطا بوده ؟
	  if (result.isFailure()) {
		  Log.d(G.TAG, "Error purchasing: " + result);
		  Toast.makeText(G.context, "پرداخت انجام نشد", Toast.LENGTH_LONG).show();
		  return;
	  }
	  else if (purchase.getSku().equals(G.SKU_PREMIUM)) {
		  G.setPremiumState(true);
		  Toast.makeText(G.context,
"با تشکر ، شما با موفقیت به کاربر ویژه ارتقا پیدا کردید",
Toast.LENGTH_LONG).show(); finish(); // صفحه ی پرادخت رو میبندیم } } };

شما میتونید بر اساس این سند توست های کامل تری چاپ کنید و کاربر رو بیشتر در جریان بزارید !

حالا کافیه تو هر رویدادی که دوست دارید (مثل کلیک شدن یک دکمه ) این کد رو قرار بدید

btnGoToBazaar.setOnClickListener(new OnClickListener() {

	@Override
	public void onClick(View arg0) {
		try {
			G.mHelper.launchPurchaseFlow(ActivityPayment.this,
                              G.SKU_PREMIUM, 0,  mPurchaseFinishedListener);
		}
		catch (Exception e) {
			e.printStackTrace();
			Toast.makeText(G.context,
                                "Some Error Happend , Restart App please...",
                                      Toast.LENGTH_SHORT).show();
		}
	}
});

خوب دید که من تو کچ کردن خطا هم توست میدم ، یعنی اگه خطا داشت کاربر نگه کار نمیکنه ، پیام دادم دوباره تلاش کن یا برنامه را ری استارت کن !

در نهایت هم باید این کد رو عینا بزاریم آخر اکتیویتی پرداخت

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
	super.onActivityResult(requestCode, resultCode, data);
	if ( !G.mHelper.handleActivityResult(requestCode, resultCode, data)) {
		super.onActivityResult(requestCode, resultCode, data);
	}
}


@Override
public void onDestroy() {
	super.onDestroy();
	if (G.mHelper != null)
		G.mHelper.dispose();
	G.mHelper = null;
}

خوب ، اونایی که فقط واسه دسترسی ویژه میخواستن ، دیگه وقتشه برن به سلامت ، موفق باشید D:

0 0
ببینم برای پرداخت درون برنامه ای باید دو تا نرم افزار درست کنیم یکی رایگان و یکی پولی یا نه یک نر م افزار درست میکنیم بقیه قسمتاش را قفل میکنیم این را لطفا توضیح بدید که باید چیکار کرد؟؟ (9 سال پیش)
0 0
برنامه با پرداخت بصورت کامل فعال خواهد شد ! - قبل از پرداخت محدودیت هایی اعمال میکنیم :) (9 سال پیش)
0 0
راستی token چیه چیکار میکنه؟ تو کد هام بهش ایراد گرفته (9 سال پیش)
0 0
توکن یک متغییره که مقدار Tokan خرید رو در برمیگیره ، توکن خرید هم مقداری هست که بازار به عنوان شناسه خرید ازش استفاده میکنه و خودش تولیدش میکنه (9 سال پیش)
+1 0
این قسمت برای من nullPointerExeption میگیره! همونجا که پیغام میده "Some Error Happend , Restart App please..." دقیقا تو خط G.mHelper.launchPurchaseFlow(ActivityPayment.this, G.SKU_PREMIUM, 0, mPurchaseFinishedListener); (9 سال پیش)
0 0
سوالتون رو آخرای همین تاپیک مطرح کرده بودید ، من ویرایش کردم و جواب دادم :) (9 سال پیش)
0 0
ببخشید دوستان.این اکتیویتی پرداخت که میگید دقیقا کدوم اکتیویتی میشه؟اونی که میخوام با خریدن باز بشه؟ مثلا من 5 تا دکمه دارم که 2تاش اولش بازه و 3 تای بعدی با خریدن باز میشه.حالا این اکتیویتی پرداخت اون 3 تا میشن.در کل این onclick که گفتین برای اون دکمه نوشته بشه باید برای این 3 تا نوشته بشه؟ (9 سال پیش)
0 0
اکتیویتی ای که قرار هست View ( ها ) ای که با کلیک بر روی اونها Intent بازار صدا زده بشه ، اکتیویتی پرداخت اطلاق شدن ! ، هیچ ربطی به جایی که قرار هست از ویژه شدن استفاده بشه نداره (9 سال پیش)
پاسخ به سوال 
مجتبی یگانه  9 سال پیش
+12 0

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

کاربر شما وقتی یک بار محصولی مثل "wallpaper2"  را بخره ، دیگه بلافاصله بعد از باز شدن بازار ، بازار پاسخ مثبت میده و میگه آره ، پرداخت انجام شد ، و تمام اطلاعت مربوط به پرداخت قبلیش هست ، اما خوب ما میخوایم کاربر 10 دفعه بتونه بنزین بزنه ! :))

برای مصرف کردن خرید ، شما باید یک جدول در بانک تون درست کنید و محصولاتی که واسش پرداخت انجام شده رو در جدول ذخیره کنید. جدول ها به این شکل هستن

 Products Table
-----------------------------------------
ID | name | SKU (کدی که از بازار گرفتی)
-----------------------------------------
1 | A | 0001
2 | B | 0002

paid products
-----------------------------------------
ID | prductID | itemType | signature | json | isConsume
1 | 2 | Value | value | JSON Value | 1
2 | 4 | Value | value | JSON Value | 0

ما برای اینکه بتونیم هر وقت خواستیم فرایند مصرف رو انجام بدیم باید ورودی ها رو ذخیره کنیم یـــــــــــــــــا برای اینکه مصرف اش کنیم ، یه بار اول درخواست خرید اش رو بدیم که بازار همین مقدار ها رو در قالب یک purchase به ما بده !

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

String itemType = purchase.getItemType();
String signature = purchase.getSignature();
String json = purchase.getOriginalJson();

برای مصرف کردن خرید ، بعد از فراخوانی درخواست آماده سازی ، درخواست مصرف رو به mHelper میدیم !

btn.setOnClickListener(new OnClickListener() {

	@Override
	public void onClick(View arg0) {
		G.prepareBazaarInAppBilling(false, null);
		purchases purchase = new Purchase(itemType, jsonPurchaseInfo, signature)
		G.mHelper.consumeAsync(purchases,lisetner);
	}
});

این هم لیسنر اش : 

 IabHelper.OnConsumeFinishedListener listener = new IabHelper.OnConsumeFinishedListener() {
	
	@Override
	public void onConsumeFinished(Purchase purchase, IabResult result) {
		// TODO Auto-generated method stub
		if(result.isSuccess()){
			// Consumed !
		}
	}
};
0 0
سلام آقا مجتبی، من می خوام دقیقا همون موقعی که پرداخت انجام می شه کل خرید مصرف بشه و نمی خوام هیچ کلیک لیسنری مثل نمونه ای که شما در بالا گذاشتید براش تعریف کنم که بعدش خرید استفاده بشه، یعنی دقیقا همون جایی که شما تست موفقیت رو گذاشتید. حالا دو سوال : 1- آیا نیاز هست که حتما اون جدول هایی که در بالا اومده رو توی دیتابیس تعریف کنم ؟ 2- توی کدوم قسمت باید کدهای داخل کلیک لیسنر و لیسنر IabHelper رو تعریف کنم؟ (پیشاپیش از پشتیبانی خوبتون توی تاپیک سپاسگذارم.) (9 سال پیش)
+3 0
کافیه این خط رو بعد پرداخت موفق اجرا کنید ، در آموزش هم هست G.mHelper.consumeAsync(purchases,lisetner)z (9 سال پیش)
0 0
باز هم ممنون آقا مجتبی، این purchase رو که از بازار می گیریم چجوری تعریفش می کنیم؟ (9 سال پیش)
+1 0
خود بازار در onPurchaseFinished یک purchase بهتون میده ، همون رو با یک onCosumeFinishedListener بدید به متد ، در آموزش هست ، مطالعه کنید (9 سال پیش)
0 0
با سلام خدمت استاد آقاجانی و بقیه دوستان عزیز در مورد پرداخت درون برنامه ای آیا امکان این هست که کاربری که ویژه نشده بتواند یک محصول صفر ریالی را بخرد تا از امکانات دمو برنامه استفاده کند ، مثلا در یک برنامه کاربر عادی می تواند 5 عکس را به انتخاب خود دانلود کند حالا اگر کاربر 5 عکس خود را دانلود کند و بعد از این دومرتبه برنامه را ری اینستال کند مجدد می تواند 5 عکس دیگر دانلود کند ،اما اکر مشخصات کاربر در سرور بازار ذخیره شود بعد از ری اینستال هم دیگر نمی تواند از امکانات رایگان استفاده کند .و سوال دیگر اینکه آیا مقدار باقی مانده محصول خریداری شده در سرور بازار ذخیره می شود . اگر سوالات ناشیانه بود عذر خواهی می کنم ، اولین کامنتم تو سایت بود :-) (9 سال پیش)
+3 0
(با اجازه بزگترهای سایت) امکان خرید محصولی با قیمت صفر وجود دارد، اما به نظر من کار درستی نیست چون خیلی از کاربرها هستند که اصلا حساب کاربری در بازار ندارند. خرید محصولات (حتی صفر ریالی) فقط برای کاربرانی ممکن است که اولا حساب کاربری داشته باشند، و ثانیا داخل حسابشان مقداری پول باشد. پس ممکن است بسیاری از مردم نتوانند یا رغبت نکنند دموی برنامه شما را بخرند. (من به شخصه معتقدم اگر کسی اون قدر محتاج برنامه است که حاضره هر روز اون رو پاک کنه و دوباره نصب کنه، برنامه من به عنوان صدقه حلالش باشه! اشکالی نداره.) (9 سال پیش)
+1 0
البته جدا از بحثی که b.fat بهش اشاره کردند ، این موضوع هم راه حل داره و راه حلش گذاشتن ثبت نام هست ، در این حالت کاربر برای هر 5 تا عکس باید یه ایمیل بسازه ، که اگه بخواد 500 تا عکس داشته باشه 100 تا ایمیل میخواد D: (9 سال پیش)
0 0
عرض سلام و وقت بخیر خدمت A.L.U عزیز و دوستان. اگر فقط یک محصول مصرفی داشته باشیم چطور؟ یعنی یک شناسه کالا که چند بار بشه خریدش! (8 سال پیش)
پاسخ به سوال 
Reza AF  9 سال پیش
+7 0

من وقتی میخام صفحه پرداختم رو اجرا کنم این خطا میاد و کرش میکنه : این خطا واسه چیه؟

 06-15 11:30:38.733: E/AndroidRuntime(1579): java.lang.RuntimeException: 
Unable to start activity 
ComponentInfo{....pardakht/....Pardakht}:
 java.lang.IllegalStateException: IAB helper is not set up. Can't 
perform operation: launchPurchaseFlow

 پاسخ A.L.U

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

بهتر هست قبل از شروع پرداخت از نصب بودن بازار مطمئن بشیم

 public static boolean isPackageInstalled(String packagename) {
	PackageManager pm = context.getPackageManager();
	try {
		pm.getPackageInfo(packagename, PackageManager.GET_ACTIVITIES);
		return true;
	}
	catch (NameNotFoundException e) {
		return false;
	}
}
if (isPackageInstalled("com.farsitel.bazaar")) {
     // بازار نصب است
}

توضیح کامل تر در :  4 امین محتوا (سومین پاسخ)

0 0
مشکل رفع شد، کد اجرای پرداخت رو توی یک باتن گذاشتم و مشکل رفع شد. ولی چرا حتما باید باتن باشه؟ نمیشه یهو خودش اجرا کنه بدون کلیک شدن؟ (9 سال پیش)
+1 0
دلیلش رو من اینجوری فهمیدم که عملیاتی که خط mHelper.startSetup میخواد انجام بده، کمی طول میکشه. درواقع این خط یه بار یه بازار یه سیگنال میفرسته که آیا این بابا قبلا فعال کرده یا نه؟ و جواب رو ر میگردونه. حالا اگه طی این مدت شما کلیکی درخواست رفتن به صفحه پرداخت رو بکنید، برنامه کرش میکنه. همین الان هم که یه دکمه خالی گذاشتید، اینو که میگم امتحان کنید: به محض ورود به صفحه ای که دکمه پرداخت توشه، دکمه پرداخت رو بزنید. میبینید که برنامه کرش میکنه!(برای رفعش یا پروگرس دیالوگ بذارید یا دکمه رو تا اومدن جواب اولیه بازار غیرفعال کنید) (9 سال پیش)
0 0
همونطور که گفتم این آماده سازی یکم طول میکشه (تا موقعی که reesponse اولیه از بازار بیاد که حدود 5 تانیه میشه). تو این مدت تو میتونی به پروگرس دیالوگ به کاربر نشون بدی. پروژه پرداخت درون برنامه ای hamedjj رو هم اگه دیده باشی میبینی که وقتی وارد صفحه online permium میشی یه پروگرس بهت نشون میده و اگه قبلا فعال کرده باشی خودش بهت اعلام میکنه (همون جواب اولیه بازار رو اعلام میکنه) (9 سال پیش)
پاسخ به سوال 
Reza AF  9 سال پیش
+5 0

سلام، ببخشید من هی این تاپیک رو میارم بالا. پرداخت برنامه من دست شد و گذاشتمش بازار جهت بررسی اما یهو امروز دیدم باز کرش میکنه، این شد که سریع از حالت بررسی خارجش کردم، شانس آوردم تایی نشده بود.(این تاخیرهای بازار یجا مفید واقع شد!)

الان این پیغام رو میده :

 06-22 16:47:26.292: E/AndroidRuntime(2246): java.lang.IllegalStateException:
Can't start async operation (launchPurchaseFlow)
because another async operation(refresh inventory) is in progress.

شماره خطی هم که خطا داره همون خطیه که بازار رو فراخوانی میکنم .

ممنون میشم راهنمایی کنید،

+1 0
لینک - ممکنه onDestroy رو فراموش کرده باشید ، یا اینکه helper رو prepare نکردید یا طبق آموزش قبلی و آموزش بازار در همون صفحه ی درخواست گرفتن وضعیت کاربر رو دادید ! - به هر حال این مشکل واسه یک ماه پیش هست و اگه حل شده و یادتون میاد علت دقیقا چی بود ، لطفا ذکر کنید :) (9 سال پیش)
پاسخ به سوال 
مجتبی یگانه  9 سال پیش
+14 0

آموزش با توضیحات این پاسخ ام بازنویسی شد !

سلام ، بالاخره امتحان های من تموم شد و فرصت شد تا به عنوان شروع مجدد طبق قولی که به دوستان دادم ، یه سری توضیحات اضافه در مورد پرداخت درون برنامه ای بازار بدم ، خوب اینها فقط اظهار نظر شخصی من هست ، پس اگر اشتباه میکنم ، لطفا اساتید من رو به مسیر درست هدایت کنند :)

بازار یه سری کد رو از سورس کد های گوگل پلی کور کورانه کپی کرده و طبق اون این سیستم رو راه اندازی کرده و مشکلات زیادی هم داره که خودشون بهتر از ما به این موضوع واقف هستن ، اما ما خودمون هم باید طبق منطق خودمون سیستم رو برسی کنیم ، که من این کار رو انجام دادم و برداشت ام این بود !

    1- چرا باید در هنگام باز شدن اکتیویتی پرداخت درخواستی به سرور ارسال بشه ؟

بازار اصرار داره در onCreate ما یک متد رو به شکل زیر فراخوانی کنیم ، در طول اجرا این متد هم یک دیالوگ لودینگ نشون بدیم :|

mHelper.queryInventoryAsync(mGotInventoryListener);

چرا من با این کار مخالف ام ؟

  1. ما معمولا قبل از باز شدن صفحه ی پرداخت به اطلاعات ویژه بودن یا نبودن کاربر درسترسی داریم ، پس نیازی نیست به بازار درخواست بدیم که یه برسی سریع داشته باشه !
  2. فرض رو بر این بگیریم ، کاربر برنامه رو حذف کرده و دوباره نصب کرده ، اگر این کار رو انجام ندیم چی میشه ؟ ، خوب هیچی ، برنامه به عنوان کاربر معمولی ، کاربر رو به صفحه پرداخت هدایت میکنه ، کاربر روی دکمه ی پرداخت کلیک میکنه اما بازار بلافاصله متوجه میشه کاربر قبلا پرداختی داشته ، بنابراین ، ResultCode 0 یعنی موفق و Token خرید قبلی رو در پاسخ بر میگردونه.

با حذف اون قسمت دیگه حتی باز شدن صفحه ی پرداخت در onCreate اکتیویتی هم باعث کرش نمیشه ، علت کرش ها این بود که هنوز بازار در حال انجام اون عملیات هست و ما به جای نشون دادن لودینگ میخوایم پرداخت رو انجام بدیدم !

با این کار دیگه به mGotInventoryListener هم نیازی نداریم و سورس کد کوتاه تر میشه !

پیش از شروع پرداخت ، برسی کنید که آیا بازار بر روی دستگاه نصب است یا خیر !

در صورتی که بازار نصب نباشه ، عملا کار ما بیهوده است یعنی پرداخت غیر قابل انجام هست ، با این تابع میتونیم از نصب بودن هر پکیجی مطمئن بشیم :)

public boolean isPackageInstalled(String PackageName) {
	PackageManager manager = getPackageManager();
	boolean isAppInstalled = false;
	try {
		manager.getPackageInfo(PackageName, PackageManager.GET_ACTIVITIES);
		isAppInstalled = true;
	}
	catch (PackageManager.NameNotFoundException e) {
		e.printStackTrace();
	}
	return isAppInstalled;
}

مثلا برای برسی نصب بودن بازار به این شکل عمل میکنیم :

if (isPackageInstalled("com.farsitel.bazaar")) {
	// Bazar is installed
}
else {
	// Bazar is not installed
}

پس اگر بازار نصب بود باید عملیات پرداخت را شروع کنیم ! ، اما ممکنه هر خطایی اتفاق بی افته شایع ترین نوع خطا مربوط به همون Async نبودن هست (مورد اول ، queryInventoryAsync ) پس ما احتمالا کمتر کرش داریم (چون از اون استفاده نمی کنیم ) ، اما بازم نمیشه  خطاهای احتمالی رو نادیده گرفت ، پس با یه Try , Catch از کرش کردن برنامه جلوگیری می کنیم

 if (isPackageInstalled("com.farsitel.bazaar")) {
	// Bazar is installed
	try {
		mHelper.launchPurchaseFlow(this, SKU_PREMIUM, 0, mPurchaseFinishedListener);
	}
	catch (Exception e) {
		e.printStackTrace();
		Toast.makeText(getApplicationContext(),
"Reopen App and Try Again", Toast.LENGTH_SHORT).show(); } } else { // Bazar is not installed //open Bazzar Home Page To Download It ! }

و دیگر هیچ !

0 0
البته چند جا دیگه هم کرش داره، مثلا اینکه اگه کاربر وارد یوزر خودش توی بازار نشده باشه، بجای پنجره پرداخت ، پنجره ورود نمایش داده میشه و اینجا اگه کاربر کنسل کنه برنامه کرش میکنه! (9 سال پیش)
0 0
خیر ! ، اینجا result Code 1 یعنی "عملیات متوقف شد" بر میگرده ، اون دیگه بستگی به نحوه ی پردازش این Result Code داره ، اگر نیاز باشه باید در تابع پردازش نتیجه ای که نوشتید (که در کد من ShowReslut هست ) این تغییرات رو اعمال کنید (9 سال پیش)
0 0
شایدم بخاطر کد دیالوگ من بوده باشه (9 سال پیش)
0 0
مجدد برسی میکنم ، ولی احتمالا مشکل از کد شخصی شماست (9 سال پیش)
0 0
خیلی ممنون (9 سال پیش)
0 0
خیلی ممنون مجتبی جان، عالی بود! موفق باشی، شما هم ما رو تو این ماه مبارک دعا کن. (9 سال پیش)
0 0
like (9 سال پیش)
0 0
برای دوستانی که هنوز این پاسخ رو نخوندن ! ، به نظرم این از اصل آموزش مهم تره ، تعداد علاقه مندان به این تاپیک زیاده و متاسفانه مشترک نیستن ! ، بنابراین فقط باید تاپیک رو بیارم بالا تا بقیه هم این پاسخ رو ببیند ! (9 سال پیش)
0 0
در مورد اول : alu جان بازار اسرار نداره که از این کد استفاده کنی ... تو برنامه trivialDrive از این کد استفاده شده که بهترین وامن ترین راه برای تایید کاربر از پرداخت است ، به طوری که با هر بار ورود به برنامه تایید را از بازار میگیره و مثلا اگر من برنامه را خرید کرده باشم و ایمیل خودم را به تو بدم که یک باز باهاش برنامه را ارتقا بدی ، اگر از sharedpreferences استفاده بشه خوب بدون خرید کردن برنامه راحت میتونی از برنامه استفاده کنی ، اما اگر از این روش استفاده کنی هر بار نیاز به ایمیل و پسورد من داری و این کمی مشکل ساز میشه .. من خودم این روش را تایید و تاکید میکنم .. با یه صفحه splashScreen میشه وضعیت کاربر را بررسی کرد (9 سال پیش)
0 0
ای بابا بزارین کامنت را وارایش کنیم دیگه .... آقا اصرار نه اسرار ... شرمنده (9 سال پیش)
0 0
ویرایش هم اشتباه نوشتم ... ااااا (9 سال پیش)
0 0
خوب پس چه دلیلی داره برسی وضعیت کاربر رو در صفحه ی پرداخت انجام بدیم که منجر به کرش بشه ! ، تو همون Splash یک باز انجام میدیم دیگه ! ، تازه اگه اونطور باشه ، بازم برنامه کرش میکنه چرا که باید قبلش اتصال به اینترنت و نصب بودن بازار برسی بشه و ... ! ، اما خوب راه خوبیه واسه جلوگیری از ویرایش Prefrences ها ، البته برای ویرایش دستی هم باید گوشی روت باشه و کاربر معمولی خیلی سر در نمیاره ! ، اما بازم EndUser ها میتونن دست کاری کنن ، اینترنت رو قطع کنن ، برنامه رو استفاده کنن ! (اوه اوه اینجوری که ما هم EndUser ایم D: )- در کل انجامش خوبه ولی نه تو اکتیویتی پرداخت ! (9 سال پیش)
+1 0
ولی بنظر من نباید اینقدر سخت گرفت، واسه شخص خود من کرش نکردن برنامه و پیاده سازی سریع مهمتر ازینه که شاید چندتا کاربر خفن! بتونن بدون پرداخت برنامه منو استفاده کنن. (9 سال پیش)
+1 0
آفرین .... 1 - برنامه trivial Drive ماله گوگله و برنامه google play در همه دستگاه ها نصب هست (پس از این لحاظ کرش نداریم) بازار هم فکر کرده که چون هر کسی از سیستم پرداخت درون برنامه ای خودش استفاده کنه حتما برنامش را فقط در بازار قرار میده دیگه که قطعا همینه و بازار دیگه نمیتونه فکر این باشه که آیا طرف برنامه خودشو تو اینترنت پخش میکنه یا نه که اگه پخش کنه و از پرداختش استفاده کنه برنامه کرش میشه ... اینو دیگه باید توسعه دهنده به فکرش باشه 2 - دسترسی به اینترنت هم که میشه با یه تیکه کد و try/catch حلش کرد. 3 - کسی اجبار نکرد که کدها را طبق این برنامه نمونه پیاده سازی کنید ... هر کار خواستید باهاش بکنید .. برنامه trivial drive فقط برای نمایش نحوه عملکرد سیستم در یک اکتیویتی پیاده سازی شده همین .... پس قسمت پیاده سازی api در مستندات برای چیه (که البته خود کسی که اونو نوشته بخونه متوجه نمیشه ) (9 سال پیش)
0 0
رضا جان قرار نیست برنامه کرش بده ... 4 تا خط کد رو سرعت پیاده سازی تائیر داره!!!!! (9 سال پیش)
0 0
من خودم با رضا موافق ام ، اما خوب بچه ها موافق نیستن ! ، آقا کافیه من یه برنامه بدم بیرون ، یه کسی تو یه جای دنیا بگه آقا برنامت رو اینطوری یا اونطوری استفاده کردم ! ، دیگه خدا میدونه که موج اعتراض میاد سمت من ! (9 سال پیش)
0 0
خوب خودت که راه حل کرش نکردن را گذاشتی ...دیگه مشکل چیه (9 سال پیش)
0 0
رضا جان با مطالعه ی بیشتر الان با گفته ی شما مخالف ام ، وقتی میشه با سرور پر سرعت بازار تو زیر 3 ثانیه مطمئن بشیم کاربر ویژه است ، چرا این کار رو نکنیم ؟! - توضیحات هم اضافه شد. (9 سال پیش)
0 0
آقا توضیحاتتون خیلی عالی بود ممنون. ولی متاسفانه با کپی کدهاتون هنوز مشکلاتی هست. اگه ممکنه محتویات کامل فایلهای اسپلش - کلاس جی و اکتیوتی پرداخت را قرار بدید. باتشکر فراوان/ (9 سال پیش)
پاسخ به سوال 
Reza AF  9 سال پیش
+4 0

سلام

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

پاسخ  A.L.U

بر اساس آموزش جدید ، ما SKU_Premium رو در کلاس G تعریف کردیم ، پس بر اساس شرایط می تونه تغییر کنه بعد فرایند پرداخت رو شروع کنید !

کلید RSA هم که در تمام برنامه یکسان هست و نیازی به تغییرش نیست !

پاسخ به سوال 
MiRHaDi  9 سال پیش
+3 0

سلام

چند عدد سوال دارم :-)

1 -  من میخوام بدونم حساب کاربر چقدر پول توش هست ؟ یعنی قبل از اینکه تموم بشه متوجه بشم و اخطار بدم که مثلا 10 بار دیگه بیشتر نمیتونه استفاده کنه ، بره شارژ کنه

2 - مقدار شارژ را میخوام بتونم خودم مشخص کنم. مثلا یک بار بگم 1000 تومان یک بار 10000 تومان

3 - فرض کنیم برنامه ما هزینه ماهیانه برای شارژ میگیره و میخوایم بعد از 30 روز حساب طرف از حالت پریمیوم در بیاد چه باید کرد؟

4 - اگر بخوایم برنامه در هنگاه پرداخت به ما گزینه بده که میخوای با بازار پرداخت کنی یا گوگل یا سیستمهای بانکی چه باید کرد؟

5 - فرض کنید برنامه ای مثل فروش شارژ نوشته ایم ، شارژ 2000 تومانی را که بفروشیم باز هم 600 تومان را بازار بر میدارد ؟ هزینه تمام شده شارژ بیشتر از 1400 میشود. در حالت فروش چگونه میتوانیم از این سرویس استفاده کنیم ؟

پاسخ  A.L.U

  1. تا جایی که من میدونم شدنی نیست یعنی نمیشه از بازار بپرسی این کاربر ما چقدر پول داره !
  2. میتونید محصولات متفاوت ایجاد کنید و بر اساس پاسخی که به سوال قبل دادم ، در زمان اجرا محصول رو عوض کنید اما طبق مکاتبه ای که با بازار داشتم ، فعلا پرداخت مبلغی که در زمان اجرا تعیین بشه ، ممکن نیست
  3. بازار نوع محصول اکانت ماهیانه - اکانت سالیانه رو اضافه کرده ، طبق آموزش جدید ، وقتی در لحظه ی شروع از بازار سوال کنیم آیا ویژه هست یا نه و برنامه رو براساس اون پیش ببریم ، دقیقا یک ماه یا یک سال بعد از پرداخت ، برنامه غیر فعال میشه !
  4. باید سیستم بانکی خودتون رو پیدا کنید !
  5. بله ، اما بازار گفته در این موارد باهاش مکاتبه کنید !
پاسخ به سوال 
masih  9 سال پیش
+3 0

از من چرا داره خطا میگیره ؟؟؟ خداوکیلی پدرمو در اورده این پرداخت درون برنامه ای

پاسخ A.L.U

شما به درستی پکیچ ها رو وارد پروژه تون کردید ، وقتی پکیچ ها رو طبق اولین قسمت های آموزش وارد پروژه کردید ، موس را روی mHelper نکه دارید و این کتابخانه رو ایمورت کنید

import util.IabHelper;
پاسخ به سوال 
Hossein Rezaei  9 سال پیش
+1 0

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

+1 0
آقا مجتبی ممنون، حل شد، توو Log های مربوط به protected void onActivityResult مشکل داشت،برش داشتم حل شد . (9 سال پیش)
+1 0
خواهش میکنم - موفق باشید :) (9 سال پیش)
پاسخ به سوال 
mf2010  9 سال پیش
+2 0

سلام دادش یگانه عزیز میخاستم ببینم از پرداخت درون برنامه ای  این قسمت کالاهای مصرفی رو بیشتر توضیح میدید گفتید از این کد استفاده کنیم  

mHelper.consumeAsync(info, consumeFinishedListener);

حالا یه مثال کوچیک اگه ازش بزنید ممنون میشم کجا از این کد استفاده کنیم 

پاسخ A.L.U

در آموزش جدید ، این مورد رو بیشتر توضیح دادم ، اما باز هم بین علما در این مورد اختلاف زیاد هست :)) 

بازار هم مثل همیشه پاسخ اش اینه : 

"ما پرداخت درون برنامه ای خود را بر اساس پرداخت درون برنامه ای گوگل پیاده کرده ایم ، می توانید از مستندات گوگل استفاده کنید"

پاسخ به سوال 
نورحسینی  9 سال پیش
+1 0

سلام بر همه اساتید من طبق دستور العمل پیش رفتم . 5 تا فیلد بازار رو گزاشتم قبل از oncreate و اون کدها رو هم که گفته شد طبق مستندات بازاره گزاشتم بعد از oncreate . کلید RSA رو هم توی گیومه گزاشتم .  چند جا ایراد import گرفت که برطرف شد . اما ایراد آخر اینه که به mGotInventoryListener ایراد می گیره و میگه یا باید local variable بکنیش یا فیلدش بکنی و چند راه دیگه که گفتم فیلدش کن مشکل حل شد حالا باید چه کار کنم ؟ برنامه هم بدون مشکل اجرا شد  . تا اینجای کار رو اومدم و بقیه اش رو نرفتم . یعنی نمی دونم باید چه کار کنم . ببینید در کل من یک صفحه پرداخت دارم که یک کلید توشه به نام btnpurchase حالا از این به بعد چیه و لیسنری که باید برای دکمه نوشته بشه چیه و چه کاری قراره بکنه ؟ ممنون دوستان لطفا  به زبون ساده راهنمایی کنید  ... عکسم هر کاری کردم آپلود نشد  ولی کد رو میزارم :

 
import util.IabHelper;
import util.IabHelper.QueryInventoryFinishedListener;
import util.IabResult;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Typeface;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class ActivityPurchase extends Activity {
static final String TAG = "";
static final String SKU_PREMIUM = "";
boolean mIsPremium = false;
static final int RC_REQUEST =0 ;
IabHelper mHelper;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.purchase);

String base64EncodedPublicKey = "RSA code here ";
mHelper = new IabHelper(this, base64EncodedPublicKey);

Log.d(TAG, "Starting setup.");
mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {

private QueryInventoryFinishedListener mGotInventoryListener;

public void onIabSetupFinished(IabResult result) {
Log.d(TAG, "Setup finished.");

if (!result.isSuccess()) {
// Oh noes, there was a problem.
Log.d(TAG, "Problem setting up In-app Billing: " + result);
}
// Hooray, IAB is fully set up!
mHelper.queryInventoryAsync(mGotInventoryListener);
}
});

Button btnpurchase = (Button) findViewById(R.id.btnpurchase);

// btnpurchase.setOnClickListener(new OnClickListener() {
//
// @Override
// public void onClick(View arg0) {
// // TODO Auto-generated method stub
// Intent intent = new Intent(ActivityPurchase.this, ActivityIndex.class);
// ActivityPurchase.this.startActivity(intent);
// ActivityPurchase.this.finish();
//
// }
// });
}

}

پاسخ A.L.U

شما باید کارهای گفته شده در 6 امین محتوا (5 امین پاسخ) را انجام بدید و یک OnIabPurchaseFinishedListener بنویسید !

پاسخ به سوال 
Rabbit  9 سال پیش
+1 0

سلام دوستان، طبق دستوراتی که توی پست اومده داخل اکتیوتی منو یک رابطی قرار دادم که با اون کاربر به صفحه خرید منتقل میشه اما مشکل NullPointer Exception دارم !

پاسخ A.L.U

در آموزش جدید به این خطا اشاره کردم :

  1. مطمئن بشید که تابع prepareBazaarInAppBilling یا همون آماده سازی درون پرداخت بازار در oncreate فراخوانی شده و mHelper در اون نقطه null نیست
  2. برسی کنید آیا بازار نصب هست  (بالا تر با تابع isPackageInstalled  توضیح دادم ) من خودم در این حالت اگه بازار نصب نباشه ، دکمه پرداخت رو مخفی میکنم و دکمه دانلود بازار رو نمایش میدم :)
  3. مجوز بازار را در برنامه قرار بدید
پاسخ به سوال 
احسان منصوری  9 سال پیش
+2 0

سلام. ALUجان اینم Log خطای برنامه آقا حسین رضایی:

+1 0
به نظر میاد مشکل از onActivityResult ایشون هست ، من به سورس کدش دسترسی ندارم ، اما به نظر میشه برسی کرد اگه null بود انجام نشه و یا با try Catch هندل اش کرد :) (9 سال پیش)
0 0
ممنون از دوستان عزیز،لطف کردید. حالا باید ببینم با try/catch میشه یا نه. فقط یک مشکل دیگه که آقای نورحسینی هم مطرح کردن و متاسفانه درست هم بود!! اینه که کاربر اگر برنامه رو حذف کنه و دوباره اقدام به خرید کنه بازم باید پول پرداخت کنه، به نظر شما آیا مشکل از کده؟ نباید خود بازار از این موضوع جلوگیری کنه؟ چکاری از دست ما ساخته است؟؟! (9 سال پیش)
0 0
شاید sku Premium تغییر میکنه که خیلی بعید به نظر میاد ! ، وگرنه بازار باید خودش مدیریت کنه :) (9 سال پیش)
پاسخ به سوال 
Hossein Rezaei  9 سال پیش
+2 0

بچه ها بازار ایمیل من رو جواب داد:

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

pardakht.cafebazaar.ir

حالا من از قسمت "طی پرداخت یا خرید به مشکلی برخورد کرده اید؟" با اکانت خودم وارد شدم، دیدم توکن خرید هام هست، اما ما چجوری از این توکن در برنامه برای تشخیص اینکه آیا برنامه ما قبلا توسط کاربر خریداری شده یا نه استفاده کنیم؟

پاسخ A.L.U

بعد از برسی ، مشخص شد قسمت ارسال SKU به سرور بازار مشکل داشت

0 0
من فکر کنم یه جایی تو چک کردن SKU مشکل داری ، اگه خواستی سورس پروژه یا یه پروژه معمولی با روش پرداخت خودت رو بده چک کنم. (9 سال پیش)
پاسخ به سوال 
hosseinAmini  9 سال پیش
0 0

مجتبی ممنونم بابت توضیحات و زحمتی که کشیدی

آقا من خیلی مشکل دارم... حدودا 80% مطالب رو نمی فهمم چون اصلا هیچ دیدی نصبت به پرداخت درون برنامه ای ندارم.
مثلا من یه برنامه دارم که 100نا تصویر آنلاین نمایش میده حالا میخوام کاری کنم که کسانی که پول ندادند فقط 20تا تصویر رو ببینند چیکار باید کنم الان؟
سوال بعدیم که splash چیه که تو آموزش گفتی splash...
سوال دیگم اینه که برای پرداخت درون برنامه ای  باید یک اکتیویتی ایجاد کنم و از داخل اون اکتیویتی کاربر پرداخت کنه؟ حالا این اکتیویتی وقتی کاربر پول رو  پرداخت می کنه دیگه نمایش داده نمیشه؟ چه جوری :))
سوال آخر هم اینکه من یه برنامه مثل قسمت اول آموزش (تا جایی که تو manifest جواز بازار رو می نویسیم) ساختم و برای بازار ارسال کردم حالا چه جوری پاکش کنم؟ چون برنامه الکی بود...

ممنون میشم اگه راهنماییم کنید

0 0
راستی اگر امکان داره خیلی مبتدی توضیح بدید. ممنون (9 سال پیش)
+2 0
splash > همون Activityـی که برخی از برنامه ها موقع اجرا نشونش میدن ، معمولا یه لوگویی ، اسم برنامه ای ، اسم برنامه نویسی و ... رو توش مینویسن ، ممکنه انیمیشنی هم داشته باشه ، چند ثانیه ظاهر میشه و بعد خود بخود بسته میشه و برنامه میره به صفحه Activity اصلیش :) (9 سال پیش)
0 0
خب این تو پرداخت درون برنامه ای به چه دردی می خوره؟ ممنون (9 سال پیش)
+2 0
رابطه مستقیمی با این مبحث نداره ، ولی میشه از اون چند ثانیه که این Activity در حال اجرا هست استفاده کرد و در پشت پرده یه کارایی انجام داد تا از زمان استفاده بهنیه رو کرده باشیم (این تاپیک رو هنوز اساسی نخوندم) (9 سال پیش)
0 0
ممنون سوال splash حل شد دوتای دیگه رو لطفا راهنمایی کنید (9 سال پیش)
0 0
بقیش مهمتر بود من هم همین مشکلا رو دارم (9 سال پیش)
0 0
یه مشکل دیگه هم هست متد setPremiumState در g تعریف نشده پس چه جوری استفاده کردید وهم متد goToNextActivity(); در کد های اسپلش (9 سال پیش)
0 0
یه مشکل دیگه هم هست متد setPremiumState در g تعریف نشده پس چه جوری استفاده کردید وهم متد goToNextActivity(); در کد های اسپلش (9 سال پیش)
0 0
activitypayment چه طور؟ (9 سال پیش)
0 0
یه راهی هم اگه برای محصول های مصرفی پیدا کردید خبر بدید چون چند روز دیگه بهشون نیاز پیدا میکنم :) (9 سال پیش)
+1 0
خیلی راحته داخل کد صفحه پرداختت یه تابع آپدیت میذاری میگی وقتی پرداخت انجام شد و بازار به ما گفت پرداخت صحیح بوده اون تابع اجرا شه حالا داخل اون تابع یه پرفنمنس قرار میدی و موقعیت رو ذخیره میکنی و داخل هر صفحه ای که میخای بعد از پرداخت تغییر کنه یه if میذاری میگی اگر اون پرفنمنس مثلا true بود این تغییرات رو تو صفحه بده مثلا این دکمه رو مخفی کن و اگر false بود تغییری ایجاد نکن البته این راهش بود بسته به پروژت خودت باید راه مناسب رو پیدا کنی ولی اساس کارس با SharedPreferences و کلاس G هستش بقیه موارد رو مجتبی جان به صورت کامل آموزش دادن تو همین صفحه (9 سال پیش)
+1 0
مرسی از راهنماییت فقط اینکه بخوایم پرداخت درون برنامه ای بزاریم حتما اول باید برنامه رو به بازار ارسال کنیم؟ که کلید RSA رو بگیریم یا اینکه تو کدها به این کلید نیازی نیست و میشه برنامه رو تو کامپیوتر کامل نوشت و بعد برنامه رو ارسال کرد؟ (9 سال پیش)
0 0
یه مشکل دیگه هم هست متد setPremiumState در g تعریف نشده پس چه جوری استفاده کردید وهم متد goToNextActivity(); در کد های اسپلش ( در 1 ساعت پیش ) (9 سال پیش)
+1 0
بله اول باید برنامه را ارسال کنید و حتما دسترسی پرداخت درون برنامه ای را هم به آن داده باشید بعد از آپلود برنامه در پنل در سمت راست برنامه آپلود شده یه گزینه به نام ورود ظاهر میشود آن را کلیک کرده و میتوانید کلید rsa را دریافت و در برنامه جایگزین کنید (9 سال پیش)
0 0
ببخشید میشه جواب من رو هم بدین setPremiumState و goToNextActivity(); در کد های اسپلش (9 سال پیش)
0 0
بعد که این کار رو کردیم برنامه کامل رو به عنوان آپدیت باید بفرستیم؟ ممنون (9 سال پیش)
0 0
محمد جان من از روش این تایپک نرفتم نمیدونم دقیقا راه حل مشکل شما چیه بله حسین جان به عنوان آپدیت میفرستی قبلش خودت هم یه محصول اضافه کن و تست کن ببین کار میکنه یا نه بعد از اضافه کردن محصول و کد شناسه محصول و rsa کار شما دیگه تموم شدش . (9 سال پیش)
0 0
ممنون (9 سال پیش)
0 0
اقا مجتبی کجایی جواب بدی هرکی خربزه میخوره پای لرزشم میشینه تایپیک درست کردی باس جواب بدی داداش (9 سال پیش)
0 0
:| ، من همیشه جواب میدم ، خربزه و هندونه نداره که ! ، یه مدتی نبودم (9 سال پیش)
0 0
دمت هم گرم پس در مورد اینا توضیح میدی:1. setPremiumState و goToNextActivity(); در کد های اسپلش 2.قسمتی که درآن عضویت ویژه قطعی میشه تا بتونم تغییرات رو اعمال کنم (9 سال پیش)
0 0
سلام آقا مجتبی ببخشید دوباره مزاحم میشم . میخواستم بدونم برای سایت ایران اپس هم از همین روش استفاده کنیم درسته و فقط موارد افزودنی مثل پوشه util و.... رو تغییر بدیم درست میشه ممنون (9 سال پیش)
0 0
نمیدونم ! ، من با مارکت های دیگه کار نکردم ، اما اصولا اگه بر اساس درون پرداخت گوگل نوشته شده باشه ، مشکلی نداره (9 سال پیش)
پاسخ به سوال 
مجتبی یگانه  9 سال پیش
+5 0

سوالات hosseinAmini  

  1.  Splash رو دوستان توضیح دادن ، منظور صفحه ی نمایش لوگوی برنامه بود ، که ما میتونیم از یک تایم 2 ثانیه ی استفاده کنیم و کار برسی وضعیت کاربر از بازار رو در اونجا شروع کنیم
  2. شما با کلیک کردن رو یه دکمه وارد اکتیویتی پرداخت میشین ! ، پس وقتی اون دکمه مخفی بشه ، مثل این هست که اون اکتیویتی دیگه وجود نداره ! ، View.setVisibility(View.GONE)z
  3. من که خیلی با بازار کار نمیکنم ، ولی از دوستان شنیدم باید بهشون ایمیل بزنید :)

سوالات mohammad

  1. goToNextActivity  متدی هست که نوشته بودم تا یک intent بسازه و startActivity کنه تا بره به اکتیویتی بعدی ! ، شما هم بسازید :)
  2. setPremiumState متدی بود که نوشته بودم ، تا مقدار boolean وضعیت کاربر رو بهش بدم ، و اون رو به عنوان وضعیت کاربر در preference ها ثبت کنم ! ، تا بعدا هم قابل استفاده باشه و یک متد به نام getPremiumState هم دارم !
  3. یک متغییر premiumState هم در کلاس G دارم که وضعیت فعلی کاربر هست ، مثلا میخوام بگم اگه ویژه بود یه دکمه ی پرداخت مخفی بشه
if(G.premiumState){
btnPay.setVisibility(View.GONE);
}
0 0
ممنون مجتبی جان روش کار میکنم اگه هنوز سوال داشتم باز مزاحم میشم داداش (9 سال پیش)
0 0
توی برنامه من، کاربر به «بازار» هدایت میشه، اما اونجا با ارور 404 مواجه میشه. دلیلش چی میتونه باشه؟ (9 سال پیش)
0 0
مجتبی جان شما که این همه لطف کردی، بیا و این لطف دیگه هم بکن و متد setPremiumState و getPremiumState رو هم برامون قرار بده. (9 سال پیش)
+1 0
@amir ، من مشکلی ندارم ، اما اگر شما واقعا با ذخیره کردن یک Boolean در Preference ها مشکل دارید ، قطعا در سایر بخش ها هم به مشکل می خورید ، پیشنهاد میکنم آموزش Preference های استاد آقاجانی رو ببینید ، بعد اگر نتونستید این متد ها رو بنویسید ، سوال کنید راهنمایی تون می کنیم. (9 سال پیش)
0 0
ممنونم مجتبی جان. چشم مرسی از راهنماییت. منن واسه یک مقایسه این کد را نیاز داشتم که مینویسم. (9 سال پیش)
پاسخ به سوال 
aliakbar333  9 سال پیش
+3 0

آموزش ویدئویی پرداخت درون برنامه ای بازار :

البته این آموزش در محیط Basic4Android  

لینک    حجم حدود 49 مگابایت 

خالی از لطف نیست.

پاسخ به سوال 
PandaStudio  9 سال پیش
0 0

سلام دوستان

من یه برنامه از قبل منتشر کردم و الان میخوام توی نسخه جدید پرداخت درون برنامه ای بزنم. تمام این روش ها که توضیح دادید قبل از انتشار برنامه اون را آپلود میکنیم و توی قسمت محصول جدید برنامه را انتخاب می کنیم و کلید مربوطه را میگیریم اما من الان برنامم منتشره و حتی نسخه جدید هم با دسترسی پرداخت آپلود کردم اما توی قسمت محصولات جدید توی بازار نمیتونم برنامه را انتخاب کنم و اصلا توی لیست نیست. به نظرتون باید چکار کنم؟

+1 0
دقیقا شرایط همونه ! ، با این تفاوت که نسخه ی جدید بارگذاری می کنید ، که بخش ورود به پرداخت درون برنامه ای واستون فعال میشه ! (9 سال پیش)
0 0
برای بازار ایمیل زدم جواب دادن حدود یک روز طول میکشه تا پکیجتون توی لیست قرار بگیره و بتونید کلیدش را بگیرید (9 سال پیش)
0 0
نمیدنم ولی منظقی به نظر نمیاد ! ، اخه کار آنلاین و منتظر تایید موندن نیاز نداره ، شما بعد پیاده کردن اش درخواست برسی می دید :) (9 سال پیش)
پاسخ به سوال 
Reza.M  9 سال پیش
+17 0

سلام خدمت دوستان.مخصوصا استاد تاپیک مجتبی یگانه عزیز.

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

هر کی استفاده کرد یه صلوات بفرسته .

 

کد صفحه پرداخت :

 public class Payment extends Activity {

    @Override
    protected void onResume() {
        G.currentActivity = this;
        super.onResume();
    }


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        overridePendingTransition(R.anim.zoom_enter, R.anim.zoom_exit);
        this.requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.payment);

        Button pay = (Button) findViewById(R.id.btn_pay);
        
        pay.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                if (isPackageInstalled("com.farsitel.bazaar")) {
                    // Bazar is installed
                    try {
                        G.mHelper.launchPurchaseFlow(Payment.this, G.SKU_PREMIUM, 0, mPurchaseFinishedListener);
                    }
                    catch (Exception e) {
                        e.printStackTrace();
                        Toast.makeText(G.context,"Some Error Happend , Restart App please...",
                                Toast.LENGTH_SHORT).show();
                    }
                }
                else {
                    // Bazar is not installed
                    //open Bazzar Home Page To Download It !
                    Toast.makeText(G.context,
                            "لطفا برنامه کافه بازار را بروی دستگاه گوشی نصب کنید",
                            Toast.LENGTH_SHORT).show();
                }

            }
        });

        G.prepareBazaarInAppBilling(false, null);
    }



OnIabPurchaseFinishedListener mPurchaseFinishedListener =
new OnIabPurchaseFinishedListener() { @Override public void onIabPurchaseFinished(IabResult result, Purchase purchase) { if (result.isFailure()) { Log.d(G.TAG, "Error purchasing: " + result); Toast.makeText(G.context, "پرداخت انجام نشد", Toast.LENGTH_LONG).show(); return; } else if (purchase.getSku().equals(G.SKU_PREMIUM)) { G.setPremiumState(true); Toast.makeText(G.context, " پرداخت با موفقیت انجام شد.", Toast.LENGTH_LONG).show(); finish(); } } };
public static boolean prepareBazaarInAppBilling(final boolean requireUpdatePrefrences, final QueryInventoryFinishedListener mGotInventoryListener) { try { G.mHelper = new IabHelper(G.context, G.base64EncodedPublicKey); Log.d(G.TAG, "Starting setup."); IabHelper.OnIabSetupFinishedListener listener = new IabHelper.OnIabSetupFinishedListener() { @Override public void onIabSetupFinished(IabResult result) { Log.d(G.TAG, "Setup finished."); if ( !result.isSuccess()) { Log.d(G.TAG, "Problem setting up In-app Billing: " + result); } if (requireUpdatePrefrences && mGotInventoryListener != null) { G.mHelper.queryInventoryAsync(mGotInventoryListener); } } }; G.mHelper.startSetup(listener); return true; } catch (Exception e) { e.printStackTrace(); return false; } }

public boolean isPackageInstalled(String PackageName) { PackageManager manager = getPackageManager(); boolean isAppInstalled = false; try { manager.getPackageInfo(PackageName, PackageManager.GET_ACTIVITIES); isAppInstalled = true; } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } return isAppInstalled; }

@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if ( !G.mHelper.handleActivityResult(requestCode, resultCode, data)) { super.onActivityResult(requestCode, resultCode, data); } }

@Override public void onDestroy() { super.onDestroy(); if (G.mHelper != null) G.mHelper.dispose(); G.mHelper = null; } }

 

کد صفحه اسپلش :

 public class SplashScreen extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        G.HANDLER.postDelayed(new Runnable() {

            @Override
            public void run() {
                Intent intent = new Intent(SplashScreen.this, ActivityCategory.class);
                SplashScreen.this.startActivity(intent);
                SplashScreen.this.finish();
                overridePendingTransition(R.drawable.fadein, R.drawable.fadeout);
            }
        }, 2000);

        QueryInventoryFinishedListener mGotInventoryListener = new IabHelper.QueryInventoryFinishedListener() {

            @Override
            public void onQueryInventoryFinished(IabResult result, Inventory inventory) {
                if ( !result.isFailure()) {
                    boolean state = inventory.hasPurchase(G.SKU_PREMIUM);
                    Log.i(G.TAG, "Bazaar say isPremiumUser is : " + state);
                    G.setPremiumState(state);
                }
                //goToNextActivity();
            }
        };
        G.prepareBazaarInAppBilling(true, mGotInventoryListener);
    }


}

 

و کلاس G

 public class G extends Application {

    public static Context               context;
    public static LayoutInflater        inflater;
    public static Activity              currentActivity;
    public static final Handler         HANDLER                = new Handler();


    //vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
    public static final String          TAG                    = "";
public static final String SKU_PREMIUM = "eshgh_full";//شناسه محصول public static final int RC_REQUEST = 0; public static boolean mIsPremium = false; public static IabHelper mHelper; public static String base64EncodedPublicKey = "MIHNMA0GCSqGSIb..."; public static boolean setPremiumState = false; public static boolean premiumState = false; public static SharedPreferences preferences; //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@Override public void onCreate() { super.onCreate(); context = this.getApplicationContext(); inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
preferences = PreferenceManager.getDefaultSharedPreferences(context); premiumState = preferences.getBoolean("IS_PREMIUM", false); }
public static boolean prepareBazaarInAppBilling(final boolean requireUpdatePrefrences, final QueryInventoryFinishedListener mGotInventoryListener) { try { mHelper = new IabHelper(G.context, base64EncodedPublicKey); Log.d(TAG, "Starting setup."); IabHelper.OnIabSetupFinishedListener listener = new IabHelper.OnIabSetupFinishedListener() { @Override public void onIabSetupFinished(IabResult result) { Log.d(TAG, "Setup finished."); if ( !result.isSuccess()) { Log.d(TAG, "Problem setting up In-app Billing: " + result); } if (requireUpdatePrefrences && mGotInventoryListener != null) { mHelper.queryInventoryAsync(mGotInventoryListener); } } }; mHelper.startSetup(listener); return true; } catch (Exception e) { e.printStackTrace(); return false; } }

QueryInventoryFinishedListener mGotInventoryListener = new QueryInventoryFinishedListener(){ @Override public void onQueryInventoryFinished(IabResult result, Inventory inventory) { Log.d(TAG, "Query inventory finished."); if (result.isFailure()) { Log.d(TAG, "Failed to query inventory: " + result); return; } else{ Log.d(TAG, "Query inventory was successful."); // does the user have the premium upgrade? mIsPremium = inventory.hasPurchase(SKU_PREMIUM); // update UI accordingly Log.d(TAG, "User is " + (mIsPremium ? "PREMIUM" : "NOT PREMIUM")); } Log.d(TAG, "Initial inventory query finished; enabling main UI."); } };


OnIabPurchaseFinishedListener mPurchaseFinishedListener = new OnIabPurchaseFinishedListener(){ @Override public void onIabPurchaseFinished(IabResult result, Purchase purchase) { if (result.isFailure()) { Log.d(TAG, "Error purchasing: " + result); return; } else if (purchase.getSku().equals(SKU_PREMIUM)) { // give user access to premium content and update the UI } } };
public static void setPremiumState(boolean state) { SharedPreferences.Editor editor = preferences.edit(); editor.putBoolean("IS_PREMIUM", state); editor.commit(); premiumState = state;
} }

 
اکتیویتی هم که میخوایید محتوا (در صورت خرید) نشوون داده بشه  :

if (G.premiumState){// اگر پرداخت شد

// نمایش همه محتوا

}else{// اگر پرداخت نشده بود

// نمایش محدود محتوا

}

بچه ها دعای خیر یادتون نره

0 0
از اِکلیپتس استفاده میکنین یا اندروید استودیو ؟ فایل xml رو ساختین ؟ (9 سال پیش)
0 0
اره اسدی جان از اکلیپس استفاده میکنم (9 سال پیش)
0 0
فراموش کردم ، اره فایل XML مربوط به اکتیویتی ها رو هم ساختم (9 سال پیش)
0 0
خب وقتی خرید با موفقعیت انجام شد برید فایل XML رو باز کنین و IS_PREMIUM رو بررسی کنید، بینم به true تغییر کرده یا نه. (9 سال پیش)
0 0
شرمنده داداش ، متوجه نمیشم ، منظورتون چیه فایل XML رو باز کنم (کدوم فایل XML) ، اصن فایل ایکس ام ال واسه چی (9 سال پیش)
0 0
طبق اموزش های تاپیک جلو رفتم ، هرچی هم کد به برنامه اضافه کردم ، بالا نوشتم، حالا نمیدونم مشکل کدم از کجاست ، احتمالا باید جایی True بشه نمیشه (9 سال پیش)
0 0
آموزش های بخش لینک رو ببنید (استفاده از Preferences) (9 سال پیش)
0 0
حالا متوجه منظورتون شدم ، کدوم فایل XML رو میگفتید. متاسفانه چون شبیه ساز من گوشی م هستش اون مسیری که استاد تو آموزش گفتن و پیدا نکردم.یعنی شاخه هاش هست ولی خالی.ببخشید احمد جان دردسر شدم واست. (9 سال پیش)
0 0
سلام ، کدتون به نظر درست میاد ، یعنی در OnIabPurchaseFinishedListener درست برسی کردید که پرداخت انجام شده یا نه ! ، حالا اگه تو این قسمت واسه پرداخت ناموفق هم میگه موفق (که بعید به نظر میاد) باید کدتون رو برسی کنید ، اما اگر پرداخت رو درست تشخیص میده اما شما درست مدیریت اش نمیکنید یه بحث دیگه است ، شما در setPremiumState باید اون مقدار true یا false رو در preference ها ذخیره کنید که دوستمون لینک دادند ، و همین طور در G.isPremium و حالا اون شرط براتون درست کار میکنه (9 سال پیش)
0 0
آفرین هر چی باشه کل بحث را کجا جمع بندی کردید .A.L.U عزیز شما که زحمت کشیدید اگه امکان داره همین را بصورت یک پروژه قرار بدید ،از دیروز هر چی تلاش کردم یه جای کار ایراد می گیره . (9 سال پیش)
0 0
یک آموزش تصویری کامل برای google بازار کجاش را تغییر داده ؟ لینک (9 سال پیش)
0 0
یکی دیگه اما بازم نمیشه ! لینک (9 سال پیش)
0 0
حالا یه تغییر کوچیکی دادم ، ظاهرا که درست شده (اینطور به نظر میاد :)). برنامه رو برا بازار فرستادم اگه اوکی بود اون تغییری که دادم و تو همین جا میذارم که بقیه دوستان هم اگه مشکل بنده رو داشتن براشون مفید باشه. (9 سال پیش)
0 0
مجتبی جان به کمکت نیاز دارم. اولین بار ، بازار برنامه رو رد کرد (کدهام هم همون کدهای بالا بود). بعد تو کلاس جی این (premiumState = true) رو به (premiumState =state) تغییر دادم. این دفعه هم بازار برنامه رو رد کرد. ولی دلیلش اینو گفت: پس از تلاش برای ارتقاء برنامه پیام «فراخوانندهٔ درخواست خرید با درخواست کننده‌اش یکی نیست.» نمایش داده می‌شود. میتونی حدس بزنی مشکل از کجاشه؟؟؟ (9 سال پیش)
0 0
سلام ، این یکی رو واقعا تا الان بهش بر نخوردم :| ، فکر کنم داری به سیستم بازار نفوذ میکنی آ ههه :)) - اما چند تا احتمال میدم ، بازار یه چیزی داره به اسم preload ، که اجازه نصب یک پرداخت رو چند دستگاه رو نمیده ، ببینید از اون استفاده نکرده باشید و طبق آموزش پیش برید ، یا احتمال زیاد قسمت چک کردن پرداخت ، رو درست انجام ندادید ، چون باید یکبار به بازار بره و ببینه انجام شده یا نه تو FinishedListener - بازم طبق آموزش پیش برید (9 سال پیش)
0 0
اتفاقا این اشتباهو کردم. روی گوشیم با دوتا اکانت وارد شدم و خرید کردم تا مراحل خرید رو تست کنم که انجام میشه یا نه. خب حالا چه کنم؟ (9 سال پیش)
0 0
خوب نصب شد یا نه ؟! ، کافیه کد خطای برگشتی رو مدیریت کنید اگه واقعا میخواین رو چند دیوایس نصب نشه ! (9 سال پیش)
+1 0
اشتباه به این صورت اتفاق افتاده: اولین بار که برنامه رو تست میکردم وقتی ارتقا برنامه رو کلیک میکردم به صفحه ارتقا برنامه هدایت میشد و قیمت نشون داده میشه ، همه چی عادی بود ، خرید کردم و از اکانت هم خارج شدم.بعد از خرید ، همه امکانات برنامه قابل دسترسی بود. برای بار دوم خواستم تست کنم ، برنامه نصب شده که ارتقا هم داده بودم رو حذف کردم ، دوباره نسخه رایگان رو گوشی نصب کردم و برا ارتقا با یه اکانت دیگه وارد شدم و بازم تونستم ارتقا بدم و خرید انجام شد.بازم از اکانت دومی هم خارج شدم. سومین بار که تست میکردم خطای «فراخوانندهٔ درخواست خرید با درخواست کننده‌اش یکی نیست.» رو نشون داد. حتی تو یه گوشی دیگه با یه اکانت دیگه اقدام به ارتقا کردم ، بازم خطا رو نشون داد. (9 سال پیش)
0 0
محسن جان پرداخت درون برنامه ای اوکی شد. شما لطف کن همه نظرات این پست رو حذف کن ، حتی همین نظری که نوشتم ، میخوام یه پست تمیز بشه که بچه هام بتونن ازش استفاده کنن. قربونت (9 سال پیش)
0 0
من هنوز استفاده نکردم ولی بازم ممنون ایشالا توی یکی از برنامه های ایندم به کار ببرم :)) ممنون (9 سال پیش)
0 0
مجتبی جون نمیخوای اصلاحات رو انجام بدی؟ (9 سال پیش)
+1 0
در واقع شما نباید سوالتون رو در این تاپیک مطرح کردید ، سوالتون باید یک تاپیک جداگانه میشد تا تاپیک تمیز باقی بمونه ، سر فرصت تاپیک رو دوباره تمیز میکنم ، ضمنا مدیر ها دسترسی حذف پیام ندارند ، فقط میتونن کامنت ها رو اسپم کنند. (9 سال پیش)
+1 0
به نظرم شما بردار تاپیک جدیدی ایجاد کن به همین نام و تمیز در اون توضیح بده و بنویس که کسی نظر نذاره. و اسم این تاپیک رو بذار پرسش و پاسخ در رابطه با پرداخت درون برنامه ای. و تغییرات جدید رو در اینجا بذار و بعد از بدست اومدن مطلب جدیدی به اون بخش تمیز اضافش کن. (9 سال پیش)
0 0
من از این روش استفاده کردم متاسفانه تازه متوجه شدم یک مشکل اساسی داره و دور زده میشه ، اگر روی ارتقا کلیک کنید و وارد اکانت بازار شوید خرید را انجام نداده خارج شوید ، برنامه را بطور کامل ببندید و دوباره باز کنید می بینید اکتیو شده ! دوستان لطفا کمک کنید مشکل از کجاست من دقیقا مثل این جمع بندی عمل کردم (9 سال پیش)
+1 0
@hamClas خوب مثل اینکه مشکل تون حل شده ، اما توجه کنید برسی پرداخت در اسپلش یک تکنیک امنیتی هست ، اما به نوعی اگه بد پیاده کنید ، یه باگ آزار دهنده ، باید ببینید دسترسی به اینترنت وجود داره ، بازار نصبه ، بعد درخواست رو بدید ، زمان نمایش اسپلش رو تا پایان کار بازار کنترل کنید و اجازه ندید خیلی زیاد بشه ! ، من خودم که ترجیح میدادم بی خیال این قسمت بشم ، چون مهم نیست n درصد از کاربرانی که دستگاه روت دارند ، و n-m درصد کاربرانی که دستگاه روت دارن و سواد خوندن preference ها شما رو دارن و n-m-z درصدی که تصمیم میگیرن برنامه ی x تومنی شمارو رایگان استفاده کنن ، چقدر درآمد حاصل تون میکنن ! ، پس ترجیح میدم تجربه ی کاربری اون درصد بیشتر ( تر تر تر :)) ) کاربر ها رو خراب نکنم ، اما خوب دوستان خواستند و من آموزش دادم ! (9 سال پیش)
پاسخ به سوال 
hamcalas  9 سال پیش
+6 0

قربونت برم آقا مجتبی ،بالاخره  مفهمومی یاد گرفتم ،قبلا کپی پیست کرده بودم یک مشکلی داشت

با توجه به آموزش های آقا مجتبی عزیز ، کد کامل دورن پرداخت بازار این شکلی جمع بندی میشه البته برای غیر مصرفی ها

کد صفحه اسپلش :

         QueryInventoryFinishedListener mGotInventoryListener = new IabHelper.QueryInventoryFinishedListener() {

public void onQueryInventoryFinished(IabResult result, Inventory inventory) {
if ( !result.isFailure()) {
boolean state = inventory.hasPurchase(G.SKU_PREMIUM);
Log.i(G.TAG, "Bazaar say isPremiumUser is : " + state);
G.setPremiumState(state);
}
//goToNextActivity();
}
};
G.prepareBazaarInAppBilling(true, mGotInventoryListener);

کلاس G  :

     ////پرداخت بازار

public static final Handler HANDLER = new Handler();
public static final String TAG = "TAG"; //bazaar
public static final String SKU_PREMIUM = "شناسه"; //bazaar
public static final int RC_REQUEST = 0; //bazaar
public static boolean mIsPremium = false; //bazaar
public static IabHelper mHelper; //bazaar
public static String base64EncodedPublicKey = "کد طویل !";
public static boolean setPremiumState ;
public static boolean premiumState ;
public static SharedPreferences preferences;


//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
context = getApplicationContext();
preferences = PreferenceManager.getDefaultSharedPreferences(context);
premiumState = preferences.getBoolean("IS_PREMIUM", false);


}



////////////////////////////////////////////////پرداخت بازار/////////////////
/////////////////////////////////////////////////////////////////////////////
public static boolean prepareBazaarInAppBilling(final boolean requireUpdatePrefrences,
final QueryInventoryFinishedListener mGotInventoryListener) {
try {
mHelper = new IabHelper(G.context, base64EncodedPublicKey);
Log.d(TAG, "Starting setup.");
IabHelper.OnIabSetupFinishedListener listener =
new IabHelper.OnIabSetupFinishedListener() {

public void onIabSetupFinished(IabResult result) {
Log.d(TAG, "Setup finished.");
if ( !result.isSuccess()) {
Log.d(TAG, "Problem setting up In-app Billing: " + result);
}
if (requireUpdatePrefrences && mGotInventoryListener != null) {
mHelper.queryInventoryAsync(mGotInventoryListener);
}
}
};
mHelper.startSetup(listener);
return true;
}
catch (Exception e) {
e.printStackTrace();
return false;
}
}


///////

public static void setPremiumState(boolean state) {
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean("IS_PREMIUM", state);
editor.commit();
premiumState = state;
}



////////////////////////////////////////////////کار در کلاس جی تمام شد ///////
/////////////////////////////////////////////////////////////////////////////



}

کد صفحه پرداخت  :

     public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_payment);
G.prepareBazaarInAppBilling(false, null);
ImageView pay = (ImageView) findViewById(R.id.imgPay);
pay.setOnClickListener(new OnClickListener() {

public void onClick(View arg0) {
if (isPackageInstalled("com.farsitel.bazaar")) {
// Bazar is installed
try {
G.mHelper.launchPurchaseFlow(Payment.this,
G.SKU_PREMIUM, 0, mPurchaseFinishedListener);
}
catch (Exception e) {
e.printStackTrace();
Toast.makeText(G.context, "مشکلی در پرداخت کافه بازار بوجود آمد لطفا بعدا امتحان کنید ",
Toast.LENGTH_SHORT).show();
}
}
else {
// Bazar is not installed
//open Bazzar Home Page To Download It !
Toast.makeText(G.context,
"لطفا برنامه کافه بازار را بروی دستگاه گوشی نصب کنید ",
Toast.LENGTH_SHORT).show();
}

}
});

}

////////////////////////////////

OnIabPurchaseFinishedListener mPurchaseFinishedListener =
new OnIabPurchaseFinishedListener() {

public void onIabPurchaseFinished(IabResult result, Purchase purchase) {
if (result.isFailure()) {
Log.d(G.TAG, "Error purchasing: " + result);
Toast.makeText(G.context, "پرداخت انجام نشد لطفا مجددا سعی کنید", Toast.LENGTH_LONG).show();
//G.setPremiumState(false);
return;
}
else if (purchase.getSku().equals(G.SKU_PREMIUM)) {
G.setPremiumState(true);
Toast.makeText(G.context, " با تشکر نسخه کامل فعال شد یکبار برنامه را بسته دوباره اجرا کنید", Toast.LENGTH_LONG).show();
finish();
}
}
};


///////////////آیا بازار نصب است ؟/////////////////////////////////////

public boolean isPackageInstalled(String PackageName) {
PackageManager manager = getPackageManager();
boolean isAppInstalled = false;
try {
manager.getPackageInfo(PackageName, PackageManager.GET_ACTIVITIES);
isAppInstalled = true;
}
catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
return isAppInstalled;
}


///////////////////این هم کدی که باید آخراکتیویتی پرداخت باشه////////////////
/////////////////////////////////////////////////////////////////////////////
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if ( !G.mHelper.handleActivityResult(requestCode, resultCode, data)) {
super.onActivityResult(requestCode, resultCode, data);
}
}


@Override
public void onDestroy() {
super.onDestroy();
if (G.mHelper != null)
G.mHelper.dispose();
G.mHelper = null;
}

/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
}

 خوب تمام شد حالا هر جایی خواستید می توانید چک کنید آیا پرداخت شده یا نه ، اگر پرداخت نشده بفرست به اکتیوتی پرداخت :

     if (G.premiumState) {// اگر پرداخت شد



} else {// اگر پرداخت نشده بود

Toast.makeText(G.context, "لطفا نسخه کامل را تهیه فرمایید ", Toast.LENGTH_LONG).show();
Intent intent2 = new Intent(G.Curreantactivity, Payment.class);
G.Curreantactivity.startActivity(intent2);

}

 

فعلا که کار می کنه و مشکلی که در پست بالا گفتم را نداره ، دوباره از آموزشی که دادی تشکر می کنم ،و از دوست عزیمان هم که با جمع بندی یک دید کلی دادند تشکر می کنم ،

0 0
ی سوال دوست عزیز.این فایل xml اکتیویتی پرداخت محتواش چی باید باشه؟ (9 سال پیش)
0 0
هر چیزی می تونه باشه ، فقط یک دکمه باید باشه که روش کلیک کنی ،مثلا من یک ImageView گذاشتم که روش کلیک می کنی .... (9 سال پیش)
0 0
مثل اینکه باز م مشکلی هست ، الان از روش بالا استفاده کردم ، پرداخت انجام میشه از برنامه خارج میشم برمی گردم میگه دوباره پرداخت کن ! مجابی جان بی زحمت یک نگاهی به کد بالا می کنی ؟ (9 سال پیش)
0 0
خوب نمیدونم چرا در امولتور جواب میده ولی در گوشی جواب نمیده اصلا در گوشی G.setPremiumState(state); الان با توست متوجه شدم پاسخش منفی هست اما در امولاتور جواب میده چرا ؟ (9 سال پیش)
0 0
ببخشید دوستان.این کد بالخره سالمه استفاده کنیم یا هنوزم مشکلی که جناب hamclass میگن هست؟ (9 سال پیش)
0 0
الان کد بالا که با توجه به آموزش های یگانه تهیه شده مشکلی ندارد و می توانید با خیال راحت استفاده کنید، بازار هم گفت مشکلی نداره (چون قیمت صفر بوده بعد قرار دادن قیمت واقعی باید واقعا خرید می کردم که من انجام نمی دادم و فکر می کردم مشکل از کدهاست)، اما از کدهایی که Reza.M قرار داده و پس از رفع مشکل اصلاحش نکرده استفاده نکنید مشکل داره من قبلا روی شعر بازی استفاده کردم با 10000 دانلود فقط 100نفر خریده بودند که متوجه شدم پس از خروج از بارنامه و بازگشت مجدد برنامه بدون پرداخت اکتیو می شده.در نهایت مجددا از یگانه ی عزیز بخاطر اموزشش تشکر می کنم ، تمامیدوستان می توانند از کدهایی که جمع بندی کردم با خیال راحت استفاده کنند مشکلی مشاهده نشده ! (9 سال پیش)
0 0
سلام جناب Hamcalass.من از این کدی که شما نوشتین استفاده کردم و همه چیز کاملا سالمه.وقتی که پرداخت میکنم تا زمانی که تو برنامه باشم مشکلی نداره اما به محض اینکه خارج میشم و دوباره وارد میشم درخواست پرداخت میخواد.(فکر کنم دقیقا همون مشکل شمارو دارم.)حالا میشه بگید چطور این مشکل حل کردین؟در ضمن من فعلا همون قیمت 0 تومان براش گذاشتم. (9 سال پیش)
0 0
یک تغییر کوچک در کدها دادم دوباره کپی کنیید . کاری نکردم وقتی قیمت واقعی را زدم و خرید کردم مشکلی نبود (9 سال پیش)
0 0
ببخشید mHelper.queryInventoryAsync(mGotInventoryListener) کارش چیه؟ اگه اول برنامه اجراش نکنیم و وضعیت کاربر رو چک نکنیم، حتما باید موقع پرداخت اجرا بشه؟ (9 سال پیش)
0 0
این تغییر رو کی دادین؟من ظهر امروز کپی کردم. (9 سال پیش)
0 0
من هم اگه اول برنامه کد اسپلش رو بذارم مشکلی مشابه مشکل Delina رو دارم. (9 سال پیش)
0 0
من امتحان نکردم بدون کد صفحه اسپلش.یعنی اگه اون کد نزاریم کار میکنه؟ (9 سال پیش)
0 0
این کدها درست هست یا هنوز مشکل داره؟ (8 سال پیش)
0 0
این کدها درست هست یا هنوز مشکل داره؟ (8 سال پیش)
0 0
آقا ممنون این کد ها کاملا صحیح هستند به شرطی که دقیقا عین خودش در جای مناسب به کار برده شوند یعنی دقیقا نوشته شده که هر کد رو در کجای برنامه بگزاریم( اسپلش و G و... ) فقط یه نکته اینکه حتما از اسپلش استفاده کنید تشکر از همه کسانی که همکاری کردند (8 سال پیش)
0 0
سلام به همه دوستان من کدهای بالا رو دقیقا داخل برنامه اضافه کردم اما وقتی run می کنم خطا میده این هم کد خطا ctx=null کسی از دوستان میتونه راهنمایی کنه چکار کنم؟ (8 سال پیش)
0 0
ممنون از اموزش خوبت. من کد صفحه ی پرداخت رو تو ی اکتیویتی جداا گذاشتم ک کاربر با کلیک روی دکمه ارتقا با اینتنت ب این اکتیویتی فرستاده میشه ولی "مشکلی در پرداخت کافه بازار بوجود آمد لطفا بعدا امتحان کنید" نمایش داده میشه. چی کار کنم؟ (6 سال پیش)
پاسخ به سوال 
r22222  9 سال پیش
0 0

ببخشید mHelper.queryInventoryAsync(mGotInventoryListener) کارش چیه؟ اگه اول برنامه اجراش نکنیم و وضعیت کاربر رو چک نکنیم، حتما باید موقع پرداخت اجرا بشه؟ 

پاسخ به سوال 
Alireza_Ghamkhar  9 سال پیش
0 0

کد بنده به صورت زیر میباشد:

    public static final String SKU_PREMIUM = "***";

    
    public boolean mIsPremium = false;

    
    public static final int RC_REQUEST = 0;
    public IabHelper mHelper;
     @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ((AnalyticHelper) getApplication())
                .getTracker(AnalyticHelper.TrackerName.APP_TRACKER);

        String base64EncodedPublicKey = "****";
        mHelper = new IabHelper(this, base64EncodedPublicKey);
        mHelper.enableDebugLogging(true);

        Log.d(TAG, "Starting setup In app Purchase.");

        mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
            public void onIabSetupFinished(IabResult result) {
                Log.d(TAG, "Setup finished.");

                if (!result.isSuccess()) {
                    // Oh noes, there was a problem.
                    Log.e(TAG, "Problem setting up in-app billing: " + result);
                    return;
                }

                // Have we been disposed of in the meantime? If so, quit.
                if (mHelper == null) return;

                // IAB is fully set up. Now, let's get an inventory of stuff we own.
                Log.d(TAG, "Setup successful. Querying inventory.");
                mHelper.queryInventoryAsync(mGotInventoryListener);
            }
        });

        
    }
     IabHelper.QueryInventoryFinishedListener mGotInventoryListener = new IabHelper.QueryInventoryFinishedListener() {
        @Override
        public void onQueryInventoryFinished(IabResult result, Inventory inventory) {
            Log.d(TAG, "Query inventory finished.");
            if (result.isFailure()) {
                Log.d(TAG, "Failed to query inventory: " + result);
                return;
            } else {
                Log.d(TAG, "Query inventory was successful.");
                // does the user have the premium upgrade?
                mIsPremium = inventory.hasPurchase(SKU_PREMIUM);

                // update UI accordingly

                Log.d(TAG, "User is " + (mIsPremium ? "PREMIUM" : "NOT PREMIUM"));

            }

            Log.d(TAG, "Initial inventory query finished; enabling main UI.");
        }
    };


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

خیلی ممنون میشم یکی منو راهنمایی کند.

0 0
دوست عزیز تو این چند ساعت که من سوال بالارو پرسیدم و کسی جواب نداد تقریبا دلیل این مشکل دونستم فقط شما بگو وقتی پرداخت انجام میشه قبل از خروج از برنامه مشکلی هست یا راحت قسمت های پرمیوم باز میشه؟ (9 سال پیش)
0 0
اصن خارج نشدم یه پنجره باز شد و اکی رو زدم رو رمزم رو هم زدم و تمام و بعدش پرمیوم باز شد. از اون به بعد هربار که برنامه رو باز میکنم درون Log به من Is Permium رو false نشون میده در صورتی که نباید اینجوری باشه چون از بازار داره میپرسه آیا این محصول رو خریده که بازار باید بهش true برگردونه... (9 سال پیش)
پاسخ به سوال 
Delna  9 سال پیش
0 0

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

مشکل کامنتای بالا چیه؟؟؟

همونطور که خودم و چندتا از دوستان به این مشکل برخوردیم وقتی پرداخت رو از طریق بازار انجام میدیم تا زمانی که داخل برناممون هستیم هیچ مشکلی پیش نمیاد اما به محض اینکه از برنامه خارج میشیم و دوباره وارد میشیم درخواست پرداخت میکنه.

چرا این مشکل (درواقع یه  حسن)بوجود میاد؟

ما تو کدامون گفتیم که وقتی پرداخت انجام شد premiumstate رو از false به true تغییر بده.به همین دلیل تا وقتی تو برنامه هستیم قسمت های قفل شده premiumstateرو چک میکنن و چون true هست باز میشن اما وقتی برنامه رو دوباره اجرا میکنیم معجزه صفحه splash رخ میده.اگر به اینترنت وصل نباشه که از حالت ذخیره شده استفاده میکنه وبازم اون قسمتا باز میشن اما  اگه به اینترنت وصل یاشه از بازار درخواست میکنه.بازارم در کمال تعجب میگه ((نه)).واون true ذخیره شده دوباره تبدیل به false میشه.درسته که ما قبلا پرداخت رو انجام دادیم اما توجه داشته باشین که ما فقط داریم برناممون رو تست میکنیم و هنوز کامل برای فروش نزاشتیمش.بازار چیزی رو به عنوان خرید قبول میکنه که واقعا خرید شده باشه.

از کجا معلوم که حرفای من درست باشه؟؟؟

به دو دلیل:1.همونطور که گفتم اگه به اینترنت وصل نباشه بازم قسمتای قفل شده بازن یعنی حالت ذخیره شده همون true مونده.پس کدای پرداخت کاملا درسته.2.اگه قیمت رو صفر هم نزاریم و مثلا 100 تومن بزاریم بعد از پرداخت ایمیل بازار میاد اما هیچ پولی کم نمیشه پس بازار این فرایند رو به عنوان یه خرید قبول نداره تا زمانی که برنامه واقعا منتشر بشه.

البته این چیزی بود که من فهمیدم.لطفا اساتید بگن این نظر من درسته یا نه؟

با تشکر.

0 0
پس بی زحمت اگه برنامتو با این روش منتشر کردی و جواب داد به ما هم بگو چون من بدون کدای اسپلش زدم فرستادم رفت. (9 سال پیش)
0 0
من که متوجه نشدم دقیقا. خوب توقع بر این است که وقتی میپرسیم که isPermium باید بهمون true بده. (8 سال پیش)
پاسخ به سوال 
mortezadalil  8 سال پیش
0 0

یک سوال ، این ریسپانسایی که بازار بعد از خرید میفرسته، برای من به شکل رندم تغییر میکنه! (به جز حالت خرید که همه چیش درست هست) مثلا اگه خرید تکراری باشه دوباره مقدار صفر که یعنی موفقیت آمیز بوده رو برمیگردونه یا گاهی اعداد دیگه از صفر تا 9 ؛ دلیلش چیه؟

پاسخ به سوال 
par4301  8 سال پیش
+6 0

یک نکته تکمیلی

خواستم خیلی تشکر کنم، چون من این چند روز درگیر اضافه کردن پرداخت درون برنامه ای به پروژه جدیدم بودم و این آموزش، آموزش آقای کاشی زاده و hamedjj خیلی به من کمک کرد، فقط خواستم یک نکته تکمیلی اضافه کنم که برای من فقط روی امولاتور  وقتی که بازار نصب نبود و در مرحله برگشت به activity اصلی اتفاق می افتاد و شاید مشکل بعضی ها باشه

به قول کسی که این سئوال را در stack overflow مطرح کرده بود، شاید کمتر از 1% مواقع، ولی این خطا پیش می آید که خیلی جالب نیست:

Unable to destroy activity:: java.lang.IllegalArgumentException:Service not registered

 و همین طور که در لینک بالا اشاره شده، مشکل با تغییر این خط در IabHelper حل خواهد شد (ظاهراً از باگ های پروژه تستی موجود در google play هست که بازار هم همون را استفاده کرده):

if (mContext != null) mContext.unbindService(mServiceConn);

به این صورت:

if (mContext != null && mService != null) mContext.unbindService(mServiceConn);

+2 0
به نکته خوبی اشاره کردید . تشکر از شما (8 سال پیش)
پاسخ به سوال 
125485  8 سال پیش
0 0

سلام
در target 21 به بالا با ارور مواجه می شویم‌
از کلاس ٖIabHelper.java هم ایراد می گیره

کسی راه کاری پیدا نکرده ؟    واقعا کلافه شدم

پیشا پیش تشکر

پاسخ به سوال 
Pooya  8 سال پیش
0 0

اگر در هنگام خرید درون برنامه ای و در کد زیر وارد کچ می شه و پیغام مشکل در . . . توست می شه ، ایراد از کجا می تونه باشه ؟ ممنون

 if (isPackageInstalled("com.farsitel.bazaar")) {
// Bazar is installed
try {
G.mHelper.launchPurchaseFlow(ActivityPayment.this, G.SKU_PREMIUM, RC_REQUEST, mPurchaseFinishedListener);
}
catch (Exception e) {
e.printStackTrace();
Toast.makeText(G.context, "مشکلی در پرداخت کافه بازار بوجود آمد لطفا بعدا امتحان کنید ",
Toast.LENGTH_SHORT).show();
}
}
else {
// Bazar is not installed
//open Bazzar Home Page To Download It !
Toast.makeText(G.context,
"لطفا برنامه کافه بازار را بروی دستگاه گوشی نصب کنید ",
Toast.LENGTH_SHORT).show();
}

0 0
ایراد زیر اتفاق میفته java.lang.IllegalStateException: IAB helper is not set up. Can't perform operation: launchPurchaseFlow (8 سال پیش)
پاسخ به سوال 
mmz2010  8 سال پیش
0 0

با سلام به همه عزیزان

 

فایده کلید RSA  چیه؟

آخه بدون اون هم می شه پرداخت کرد و ثبت خرید در تراکنش های ما قرار می گیره.

اگر کسی اونو هک کنه چه اتفاقی می افته؟!

0 0
این جواب بازار در مورد RSA : توصیهٔ امنیتی: برای ایمن نگه داشتن کلید عمومی‌ از گزند کاربران مخرب یا هکرها، سعی کنید آن را به صورت رشته‌ای ثابت درون کد قرار ندهید. در عوض برای پنهان کردن کلید اصلی‌، رشته را به طریقی در زمان اجرا بسازید یا از دستکاری بیت‌ها (مانند XOR با چند رشتهٔ دیگر) استفاده کنید یا آن را از یک مخزن رمزشده بگیرید. کلید به خودی خود دادهٔ محرمانه‌ای نیست، امامطمئناً نمی‌خواهید کار را برای هکر‌ها جهت جایگزینی کلید عمومی‌ برنامهٔ شما با کلیدی دیگر آسان کنید. (8 سال پیش)
0 0
بله من اینو چندین بار خونده بودم . ولی انگار یه چیز الکیه و در واقع کاربردی نداره. این متن هم ترجمه ای هست که بازار از گوگل آورده و فقط اونو ترجمه کرده. من این سوال رو از خود بازار هم پرسیدم ، فعلا که بهم جوابی ندادن. اگه می شد از گوگل بپرسیم خوب بود. (8 سال پیش)
پاسخ به سوال 
Mseif  8 سال پیش
0 0

سلم خدمت اساتید عزیز چنتا مشکل دارم : 

1 - چرا پرداخت درون برنامه توی اندروید 5 به بالا کرش میکنه و خطا میده که مشکل از IabHelper.java هست 

2 - من طبق آموزش های A.L.U پیش رفتم و مشکلی ندارم ولی موقعی که روی دکمه کلیک میکنم Lucky Patcher  بالا میاد که دورش بزنه جلو چشم خودم :|  

کد لیستنر ها رو به همراه mHelper رو داخل یه تابع گذاشتم به نظرتون کاره درستیه ؟

  public static void Inventory(final String SKU) {  
mGotInventoryListener = new IabHelper.QueryInventoryFinishedListener() {
public void onQueryInventoryFinished(IabResult result, Inventory inventory) {

if (result.isFailure()) {
Toast.makeText(G.context, "دریافت اطلاعات از بازار ناموفق بود: " + result, Toast.LENGTH_SHORT).show();
return;
}
else {
Toast.makeText(G.context,"دریافت اطلاعات از بازار با موفقیت انجام شد",Toast.LENGTH_SHORT).show();
mIsPremium = inventory.hasPurchase(SKU);
Toast.makeText(G.context,"کاربر : " + (mIsPremium ? "ویژه" : "ویژه نیست"),Toast.LENGTH_SHORT).show();
}

}
};


mConsumeFinishedListener = new IabHelper.OnConsumeFinishedListener() {

@Override
public void onConsumeFinished(Purchase purchase, IabResult result) {
// TODO Auto-generated method stub
if(result.isSuccess()){
// Consumed !
}
}
};


mPurchaseFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() {
public void onIabPurchaseFinished(IabResult result, Purchase purchase) {
if (result.isFailure()) {
Toast.makeText(G.context,"پرداخت با موفقیت انجام نشد" + result,Toast.LENGTH_SHORT).show();
return;
}
else if (purchase.getSku().equals(SKU)) {
Toast.makeText(G.context,"پرداخت انجام شد ... !!" + result,Toast.LENGTH_SHORT).show();
mHelper.consumeAsync(purchase, mConsumeFinishedListener);
}
}
};



mHelper = new IabHelper(G.context, base64EncodedPublicKey);
mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
public void onIabSetupFinished(IabResult result) {

if (!result.isSuccess()) {
Toast.makeText(G.context, "پرداخت انجام نشد", Toast.LENGTH_LONG).show();
}

mHelper.queryInventoryAsync(mGotInventoryListener);

}
});


}

اینم بخش اتصال به بازار هست : 

G.Inventory(SKU_SEKE2); //این همون تابع بالاست

if (isPackageInstalled("com.farsitel.bazaar")) {
try {
G.mHelper.launchPurchaseFlow(this, SKU_SEKE3, G.RC_REQUEST, G.mPurchaseFinishedListener, "payload-string");
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(G.context, "یک اتفاقی رخ داده است لطفا بعدا سعی کنید", Toast.LENGTH_SHORT).show();
}
}else {
Toast.makeText(G.context,"جهت افزایش سکه نیازمند برنامه بازار می باشید",Toast.LENGTH_SHORT).show();
}

ممنون میشم راهنمایی کنید

0 0
دوستان کسی به این مشکل برنخورده ؟ (8 سال پیش)
پاسخ به سوال 
114746  7 سال پیش
0 0

سلام

من قبلا پرداخت درون برنامه ای رو پیاده کرده بودم. این چنده روزه خواستم دوباره بنویسم ولی متوجه شدم بازار نیاز به سرور رو هم در نظر گرفته. ایا داشتن سرور ضروریه؟

 

0 0
دوستان در مورد پیاده‌سازی پرداخت درون‌برنامه‌ای توسط API پرداخت راهنمایی کنند...ممنون (7 سال پیش)
پاسخ به سوال 
DV  7 سال پیش
0 0

سلام ممنون از تاپیک خوبتون

جناب  ALU درمورد کلاس G بیشتر توضیح میدید ؟

کدی که قرار دادین رو کجای کلاس باید بزارم؟ کلاس باید extend به چی باشه ؟

ممنون...

0 0
دوست عزیز مگه آموزشها رو دنبال نمیکنید؟ استاد کامل توضیح دادن (7 سال پیش)
0 0
عزیزم این تاپیک یعنی هنوز به آموزش استاد نرسیدم اما نیاز دارم بدونم که چی هست؟ شما هم اگه نمیخای جواب بدی لازم نیست الکی وقت خودت و من رو بگیری :) (7 سال پیش)
پاسخ به سوال 
ramandi  3 سال پیش
0 0

سلام آقایALU ، در سورسهای فعلی بازار برای پرداخت درون برنامه ای، تمام خطاها رو برطرف کردم، امّا این خطای پایین رو هرکاری کردم حل نشد، اشکال از چیه، یک هفته ست درگیر این مشکلم.

برای خطای R راه حلی پیدا نکردم، نه در stackOverFlow نه قسمت پرسش های انجمنuncox، اما خطای getLongVersioncode رو برطرف کردم.

خواهشا اگر کسی این پرداخت درون برنامه ای رو کامل انجام داده، برای این مشکل یه راه حل بده. تشکر از همگی دوستان


پاسخگویی و مشاهده پاسخ های این سوال تنها برای اعضای ویژه سایت امکان پذیر است .
چنانچه تمایل دارید به همه بخش ها دسترسی داشته باشید میتوانید از این بخش لایسنس این آموزش را خریداری نمایید .