使用PHP加密动态“添加到购物车”PayPal按钮时出现问题

3
我使用PHP在WordPress中集成了简单的PayPal支付系统。我基本上建立了一个列表,每个列表项从WordPress中的特定页面检索元数据(每个产品对应一个页面),并使用这些数据动态构建了一个“添加到购物车”PayPal按钮。这很好用!但是......

然后,出于显而易见的原因,我尝试加密“添加到购物车”按钮。我找到了一个PHP程序来做到这一点(根据我在不同互联网论坛上看到的大多数情况下都可以实现),并且我认为我按照PayPal的所有说明进行了操作(私有、公共、PayPal等证书)。

虽然我的html页面没有出现任何错误,但当我点击“添加到购物车”按钮时,我收到了PayPal错误:“我们检测到这个购物车存在问题。如果问题仍然存在,请联系商家。” 但我不知道具体是哪里出了问题和我做错了什么……

我已经拥有了一个PayPal商家账户。

为了消除不必要的杂乱和噪音,我创建了一个带有静态数据的测试页面来检查按钮是否正常工作,在此提供给需要帮助的人。

基本测试页面:

<?php
include_once "testfunctions.php";
//inserting some test data
$themetacost='100';
$themetaname="testbook";
$themetashipping='20';
//building the paypal button
$line='';
$line.='<form target="paypal" action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_blank" id="payform" >
            <input type="hidden" name="cmd" value="_cart">
                        <input type="hidden" name="encrypted" value="';
$line.= buildbutton($themetacost,$themetaname,$themetashipping);
$line.='">';
$line.='<input type="image" src="https://www.paypalobjects.com/WEBSCR-640-20110429-1/he_IL/i/btn/btn_cart_SM.gif" border="0" name="submit" alt="PayPal - הדרך הקלה והבטוחה לשלם באופן מקוון!">
                <img alt="" border="0" src="https://www.paypalobjects.com/WEBSCR-640-20110429-1/he_IL/i/scr/pixel.gif" width="1" height="1">
                </form><br/>';
echo $line;

?>

PHP构建按钮和加密函数:

<?php
function buildbutton($amount,$bname,$shipping) {
//Sample PayPal Button Encryption: Copyright 2006-2010 StellarWebSolutions.com
//Not for resale  - license agreement at
//http://www.stellarwebsolutions.com/en/eula.php
//Updated: 2010 02 01



$form = array('cmd' => '_cart',
        'business' => 'X@XXX.CO.il', // changed from the original
        'cert_id' => 'XXXXXXXXXXX',// changed from the original
    'shipping' => $shipping,
        //'invoice' => '', //check what this is
        'currency_code' => 'ILS',
        //'no_shipping' => '0', //refers to shipping address
        'add'=>'1',
    'item_name' => $bname,
    'amount' => $amount
    );


    $encrypted = paypal_encrypt($form); 

return $encrypted;
}
function paypal_encrypt($hash)
{
    //Sample PayPal Button Encryption: Copyright 2006-2010 StellarWebSolutions.com
    //Not for resale - license agreement at
    //http://www.stellarwebsolutions.com/en/eula.php
    # private key file to use //

$MY_KEY_FILE = "/home/paypal/my-prvkey.pem";
# public certificate file to use
$MY_CERT_FILE = "/home/paypal/my-prvkey.pem";// 

# Paypal's public certificate
$PAYPAL_CERT_FILE = "/home/paypal/paypal_cert.pem";

# path to the openssl binary
$OPENSSL = "/usr/bin/openssl";

    if (!file_exists($MY_KEY_FILE)) {
        echo "ERROR: MY_KEY_FILE $MY_KEY_FILE not found\n";
    }
    if (!file_exists($MY_CERT_FILE)) {
        echo "ERROR: MY_CERT_FILE $MY_CERT_FILE not found\n";
    }
    if (!file_exists($PAYPAL_CERT_FILE)) {
        echo "ERROR: PAYPAL_CERT_FILE $PAYPAL_CERT_FILE not found\n";
    }
        if (!file_exists($OPENSSL)){
                echo "error with openssl $OPENSSL not found \n";
        }


    //Assign Build Notation for PayPal Support
    //$hash['bn']= 'StellarWebSolutions.PHP_EWP2'; //this is not needed cause i dont have a ewp

    $data = "";
    foreach ($hash as $key => $value) {
        if ($value != "") {
            //echo "Adding to blob: $key=$value\n";
            $data .= "$key=$value\n";
        }
    }

    $openssl_cmd = "($OPENSSL smime -sign -signer $MY_CERT_FILE -inkey $MY_KEY_FILE " .
                        "-outform der -nodetach -binary <<_EOF_\n$data\n_EOF_\n) | " .
                        "$OPENSSL smime -encrypt -des3 -binary -outform pem $PAYPAL_CERT_FILE";

    exec($openssl_cmd, $output, $error);

    if (!$error) {
        return implode("\n",$output);
    } else {
        return "ERROR: encryption failed";
    }
}

