Google play之應(yīng)用內(nèi)支付接入

前言

如果要接入google登錄,可以參考我的前一篇文章Google Play登錄SDK接入

官方文檔

google應(yīng)用內(nèi)支付V3接入Android官方文檔

官方Sample

Google應(yīng)用內(nèi)支付官方樣例

google提供的官方sample是已經(jīng)對(duì)官方api經(jīng)過(guò)封裝了的,而google官方文檔是按照最原裝的代碼進(jìn)行
描述的,所以本文將按照sample方式接入

SDK接入

  • google應(yīng)用內(nèi)支付不用添加jar包喇完,不用添加依賴,只需要一個(gè)aidl文件:IInAppBillingService.aidl 可以從sample中獲得财边,并且將其放在: com.android.vending.billing包下
  • 將sample中的util中的所用類(lèi)拷貝到自己的項(xiàng)目的util下着撩,這些類(lèi)是已經(jīng)對(duì)官方的api進(jìn)行二次封裝了

配置資源文件

在AndroidManifest.xml文件中,添加以下權(quán)限:

<uses-permission android:name="com.android.vending.BILLING" />

SDK中的API調(diào)用

  • 初始化
//設(shè)置自己從google控制臺(tái)得到的公鑰
 mHelper = new IabHelper(activity, "YOUR_PUBLIC_KEY");
        //調(diào)試模式
        mHelper.enableDebugLogging(true);
        Log.d(TAG, "Starting setup.");
        mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
            @Override
            public void onIabSetupFinished(IabResult result) {
                Log.d(TAG, "Setup finished.");
                if (!result.isSuccess()) {
                    Log.d(TAG, "Setup fail.");
                    return;
                }
                if (mHelper == null){
                    Log.d(TAG, "Setup fail.");
                    return;
                }
                Log.d(TAG, "Setup success.");
            }
        });
  • 查詢庫(kù)存
/**
     * 查詢庫(kù)存
     * */
 private void queryInventory(){
        Log.e(TAG, "Query inventory start");
        try {
            mHelper.queryInventoryAsync(mGotInventoryListener);
        } catch (IabHelper.IabAsyncInProgressException e) {
            e.printStackTrace();
        }
    }

/**查詢庫(kù)存的回調(diào)*/
private IabHelper.QueryInventoryFinishedListener mGotInventoryListener = new IabHelper.QueryInventoryFinishedListener() {
        @Override
        public void onQueryInventoryFinished(IabResult result, Inventory inventory) {
            Log.e(TAG, "Query inventory finished.");
            if (result.isFailure()) {
                Log.e(TAG, "Failed to query inventory: " + result);
                return;
            }
            Log.e(TAG, "Query inventory was successful." + inventory.getPurchase(mPayInfo.getProductId()));
            if (inventory.hasPurchase(mPayInfo.getProductId())){
                //庫(kù)存存在用戶購(gòu)買(mǎi)的產(chǎn)品沈条,先去消耗
            }else{
                //庫(kù)存不存在
            }
        }
    };
  • 購(gòu)買(mǎi)商品
    google應(yīng)用內(nèi)支付調(diào)用購(gòu)買(mǎi)接口的時(shí)候需忿,應(yīng)先確保用戶沒(méi)有存在這個(gè)商品的購(gòu)買(mǎi)(買(mǎi)了但是沒(méi)有消耗)
//在合適的地方調(diào)用購(gòu)買(mǎi)
mHelper.launchPurchaseFlow(mActivity, sku, RC_REQUEST, mPurchaseFinishedListener, extra);

購(gòu)買(mǎi)的回調(diào)

private IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() {
        @Override
        public void onIabPurchaseFinished(IabResult result, Purchase purchase) {
            Log.d(TAG, "Purchase finished: " + result + ", purchase: " + purchase);
            if (result.isFailure()) {
                // Oh noes! pay fail
                Log.d(TAG,"Error purchasing: " + result);
                return;
            }

            Log.d(TAG, "Purchase successful.");
            //模擬檢測(cè)public key
            checkPk(purchase);
        }
    };

購(gòu)買(mǎi)成功后,應(yīng)該將購(gòu)買(mǎi)返回的信息發(fā)送到自己的服務(wù)端,自己的服務(wù)端再去利用public key去驗(yàn)簽

  • 消耗商品
    用戶購(gòu)買(mǎi)成功后屋厘,如果是可重復(fù)購(gòu)買(mǎi)的商品涕烧,應(yīng)該立刻將這個(gè)商品消耗掉,以及在購(gòu)買(mǎi)之前應(yīng)確保用戶不存在這個(gè)商品汗洒,如果存在就調(diào)用消耗商品的接口去將商品消耗掉
