ios – I am unable to validate the Apple subscription in NestJS

ios – I am unable to validate the Apple subscription in NestJS


I’ve created an endpoint in my app that enables me to ship the person ID and Apple receipt to validate the subscription instantly in my app.

I am utilizing node-apple-receipt-verify
However I am getting the next error:

0|app-backend  | Apple validation response: [
0|app-backend  |   app-backend  
0|app-backend  | ]
0|app-backend  | Invalid receipt obtained: [
0|app-backend  |   app-backend  
0|app-backend  | ]
0|app-backend  | Error throughout Apple receipt verification: Error: Invalid receipt
0|app-backend  |     at SubscriptionService.verifyAppleSubscription (src/subscription/subscription.service.ts:69:15)
0|app-backend  |     at node_modules/@nestjs/core/router/router-execution-context.js:46:28
0|app-backend  |     at node_modules/@nestjs/core/router/router-proxy.js:9:17

Listed here are the completely different codes I exploit:

  @Put up('confirm')
  async verifySubscription(
    @Physique('userId') userId: quantity,
    @Physique('receipt') receipt: string,
    @Physique('platform') platform: string,
  ) {
    if (!userId || !receipt || !platform) {
      throw new BadRequestException('Lacking parameters');
    }

    if (platform !== 'ios') {
      throw new BadRequestException('Solely iOS receipts are supported');
    }

    return this.subscriptionService.verifyAppleSubscription(userId, receipt);
  }


async onModuleInit() {
    if (!course of.env.APPLE_WEBHOOK_SECRET) {
      throw new Error(
        'APPLE_WEBHOOK_SECRET isn't outlined in atmosphere variables',
      );
    }

    verifyAppleReceipt.config({
      secret: course of.env.APPLE_WEBHOOK_SECRET,
      atmosphere: 'manufacturing',
    });

    console.log('Apple receipt verification configured efficiently');
  }

  async verifyAppleSubscription(
    userId: quantity,
    receipt: string,
  ): Promise<{ success: boolean; message: string }> {
    userId = Quantity(userId);

    const person = await this.userService.findOne(userId);

    const userEmail = person.userEmail;
    console.log('[User Email]', userEmail);

    console.log('[START] verifyAppleSubscription known as with:', {
      userId,
      receipt,
    });

    console.log('Kind de userId:', typeof userId, 'Valeur:', userId);
    if (isNaN(userId)) {
      console.log('userId est NaN ! ');
    }

    if (!userId || !receipt) {
      console.log('Lacking parameters:', { userId, receipt });
      throw new BadRequestException('Lacking userId or receipt');
    }

    attempt {
      console.log('Sending receipt for validation...');

      const trimmedReceipt = receipt.trim();
      const validationResponse = await verifyAppleReceipt.validate({
        receipt: trimmedReceipt,
      });

      console.log('Apple validation response:', validationResponse);

      if (!validationResponse || !validationResponse.receipt) {
        console.log('Invalid receipt obtained:', validationResponse);
        throw new Error('Invalid receipt');
      }

      const latestReceiptInfo = validationResponse.latest_receipt_info;
      console.log('Newest receipt information:', latestReceiptInfo);

      const isActive = latestReceiptInfo?.some((sub) => {
        const productId = sub.product_id?.trim();
        console.log('Produit analysé:', productId);

        console.log('Checking subscription expiration:', {
          expires_date_ms: sub.expires_date_ms,
          expires_date: new Date(Quantity(sub.expires_date_ms)),
          now: new Date(),
        });

        return new Date(Quantity(sub.expires_date_ms)) > new Date();
      });

      console.log('Is subscription energetic?', isActive);

      if (isActive) {
        console.log('Subscription is energetic. Updating person in DB...');

        await this.userRepository.replace(userId, { isSubscribed: true });

        console.log('Person subscription up to date efficiently.');
        return { success: true, message: 'Subscription verified and up to date' };
      } else {
        console.log('Subscription is expired or invalid.');
        return { success: false, message: 'Subscription expired or invalid' };
      }
    } catch (error) {
      console.log('Error throughout Apple receipt verification:', error);

      throw new BadRequestException(
        `Apple receipt verification failed: ${error.message}`,
      );
    }
  }
}

Are you aware the best way to repair this downside?
Thanks a lot prematurely.

Leave a Reply

Your email address will not be published. Required fields are marked *