Android 商品订阅功能-服务端开发笔记

说明下场景: 玩家在游戏内购买一个订阅的商品, 每月定时从google平台扣款并通知到设定URL

大概流程应该是这样: 玩家->游戏前端购买订阅商品->谷歌->通知设定的URL->发货给玩家,后续的每月谷歌会定时通知

我仅负责服务端接收google通知并通知游戏发货, 所以跟google的N多服务要打交道

首先, 这个文档要仔细看

https://developer.android.com/google/play/billing/realtime_developer_notifications

一定要按照上面的步骤来, 如果你用的是子账号, 那么一定会遇到权限的各种问题, 比如要为子账号开通GCP权限

我们使用的谷歌的推送方式 https://cloud.google.com/pubsub/docs/push

意思是我提供接口,让google将信息传给我, 我在去调用google的接口去验证并获取详情

大致步骤如下:

1 选择你的项目

2 在此页面增加你的订阅项目

 

 3 增加服务账号, 大概步骤(这一步本人无法100%确认, 因为我用的子账号, 这一步看不到)

  • 绑定项目(项目不能绑定错,项目不能绑定错,项目不能绑定错)
  • Play Console > 设置 > API 权限 > 检查“关联的项目”是否有开启
  • "APIs & auth" subcategory "Credentials" > service account ID (客户端ID)

设置 server accounts 时 会提示下载 json 或 p12文件,选择json就好
当前JSON文件非常重要,这是免登入直接获得google play授权的凭证
尤于我不是通过OAuth2去验证,是通过的免登录获得授权,所以其他博客要创建的一些东西,我是可以不创建的(当然创建了也没关系)

权限要加好, 否则后面会报403错误


4 增加专题

此处要按照上面发的文档步骤来, 其中在传送类型里选择推送,

然后填入要通知的URL, 如果提示参数错误, 可能又两个原因, 1 是权限, 2是填入的URL没有验证

5 增加API服务

然后创建凭证

建立之后查看其信息

下载json文件, 客户端id, 客户端密匙, 保存好, 程序里要用到

大概步骤如上, 由于我不是管理员账号, 所以怎么关联的那块, 我看不到具体的页面长什么样...

接下来就是服务端接收与验证了

首先要现在google-client sdk

github: https://github.com/googleapis/google-api-php-client

建议使用composer将其下载下来

composer require google/apiclient:"^2.0"

主逻辑大致如下


        $json = file_get_contents('php://input');
        $message = json_decode($json, true);
        $data = json_decode(base64_decode($message['message']['data']), true);
        if (empty($data)) {
            logs("parse message->data error");
            return;
        }
        $purchase_token = $data['subscriptionNotification']['purchaseToken'];
        $product_id = $data['subscriptionNotification']['subscriptionId'];
        $package_name = $data['packageName'];

        require_once APPPATH . 'third_party/google-client/autoload.php';
        try {
            $client = new Google_Client();
            $client->setAuthConfig("json文件");
            $client->setApplicationName($package_name);
            $client->addScope(Google_Service_AndroidPublisher::ANDROIDPUBLISHER);
            $client->setClientId("客户端id");
            $client->setClientSecret("客户端密匙");

            $publisher = new Google_Service_AndroidPublisher($client);
            $subs = $publisher->purchases_subscriptions->get($package_name, $product_id, $purchase_token);
            $subs_array = (array) $subs;
            $this->_logMessage($subs_array);

            //支付状态: 0 付款等待中, 1 已收到付款, 2 免费试用, 3 待延期升级/降级
            $pay_status = $subs_array['paymentState'];
            //取消原因: null 续订中, 0 用户取消了订阅, 1 订阅已被系统取消,例如由于计费问题, 2 订阅已被新订阅所取代, 3 订阅已被开发者取消
            $cancel_reason = $subs_array['cancelReason'];
            //确认状态: 0 还未确认, 1 已确认
            $ack_status = $subs_array['acknowledgementState'];

            if ($cancel_reason !== null) {
                $this->json(Constants::ORDER_SUBSCRIBE_CANCEL, "subscribe cancel, status: {$cancel_reason}");
            }
            if ($pay_status != 1) {
                $this->json(Constants::ORDER_SUBSCRIBE_UNPAID, "subscribe unpaid, status: {$pay_status}");
            }
            if ($ack_status != 1) {
                $this->json(Constants::ORDER_SUBSCRIBE_UNCONFIRMED, "subscribe unconfirmed, status: {$ack_status}");
            }
            //透传字段样例:{"game_id":N, "app_id": N ,"server_id":"1","role_id":"135","uid":"700000000027","goods_id":"test.subs.monthlycard3","order_status":4,"cp_order_id":"测试订单1560942046","server_name":"测试服","src":3}
            $payload = json_decode($subs_array['developerPayload'], true);
            if (empty($payload)) {
                $this->json(Constants::ORDER_SUBSCRIBE_DEVELOPER_PAYLOAD_ERROR, "developerPayload parse fail");
            }
            //验证谷歌的订单号是否存在
            $google_order_id = $subs_array['orderId'];

            //下面就是业务逻辑了


        } catch (Exception $exception) {
            $this->_logMessage("android subscribe exception: " . $exception->getMessage());
            $this->json(Constants::FAILURE);
        }

返回的字段信息说明

https://developers.google.com/android-publisher/api-ref/purchases/subscriptions#resource

 

遇到过这个问题

{ "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." } }

后来通过管理员将创建的服务账号与api正确关联之后就正确了

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值