mHelper.consumeAsync(purchase, mConsumeFinishedListener);

消耗商品的回調(diào)

 private IabHelper.OnConsumeFinishedListener mConsumeFinishedListener = new IabHelper.OnConsumeFinishedListener() {
        @Override
        public void onConsumeFinished(Purchase purchase, IabResult result) {
            Log.d(TAG, "Consumption finished. Purchase: " + purchase + ", result: " + result);
            if (result.isSuccess()) {
                Log.d(TAG, "Consumption successful. Provisioning.");
            }
            else {
                Log.d(TAG,"Error while consuming: " + result);
            }
        }
    };

安全問(wèn)題

  • 由于利用官方的sample實(shí)現(xiàn)方式是在app客戶端利用公鑰進(jìn)行驗(yàn)簽议纯, 也就是將支付的回調(diào)暴露在客戶端了,這種方式不可取溢谤,可以對(duì)sample里面進(jìn)行驗(yàn)簽的部分代碼進(jìn)行改造瞻凤,取消本地驗(yàn)簽,然后將支付成功回調(diào)的信息傳輸?shù)阶约悍?wù)器世杀,在服務(wù)器驗(yàn)簽再將結(jié)果返回給客戶端

常見(jiàn)問(wèn)題

  • 確保包名和google控制臺(tái)配置一致
  • 確保購(gòu)買(mǎi)時(shí)候傳輸?shù)膒roductId和在google控制臺(tái)配置一致
  • 確保App的version和google控制臺(tái)的version一致
  • 確保keystore和上傳到google控制臺(tái)的keystore一致
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末鲫构,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子玫坛,更是在濱河造成了極大的恐慌结笨,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,978評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件湿镀,死亡現(xiàn)場(chǎng)離奇詭異炕吸,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)勉痴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門(mén)赫模,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人蒸矛,你說(shuō)我怎么就攤上這事瀑罗。” “怎么了雏掠?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,623評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵斩祭,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我乡话,道長(zhǎng)摧玫,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,324評(píng)論 1 282
  • 正文 為了忘掉前任绑青,我火速辦了婚禮诬像,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘闸婴。我一直安慰自己坏挠,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,390評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布邪乍。 她就那樣靜靜地躺著降狠,像睡著了一般对竣。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上喊熟,一...
    開(kāi)封第一講書(shū)人閱讀 49,741評(píng)論 1 289
  • 那天柏肪,我揣著相機(jī)與錄音姐刁,去河邊找鬼芥牌。 笑死,一個(gè)胖子當(dāng)著我的面吹牛聂使,可吹牛的內(nèi)容都是我干的壁拉。 我是一名探鬼主播,決...
    沈念sama閱讀 38,892評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼柏靶,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼弃理!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起屎蜓,我...
    開(kāi)封第一講書(shū)人閱讀 37,655評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤痘昌,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后炬转,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體辆苔,經(jīng)...
    沈念sama閱讀 44,104評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年扼劈,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了驻啤。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,569評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡荐吵,死狀恐怖骑冗,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情先煎,我是刑警寧澤贼涩,帶...
    沈念sama閱讀 34,254評(píng)論 4 328
  • 正文 年R本政府宣布,位于F島的核電站薯蝎,受9級(jí)特大地震影響磁携,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜良风,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,834評(píng)論 3 312
  • 文/蒙蒙 一谊迄、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧烟央,春花似錦统诺、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,725評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春啄寡,著一層夾襖步出監(jiān)牢的瞬間豪硅,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,950評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工挺物, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留懒浮,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,260評(píng)論 2 360
  • 正文 我出身青樓识藤,卻偏偏與公主長(zhǎng)得像砚著,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子痴昧,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,446評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,732評(píng)論 25 707
  • 分手后的兩個(gè)人,要么挽回豪娜,要么徹底分開(kāi)餐胀,形如陌路。成為朋友侵歇,不是不可以骂澄,只是太難,太尷尬惕虑。我想這個(gè)道理誰(shuí)都懂坟冲,而即...
    一世愛(ài)情閱讀 443評(píng)論 0 2
  • 迎接清晨的第一縷陽(yáng)光,早上6:50溃蔫,我早早到達(dá)公司健提,按照公司的統(tǒng)一要求,換好工作服伟叛,整理儀容儀表私痹,穿戴整齊大方,統(tǒng)...
    huihui15995閱讀 299評(píng)論 0 0