当前位置: 首页 > 知识库问答 >
问题:

ios - 如何在NestJS中实现iOS应用的订阅功能?

公沈浪
2024-12-23

我使用nestjs开发ios端app的后端.现在有一个订阅功能.
我查到的资料是, 支付前业务服务端需要调苹果的接口, 验证客户端传过来的票据.如果票据验证通过则客户端支付, 并且在数据库添加交易记录.支付后苹果支付中心会调用业务服务端的接口, 在这个接口里, 可以更新交易记录的状态, 并且更新用户的会员权限.

我不确定这个逻辑是否正确.
有没有那个大佬可以详细说说.
我使用了@apple/app-store-server-library这包, 但是这个包似乎只有回调相关的逻辑

共有2个答案

狄富
2024-12-23

安装依赖项 ↓

npm install @nestjs/common @nestjs/core @nestjs/platform-express axios

简单的实现代码(注释为文件名):

// subscription.service.ts
import { Injectable, HttpService } from '@nestjs/common';

@Injectable()
export class SubscriptionService {
    constructor(private readonly httpService: HttpService) {}

    async verifyReceipt(receipt: string): Promise<any> {
        const url = 'https://buy.itunes.apple.com/verifyReceipt';
        const response = await this.httpService.post(url, {
            'receipt-data': receipt,
            'password': 'your_shared_secret'
        }).toPromise();
        return response.data;
    }

    async handleSubscription(data: any) {
    }
}

// subscription.controller.ts
import { Controller, Post, Body } from '@nestjs/common';
import { SubscriptionService } from './subscription.service';

@Controller('subscription')
export class SubscriptionController {
    constructor(private readonly subscriptionService: SubscriptionService) {}

    @Post('verify')
    async verify(@Body() body: { receipt: string }) {
        const verificationResult = await this.subscriptionService.verifyReceipt(body.receipt);
        
        if (verificationResult.status === 0) {
            await this.subscriptionService.handleSubscription(verificationResult);
            return { success: true, message: 'Subscription verified successfully.' };
        } else {
            return { success: false, message: 'Invalid receipt.' };
        }
    }
}

// webhook.controller.ts
import { Controller, Post, Body } from '@nestjs/common';
import { SubscriptionService } from './subscription.service';

@Controller('webhook')
export class WebhookController {
    constructor(private readonly subscriptionService: SubscriptionService) {}

    @Post('apple')
    async handleAppleWebhook(@Body() body: any) {
        const { notificationType, data } = body;

        if (notificationType === 'RENEWAL') {
            await this.subscriptionService.handleSubscription(data);
        }
        
        return { success: true };
    }
}

// app.module.ts
import { Module, HttpModule } from '@nestjs/common';
import { SubscriptionController } from './subscription.controller';
import { SubscriptionService } from './subscription.service';
import { WebhookController } from './webhook.controller';

@Module({
    imports: [HttpModule],
    controllers: [SubscriptionController, WebhookController],
    providers: [SubscriptionService],
})
export class AppModule {}
// main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
    const app = await NestFactory.create(AppModule);
    await app.listen(3000);
}
bootstrap();
程项禹
2024-12-23

回答

你的逻辑基本正确,但让我们详细解释一下如何在NestJS中实现iOS应用的订阅功能,并包括一些关键步骤和注意事项。

步骤概述

  1. 客户端请求订阅

    • iOS应用用户发起订阅请求。
    • iOS应用通过Apple Pay接口完成订阅,并获取到收据(Receipt)。
  2. 验证收据

    • iOS应用将收据发送到你的NestJS后端服务器。
    • 后端服务器使用@apple/app-store-server-library包或其他方式验证收据的有效性。
    • 如果收据验证通过,后端服务器在数据库中记录订阅交易(包括收据信息、用户ID、订阅类型等)。
  3. 处理订阅回调

    • Apple会定期(如订阅状态变化、续订失败等)向你的服务器发送通知(Webhook)。
    • 你的NestJS后端服务器需要设置一个端点来接收这些通知。
    • 使用@apple/app-store-server-library包解析这些通知,并更新数据库中相应的订阅记录和用户权限。

