PDA

View Full Version : سوال درباره ی پرداخت درون برنامه ای



esmail3309
شنبه 29 شهریور 1393, 16:28 عصر
سلام دوستان

چند تا سوال درباره ی پرداخت درون برنامه ای داشتم

من برنامم چهار قسمت کلی داره که من میخوام بره هر قسمت پرداخت و قیمت مجزایی تعیین کنم (یک صفحه ی خرید و چهار دکمه هر کدوم بره خرید یک قسمت از برنامه)

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

ممنون میشم کامل توضیح بدبد

omid.n1990
شنبه 29 شهریور 1393, 16:50 عصر
سلام، شما برای همین پکیج، چهارتا محصول تو بازار باید تعریف کنی،
بعد تو برنامه ات چهارتا چک کردن و پرداخت نیاز داری.
یعنی اونجایی که کد محصول رو میدی و ازش استفاده میکنی رو باید چهاربار انجام بدید. دراقع یکسری از کلاس فعلی ات که داره پرداخت رو انجام میده و چک میکنه رو باید چهار بار انجام بدی با مقادیر مختلف برای کد محصول.
این روش روبرو توصیه نمیکنم چون کپی کردن کلاسها خوب نیست: یا اینکه کلا از کلاس فعلی چهاربار کپی بگیری و اونجایی که کد محصول رو تعیین میکنی برای هر محصول تعیین کنی.

منم یک سوال داشتم. چندروزی میشه لغت "
بره " زیاد میشنوم تو فروم و ظاهرا به معنی "برای" است. داستان این لغت چیه؟؟؟

esmail3309
شنبه 29 شهریور 1393, 16:59 عصر
ممنون دوست عزیز بره جوابت

فقط میتونی یک سورس مثال معرفی کنی؟

esmail3309
شنبه 29 شهریور 1393, 18:10 عصر
راستی چه طور میتونم برناممو تست کنم که پرداختش عمل میکنه یا نه؟ (چون تا برناممو برسی کنن کلی طول میکشه)

omid.n1990
شنبه 29 شهریور 1393, 19:10 عصر
نیاز به بررسی بازار نیست. شما اگر برنامه ات پرداخت درون برنامه ای باشه (توی مانیفست برنامه مجوزش تعریف شده باشه)، محصول رو تعریف کنی همون لحظه و حتی قبل از ارسال درخواست به بازار میتونی برنامه ات رو تست کنی و مشکلی نیست. قیمت محصول رو صفر بزنی یک درگاه الکی به اصلاح ایجاد میکنه یا با صد تومان هم میتونی تیست کنی.
کد Hamedjj رو میتونید بررسی کنید هم ساده است و هم توضیح داده شده. یک بخشی از اون کد،شناسه محصول رو تعریف کرده.
اونجایی که داره شناسه محصول رو میخونه شما باید هربار براساس نیاز شناسه محصول خودت رو بهش بفرستی. این شناسه محصول تو کد رو خودتون برای هر محصولی که خواستید بررسی کنید تغییر بدید. یعنی برای چهار محصول، چهار شناسه محصول دارید و هر محصول بخشی رو فعال میکنه که قسمت مناسب اش رو باید تغییر بدید. به نظرم بهترین کار اینه که کد hamedjj رو کاملا کاملا بخونید و متوجه بشید بعد خیلی راحت میتونید تغییرات خودتون را اعمال کنید.

esmail3309
شنبه 29 شهریور 1393, 19:21 عصر
خیلی ممنون امید جان

پرداخت درون برنامه ای رو به طور کامل پیاده سازی کردم (hamedjj)

فقط موند یه چیزی

چند تا گزینه توی برنامم دارم که میخوام یکی-دو تای اول باز باشه و بره:لبخند: باقی گزینه ها توتست نشون بده که باید برنامه رو ارتقاع بدی

خب تا اینجا که درسته

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

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

