Verifying windows 8 purchases (receipts) using PHP

后端 未结 2 1280
别跟我提以往
别跟我提以往 2021-01-03 04:06

I need to verify in-app purchases made in Windows 8 applications server-side using PHP. MSDN\'s documentation page has an example only in C#. Right now I\'ve spent a whole d

2条回答
  •  谎友^
    谎友^ (楼主)
    2021-01-03 04:52

    I managed to verify WP8 IAP receipt using xmlseclibs library.

    Also, you need php curl enabled.

    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
    }
    

提交回复
热议问题