详细实现

  1. 安装@apple/app-store-server-library

    npm install @apple/app-store-server-library
  2. 验证收据的API
    在你的NestJS控制器中创建一个API端点来接收和验证收据。

    import { Controller, Post, Body } from '@nestjs/common';
    import { verifyReceipt } from '@apple/app-store-server-library';
    import * as fs from 'fs';
    import * as path from 'path';
    
    @Controller('subscriptions')
    export class SubscriptionController {
      @Post('verify-receipt')
      async verifyReceipt(@Body() body: { receipt_data: string }) {
        const service = new verifyReceipt.Service({
          url: 'https://buy.itunes.apple.com/verifyReceipt',
          password: 'YOUR_SHARED_SECRET', // 从Apple开发者账户获取
        });
    
        try {
          const receiptData = Buffer.from(body.receipt_data, 'base64');
          const receipt = JSON.parse(receiptData.toString('utf8'));
    
          const result = await service.verify(receipt);
    
          // 在数据库中记录订阅信息
          // ...
    
          return { success: true, result };
        } catch (error) {
          return { success: false, error: error.message };
        }
      }
    }
  3. 处理Apple的Webhook回调
    创建一个API端点来接收Apple的Webhook通知。

    @Post('apple-webhook')
    async handleAppleWebhook(@Body() rawBody: any) {
      try {
        const parsedBody = JSON.parse(rawBody.toString());
    
        // 使用@apple/app-store-server-library解析通知
        const notification = verifyReceipt.Notification.fromRawBody(parsedBody);
    
        // 根据notification的类型(如RENEWAL, CANCEL, INTERRUPTION等)更新数据库中的订阅记录和用户权限
        // ...
    
        return { success: true };
      } catch (error) {
        // 处理错误
        return { success: false, error: error.message };
      }
    }
  4. 配置Webhook URL

    • 登录到你的Apple开发者账户。
    • 在App Store Connect中,为你的应用配置Webhook URL(即你的NestJS服务器接收Apple通知的端点URL)。

注意事项

  • 安全性:确保你的服务器和Apple之间的通信是安全的,使用HTTPS。
  • 错误处理:处理各种可能的错误情况,如网络错误、验证失败等。
  • 日志记录:记录所有与订阅相关的请求和响应,以便进行调试和审计。
  • 测试:在沙盒环境中彻底测试你的订阅流程,确保一切正常工作后再发布到生产环境。

通过上述步骤,你应该能够在NestJS中实现iOS应用的订阅功能。

 类似资料:
  • 问题内容: 我尝试了许多方法来实现这一目标,但失败了。 我必须使用URL在facebook上共享信息,单击URL时,它将重定向到我的应用程序的特定页面。 它正在工作并成功共享该帖子。当我单击链接时,它正在重定向到应用程序,没有太多信息可以重定向到特定的ViewController。 第2步 在这里,我使用Open Graph发布并成功发布了信息。但是,单击链接时不要重定向到我的应用程序。 注意:

  • 如何使用 Graphql SPQR 库实现 GraphQL 的订阅功能?

  • 问题内容: 我是一名iOS开发人员,我尝试构建一个具有自动激活功能的移动应用程序,我发现了不仅仅可以读取短信的方法,而且仅使用私有API会导致Apple拒绝我的应用程序。我有两个问题,不胜感激任何反馈都可以帮助我。 1-有什么方法可以在iOS平台上阅读SMS消息而不会遭到Apple拒绝?2-有人可以向我提供Apple开发人员文档中的相关部分,该部分描述了该部分不允许在iOS平台上读取SMS消息吗?

  • 本文向大家介绍IOS开发实现录音功能,包括了IOS开发实现录音功能的使用技巧和注意事项,需要的朋友参考一下 导入框架: 声明全局变量: 在ViewDidLoad中: 按钮的触发事件 代理方法:

  • 本文向大家介绍iOS实现手势密码功能,包括了iOS实现手势密码功能的使用技巧和注意事项,需要的朋友参考一下 手势密码实现 手势密码 一般常常用于金融项目,做的是安全相关的业务。具体实现如下思路,我把它分为view层和逻辑层。我将数据层合并到view层中了,最好是加上数据层用于处理加密的密码和密码的存储 view层 view层主要处理,包括(九个按钮)touchesBegan,touchesMove

  • 本文向大家介绍vue单应用在ios系统中实现微信分享功能操作,包括了vue单应用在ios系统中实现微信分享功能操作的使用技巧和注意事项,需要的朋友参考一下 表示是第一次使用vue做单应用显目,也是在逐渐的摸索中~更是各种踩坑,各种填坑,打算写博客么?是因为不想写笔记了,嗯嗯 就是这么简单 进入正题。 刚开始做微信分享的这个功能的时候,脑补了官方文档微信JS-SDK说明文档 基础的知识不多说了,反正

  • 本文向大家介绍Paypal实现循环扣款(订阅)功能,包括了Paypal实现循环扣款(订阅)功能的使用技巧和注意事项,需要的朋友参考一下 起因 业务需求要集成Paypal,实现循环扣款功能,然而百度和GOOGLE了一圈,除官网外,没找到相关开发教程,只好在Paypal上看,花了两天后集成成功,这里对如何使用Paypal的支付接口做下总结。 Paypal现在有多套接口: 通过Braintree(后面会

  • 本文向大家介绍iOS实现二维码的扫描功能,包括了iOS实现二维码的扫描功能的使用技巧和注意事项,需要的朋友参考一下 直接上代码,就不多废话了