Verifying windows 8 purchases (receipts) using PHP

后端 未结 2 1255
别跟我提以往
别跟我提以往 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
    }
    
    0 讨论(0)
  • 2021-01-03 04:53

    Speak for yourself. I love phpseclib's "build your own example" approach to documentation.

    That said, I don't think phpseclib can really be used in this case. So you have the SignatureValue tag. What does that signature cover though? With XML Signatures, my understanding is that the signature covers a normalized form of the XML. xmlseclibsnormalizes an XML doc but phpseclib doesn't as it's a crypto lib - not an XML lib.

    0 讨论(0)
提交回复
热议问题