谷歌支付

谷歌支付验证

后端对谷歌支付进行验证的时候遇到些问题,为了方便以后查阅,记录整个过程

1 说明

  • 本文讲述后端使用谷歌api验证支付的过程
  • 流程: 前端支付完毕之后会获取token,将token发送至后端,后端将此token发向google进行查询,如果是正常有效的token,谷歌会返回对应订单的详细信息,验证通过后再通知前端进行消费(也可以前端先消费再通知后端验证发货)

2 前期准备

2-1 创建 api 项目

  • 填写项目名称后,项目就创建完成了

  • 创建完成之后,需要启用所需要的api服务,点击启用API和服务

  • 搜索Google Play Android Developer API,我们将使用这个 API 服务来查询订单,点击启用它

  • 点击创建凭据

  • 实际上是跳转到test-api这个项目的凭据创建了,点击信息中心,可以看到API列表中出现了Google Play Android Developer API,还有请求次数,错误,错误率等信息

2-2 创建 OAuth 客户端 ID

  • 接下来准备创建OAuth客户端ID,点击凭据

  • 先填写OAuth同意屏幕,应用名称那一行可以随便填写,反正是给自己看的,填完应用名称之后,还需要填已授权的网域,然后点击最下方的保存按钮

  • 已授权的网域最好填写要发起请求的后台所用的域名,假设我的后台为sdk.keylala.cn,则此处填写keylala.cn

  • 准备创建OAuth客户端ID

  • 填写的内容 _ 应用类型选择: 网页应用 _ 名称:随意填写了 _ 已获授权的 JavaScript 来源: https://keylala.cn _ 已获授权的重定向 URI: https://keylala.cn,这个随便,比如写成https://keylala.cn/callback,不一定需要这个接口真实存在的,但一定要记着这个URI,后文中我们称之为redirectURI

  • 点击创建按钮,获得客户端 ID 和客户端密钥,下文中分别称为clientIdclientSecret

2-3 获取 code

  • 请将下方url中的redirect_uriclient_id填写上2-2中获取的参数

https://accounts.google.com/o/oauth2/auth?scope=https://www.googleapis.com/auth/androidpublisher&response_type=code&access_type=offline&redirect_uri=...&client_id=...

  • 放到浏览器上(此时不要关闭之前的页面, 此浏览器需要登录谷歌开发者账号,且不能点退出),另起一个页面标签,复制上去,点击允许
  • 这时候会跳转到redirect_uri开头的地址,如果redirect_uri是胡乱填的,这里会出现一个404页面或者无法访问的提示,不过没关系,请将地址栏中的地址复制下来,把code=4/xxxxx的值取出来,这里就获得了code的值。
  • code的值类似这样的一长串: 4/eWdxD7b-YSQ5CNNb-c2iI83KQx19.wp6198ti5Zc7dJ3UXOl0T3aRLxQmbwI

2-4 获取 refresh_token

  • 发送POST请求到https://accounts.google.com/o/oauth2/token

  • 参数:

    • grant_type=authorization_code
    • code={2-3 获得的 code 值}
    • client_id={2-2 获得的 clientId}
    • client_secret={2-2 获得的 clientSecret}
    • redirect_uri={2-2 填写的 redirectURI}
  • 这里使用Postman工具发送请求

  • 这样就获取了refresh_token,下文中称refreshToken,这个token是一个长久有效的token,可以保存起来

3 项目关联

  • 2中我们创建了一个API服务,名为: test-api,以及获取了这个api的一系列参数

  • 我们可以创建很多个 api,给不同 api 启用不同的谷歌 api

  • 这里我们要将我们的游戏应用与我们所需要的API服务关联起来

  • 登录Google Play Console, 链接: https://play.google.com/apps/publish,登录之后点击设置按钮

  • 点击API权限之后,能在右侧发现我们前面创建的test-api这个项目,点击关联,这样我们就可以用test-api中谷歌提供的接口Google Play Android Developer API来查询这个账号下所有应用的订单信息了

4 参数保存

  • 要验证订单我们需要以下参数,这些参数可以保存在后台中
    • clientId: OAuth 客户端 ID
    • clientSecret: OAuth 客户端密钥
    • redirectURI: 自己填写的重定向地址
    • code
    • refreshToken

5 验证

5-1 获取 access_token

  • 通过前面获取的refreshToken来获得access_token

  • 代码中使用POST方式调用https://accounts.google.com/o/oauth2/token

  • 参数:

    • grant_type : refresh_token
    • client_id
    • client_secret
    • refresh_token
  • 返回值:

    {
        "access_token" : "ya29.AHES3ZQ_MbZCwac9TBWIbjW5ixxxxxxxxx2",
        "token_type" : "Bearer",
        "expires_in" : 3600,
    }
    
    

5-2 查询订单信息

  • 使用GET方法调用以下接口: https://www.googleapis.com/androidpublisher/v3/applications/packageName/purchases/products/productId/tokens/token?access_token=access_token

  • packageName: 该应用的包名, 比如com.test.xxx

  • productId: 商品 ID,即内购 ID

  • token: 充值的时候,前端获取的token

  • access_token: 在5-1中获取的

  • 如果订单是有效的,会返回如下内容:

    {
        "kind": "androidpublisher#productPurchase",
        "purchaseTimeMillis": "1539054135375",  // 支付时间, 毫秒
        "purchaseState": 0, // 是否付费: 0 已支付, 1 取消
        "consumptionState": 0, // 是否被消费: 0 未消费, 1 已消费
        "developerPayload": "xxxxx", // 开发者透传参数
        "orderId": "GPA.3337-xxxx-xxxx-xxxx", // 谷歌订单号
        "purchaseType": 0 // 支付类型:  0 测试, 1 真实
    }
    
    
  • 如果订单是无效的,会返回以下内容:

    {
        "error": {
         "errors": [
          {
           "domain": "global",
           "reason": "invalid",
           "message": "Invalid Value"
          }
         ],
         "code": 400,
         "message": "Invalid Value"
        }
    }
    
    

5-3 403 错误

  • 在测试过程中,遇到了403错误,报错如下

    {
        "error": {
            "errors": [{
                "domain": "androidpublisher",
                "reason": "projectNotLinked",
                "message": "The project id used to call the Google Play Developer API has not been linked in the Google Play Developer Console."
            }],
            "code": 403,
            "message": "The project id used to call the Google Play Developer API has not been linked in the Google Play Developer Console."
        }
    }
    
    
  • 产生的原因 1:项目没有关联,或者关联到错误的API项目上了,请看3 项目关联

  • 产生的原因 2:谷歌服务的 BUG,这时候只要在该应用的商店内,随意增加一个内购或者订阅,再看看是不是这个问题就消失了。新增的内购或者订阅可以删除的。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345

推荐阅读更多精彩内容