如何整合PayPal快速结账?

时间:2015-10-30 08:08:12

标签: php wordpress paypal wordpress-plugin paypal-sandbox

我正在开发一个需要PayPal Express结帐功能的wordpress插件。

我在paypal网站上关注如何整合上下文结账功能(https://developer.paypal.com/webapps/developer/docs/classic/express-checkout/integration-guide/ECGettingStarted/#id53620a28-e357-4744-9979-66ed5c592183)的这篇文章,它在一步中给了我以下表格。

<form method=post action=https://api-3t.sandbox.paypal.com/nvp>
    <input type=hidden name=USER value=API_username>
    <input type=hidden name=PWD value=API_password>
    <input type=hidden name=SIGNATURE value=API_signature>
    <input type=hidden name=VERSION value=XX.0>
    <input type=hidden name=PAYMENTREQUEST_0_PAYMENTACTION value=Sale>
    <input name=PAYMENTREQUEST_0_AMT value=19.95>
    <input type=hidden name=RETURNURL value=https://www.YourReturnURL.com>
    <input type=hidden name=CANCELURL value=https://www.YourCancelURL.com>
    <input type=submit name=METHOD value=SetExpressCheckout>
</form>

我添加了自己的API_username,API_password&amp;来自PayPal的API_Signature,但在提交时会显示ACK=Failure

以下是来自Paypal的消息:我正在寻找:

TIMESTAMP=2015%2d10%2d30T05%3a27%3a09Z&CORRELATIONID=24cb45b8dd36b&ACK=Failure&VERSION=0%2e000000&BUILD=18308778&L_ERRORCODE0=10002&L_SHORTMESSAGE0=Security%20error&L_LONGMESSAGE0=Security%20header%20is%20not%20valid&L_SEVERITYCODE0=Error

因此我无法转到PayPal文档的第2步,所以需要帮助。我做错了什么?

3 个答案:

答案 0 :(得分:8)

尝试使用我在项目中使用的代码并运行。

PHP:

$paypal_url='https://www.paypal.com/cgi-bin/webscr'; 
$paypal_id='example@example.com';

HTML:

<form action='<?php echo $paypal_url; ?>' method='post' name='frmPayPal1'>
    <input type='hidden' name='business' value='<?php echo $paypal_id;?>'>
    <input type='hidden' name='cmd' value='_xclick'>
    <input type='hidden' name='item_name' value='Products Total'>
    <input type='hidden' name='amount' value='<?php echo $tot;?>'>
    <input type='hidden' name='no_shipping' value='1'>
    <input type='hidden' name='currency_code' value='USD'>
    <input type='hidden' name='handling' value='0'>
    <input type='hidden' name='cancel_return' value='http://localhost/paypal/cancel.php'>
    <input type='hidden' name='return' value='http://localhost/paypal/success.php'>
    <input type="image" src="https://www.sandbox.paypal.com/en_US/i/btn/btn_buynowCC_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!">
    <img alt="" border="0" src="https://www.sandbox.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1">
</form>

答案 1 :(得分:3)

要实现PayPal Express Checkout,您需要执行一些服务器端代码(PHP,ASP.Net,...)。你要做的是一个不会起作用的HTML表单。 您必须执行3次API调用才能验证完整付款。

在每次通话中,您都将使用您的API凭据。

答案 2 :(得分:3)

我建议实施PayPal Express Checkout API。

使用此方法代替您用于创建wordpress插件的好处。主要原因是响应将立即传递,您不会使用IPN方法来检查事务是否成功。您还可以在一个会话中添加多个定期付款和一次性付款,包括税收和福利。你可以自由地添加所有这些东西,几乎所有东西 - 你的wordpress插件需要很酷!

这就像推荐一样。这里有一个简单的(PHP)示例,如何使用多个产品设置事务(也是定期付款):

// Parameters for SetExpressCheckout, which will be sent to PayPal
$padata['L_BILLINGAGREEMENTDESCRIPTION0'] = 'Product description'; $padata['L_BILLINGAGREEMENTDESCRIPTION0'] = $padata['L_BILLINGAGREEMENTDESCRIPTION0'] . ' $'.$product->price.'/month'; $padata['L_PAYMENTREQUEST_0_DESC0'] = $padata['L_BILLINGAGREEMENTDESCRIPTION0'] . ' $'.$product->price.'/month';
$padata['PAYMENTREQUEST_0_NOTIFYURL'] = 'http://site_url/paypal/ipn'; $padata['PAYMENTREQUEST_0_DESC'] = $product->name; $padata['RETURNURL'] = 'http://site_url/paypal/returnurl'; $padata['CANCELURL'] = 'http://site_url/paypal/cancelurl';
$padata['PAYMENTREQUEST_0_CURRENCYCODE'] = 'USD'; $padata['PAYMENTREQUEST_0_PAYMENTACTION'] = 'SALE'; $padata['PAYMENTREQUEST_0_ITEMAMT'] = $product->price;
$padata['PAYMENTREQUEST_0_AMT'] = $product->price;
$padata['L_BILLINGTYPE0'] = 'RecurringPayments';
$padata['L_PAYMENTREQUEST_0_NAME0'] = $product->name;
$padata['L_PAYMENTREQUEST_0_NUMBER0'] = '322';
$padata['L_PAYMENTREQUEST_0_QTY0'] = '1';
$padata['L_PAYMENTREQUEST_0_AMT0'] = $product->price; $padata['L_PAYMENTREQUEST_0_NAME1'] = 'Second Product name';
$hosteddata['L_PAYMENTREQUEST_0_DESC1'] = 'second product description';
$hosteddata['L_PAYMENTREQUEST_0_NUMBER1'] = $secondproduct->id;
$hosteddata['L_PAYMENTREQUEST_0_QTY1'] = '1';
$hosteddata['L_PAYMENTREQUEST_0_AMT1'] = $secondproduct->price; $paypal_data = http_build_query($padata); $httpParsedResponseAr = $this->PPHttpPost('SetExpressCheckout', $paypal_data); //Respond according to message we receive from Paypal if("SUCCESS" == strtoupper($httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($httpParsedResponseAr["ACK"])){ //Redirect user to PayPal store with Token received. $paypalurl ='https://www.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token='.$httpParsedResponseAr["TOKEN"].''; header('Location: '.$paypalurl); }else{ echo 'Error : '.urldecode($httpParsedResponseAr["L_LONGMESSAGE0"]).'';
}

