cthulhu/ios-receipt-parser

解析苹果签发的PKCS#7容器中的收据的实用程序

v1.0.0 2020-09-01 19:18 UTC

This package is auto-updated.

Last update: 2024-09-29 05:55:52 UTC


README

此库可以用于解析符合 https://developer.apple.com/library/archive/releasenotes/General/ValidateAppStoreReceipt/Chapters/ValidateLocally.htmlhttps://developer.apple.com/library/archive/releasenotes/General/ValidateAppStoreReceipt/Chapters/ReceiptFields.html 的Apple计费收据,而不调用Apple服务器。

这特别适用于您使用最新的XCode功能来测试您的计费流程时: https://developer.apple.com/documentation/xcode/setting_up_storekit_testing_in_xcode,因为这样生成的收据是由您的本地专用证书签发的,无法通过Apple自己的服务器进行验证。

在其他所有情况下,您应强烈建议对所有收据进行Apple服务器验证。

安装

composer install cthulhu/ios-receipt-parser

用法

主要用例是解析您本地由StoreKit生成的收据,因此您无需验证签名

<?php

use Cthulhu\IosReceiptParser\InApp;
use Cthulhu\IosReceiptParser\Parser;
use Cthulhu\IosReceiptParser\Receipt;

include __DIR__ . '/vendor/autoload.php';

const RECEIPT = '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';

$receipt = (new Parser())->parseUnverified(RECEIPT);

// Just for documentation purpose
assert($receipt instanceof Receipt);

var_dump($receipt->getBundleId());

foreach ($receipt->getInApp() as $inApp) {
    // Just for documentation purpose
    assert($inApp instanceof InApp);

    var_dump("{$inApp->getQuantity()} x {$inApp->getProductIdentifier()}");
}

验证签名

您可以将另一个PKCS#7读取器的实例传递给Parser,该实例将实际验证签名。目前,仅实现了这样的一个读取器,这要求您也安装symfony/process,在您的系统中安装openssl,并且您必须配置php以允许执行shell脚本。

<?php

use Cthulhu\IosReceiptParser\ASN1\OpenSslProcessPkcs7Reader;
use Cthulhu\IosReceiptParser\Parser;

include __DIR__ . '/vendor/autoload.php';

$parser = new Parser(new OpenSslProcessPkcs7Reader());

// certificates must be PEM-encoded x.509 certificates
$receipt = $parser->parseUsingOnlyTrustedCerts(RECEIPT, CERT_OR_PATH_TO_CERT, OTHER_CERT);

var_dump($receipt->getBundleId());

使用parseUsingOnlyTrustedCerts确保PKCS#7中的签名已经通过您提供的证书之一进行了验证。证书被认为是可信的(它们的签名没有进行验证),因此请务必仅传递已知有效的证书给此函数。