omid.n1990
شنبه 29 شهریور 1393, 19:41 عصر
شما بعد از اینکه کاربر ارتقاء داد نسخه اش رو و نتیجه از بازار گرفتی، سطح کاربر رو تو یک جایی ذخیره میکنی. به گمانم پروژه hamedjj با shared prefrences نتیجه رو ذخیره میکرد.

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

برای اینکار در هربار کلیک کاربر بر روی لیست گزینه هاتون (گزینه سه تا هشت)، مقدار ذخیره شده در shared preferences رو میخونی. با یک if خیلی ساده باید بررسی کنید که اگر مقدار ذخیره شده در shared preferences نماینگر سطح طلایی بود (true بود) کاربر وارد میشه و مشکلی نیست و در غیر اینصورت (false بود) پیغام نشون بده که نسخه طلایی رو بخرید.

esmail3309
یک شنبه 30 شهریور 1393, 10:41 صبح
public class litviewactivity extends Activity{


Button btn2;

public ProgressDialog dialog;

SharedPreferences preferences = null ;

private String PACKAGENAME = "" ;

final String KEY = "PERIMIUM" ;

// Debug tag, for logging
static final String TAG = "savedPremium";

// SKUs for our products: the premium upgrade (non-consumable)
static final String SKU_PREMIUM = "online";

// Does the user have the premium upgrade?
boolean mIsPremium1 = false;

// (arbitrary) request code for the purchase flow
static final int RC_REQUEST = 10001;

// The helper object
IabHelper mHelper;


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.listviewactivity);




btn2 = (Button) findViewById(R.id.normalbtn);
// load your setting that are you premium or not?
preferences = getSharedPreferences(PACKAGENAME,Context.MODE_PRIV ATE);
PACKAGENAME = getClass().getName();
Log.e("TAG", PACKAGENAME);
mIsPremium1 = preferences.getBoolean(KEY, false);
if (mIsPremium1 == true) {
updateUi();
return;
}

// show loading dialog with ProgressDialog
dialog = new ProgressDialog(this);
dialog.setMessage("loading...");
dialog.setCancelable(false);
dialog.setInverseBackgroundForced(false);
dialog.show();


String base64EncodedPublicKey = "MIHNMA0GCSqGSIb3DQEBAQUAA4G7ADCBtwKBrwDGhl8/QU3vPjgmTutAbItCBpdwwgFWSAFvzM/OOXVSMHaeH9fjRIxa3aLXVAfuoRJ3Q1ynbQL1Dc2hAvlTAgEeR FNmVkkjypzhZxK3O18wIYJiNleLd/pXZyWaoHeQB6s3eH3KB8uDn2TdZoYzmXxZkvMoDW2db3mT1NmP xJYm+xF7AN/p/Sr9YqEXpIpzsXbe6T30seUHmPDdM4r7h/r6hx/R/2hHvR/vnN0i6w8CAwEAAQ==";
// You can find it in your Bazaar console, in the Dealers section.
// It is recommended to add more security than just pasting it in your source code;
mHelper = new IabHelper(this, base64EncodedPublicKey);


Log.d(TAG, "Starting setup.");
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.d(TAG, "Problem setting up In-app Billing: " + result);
}
// Hooray, IAB is fully set up!
mHelper.queryInventoryAsync(mGotInventoryListener) ;

}
});
}

IabHelper.QueryInventoryFinishedListener mGotInventoryListener = new IabHelper.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);
dialog.hide();
return;
}
else {
Log.d(TAG, "Query inventory was successful.");
// does the user have the premium upgrade?
mIsPremium1 = inventory.hasPurchase(SKU_PREMIUM);

// update UI accordingly

Log.d(TAG, "User is " + (mIsPremium1 ? "PREMIUM" : "NOT PREMIUM"));
}
dialog.hide();
updateUi();
setWaitScreen(false);
Toast.makeText(getApplicationContext(), mIsPremium1? R.string.premium : R.string.notpremium, Toast.LENGTH_SHORT).show();
Log.d(TAG, "Initial inventory query finished; enabling main UI.");

}

};

