Google Billing API:订阅购买后不久,触发订阅过期,紧接着订阅续订 [英] Google Billing API: Shortly after subscription purchase, subscription expired is triggered, directly followed by subscription renewed
问题描述
我正在使用 Firebase Cloud Functions 来处理应用内购买的后端流程.如果我购买订阅(在 Flutter/Android 客户端上),购买流程没有问题.但是,当第一次续订发生时,我首先收到订阅已过期的实时开发人员通知,大约 50 秒后,我收到订阅已续订的新通知.
I am using Firebase Cloud Functions to handle the back-end process for In-App-Purchases. If I purchase a subscription (on Flutter/Android client), the purchase flow works without problems. However, when the first Renewal happens, I get first a Real Time Developer Notification that the Subscription has Expired, and around 50 Seconds later I get a new notification that the subscription got renewed.
详细流程如下:
1.在客户端购买订阅(目前处于内部测试模式)
1. Purchase subscription on Client (at the moment in internal testing Mode)
--- Google Cloud Logging 事件开始 (hh:mm:ss):
--- Start of Google Cloud Logging Events (hh:mm:ss):
<强>2.00:00:00 - 通知订阅已触发(空函数,只打印到控制台)
2. 00:00:00 - Notification Subscription Purchased Triggered (empty function, only prints to console)
3.在Client,触发InAppPurchaseConnection purchaseUpdatedStream(Flutter),Client向后端发送数据,触发Cloud Function verifyPurchase.
3. On Client, InAppPurchaseConnection purchaseUpdatedStream (Flutter) is triggered, Client sends data to back-end and Cloud Function verifyPurchase is triggered.
4.00:00:03 - verifyPurchase 函数执行开始
4. 00:00:03 - verifyPurchase function execution started
5.00:00:05 - 收到状态 200 响应
5. 00:00:05 - Status 200 response received
6.00:00:06 - 收到确认响应(状态 204)
6. 00:00:06 - Acknowledge Response received (Status 204)
7. 直到这里一切正常,我可以在 Firestore DB 中看到正确的数据
8.00:04:08 - 通知订阅过期触发(后端撤销订阅,用户没有购买任何附加服务)
订阅状态响应:
8. 00:04:08 - Notification Subscription Expired Triggered
(back-end revokes subscription, leaving the user without any additional services she/he purchased)
Subscription Status response:
{"startTimeMillis":"1616129098091",
"expiryTimeMillis":"1616130591517",
自动更新":假,
"priceCurrencyCode":"KRW",
priceAmountMicros":2900000000",
"countryCode":"KR",
开发者有效负载":",
"取消原因":0,
"userCancellationTimeMillis":"1616130398607",
orderId":GPA.3391-[...].3",
"purchaseType":0,
确认状态":1,
种类":androidpublisher#subscriptionPurchase",
obfuscatedExternalAccountId":q[..]3"
}
{ "startTimeMillis":"1616129098091",
"expiryTimeMillis":"1616130591517",
"autoRenewing":false,
"priceCurrencyCode":"KRW",
"priceAmountMicros":"2900000000",
"countryCode":"KR",
"developerPayload":"",
"cancelReason":0,
"userCancellationTimeMillis":"1616130398607",
"orderId":"GPA.3391-[...].3",
"purchaseType":0,
"acknowledgementState":1,
"kind":"androidpublisher#subscriptionPurchase",
"obfuscatedExternalAccountId":"q[..]3"
}
->此处的取消原因指出:0. 用户取消了订阅(事实并非如此)
->AcknowledgementState 为 1:已确认
请参阅:REST API REF 资源:SubscriptionPurchase
9.00:05:01 - 通知订阅更新触发从这里开始,一切都按预期工作,用户收到了她/他支付的服务.
9. 00:05:01 - Notification Subscription Renewed Triggered From here on everything works as expected and the user receives the services she/he paid for.
10.~ 16. 00:10:01 ~ 00:35:20 - Notification Subscription Renewed 触发 4 次,然后取消并过期(预期行为)
10. ~ 16. 00:10:01 ~ 00:35:20 - Notification Subscription Renewed Triggered 4x times, then cancelled and expired (expected behaviour)
--- Google Cloud Logging 事件结束.
--- End of Google Cloud Logging Events.
export const verifyPurchase = functions.region("asia-northeast3").https.onCall(async (data, context) => {
const {sku, purchaseToken, packageName, purchaseType} = data;
const userId: string = context.auth?.uid ?? "";
functions.logger.log(`USER ID: ${userId}`);
let result = 0;
try {
await authClient.authorize();
functions.logger.log("START TO CHECK SUBSCRIPTION OR ONE TIME PURCHASE");
if (purchaseType === PurchaseType.subscription) {
const subscription = await playDeveloperApiClient.purchases.subscriptions.get({
packageName: packageName,
subscriptionId: sku,
token: purchaseToken,
});
functions.logger.log("SUBSCRIPTION BEING PROCESSED");
if (subscription.status === 200 && subscription?.data?.paymentState === 1 || subscription?.data?.paymentState === 2) {
functions.logger.log(`SUBSCRIPTION STATUS: ${subscription.status}`);
if (!subscription.data.linkedPurchaseToken) {
const subscriptionData: any = {
"transactionId": purchaseToken,
"userId": userId,
"expirationDateMs": subscription.data.expiryTimeMillis,
"disabled": false,
"platform": "android",
"receipt": data,
"rawData": subscription.data,
};
await admin.firestore().collection("subscriptions").add(subscriptionData).then(
async (value) => {
[...user Data being updated on DB...]
);
const acknowdlegeResponse = await playDeveloperApiClient.purchases.subscriptions.acknowledge({
packageName: packageName,
subscriptionId: sku,
token: purchaseToken,
requestBody: {
},
});
functions.logger.info(`ACKNOWLEDGE RESPONSE SUBSCRIPTION: ${JSON.stringify(acknowdlegeResponse)}`);**
} else {
await subscriptionChange(purchaseToken, userId, data, subscription);
}
result = subscription.status;
}
} else {
const oneTimePurchase = await playDeveloperApiClient.purchases.products.get({
[...part for one time purchases...]
} catch (e) {
// handle error
functions.logger.error("verifyPurchase ERROR");
functions.logger.error(e);
}
functions.logger.log(`RETURN RESULT: ${result}`);
return result;
});
所以我不完全明白为什么第 8 步(已过期)会发生.我将不胜感激.
So I don't exactly understand why step 8 (expired) happens. I would appreciate any help.
推荐答案
我认为您的问题是您在确认购买之前调用了 subscriptionPurchase API,如 此评论.
I believe your issue is that you are calling the subscriptionPurchase API before acknowledging the purchase, as stated in this comment.
尝试相应地更改您的代码.
Try changing your code accordingly.
这篇关于Google Billing API:订阅购买后不久,触发订阅过期,紧接着订阅续订的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!