2015-10-18 130 views
2

我已经使用paypal在我的服务器上设置了付款,在做了一些检查之后,它将用户重定向到paypal付款页面,然后用户通过一个自定义参数'approved'='ok将用户重定向到我的网站'或'nok'。除此之外,我还在GET参数中获得了3个字段,即payment-id,payerid和令牌成功。我想验证这些参数是否来自贝宝,并检查付款状态用户是否真的只在服务器端支付金额。Paypal Rest API支付验证serverside

有人会帮忙吗?准备提供更多信息。

我返回URL的样子:提前 http://localhost/test/payment.php?approved=ok&paymentId=PAY-6P3424788A4717248KYR6EPA&token=EC-0V6779052Y720131T&PayerID=JWTZXBN9AEBMC

感谢。

回答

0

您可以在发送参数到paypal后看到交易状态,并返回响应错误或成功消息。下面是支付过程的一个完整的例子与经常性的和普通付款后:

 
// 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;
$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"]).'';
}

页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';
$paypal_data = http_build_query($hosteddata); $hosted_saas_response = $this->PPHttpPost('CreateRecurringPaymentsProfile', $paypal_data);

我用一个单独的方法来发布参数到PayPal

 
private function PPHttpPost($methodName_, $nvpStr_) {
$api_username = '[email protected]'; $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;
}

SetExpressCheckout一次性普通付款的参数:

 
// Parameters for SetExpressCheckout for one time ordinary payment
$padata['L_BILLINGAGREEMENTDESCRIPTION0'] = 'Product descriptuion;
$padata['L_PAYMENTREQUEST_0_DESC0'] = $padata['L_BILLINGAGREEMENTDESCRIPTION0'];
$padata['PAYMENTREQUEST_0_NOTIFYURL'] = 'http://siteurl.com/paypal/ipn';
$padata['PAYMENTREQUEST_0_DESC'] = $padata['L_BILLINGAGREEMENTDESCRIPTION0'];
$padata['RETURNURL'] = 'http://siteurl.com/paypal/returnToDownload';
$padata['CANCELURL'] = 'http://siteurl.com/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_PAYMENTREQUEST_0_NAME0'] = $product->price;
$padata['L_PAYMENTREQUEST_0_NUMBER0'] = 'verification_id#@@#[email protected]#[email protected]#@[email protected]#ASDASD';
$padata['L_PAYMENTREQUEST_0_QTY0'] = '1';
$padata['L_PAYMENTREQUEST_0_AMT0'] = $product->price;
+0

感谢您的回复pavel,我希望您能理解这个问题。我已经将所有详细信息发送给paypal,用户已付款并返回到我的网站。在GET url中添加了3个额外的参数,我真正想要的是检查参数是否由paypal设置而不是由用户设置(为了确保我没有被劫持者欺骗)。我遇到了我真的不想'使用的PDT和IPN。我只想推进这3个参数。更多来自您的意见将非常感谢。再次感谢。 :) – Sudhanshu

+0

终于明白了,在我站立的位置,即我拥有所有这些3个参数。我没有实际执行付款,我只有token和payerid来执行付款。仍然必须运行您的函数PPHttpPost才能完成使用DoExpressCheckoutPayment的过程,然后我将确定所有响应,即ACK =成功或失败,CHECKOUTSTATUS = PaymentActionCompleted。从字面上挽救了我的一天。谢谢帕维尔。 – Sudhanshu

+0

并再次感谢您恢复我的信仰在计算器:) – Sudhanshu