آموزش پرداخت درون برنامه ای بازار ، صفر تا صد
:: مستندات بازار به روز شده است ! ، ممکن است بخش هایی از این آموزش با مستندات جدید تطابق نداشته باشد ! ، بازار همچنین REST API اش رو در مستندات اش اضافه کرده ، که برای برسی و تایید صحت پرداخت از سرور ، استفاده میشه :)
تغییرات آموزش جدید !
- آموزش بروز و کامل شد
- توضیحات بیشتری در مورد مصرف خرید اضافه شد
- سوالات دوستان ویرایش شد و پاسخ در خود سوال اضافه شد.
- تاپیک تمیز شد و پرسش و پاسخ های غیر مرتبط و تکراری حذف شد
توصیه میکنم با کلیک روی علامت زنگوله در این تاپیک مشترک بشید تا از تغییرات اش مطلع بشید
احتمالا شما هم قبول دارید که مستند سازی بازار در مورد پرداخت درون برنامه ای بسیار ضعیف هست و طبق مکاتبه ای که من با بازار داشتم خودشون هم این رو قبول دارند !
" بله حق با شماست، ما در حال حاضر مشغول آمادهسازی سند راهنمای پرداخت درونبرنامهای برای محیطهای غیربومی هستیم، با اتمام این پروژه، اسناد را بازبینی خواهیم کرد."
پس تصمیم گرفتم اطلاعات ام رو با شما به اشتراک بزارم :)
آموزش ویدئویی پرداخت درون برنامه ای بازار :
البته این آموزش در محیط Basic4Android
لینک حجم حدود 49 مگابایت
خالی از لطف نیست.
سلام دوستان
من یه برنامه از قبل منتشر کردم و الان میخوام توی نسخه جدید پرداخت درون برنامه ای بزنم. تمام این روش ها که توضیح دادید قبل از انتشار برنامه اون را آپلود میکنیم و توی قسمت محصول جدید برنامه را انتخاب می کنیم و کلید مربوطه را میگیریم اما من الان برنامم منتشره و حتی نسخه جدید هم با دسترسی پرداخت آپلود کردم اما توی قسمت محصولات جدید توی بازار نمیتونم برنامه را انتخاب کنم و اصلا توی لیست نیست. به نظرتون باید چکار کنم؟
سلام خدمت دوستان.مخصوصا استاد تاپیک مجتبی یگانه عزیز.
من این پرداخت درون برنامه ای (بصورت یکبار مصرف : که با خرید کل قسمت های برنامه قابل دیدن باشه) رو طبق اموزش تاپیک درست کردم ، به نوعی لقمه آماده :)
هر کی استفاده کرد یه صلوات بفرسته .
کد صفحه پرداخت :
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{// اگر پرداخت نشده بود
// نمایش محدود محتوا
}
بچه ها دعای خیر یادتون نره
قربونت برم آقا مجتبی ،بالاخره مفهمومی یاد گرفتم ،قبلا کپی پیست کرده بودم یک مشکلی داشت
با توجه به آموزش های آقا مجتبی عزیز ، کد کامل دورن پرداخت بازار این شکلی جمع بندی میشه البته برای غیر مصرفی ها
کد صفحه اسپلش :
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);
}
فعلا که کار می کنه و مشکلی که در پست بالا گفتم را نداره ، دوباره از آموزشی که دادی تشکر می کنم ،و از دوست عزیمان هم که با جمع بندی یک دید کلی دادند تشکر می کنم ،
ببخشید mHelper.queryInventoryAsync(mGotInventoryListener) کارش چیه؟ اگه اول برنامه اجراش نکنیم و وضعیت کاربر رو چک نکنیم، حتما باید موقع پرداخت اجرا بشه؟
کد بنده به صورت زیر میباشد:
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 هستش با توجه به اینکه در همان لحظه ظاهرا از بازار سوال میپرسه و جوابشو میگیره. زمانی هم که خرید رو انجام میدم همه چی نرمال انجام میشه و فقط پولی از حسابم کم نمیشه و قابلیت های پرمیومی که تعریف کردم تازه اون موقع میاد.
خیلی ممنون میشم یکی منو راهنمایی کند.
مث خیلی از دوستان واسم سوال شده بود که چرا باید تو صفحه splash کد بزنیم اما با مشکلی که تو این کامنتای بالا بهش برخوردم دلیل این کار آقای یگانه رو فهمیدم.کد زدن تو splash معجزه میکنه.
مشکل کامنتای بالا چیه؟؟؟
همونطور که خودم و چندتا از دوستان به این مشکل برخوردیم وقتی پرداخت رو از طریق بازار انجام میدیم تا زمانی که داخل برناممون هستیم هیچ مشکلی پیش نمیاد اما به محض اینکه از برنامه خارج میشیم و دوباره وارد میشیم درخواست پرداخت میکنه.
چرا این مشکل (درواقع یه حسن)بوجود میاد؟
ما تو کدامون گفتیم که وقتی پرداخت انجام شد premiumstate رو از false به true تغییر بده.به همین دلیل تا وقتی تو برنامه هستیم قسمت های قفل شده premiumstateرو چک میکنن و چون true هست باز میشن اما وقتی برنامه رو دوباره اجرا میکنیم معجزه صفحه splash رخ میده.اگر به اینترنت وصل نباشه که از حالت ذخیره شده استفاده میکنه وبازم اون قسمتا باز میشن اما اگه به اینترنت وصل یاشه از بازار درخواست میکنه.بازارم در کمال تعجب میگه ((نه)).واون true ذخیره شده دوباره تبدیل به false میشه.درسته که ما قبلا پرداخت رو انجام دادیم اما توجه داشته باشین که ما فقط داریم برناممون رو تست میکنیم و هنوز کامل برای فروش نزاشتیمش.بازار چیزی رو به عنوان خرید قبول میکنه که واقعا خرید شده باشه.
از کجا معلوم که حرفای من درست باشه؟؟؟
به دو دلیل:1.همونطور که گفتم اگه به اینترنت وصل نباشه بازم قسمتای قفل شده بازن یعنی حالت ذخیره شده همون true مونده.پس کدای پرداخت کاملا درسته.2.اگه قیمت رو صفر هم نزاریم و مثلا 100 تومن بزاریم بعد از پرداخت ایمیل بازار میاد اما هیچ پولی کم نمیشه پس بازار این فرایند رو به عنوان یه خرید قبول نداره تا زمانی که برنامه واقعا منتشر بشه.
البته این چیزی بود که من فهمیدم.لطفا اساتید بگن این نظر من درسته یا نه؟
با تشکر.
یک سوال ، این ریسپانسایی که بازار بعد از خرید میفرسته، برای من به شکل رندم تغییر میکنه! (به جز حالت خرید که همه چیش درست هست) مثلا اگه خرید تکراری باشه دوباره مقدار صفر که یعنی موفقیت آمیز بوده رو برمیگردونه یا گاهی اعداد دیگه از صفر تا 9 ؛ دلیلش چیه؟
یک نکته تکمیلی
خواستم خیلی تشکر کنم، چون من این چند روز درگیر اضافه کردن پرداخت درون برنامه ای به پروژه جدیدم بودم و این آموزش، آموزش آقای کاشی زاده و 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);
سلام
در target 21 به بالا با ارور مواجه می شویم
از کلاس ٖIabHelper.java هم ایراد می گیره
کسی راه کاری پیدا نکرده ؟ واقعا کلافه شدم
پیشا پیش تشکر
اگر در هنگام خرید درون برنامه ای و در کد زیر وارد کچ می شه و پیغام مشکل در . . . توست می شه ، ایراد از کجا می تونه باشه ؟ ممنون
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();
}
با سلام به همه عزیزان
فایده کلید RSA چیه؟
آخه بدون اون هم می شه پرداخت کرد و ثبت خرید در تراکنش های ما قرار می گیره.
اگر کسی اونو هک کنه چه اتفاقی می افته؟!
سلم خدمت اساتید عزیز چنتا مشکل دارم :
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();
}
ممنون میشم راهنمایی کنید
سلام
من قبلا پرداخت درون برنامه ای رو پیاده کرده بودم. این چنده روزه خواستم دوباره بنویسم ولی متوجه شدم بازار نیاز به سرور رو هم در نظر گرفته. ایا داشتن سرور ضروریه؟
سلام ممنون از تاپیک خوبتون
جناب ALU درمورد کلاس G بیشتر توضیح میدید ؟
کدی که قرار دادین رو کجای کلاس باید بزارم؟ کلاس باید extend به چی باشه ؟
ممنون...
سلام آقایALU ، در سورسهای فعلی بازار برای پرداخت درون برنامه ای، تمام خطاها رو برطرف کردم، امّا این خطای پایین رو هرکاری کردم حل نشد، اشکال از چیه، یک هفته ست درگیر این مشکلم.

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

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