?>

我尝试将变量更改为数字以检查问题是否存在,但没有帮助。

这是加密测试页面源代码的样子:

action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_blank" id="payform" >

            <input type="hidden" name="cmd" value="_cart">

                        <input type="hidden" name="encrypted" value="-----BEGIN PKCS7-----
MIIBdwYJKoZIhvcNAQcDoIIBaDCCAWQCAQAxggEwMIIBLAIBADCBlDCBjjELMAkG
A1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQw
EgYDVQQKEwtQYXlQYWwgSW5jLjETMBEGA1UECxQKbGl2ZV9jZXJ0czERMA8GA1UE
AxQIbGl2ZV9hcGkxHDAaBgkqhkiG9w0BCQEWDXJlQHBheXBhbC5jb20CAQAwDQYJ
KoZIhvcNAQEBBQAEgYAiFKR0WuQJcr6cQZvDCptQeDNyfipH9pDy1Q58C+ITCZWY
XRkkUOvvL3jniO1GUxsY2JleGAdZWSV1qgnO3uNjj0V3Z0AxbrAiuA0lLd8pscBT
MM+9+1RwjTOUVtOi3PASy1TC4hk6Wq01KUk1DCpbqMtqBZ6sWb5jHRxWqbL08zAr
BgkqhkiG9w0BBwEwFAYIKoZIhvcNAwcECClgCVLJPeXAgAgr8wXDhqI+og==
-----END PKCS7-----"><input type="image" src="https://www.paypalobjects.com/WEBSCR-640-20110429-1/he_IL/i/btn/btn_cart_SM.gif" border="0" name="submit" alt="PayPal - äãøê ä÷ìä åäáèåçä ìùìí áàåôï î÷ååï!">

                <img alt="" border="0" src="https://www.paypalobjects.com/WEBSCR-640-20110429-1/he_IL/i/scr/pixel.gif" width="1" height="1">

                </form><br/>

编辑:在HTML表单中更改(不是!PHP加密函数)从“_cart”到“_s-xclick”后,我得到了不同的错误:

商家的电子邮件地址未出现在加密的 blob 中。请联系您的商家。

根据PayPal论坛上的更多建议,我还尝试更新证书和密钥(所有三个..),但没有任何帮助!


为什么不仅检测篡改,而不是将其保留未加密?此外,该代码将适用于更多无法安装所有OpenSSL内容的托管计划。请查看以下答案:http://stackoverflow.com/q/14489512/105539 - Volomike
这是一个老问题,现在已经不再相关(很久以前问过了),但是:我认为“稍后验证”的方式不是一个好的策略。在特定的用例中,它会使代码变得复杂。而且我没有看到很多涉及资金转移的代码可以很好地使用“稍后验证”。 - alonisser
1
这是一个有点老的问题,但我认为这个信息对于任何来到这里的人都是相关的:https://dev59.com/_2855IYBdhLWcg3w3IRh#6886989 - Rafael
2个回答

1

我会将 cmd 更改为 _s-xclick。所有 PayPal 加密支付都使用此命令。

当我尝试时,我收到了“商家的电子邮件地址不存在于加密块中。请联系您的商家。”错误消息。您尝试过使用“安全商家 ID”而不是电子邮件吗?它在账户配置文件中。

个人建议使用按钮管理器 API 而不是加密按钮。 https://merchant.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_api_ButtonMgrAPIIntro 它的主要优点是可以调用 API 检索按钮内容。无法解密加密块以查看电子邮件是否实际存在。

希望这有所帮助。 Lorefold


1
谢谢Lorefold,我今天也弄清楚了_s-xlick的问题,现在我收到了电子邮件地址问题的消息。实际上,我确实使用了安全商户ID而不是电子邮件,反之亦然。没有帮助。我想不出来 - 我会研究一下这个按钮API并回来。 - alonisser
好的,我尝试了PayPal NVP API按钮API,它对我有效,所以我会继续这个开发路径。仍然无法弄清楚应用程序出了什么问题... - alonisser

0

检查 OpenSSL 版本是否更改或证书是否存在问题。

您可以参考Paypal重新生成证书并将其上传到 Paypal。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接