You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET服务器端App Store内购验证方案咨询(原API已废弃)

.NET环境下App Store内购验证的可行方案

针对.NET服务器无法使用官方App Store Server Library的问题,以下是几种实用的解决方案:

1. 直接调用App Store Server API

官方库本质是对App Store Server REST API的封装,.NET可以自行构造请求完成验证,核心是处理JWT签名授权。

实现步骤:

  • 在App Store Connect生成并下载用于API调用的私钥,记录私钥ID(kid)和团队ID(iss)。
  • 使用System.IdentityModel.Tokens.Jwt NuGet包生成签名JWT,作为请求的Authorization头。
  • 调用App Store Server API的/v2/receipts/verify端点验证收据。

代码示例:

using System.IdentityModel.Tokens.Jwt;
using System.Security.Cryptography;
using System.Text.Json;
using Microsoft.IdentityModel.Tokens;

// 加载苹果私钥
var privateKeyContent = File.ReadAllText("AuthKey_XXXXXXXXXX.p8");
var ecdsa = ECDsa.CreateFromPem(privateKeyContent);
var signingCredentials = new SigningCredentials(
    new ECDsaSecurityKey(ecdsa),
    SecurityAlgorithms.EcdsaSha256
);

// 生成JWT令牌
var tokenHandler = new JwtSecurityTokenHandler();
var jwtToken = tokenHandler.CreateJwtSecurityToken(
    issuer: "你的团队ID", // 如:1234567890
    audience: "appstoreconnect-v1",
    expires: DateTime.UtcNow.AddMinutes(5),
    signingCredentials: signingCredentials,
    claims: new[] { new Claim("kid", "你的私钥ID") } // 如:ABCDE12345
);
var authToken = tokenHandler.WriteToken(jwtToken);

// 构造验证请求
using var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", authToken);

var requestBody = new { receipt_data = "用户提交的Base64格式收据数据" };
var response = await httpClient.PostAsJsonAsync(
    "https://api.storekit.itunes.apple.com/v2/receipts/verify",
    requestBody
);

// 处理响应
if (response.IsSuccessStatusCode)
{
    var responseContent = await response.Content.ReadAsStringAsync();
    var verificationResult = JsonSerializer.Deserialize<dynamic>(responseContent);
    // 根据result中的status、transactionInfo等字段判断验证结果
}
else
{
    var errorContent = await response.Content.ReadAsStringAsync();
    // 处理错误,如无效收据、签名错误等
}

注意事项:

  • 确保私钥文件安全存储,避免硬编码或暴露在版本控制中。
  • 处理API的不同响应状态码,比如401(JWT无效)、404(收据不存在)等。

2. 使用第三方.NET封装库

社区已有成熟的.NET库封装了App Store Server API,无需手动处理JWT和请求构造,节省开发时间。

示例(以AppStoreServerApi NuGet包为例):

  1. 安装NuGet包:Install-Package AppStoreServerApi
  2. 初始化客户端并调用验证接口:
using AppStoreServerApi;
using AppStoreServerApi.Models;

var config = new AppStoreServerApiConfiguration(
    issuerId: "你的团队ID",
    privateKey: File.ReadAllText("AuthKey_XXXXXXXXXX.p8"),
    privateKeyId: "你的私钥ID",
    bundleId: "你的App Bundle ID" // 如:com.yourcompany.yourapp
);

var client = new AppStoreServerApiClient(config);
var verifyRequest = new VerifyReceiptRequest
{
    ReceiptData = "用户提交的Base64收据数据"
};

try
{
    var verifyResponse = await client.VerifyReceiptAsync(verifyRequest);
    if (verifyResponse.Status == 0)
    {
        // 验证成功,处理交易信息
        var transactions = verifyResponse.Receipt?.Transactions;
    }
    else
    {
        // 验证失败,根据status码排查原因
    }
}
catch (ApiException ex)
{
    // 处理API调用异常,如网络错误、权限问题
}

注意事项:

  • 选择维护活跃的库,查看NuGet包的更新记录和GitHub仓库的issues,避免使用已废弃的库。

3. 轻量Node.js中转服务(低成本替代)

如果不想编写.NET底层代码,可以搭建一个极简的Node.js服务,利用官方Node库处理验证,再由.NET服务器调用该服务。这种方案资源占用极低,成本远低于完整微服务。

Node服务示例:

const express = require('express');
const fs = require('fs');
const { AppStoreServerAPIClient } = require('@apple/app-store-server-library');

const app = express();
app.use(express.json());

// 初始化官方客户端
const client = new AppStoreServerAPIClient({
    issuerId: '你的团队ID',
    privateKey: fs.readFileSync('AuthKey_XXXXXXXXXX.p8', 'utf8'),
    privateKeyId: '你的私钥ID',
    bundleId: '你的App Bundle ID'
});

// 暴露验证接口
app.post('/verify-receipt', async (req, res) => {
    try {
        const { receiptData } = req.body;
        const result = await client.verifyReceipt({ receiptData });
        res.json(result);
    } catch (error) {
        res.status(500).json({ error: error.message });
    }
});

// 启动服务
const PORT = 3000;
app.listen(PORT, () => {
    console.log(`App Store验证服务运行在端口 ${PORT}`);
});

.NET调用示例:

using System.Text.Json;

using var httpClient = new HttpClient();
var requestBody = new { receiptData = "用户提交的Base64收据数据" };
var response = await httpClient.PostAsJsonAsync(
    "http://localhost:3000/verify-receipt",
    requestBody
);

if (response.IsSuccessStatusCode)
{
    var result = await response.Content.ReadFromJsonAsync<dynamic>();
    // 处理验证结果
}

注意事项:

  • 可以将Node服务和.NET服务器部署在同一台机器或容器中,减少网络延迟。
  • 给Node服务添加基础的身份验证(如API Key),避免被非法调用。

内容的提问来源于stack exchange,提问作者Duc Thang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 22:33:21