Page returnurl:

$hosteddata['L_BILLINGAGREEMENTDESCRIPTION0']   = 'Recurring Description';
$hosteddata['L_BILLINGAGREEMENTDESCRIPTION0'] = $hosteddata['L_BILLINGAGREEMENTDESCRIPTION0'] . ' $'.$pr->price.'/month';
$hosteddata['L_PAYMENTREQUEST_0_NAME0'] = $pr->name;
$hosteddata['PROFILEREFERENCE'] = $GetExpressCheckoutDetails['L_PAYMENTREQUEST_0_NUMBER0'];
$hosteddata['PROFILESTARTDATE'] = date('Y-m-d') . 'T' . date('H:i:s').'Z';
$hosteddata['SUBSCRIBERNAME'] = $GetExpressCheckoutDetails['FIRSTNAME'] . ' ' . $GetExpressCheckoutDetails['LASTNAME'];
$hosteddata['TOKEN'] = urlencode($_POST['token']);
$hosteddata['DESC'] = $hosteddata['L_BILLINGAGREEMENTDESCRIPTION0'];
$hosteddata['AMT'] = $pr->price;
$hosteddata['BILLINGPERIOD'] = 'Month';
$hosteddata['BILLINGFREQUENCY'] = '1';
$hosteddata['TOTALBILLINGCYCLES'] = '12';
$hosteddata['REGULARTOTALBILLINGCYCLES'] = '1';
$hosteddata['VERSION'] = '74.0';
$hosteddata['MAXFAILEDPAYMENTS'] = '1';
$hosteddata['L_PAYMENTREQUEST_0_QTY0'] = '1';
$hosteddata['L_BILLINGTYPE0'] = 'RecurringPayments';
$hosteddata['L_PAYMENTREQUEST_0_ITEMCATEGORY0'] = 'Digital';
$hosteddata['L_PAYMENTREQUEST_0_AMT0'] = $pr->price;
$hosteddata['INITAMT'] = $pr->price;
$hosteddata['L_PAYMENTREQUEST_0_NUMBER0'] = $pr->id;
$hosteddata['PAYMENTREQUEST_0_NOTIFYURL'] = 'http://site_url/paypal/ipn';
$padata['L_PAYMENTREQUEST_0_NAME1'] = 'Second Product name'; $hosteddata['L_PAYMENTREQUEST_0_DESC1'] = 'second product description';
$hosteddata['L_PAYMENTREQUEST_0_NUMBER1'] = $secondproduct->id;
$hosteddata['L_PAYMENTREQUEST_0_QTY1'] = '1';
$hosteddata['L_PAYMENTREQUEST_0_AMT1'] = $secondproduct->price; $paypal_data = http_build_query($hosteddata); $hosted_saas_response = $this->PPHttpPost('CreateRecurringPaymentsProfile', $paypal_data);

我使用了一个单独的方法将参数发布到paypal

private function PPHttpPost( $methodName_, $nvpStr_ ) {
$api_username = 'yourpaypal@email.com'; $api_password = 'QWEQWEWQEQWEQEQWE';
$api_signature = 'WQEQWEQWEQWEWQEQWEQWEQWEQWEQWE.cT';
$api_endpoint = "https://api-3t.paypal.com/nvp";
$version = '124.0'; $ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $api_endpoint);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
$nvpreq = "METHOD=$methodName_&VERSION=$version&PWD=$api_password&USER=$api_username&SIGNATURE=$api_signature&$nvpStr_";
curl_setopt($ch, CURLOPT_POSTFIELDS, $nvpreq);
$httpResponse = curl_exec($ch);

if(!$httpResponse) { exit("$methodName_ failed: ".curl_error($ch).'('.curl_errno($ch).')');
}

// Extract the response details.
$httpResponseAr = explode("&", $httpResponse);
$httpParsedResponseAr = array();

foreach ($httpResponseAr as $i => $value) {
$tmpAr = explode("=", $value);
if(sizeof($tmpAr) > 1) {
$httpParsedResponseAr[$tmpAr[0]] = $tmpAr[1];
}

} if((0 == sizeof($httpParsedResponseAr)) || !array_key_exists('ACK', $httpParsedResponseAr)) {
exit("Invalid HTTP Response for POST request($nvpreq) to $api_endpoint.");
} return $httpParsedResponseAr;
}