文章

为订阅优惠生成签名

使用你的专用密钥创建用于验证订阅优惠的签名。

概览

在服务器上创建签名之前,你必须在 App Store Connect 中完成一次性设置来生成专用密钥,具体如“设置订阅优惠”中所述。在你的 App 和服务器之间发送包括签名在内的数据时,务必要使用安全连接。有关确保数据安全的更多信息,请参阅“保护不安全的网络连接 (英文)”。

要创建签名,你需要用于标识产品和优惠的参数、由服务器生成的参数,以及你的专用密钥。要生成签名,你需要合并所需的参数,然后对生成的字符串进行签名和编码。

合并参数

在生成签名的第一步中,你需要如下参数,其中大部分也需要为 SKPaymentDiscount(英文) 提供:

appBundleID

App 套装标识符。

keyIdentifier

标识你用于生成签名的专用密钥的字符串。在 App Store Connect “用户和访问”>“密钥”中,你可以在所生成订阅密钥的“密钥 ID”列中找到这个标识符。

productIdentifier

订阅产品标识符 productIdentifier(英文)。App 可以提供这个值。

offerIdentifier

订阅折扣标识符 identifier(英文)。App 可以提供这个值。

applicationUsername

由你定义的可选字符串值;可以是空字符串。App 可以提供这个值,并在 applicationUsername(英文) 中使用。

nonce

由你服务器定义的唯一 UUID 值。这个值会缓存 24 小时。签名中所用 nonce 的字符串表示形式必须用小写字母。

timestamp

服务器以 UNIX 纪元时间格式生成的时间戳,以毫秒为单位;这个时间戳让优惠在 24 小时内保持有效。

按照如下顺序,将这些参数合并为一个 UTF-8 字符串且参数之间使用不可见分隔符 ('\u2063') 隔开:

appBundleId + '\u2063' + keyIdentifier + '\u2063' + productIdentifier + '\u2063' + offerIdentifier + '\u2063' + applicationUsername + '\u2063' + nonce + '\u2063' + timestamp

对合并的字符串进行签名

使用以下密钥和算法对合并的 UTF-8 字符串进行签名:

  • 与 UTF-8 字符串中的 keyIdentifier 对应的 PKCS#8 专用密钥 (从 App Store Connect 下载)。

  • 采用 SHA-256 哈希值的椭圆曲线数字签名算法 (ECDSA)。

得到的结果应该是数字编码规则 (DER) 格式的二进制值,即签名。

本地验证签名并进行编码

应考虑在本地验证签名,确保签名流程按照设计的方式运作。你可以从专用密钥衍生一个公钥来进行测试。生成这个密钥的一种方法是从终端运行以下 OpenSSL 命令:

openssl ec -in {downloaded_private_key} -pubout -out public_key.pem

对你生成的二进制签名进行 Base64 编码,以获取要发送到 App Store 进行验证的最终签名字符串。签名字符串类似如下所示:

MEQCIEQlmZRNfYzKBSE8QnhLTIHZZZWCFgZpRqRxHss65KoFAiAJgJKjdrWdkLUOCCjuEx2RmFS7daRzSVZRVZ8RyMyUXg==

响应请求

通过安全连接提供编码的签名字符串、noncetimestampkeyIdentifier,以响应 App 的签名请求。请注意,每个有效负载、签名和 nonce 仅对一个购买请求有效,即使购买失败也一样。

如需了解 App 的请求及其如何使用签名,请参阅“创建签名”。

另请参阅

提供订阅优惠

设置订阅优惠

App Store Connect 中为自动续期订阅生成密钥和配置优惠。

在 App 中实施订阅优惠

向符合条件的订阅用户提供自动续期订阅产品折扣价。

使用 Node.js 生成订阅优惠签名 (英文)

使用专用密钥和轻量型加密库生成签名。

class SKPaymentDiscount (英文)

应用于付款的签名折扣。