概要:Google 建議在完成支付后依據(jù)服務(wù)器返回訂單結(jié)果為準(zhǔn)所以才有了這篇文章。本文針對訂單支付完成后 驗(yàn)證購買交易 過程锨侯、踩坑記錄嫩海。開始前,先有一個(gè)大致的過程囚痴,流程圖大概說明了 向Google服務(wù)器驗(yàn)證訂單的過程叁怪,其中具體的過程下文會(huì)詳細(xì)解釋:
前提
- Google Api
- Google Play Console
- 測試App程序
- 最好使用自己應(yīng)用內(nèi)創(chuàng)建的商品(不建議使用Google提供的測試商品)
Google 文檔:Google Play Developer API、Api使用入門
Google Api
由于這里是向Google服務(wù)器驗(yàn)證深滚,需要使用調(diào)用相關(guān)的 Google Api 進(jìn)行相關(guān)操作 :
這里我選擇的是 OAuth客戶端 奕谭,OAuth客戶端需要在Google Play Console ---> 設(shè)置 -----> 開發(fā)者賬號 -----> Api 權(quán)限 進(jìn)行創(chuàng)建,如下圖:
創(chuàng)建完成后成箫,點(diǎn)擊 在Google Developers Console中查看 展箱, 進(jìn)入到 Api 控制臺(tái) ,需要新建項(xiàng)目蹬昌,創(chuàng)建項(xiàng)目完成混驰,點(diǎn)擊 OAuth同意屏幕 配置驗(yàn)證信息,比如:我使用到了../androidpublisher
Api添加即可如下圖:
添加憑據(jù)皂贩,并添加
注意栖榨,右側(cè)下載按鈕,下載出來的json明刷,包含后續(xù)所需要的參數(shù)婴栽,如下圖:
1,獲取授權(quán) Api 調(diào)用
授權(quán)接口:https://accounts.google.com/o/oauth2/v2/auth
調(diào)用辈末,這里解釋一下 必填 參數(shù)(全部可以參考上面鏈接查看)
參數(shù) | 解釋 |
---|---|
client_id | api控制臺(tái)獲取愚争,上圖也有 |
redirect_uri | api控制臺(tái)獲取,上圖也有,比如:urn:ietf:wg:oauth:2.0:oob
|
response_type | 固定值:code 挤聘。(確定Google OAuth 2.0端點(diǎn)是否返回授權(quán)碼轰枝。code為已安裝的應(yīng)用程序設(shè)置參數(shù)值。) |
scope | 我這里填入的是:https://www.googleapis.com/auth/androidpublisher 组去。范圍指的是應(yīng)用程序可以訪問的Api范圍鞍陨,附:OAuth2.0 Api范圍
|
這里的的接口,需要在瀏覽器調(diào)用 (需要你的Google賬號進(jìn)行授權(quán)) 从隆,例如我在瀏覽器調(diào)用下面的接口(需要將里面的id參數(shù)替換為自己的參數(shù)):
https://accounts.google.com/o/oauth2/v2/auth?client_id=你的id&redirect_uri=urn:ietf:wg:oauth:2.0:oob&response_type=code&scope=https://www.googleapis.com/auth/androidpublisher
-
頁面訪問url后诚撵,首先需要進(jìn)行授權(quán):
授權(quán)頁面.png -
確認(rèn)選擇、結(jié)果頁面
確認(rèn)選擇頁面.png
結(jié)果頁面.png
上面的結(jié)果键闺,就是下面所需要的 code 值寿烟,注意,這里調(diào)用一次辛燥,保存在項(xiàng)目即可韧衣,不需要每次都進(jìn)行該步驟V言濉9荷!3┟!坑2硕噩!
2,獲取access_token api調(diào)用
post 請求: https://www.googleapis.com/oauth2/v4/token
參數(shù) | 解釋 |
---|---|
code |
https://accounts.google.com/o/oauth2/v2/auth 接口返回的值缭贡,就是上面授權(quán)后獲得的值 |
client_id | api控制臺(tái)獲取炉擅,上面也有 |
client_secret | api控制臺(tái)獲取,上面json中也有 |
redirect_uri | api控制臺(tái)獲取阳惹,上面也有,比如:urn:ietf:wg:oauth:2.0:oob
|
grant_type | 固定值:authorization_code
|
比如我的網(wǎng)絡(luò)請求谍失,請求成功返回結(jié)果如下:
/**
* 獲取access_token : 每個(gè)請求,都需要拼接到后面莹汤,例如:?access_token=xxxxx
*/
String tokenUrl = "https://accounts.google.com/o/oauth2/token";
String code = "4/qQFrmvbxm5hEnXPxiBz-LYoFAf4kIqHhHvmn2CfaeI_2kq3bqtPYnUs";
String client_secret = "rlCm_3T2zOitkOA6cS4TDR_P";
OkHttpUtils.post().url(tokenUrl)
.addParams("client_id",cliendId) //GoogleApi后臺(tái)拿到
.addParams("redirect_uri",redirect_uri) //GoogleApi后臺(tái)拿到
.addParams("grant_type","authorization_code")//固定值
.addParams("code",code)//上面獲取快鱼,只需要調(diào)用一次
.addParams("client_secret",client_secret)////GoogleApi后臺(tái)拿到
.build().execute(new StringCallback() {
@Override
public void onError(Call call, Exception e, int id) {
Log.d(TAG, "onError: ");
}
@Override
public void onResponse(String response, int id) {
//返回的結(jié)果都在 response 包含
Log.d(TAG, "onResponse: ");//返回,GoogleAccsessTokenBean.java 相關(guān)內(nèi)容
}
});
********************** 返回結(jié)果 ***********************************
/**
* access_token : ya29.GltyB1aAtM7QEz0T0GVtNZk64bXldamoCWU32us0fe2zD8HvBNW3LMig4-T2p3EAc4oDfozqa6ZHIaNfCC19KFk4qFhPwAniSzy2r7OeunPHx8P6tzCwjKA1_H4F
* expires_in : 3600
* refresh_token : 1/ZSenrx4IL5iUnyA_P0TjDG9GpY6xENpEIv4LeQeo3mg
* scope : https://www.googleapis.com/auth/androidpublisher
* token_type : Bearer
*/
注意:
- 這里需要保存 access_token纲岭、refresh_token抹竹,下面會(huì)解釋refresh_token用途
- 這里返回的
access_token
就是每次調(diào)用Api,需要拼接的參數(shù)V钩薄G耘小!坑喇闸,這個(gè)access_token
必須正確(不然會(huì)報(bào)400 401錯(cuò)誤)0懒铡!
refresh_token
測試階段過了一會(huì)發(fā)現(xiàn)接口無法調(diào)通燃乍,排查發(fā)現(xiàn)原因是Token過期了(應(yīng)該沒到token過期時(shí)間,返回的過期時(shí)間是3600s不知道怎么回事~~有點(diǎn)懵逼-_- )唆樊,重新查閱文檔發(fā)現(xiàn),上面調(diào)用https://www.googleapis.com/oauth2/v4/token
接口返回的 refresh_token
是調(diào)用 刷新Token 接口(兩個(gè)是同一個(gè)接口只不過傳參不同)橘沥。
具體解釋見下圖(網(wǎng)頁翻譯了一下)具體說明了傳參以及示例窗轩。
注意:參數(shù)
grant_type
的值變成了refresh_token
小結(jié):
上面通過Google Play Console、Google API 控制臺(tái)座咆,生成OAuth2客戶端痢艺,主要是為了驗(yàn)證授權(quán)用戶,對于我們來說就是為了獲取 code介陶、access_token堤舒、refresh_token ,為調(diào)用下面的 校驗(yàn)接口 做鋪墊哺呜。
注意舌缤,坑!!9臁A晡:
- code:獲取需要網(wǎng)頁打開,需用戶登錄Google賬號授權(quán)介牙,code值生成一次壮虫,保存在項(xiàng)目即可!
- access_token :獲取需要使用上面獲得的code环础,不然各種401 404錯(cuò)誤囚似。
- 接口請求如果出現(xiàn)問題,請認(rèn)真仔細(xì)對比 接口參數(shù) 是否有誤线得!
Google Play 校驗(yàn)接口
到這里饶唤,才是真正的調(diào)用 校驗(yàn)接口,這個(gè)接口提供了兩個(gè)方法贯钩,不過返回值都一樣募狂,先說一下返回值代表意義
{
"kind": "androidpublisher#productPurchase",
"purchaseTimeMillis": long,
"purchaseState": integer,
"consumptionState": integer,
"developerPayload": string,
"orderId": string,
"purchaseType": integer,
"acknowledgementState": integer
}
參數(shù) | 類型 | 解釋 |
---|---|---|
kind | String | 這種類型代表androidpublisher服務(wù)中的inappPurchase對象。 |
purchaseTimeMillis | long | 購買產(chǎn)品的時(shí)間魏保,自紀(jì)元(1970年1月1日)以來的毫秒數(shù)熬尺。 |
purchaseState | integer | 訂單的購買狀態(tài); 0:購買 1:取消 2:掛起(待支付) |
developerPayload | String | 開發(fā)人員指定的字符串,包含有關(guān)訂單的補(bǔ)充信息谓罗。 |
orderId | String | 與購買inapp產(chǎn)品相關(guān)聯(lián)的訂單ID粱哼。 |
purchaseType | integer | 購買inapp產(chǎn)品的類型。僅當(dāng)未使用標(biāo)準(zhǔn)應(yīng)用內(nèi)結(jié)算流程進(jìn)行此購買時(shí)檩咱,才會(huì)設(shè)置此字段揭措。可能的值是:0. 測試(即從許可證測試帳戶購買)1. 促銷(即使用促銷代碼購買)2. 獎(jiǎng)勵(lì)(即觀看視頻廣告而非付費(fèi)) |
acknowledgementState | integer | inapp產(chǎn)品的確認(rèn)狀態(tài)刻蚯。0:待確認(rèn) 1:已確認(rèn) |
consumptionState | integer | inapp消費(fèi)狀態(tài)绊含。0:未消費(fèi) 1:已消費(fèi) |
Acknowledge - 確認(rèn)購買了一個(gè)inapp項(xiàng)目。
1炊汹,調(diào)用確認(rèn)接口前躬充,需要調(diào)用授權(quán)接口(其實(shí)就是需要傳入授權(quán)的access_token
)
post 請求: https://www.googleapis.com/auth/androidpublisher
該接口需要傳遞參數(shù)
參數(shù) | 類型 | 解釋 |
---|---|---|
developerPayload | String | 有效負(fù)載附加到購買,該值在 商品詳情 會(huì)有返回 |
access_token | String | 授權(quán)token,上面獲得的token |
2讨便,然后調(diào)用 確認(rèn)授權(quán)接口
POST https://www.googleapis.com/androidpublisher/v3/applications/你的應(yīng)用包名/purchases/products/商品id/tokens/商品token:acknowledge
這個(gè)請求充甚,需要注意替換三個(gè)地方,上面我也標(biāo)記出來了霸褒, 包名伴找、商品的productId、token(這里指的是商品購買返回的商品token) 注意后面有一個(gè):acknowledge
废菱, 還需要加上 參數(shù):access_token
Get - 檢查inapp項(xiàng)目購買和消費(fèi)狀態(tài)
1技矮,需要調(diào)用授權(quán)接口(其實(shí)就是需要傳入授權(quán)的access_token
)
https://www.googleapis.com/auth/androidpublisher
2抖誉,Get方法調(diào)用 ,檢查inapp項(xiàng)目的購買和消費(fèi)狀態(tài)接口
Get方法 https://www.googleapis.com/androidpublisher/v3/applications/你的應(yīng)用包名/purchases/products/商品id/tokens/商品token
這個(gè)請求衰倦,需要注意替換三個(gè)地方袒炉,上面我也標(biāo)記出來了, 包名耿币、商品的productId梳杏、token(這里指的是商品購買返回的商品token) 注意不同于上面,后面沒acknowledge淹接, 還需要加上參數(shù): access_token。
總結(jié):
服務(wù)器驗(yàn)證這步驟叛溢,折騰了好久塑悼,開始一直是接口調(diào)用不通(400 401錯(cuò)誤),中間也是沒少踩坑楷掉,如果出問題請仔細(xì)檢查下面幾項(xiàng)
- 配置檢測厢蒜,如:自己的應(yīng)用包名是否跟Google Play Console 一致、Google Api Oauth創(chuàng)建等配置是否有誤烹植。
- 接口參數(shù)斑鸦,如:Google Api 后臺(tái)獲取的
client_id、secret_id
是否正確草雕,是否授權(quán)獲取到code(僅調(diào)一次巷屿,保存即可),接口調(diào)用是否傳遞了access_token
以及是否過期 - 如果校驗(yàn)步驟遇到400(接口返回信息: Invalid Value)墩虹,建議去查一下購買的商品在Google Play Console 上是否處于 有效 狀態(tài)嘱巾,不要使用Google提供的訂單測試商品。