php - 使用 PHP 验证 Windows 8 购买(收据)

标签 php windows-8 in-app-purchase signedxml xmlseclibs

我需要使用 PHP 验证在 Windows 8 应用服务器端进行的应用内购买。 MSDN 的 documentation page仅在 C# 中有示例。现在我已经花了一整天的时间来寻找一种用 PHP 来完成它的方法。没有成功。在整个 Internet 上,只有关于此主题的 .NET 示例。

我发现了一些关于签名 XML 和 x509 的部分信息,一些库(xmlseclibs - 无用,使用不支持 sha256 的 openssl_* 函数;phpseclib - 看起来很有前途,但他们的文档和示例很差,没有帮助)。

是否可以在不学习有关签名 XML、RSA 和 x509 的所有知识的情况下以某种方式做到这一点?现在我已经阅读了几乎所有内容,但到处都是关于编码的信息。与验证无关。

最佳答案

我设法使用 xmlseclibs 验证了 WP8 IAP 收据图书馆。

此外,您需要启用 php curl。

do {
    $doc = new DOMDocument();

    $xml = $_POST['receipt_data']; // your receipt xml here!

    // strip unwanted chars - IMPORTANT!!!
    $xml = str_replace(array("\n","\t", "\r"), "", $xml);
    //some (probably mostly WP8) receipts have unnecessary spaces instead of tabs
    $xml = preg_replace('/\s+/', " ", $xml);
    $xml = str_replace("> <", "><", $xml);

    $doc->loadXML($xml);
    $receipt = $doc->getElementsByTagName('Receipt')->item(0);
    $certificateId = $receipt->getAttribute('CertificateId');

    $ch = curl_init("https://lic.apps.microsoft.com/licensing/certificateserver/?cid=$certificateId");
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);

    $publicKey = curl_exec($ch);
    $errno = curl_errno($ch);
    $errmsg = curl_error($ch);
    curl_close($ch);

    if ($errno != 0) {
        $verifyFailed = true;
        break;
    }

    // Verify xml signature
    require('./xmlseclibs.php');
    $objXMLSecDSig = new XMLSecurityDSig();
    $objDSig = $objXMLSecDSig->locateSignature($doc);
    if (!$objDSig) {
        $verifyFailed = true;
        break;
    }
    try {
        $objXMLSecDSig->canonicalizeSignedInfo();
        $retVal = $objXMLSecDSig->validateReference();
        if (!$retVal) {
            throw new Exception("Error Processing Request", 1);
        }
        $objKey = $objXMLSecDSig->locateKey();
        if (!$objKey) {
            throw new Exception("Error Processing Request", 1);
        }
        $key = NULL;
        $objKeyInfo = XMLSecEnc::staticLocateKeyInfo($objKey, $objDSig);
        if (! $objKeyInfo->key && empty($key)) {
            $objKey->loadKey($publicKey);
        }
        if (!$objXMLSecDSig->verify($objKey)) {
            throw new Exception("Error Processing Request", 1);
        }
    } catch (Exception $e) {
        $verifyFailed = true;
        break;
    }

    $productReceipt = $doc->getElementsByTagName('ProductReceipt')->item(0);
    $prodictId = $productReceipt->getAttribute('ProductId');
    $purchaseDate = $productReceipt->getAttribute('PurchaseDate');
} while(0);

if ($verifyFailed) {
    // invalid receipt
} else {
    // valid receipt
}

关于php - 使用 PHP 验证 Windows 8 购买(收据),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14649396/

相关文章:

.net - MediaCapture Windows 8 桌面 - 照片较暗

windows-8 - 发现app已经更新了

android - In App Billing getPrice() Android

php - Magento::类别和子类别

php - 如何使 DIV 部分可点击?

javascript - 滑出网站的着陆页

Android 应用内购买同一类型产品的多种类型订阅

iOS 应用内购买 : request latest cancellation date and number of cancellations

php - 如何将 mysql 查询转换为 laravel?

php - 通过用户定义的权重选择随机元素