public void onSavedUpgradeAppButtonClicked(View arg0) {
Log.d(TAG, "Upgrade button clicked; launching purchase flow for upgrade.");
setWaitScreen(true);

/* TODO: for security, generate your payload here for verification. See the comments on
* verifyDeveloperPayload() for more info. Since this is a SAMPLE, we just use
* an empty string, but on a production app you should carefully generate this. */
String payload = "gdhassdflsldaslfkahsjahsjakaasa";

mHelper.launchPurchaseFlow(this, SKU_PREMIUM, RC_REQUEST,
mPurchaseFinishedListener, payload);
}


@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);

Log.d(TAG, "onActivityResult(" + requestCode + "," + resultCode + "," + data);

// Pass on the activity result to the helper for handling
if (!mHelper.handleActivityResult(requestCode, resultCode, data)) {
super.onActivityResult(requestCode, resultCode, data);
} else {
Log.d(TAG, "onActivityResult handled by IABUtil.");
}

}

boolean verifyDeveloperPayload(Purchase p) {
String payload = p.getDeveloperPayload();

return true;
}

IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() {
public void onIabPurchaseFinished(IabResult result, Purchase purchase) {
Log.d(TAG, "Purchase finished: " + result + ", purchase: " + purchase);
if (result.isFailure()) {
Log.d(TAG, "Error purchasing: " + result);
setWaitScreen(false);
return;
}
if (!verifyDeveloperPayload(purchase)) {
complain("Error purchasing. Authenticity verification failed.");
setWaitScreen(false);
return;
}

Log.d(TAG, "Purchase successful.");

if (purchase.getSku().equals(SKU_PREMIUM)) {
Log.d(TAG, "Purchase is premium upgrade. Congratulating user.");
alert("Thank you for upgrading to premium!");
mIsPremium1 = true;
updateUi();
setWaitScreen(false);

}
}
};

@Override
public void onDestroy() {
super.onDestroy();

Log.d(TAG, "Destroying helper.");
if (mHelper != null) mHelper.dispose();
mHelper = null;
}

// Update button with updateUi
public void updateUi() {
if (mIsPremium1) {
findViewById(R.id.normalbtn).setBackgroundResource (mIsPremium1? R.drawable.blue : null);


Button btn_2 = (Button)findViewById(R.id.button2);
btn_2.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
Intent intent = new Intent(litviewactivity.this, page_2.class);
startActivity(intent);
}
});


// change the mIsPremium to true
SharedPreferences.Editor newtask = preferences.edit();
newtask.putBoolean(KEY, true);
newtask.commit();
}
}

// Enables or disables the "please wait" screen.
void setWaitScreen(boolean set) {
findViewById(R.id.screen_wait).setVisibility(set ? View.VISIBLE : View.GONE);
}

void complain(String message) {
Log.e(TAG, "**** testbilling Error: " + message);
alert("Error: " + message);
}

void alert(String message) {
AlertDialog.Builder bld = new AlertDialog.Builder(this);
bld.setMessage(message);
bld.setNeutralButton("OK", null);
Log.d(TAG, "Showing alert dialog: " + message);
bld.create().show();

}

}




با کدای آقا حامد یه چیزی نوشتم:لبخند: . من فقط updateUiرو یه تغیراتی دادم که بعد از خرید، کاربر بتونه با انتخاب دکمه به اکتیویتی مد نظر هدایت میشه

عملا که آزمایشش کردم کاملا درست بود و جواب میداد

یه نگاهی به کد میندازید؟ مشکلی نداره؟

esmail3309
یک شنبه 30 شهریور 1393, 14:55 عصر
ممنون میشم زود تر جواب بدید

