Apple In-App Kaufwebhook fehlschlägt mit Status 21002 (ungültige Quittungsdaten)IOS

Programmierung für iOS
Anonymous
 Apple In-App Kaufwebhook fehlschlägt mit Status 21002 (ungültige Quittungsdaten)

Post by Anonymous »

Ich bearbeite iOS In-App-Kauf von Webhooks in meinem Node.js-Backend mit Express. Mein Webhook verarbeitet einmalige Einkäufe und überprüft die Transaktion mit Apple. Ich stoße jedoch auf einen "Status": 21002 Fehler bei der Überprüfung der Quittung. < /P>

Code: Select all

import { Request, Response } from "express";
import { formatJsonRes } from "../utils/helper.ts";
import { IosWebhookService } from "../services/iosWebhook.service.ts";
import { IOS_EVENT_TYPES, IOS_EVENT_SUB_TYPES } from "../utils/constants.ts";

const iosWebhookService = new IosWebhookService();

export const unifiedWebhookHandler = async (
req: Request,
res: Response
): Promise => {
try {
const { signedPayload } = req.body;
console.log("reqBody: ", JSON.stringify(req.body, null, 2));

const event =
await iosWebhookService.processWebhookNotification(signedPayload);
console.log("event: ", JSON.stringify(event, null, 2))

switch (event.notificationType) {
case IOS_EVENT_TYPES.ONE_TIME_CHARGE: {
await iosWebhookService.handleCoinPurchaseEvent(event);
await iosWebhookService.verifyTransactionAndContent(signedPayload);
break;
}
...
}
default:
break;
}
return formatJsonRes(res, 200, {
status: "success",
message: "Webhook processed successfully",
});
} catch (error) {
console.error(error);
return formatJsonRes(res, 200, error);
}
};
VerifyTransactionAndContent :

Code: Select all

async verifyTransactionAndContent(signedPayload: any): Promise {
try {
if (!signedPayload) {
console.error("Missing receipt or transaction information");
return false;
}

const verificationResponse =
await this.verifyReceiptWithApple(signedPayload);
if (!verificationResponse) {
console.error("Receipt verification failed");
return false;
}

return true;
} catch (error) {
console.error("Error verifying transaction:", error);
return false;
}
}
verifyReceiptwithApple :

Code: Select all

private readonly RECEIPT_VERIFICATION = {
PRODUCTION_URL: "https://buy.itunes.apple.com/verifyReceipt",
SANDBOX_URL: "https://sandbox.itunes.apple.com/verifyReceipt",
SHARED_SECRET: "b8...",
STATUS_CODES: {
SUCCESS: 0,
SANDBOX_RECEIPT: 21007,
INVALID_RECEIPT: 21002,
AUTH_ERROR: 21003,
},
} as const;

private async verifyReceiptWithApple(
receipt: string
): Promise  {
const requestBody = {
"receipt-data": receipt,
password: this.RECEIPT_VERIFICATION.SHARED_SECRET,
"exclude-old-transactions": true,
};

try {
let response = await this.makeVerificationRequest(
this.RECEIPT_VERIFICATION.PRODUCTION_URL,
requestBody
);

if (
response.status ===
this.RECEIPT_VERIFICATION.STATUS_CODES.SANDBOX_RECEIPT
) {
console.log(
"Receipt is from sandbox environment, retrying with sandbox URL..."
);
response = await this.makeVerificationRequest(
this.RECEIPT_VERIFICATION.SANDBOX_URL,
requestBody
);
}

return this.handleVerificationResponse(response);
} catch (error) {
console.error("Error verifying receipt:", error);
return null;
}
}
Relevante Protokolle:
reqbody

Code: Select all

reqBody:  {
"signedPayload": "eyJhbGciOiJFUzI1NiIsIng1YyI6WyJNSUlFTURDQ0E3YWdBd0lCQ..."
}
Ereignis :

Code: Select all

event:  {
"notificationType": "ONE_TIME_CHARGE",
"notificationUUID": "a45cab71-85d5-488f-9a5c-f2207d2cde48",
"environment": "Sandbox",
"transactionInfo": {
"transactionId": "2000000889482224",
"originalTransactionId": "2000000889482224",
"bundleId": "com.chatreal.ai",
"productId": "com.chatreal.coins.silver_pack",
"purchaseDate": 1743665721000,
"originalPurchaseDate": 1743665721000,
"quantity": 1,
"type": "Consumable",
"appAccountToken": "e1ed7fb9-3da8-4bb9-ade2-b66043c3ce16",
"inAppOwnershipType": "PURCHASED",
"signedDate": 1743665732143,
"environment": "Sandbox",
"transactionReason": "PURCHASE",
"storefront": "IND",
"storefrontId": "143467",
"price": 999000,
"currency": "INR",
"appTransactionId": "704346128300986174"
}
}
Fehler :

Code: Select all

Event Type: RECEIPT_VERIFICATION_RESPONSE
Timestamp: 2025-04-03T07:35:34.774Z
Data: {
"status": 21002
}
===============================

Invalid receipt data provided
Receipt verification failed
Der Status 21002 -Fehler zeigt ungültige Quittungsdaten an.>

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post