Google play 实时开发者通知——一次性购买

编辑于 2022-07-13 09:02:29 阅读 2662

若使用通知需要先配置,详见:http://www.cuiwei.net/p/1632593347/

实时开发者通知 有三种类型

  • 订阅购买 - SubscriptionNotification
  • 一次性购买 - OneTimeProductNotification
  • play管理中心发出的测试消息 - TestNotification

这篇文章只说 TestNotification和OneTimeProductNotification两种

TestNotification

这个没什么好说的,就是你配置完实时开发者通知,在play管理中心发出的测试通知

WX202207111714332x.png

OneTimeProductNotification

Google play将应用内商品购买称为一次性购买

属性名称 说明
version string 此通知的版本。最初,此值为“1.0”。此版本与其他版本字段不同。
notificationType int 通知的类型。它可以具有以下值:(1) ONE_TIME_PRODUCT_PURCHASED - 用户成功购买了一次性商品。(2) ONE_TIME_PRODUCT_CANCELED - 用户已取消待处理的一次性商品购买交易。
purchaseToken string 购买时向用户设备提供的令牌。
sku string 购买的一次性商品的商品 ID(例如“sword_001”)。

注意:仅针对某些类型的一次性购买发送 OneTimeProductNotification。

如上,官方只是说“仅针对某些类型的一次性购买发送”,很模糊;经过测试,只有“客户没有在规定的时间范围内完成付款”才会发送这种消息。也就是说,正常支付是收不到OneTimeProductNotification消息的1️⃣

服务端需要做什么

解析通知,得到3个参数:packageNameproductIdpurchaseToken,然后请求Google Play Developer API得到购买详情,判断是否购买,是否确认,没有确认就确认,已购买并且已确认就可以认为支付成功

如何配置Google Play Developer API,请参考 使用服务账号请求Google Play Developer API

    /**
     * google play支付异步回调
     * 只有延迟支付才会通知
     */
    public function postPlayback() {
        $json=file_get_contents('php://input');
        $this->log($json);
        $arr= json_decode($json, true);
        $oneTimeProductNotification=base64_decode($arr['message']['data']);
        $arr['message']['data']=$oneTimeProductNotification;
        $this->log($arr);
        $notify=json_decode($oneTimeProductNotification, true);
        if ($notify['oneTimeProductNotification']['notificationType']==1){
            //notificationType: 1.用户成功购买了一次性商品 2.用户已取消待处理的一次性商品购买交易
            var_dump($notify['packageName'], $notify['oneTimeProductNotification']['sku'], $notify['oneTimeProductNotification']['purchaseToken']);
            $configLocation = $this->app->path.'/config/pc-api-***-797-ac21a2656c65.json';
//            echo file_get_contents($configLocation);exit;
            //将 JSON 设置环境变量
            putenv('GOOGLE_APPLICATION_CREDENTIALS='.$configLocation);
            try {
                $google_client = new \Google_Client();
                $google_client->useApplicationDefaultCredentials();
                $google_client->addScope(\Google_Service_AndroidPublisher::ANDROIDPUBLISHER);
                $androidPublishService = new \Google_Service_AndroidPublisher($google_client);
                $result = $androidPublishService->purchases_products->get(
                    $notify['packageName'],
                    $notify['oneTimeProductNotification']['sku'],
                    $notify['oneTimeProductNotification']['purchaseToken']
                );
//                echo json_encode($result, JSON_UNESCAPED_UNICODE);
                //purchaseState: 0.Purchased 1.Canceled 2.Pending
                //acknowledgementState: 0.Yet to be acknowledged 1.Acknowledged已确认
                //consumptionState: 0.Yet to be consumed 1.Consumed已消耗
                //已确认和已消耗的区别:
                //- 没有确认的,超时会自动退款
                //- 消耗,只能app端消耗,服务端操作不了。所以会出现已确认但未消耗的情况
                //- 消耗,会自动确认
                //- 未消耗,app端如果不处理,再次点击该sku会提示"您已经拥有此内容",无法再次购买
                if($result->purchaseState==0){//已支付
                    if ($result->acknowledgementState == 0) {//未确认
                        $androidPublishService->purchases_products->acknowledge(
                            $notify['packageName'],
                            $notify['oneTimeProductNotification']['sku'],
                            $notify['oneTimeProductNotification']['purchaseToken'],
                            new \Google\Service\AndroidPublisher\ProductPurchasesAcknowledgeRequest((array)$result->toSimpleObject())
                        );
                    }
                    //支付成功发货的逻辑,同时标记该订单已经支付完成
                }
            }catch (Exception $exception){
                return show(0, $exception->getMessage());
            }
        }
    }

⚠️注意,这里有个坑,purchaseState的值app端和服务端不一致!!

服务端:purchaseState: 0.Purchased 1.Canceled 2.Pending

详见:https://developers.google.cn/android-publisher/api-ref/rest/v3/purchases.products#ProductPurchase

app端:Purchase.PurchaseState 0.UNSPECIFIED_STATE 1.PURCHASED 2.PENDING

详见:https://developer.android.google.cn/reference/com/android/billingclient/api/Purchase.PurchaseState

参考

官方文档

1️⃣ 关于一次性购买收不到异步通知

网友收到谷歌的回复:

对于一次性购买,今天只为待定交易发送实时开发人员通知。“测试卡,始终批准”不是待定交易,这就是为什么今天没有发送通知。我们将努力在文档中更清楚地说明这一点。

是什么让所有这些实时开发人员通知变得毫无用处,因为您无法有一个地方始终如一地处理所有购买。

https://stackoverflow.com/questions/65029988/android-real-time-developer-notification-for-one-time-purchase-is-half-working

https://stackoverflow.com/questions/71037066/google-play-realtime-developer-notification-for-one-time-products-not-working

广而告之,我的新作品《语音助手》上架Google Play了,欢迎下载体验