omid.n1990
یک شنبه 30 شهریور 1393, 16:52 عصر
یک نگاه اجمالی انداختم مشکل خاصی ندیدم، اگر مشکل ندارید باهاش همچنین برنامه رو حذف و نصب کنید ببینید کاربر آیا میتونه مجدد استفاده کنه یا نه.
شما گفتید چهار خرید دارید پس باید چهار کد محصول داشته باشید و در SKU_PREMIUM قرار بدید. هر بار هم خواستید بررسی کنید باید برای هرچهار محصول انجام بدید
mIsPremium1 = inventory.hasPurchase(SKU_PREMIUM);
و کلا جاهایی که میبینید SKU_PREMIUM استفاده شده رو برای هر چهار محصول باید انجام بدید. updateUI رو هم باید برای هرچهار مورد تعریف کنید که متناسب با خرید کاربر بخشی از برنامه فعال بشه و توی sharedprefrences اعمال بشه و... .

esmail3309
یک شنبه 30 شهریور 1393, 18:02 عصر
هر بار هم خواستید بررسی کنید باید برای هرچهار محصول انجام بدید
mIsPremium1 = inventory.hasPurchase(SKU_PREMIUM);
و کلا جاهایی که میبینید SKU_PREMIUM استفاده شده رو برای هر چهار محصول باید انجام بدید

ممنون امید جان

الان همه چیز درست شد حتی بعد این که برنامه رو پاک و نصب میکنم.

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

الان همه چی اوکیه فقط وقتی یک قسمت از برنامه رو خریداری میکنم به تمام قسمت های برنامه (هر چهار قسمت برنامه) دسترسی پیدا میکنم و دیگه نیازی نیست که قسمت های دیگه رو خریداری کنم

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


یک نگاه اجمالی انداختم

یه چیز دیگه: اجمالی یعنی چی؟:قهقهه:

omid.n1990
یک شنبه 30 شهریور 1393, 21:41 عصر
ابتدا به نظرم نیاز نیست که چهارتا اکتیویتی برای چهارتا فعال سازی ایجاد کنید! خوب یک لایوت بذارید که چهارتا دکمه یا هر نوع گزینه ای داشته باشه و با کلیک روی اون به سمت خرید هدایت بشه.
مورد دوم رو هم چند بار تو همین بخش بهتون گفتم نمیدونم چرا توجه نمیکنید. بحث اینه که شما ظاهرا یک محصول با نام online رو فقط دارید تست میزنید. شما باید تو بازار چهار محصول تعریف کنید با چهار شناسه مختلف و بنابراین چهارتا SKU_PREMIUM خواهید داشت در کد بالا.
SKU_PREMIUM 1
SKU_PREMIUM 2
SKU_PREMIUM 3
SKU_PREMIUM 4
که هم باید مقدار دهی، هم فراخوانی و ... اش رو چک کنید.
بعد از اینکه کاربر خرید رو انجام داد باید تو sharedprefrences یک کلید تعریف کرده باشید و اون رو مقدار دهی کرده باشید. یعنی چهارتا key نیاز دارید.

final String KEY1 = "PERIMIUM1" ;
final String KEY2 = "PERIMIUM2" ;
final String KEY3 = "PERIMIUM3" ;
final String KEY = "PERIMIUM4" ;






بعد هرکدوم از بخشها رو خواستید به کاربر نشون بدید باید ببینید اون sharedprefrences مربوط به اون بخش فعال شده یا نه.
خلاصه: چهارتا محصول که هرکدوم یک شناسه دارد. دسترسی و بررسی هرکدام از چهار محصول را باید انجام دهید. همچینین چهارتا کلید در sharedprefrences نیاز هست که نتایج هرکدوم رو ذخیره کنید.



کد بالا خیلی کد ساده ای هست. توصیه ای میکنم خط به خط اش رو بخونید و کامل متوجه اش بشید
موفق باشید