Google API验证非续订/预付费订阅时出现内购错误
Google Play非续订订阅验证失败:调用Purchases.products:get返回404错误(unsupportedDocType)
我在应用中集成了Google Play非续订订阅服务,所有配置已完成,但云函数无法正常验证相关交易。
使用TypeScript/Node.js函数结合googleapis的androidpublisher_v3库,验证非续订订阅时,调用Purchases.products:get接口触发404错误,具体日志如下:
could not verify the purchase because of error GaxiosError: The document type is not supported. at Gaxios._request (/workspace/node_modules/gaxios/build/src/gaxios.js:136:23) at process.processTicksAndRejections (node:internal/process/task_queues:95:5) at async JWT.requestAsync (/workspace/node_modules/google-auth-library/build/src/auth/oauth2client.js:408:18) at async GooglePlayPurchaseHandler.handleNonSubscription (/workspace/lib/google-play.purchase-handler.js:85:30) at async /workspace/node_modules/firebase-functions/lib/common/providers/https.js:458:26 . . . code: 404, errors: [ { message: 'The document type is not supported.', domain: 'androidpublisher', reason: 'unsupportedDocType', location: 'token', locationType: 'parameter' } [Symbol(gaxios-gaxios-error)]: '6.5.0'"
该token是有效的,与Google订单管理系统中已成功扣款的订单所用token完全一致。
若尝试调用Purchases.subscription:get验证非续订订阅,会返回404错误Your request is invalid for this subscription purchase,这符合文档预期(预付费订阅应使用Purchases.products:get接口)。
可续订订阅(用Purchases.subscription:get)和一次性非消耗品(用Purchases.products:get)的验证均能正常工作,仅非续订订阅验证失败,已困扰一周仍未解决。
相关代码如下:
export class GooglePlayPurchaseHandler extends PurchaseHandler { private androidPublisher: AndroidPublisherApi.Androidpublisher; constructor(private dbCalls: dbCalls) { super(); this.androidPublisher = new AndroidPublisherApi.Androidpublisher({ auth: new GoogleAuth({ credentials, scopes: ["https://www.googleapis.com/auth/androidpublisher"], }), }); } async handleSubscription( userId: string, productData: ProductData, token: string, productID: string ) : Promise<boolean> { console.warn( "called Google handleSubscription" ); console.warn( `ANDROID_PACKAGE_ID: ("${ANDROID_PACKAGE_ID}")` ); console.warn( `productID: ("${productID}")` ); console.warn( `token: ("${token}")` ); try { const response = await this.androidPublisher.purchases.subscriptions.get({ packageName: ANDROID_PACKAGE_ID, subscriptionId: productID, token, }); if (!response.data.orderId) { console.error("Could not handle purchase without order id"); return false; } console.log("mapped orderId handleSubscription"); // Update order id if necessary let orderId = response.data.orderId; const orderIdMatch = /^(.+)?[.]{2}[0-9]+$/g.exec(orderId); if (orderIdMatch) { orderId = orderIdMatch[1]; } console.log("called SubscriptionPurchase handleSubscription Google Play"); const purchaseData: SubscriptionPurchase = { iapSource: "google_play", orderId: orderId, productId: productID, userId: userId, purchaseDate: new Date(parseInt(response.data.startTimeMillis ?? "0", 10)), type: "SUBSCRIPTION", expiryDate: new Date(parseInt(response.data.expiryTimeMillis ?? "0", 10)), status: [ "PENDING", "ACTIVE", "ACTIVE", "PENDING", "EXPIRED", ][response.data.paymentState ?? 4] as SubscriptionStatus, }; if (userId) { await this.dbCalls.insertPurchaseInfo( {...purchaseData, userId} as Purchase ); } else { await this.dbCalls.updatePurchaseInfo( purchaseData as Purchase ); } return true; } catch (e) { console.log("could not verify the purchase because of error", e); return false; } } }
依赖配置:
"dependencies": { "firebase-admin": "^12.1.0", "firebase-functions": "^4.9.0", "google-auth-library": "^9.8.0", "googleapis": "^134.0.0", "node-apple-receipt-verify": "^1.13.0" },
内容的提问来源于stack exchange,提问作者mendesbr
相关产品推荐
相关产品推荐

