【问题标题】:Paypal Rest API payment verification serversidePaypal Rest API 支付验证服务器端
【发布时间】:2016-01-17 01:15:43
【问题描述】:

我已经在我的服务器上使用 paypal 设置了付款,在进行了一些检查后,它会将用户重定向到 paypal 付款页面,然后使用一个自定义参数“approved”=“ok”或“nok”将用户重定向到我的网站。除此之外,我在 GET 参数中还有 3 个字段,即成功时的支付 ID、付款人 ID 和令牌。我想验证这些参数是否来自贝宝,并检查支付状态是否用户真的只在服务器端支付了金额。

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

我的返回网址如下所示: http://localhost/test/payment.php?approved=ok&paymentId=PAY-6P3424788A4717248KYR6EPA&token=EC-0V6779052Y720131T&PayerID=JWTZXBN9AEBMC

提前致谢。

【问题讨论】:

    标签: php paypal payment verification


    【解决方案1】:

    您可以在将参数发布到贝宝后查看交易状态,并返回响应错误或成功消息。下面是一个完整的支付流程示例,包括定期支付和普通支付之后:

    // SetExpressCheckout 的参数,将发送到 PayPal
    $pada['L_BILLINGAGREEMENTDESCRIPTION0'] = '产品描述'; $pada['L_BILLINGAGREEMENTDESCRIPTION0'] = $pada['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';
    $pada['PAYMENTREQUEST_0_CURRENCYCODE'] = 'USD'; $pada['PAYMENTREQUEST_0_PAYMENTACTION'] = '销售'; $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'] = $产品->价格;
    $paypal_data = http_build_query($pada); $httpParsedResponseAr = $this->PPHttpPost('SetExpressCheckout', $paypal_data); //根据我们从 Paypal 收到的消息进行响应 if("SUCCESS" == strtoupper($httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($httpParsedResponseAr["ACK"])){ //使用收到的令牌将用户重定向到 PayPal 商店。 $paypalurl ='https://www.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token='.$httpParsedResponseAr["TOKEN"].''; header('位置:'.$paypalurl); }别的{ echo '错误:'.urldecode($httpParsedResponseAr["L_LONGMESSAGE0"]).'';
    }

    页面返回网址:

    $hosteddata['L_BILLINGAGREEMENTDESCRIPTION0'] = '重复描述';
    $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('Ym-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'] = '月';
    $hosteddata['BILLINGFREQUENCY'] = '1';
    $ hostsdata['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'] = '数字' ;
    $hosteddata['L_PAYMENTREQUEST_0_AMT0'] = $pr->price;
    $hosteddata['INITAMT'] = $pr->price;
    $hosteddata['L_PAYMENTREQUE ST_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);

    我使用单独的方法将参数发布到贝宝

    私有函数 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); 如果(!$http响应){ exit("$methodName_ failed: ".curl_error($ch).'('.curl_errno($ch).')');
    } // 提取响应详细信息。 $httpResponseAr = explode("&", $httpResponse);
    $httpParsedResponseAr = 数组(); foreach ($httpResponseAr as $i => $value) { $tmpAr = explode("=", $value); 如果(大小($tmpAr)> 1){ $httpParsedResponseAr[$tmpAr[0]] = $tmpAr[1]; } } if((0 == sizeof($httpParsedResponseAr)) || !array_key_exists('ACK', $httpParsedResponseAr)) {
    exit("对 $api_endpoint 的 POST 请求 ($nvpreq) 的 HTTP 响应无效。");
    } 返回 $httpParsedResponseAr;
    }

    一次性普通支付SetExpressCheckout参数:

    // 一次性普通支付SetExpressCheckout参数
    $padata['L_BILLINGAGREEMENTDESCRIPTION0'] = '产品描述;
    $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#@@#!@#!@#@!!@#ASDASD';
    $padata['L_PAYMENTREQUEST_0_QTY0'] = '1';
    $padata[' L_PAYMENTREQUEST_0_AMT0'] = $product->价格;

    【讨论】:

    • 感谢pavel 的回复,希望您能理解问题所在。我已将所有详细信息发送到贝宝,用户已付款并返回我的网站。在 GET url 中附加了这 3 个额外的参数,我真正想要的是检查这些参数是由贝宝而不是由用户设置的(只是为了确保我不会被劫机者愚弄)。我遇到了我真的不想使用的 PDT 和 IPN。我想只使用这 3 个参数。您的更多意见将不胜感激。再次感谢。 :)
    • 终于明白了,在我站立的位置,即我拥有所有这 3 个参数。我实际上并没有执行付款,我得到的只是令牌和 payerid 来执行它。仍然必须运行您的函数 PPHttpPost 才能使用 DoExpressCheckoutPayment 完成该过程,然后我才会得到所有响应,即 ACK=success 或 failure 和 CHECKOUTSTATUS=PaymentActionCompleted。从字面上拯救了我的一天。谢谢帕维尔。
    • 再次感谢您恢复我对 stackoverflow 的信心 :)
    • 没问题...欢迎您:)
    猜你喜欢
    • 2013-04-13
    • 2020-08-05
    • 2018-04-29
    • 2011-07-08
    • 1970-01-01
    • 2017-02-16
    • 2018-09-07
    • 1970-01-01
    • 2015-05-31
    相关资源
    最近更新 更多