Я хочу интегрировать повторяющееся с потоком платежей (с размещенными страницами на paypal) для моего клиента. Но я не нашел учебник или пример кода в PHP для того же.
Кроме того, я также не могу получить ответы на следующие вопросы.
Чтобы избежать двойного тестирования, вы можете использовать цену для тестирования, например 0,01. Для создания регулярного платежа используйте эту HTML-форму:
<form method="post" name="formName" id="submitThisForm" action="https://www.paypal.com/cgi-bin/webscr" >
<input type="hidden" name="cmd" value="_xclick-subscriptions">
<input type="hidden" name="business" value="[email protected]" />
<input type="hidden" name="item_name" value="Your Membership" />
<input type="hidden" name="a3" value="0.01">
<input type="hidden" name="p3" value="1">
<input type="hidden" name="t3" value="M">
<input type="hidden" name="src" value="1">
<input type="hidden" name="sra" value="1">
<input type="hidden" name="item_number" value="2" />
<input type="hidden" name="custom" value="SECURITYCODE" />
<input type="hidden" name="currency_code" value="USD" />
<input type="hidden" name="quantity" value="1" />
<input type="hidden" name="no_shipping" value="1" />
<input type="hidden" name="return" value="page going after payment" />
<input type="hidden" name="cancel_return" value="" />
<input type="hidden" name="cbt" value="ITEM DESCRIPTION" />
<input type="hidden" name="rm" value="2" />
<input type="hidden" name="notify_url" value="your_listener_file.php" />
Когда пользователь отменяет членство, PayPal уведомит об этом «notify_url» — в вашем случае это будет файл your_listener_file.php. Внутри этого файла вы должны проверить POST-переменную PayPal ‘txn_type’ = ‘subscr_cancel’. Есть несколько важных моментов:
Вы должны проверить транзакцию IPN:
$post = array( 'cmd' => '_notify-validate' );
foreach($_POST as $key=>$value){
$post[$key] = $value;
}
$c = curl_init();
curl_setopt_array($c, array(
CURLOPT_FOLLOWLOCATION => TRUE,
CURLOPT_RETURNTRANSFER => TRUE,
CURLOPT_CONNECTTIMEOUT => 15,
CURLOPT_MAXREDIRS => 15,
CURLOPT_TIMEOUT => 15,
CURLOPT_URL => 'https://www.paypal.com/cgi-bin/webscr',
CURLOPT_POST => TRUE,
CURLOPT_POSTFIELDS => $post,
));
$res = curl_exec($c);
curl_close($c);
$res = trim($res);
if( $res != 'VERIFIED' ) {
exit();
}
Второе — проверьте, существует ли транзакция в вашей базе данных с использованием уникального ключа. Вы должны использовать переменную PayPal POST ‘custom’.
Если транзакция существует, просто сделайте несколько простых проверок:
if( !empty($_POST['txn_type']) && $_POST['txn_type'] == 'subscr_cancel' )
$paypalData['approved'] = 0;
Другой способ заключается в использовании PayPal Express Checkout. Я рекомендовал этот метод. Вот один простой (PHP) пример:
// Параметры для SetExpressCheckout, который будет отправлен в PayPal
$ padata ['L_BILLINGAGREEMENTDESCRIPTION0'] = 'Описание продукта'; $ 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); // Отвечаем согласно сообщению, которое мы получаем от Paypal if ("SUCCESS" == strtoupper ($ httpParsedResponseAr ["ACK"]) || "SUCCESSWITHWARNING" == strtoupper ($ httpParsedResponseAr ["ACK"])) { // Перенаправить пользователя в магазин PayPal с полученным токеном. $ paypalurl = 'https: //www.paypal.com/cgi-bin/webscr? cmd = _express-checkouttoken ='. $ httpParsedResponseAr ["TOKEN"]. ''; header ('Location:'. $ paypalurl); } Еще { эхоОшибка : ».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'] = дата ('Y-m-d'). «Т». Дата ( 'H: I: S'). 'Z';
$ hosteddata ['SUBSCRIBERNAME'] = $ GetExpressCheckoutDetails ['FIRSTNAME']. ''. $ GetExpressCheckoutDetails [ 'LASTNAME'];
$ hosteddata ['TOKEN'] = urlencode ($ _ POST ['token']);
$ hosteddata ['DESC'] = $ hosteddata ['L_BILLINGAGREEMENTDESCRIPTION0'];
$ hosteddata ['AMT'] = $ pr-> цена;
$ hosteddata ['BILLINGPERIOD'] = 'Месяц';
$ 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-> цена;
$ hosteddata ['INITAMT'] = $ pr-> цена;
$ 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
приватная функция 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 = $ versionPWD = $ api_passwordUSER = $ api_usernameSIGNATURE = $ api_signature $ nvpStr_";
curl_setopt ($ ch, CURLOPT_POSTFIELDS, $ nvpreq);
$ httpResponse = curl_exec ($ ch); if (! $ httpResponse) { выход («$ methodName_ failed:» .curl_error ($ ch). '('. curl_errno ($ ch). ')');
} // Извлекаем детали ответа. $ 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 («Неверный HTTP-ответ для запроса POST ($ nvpreq) на $ api_endpoint.»);
} return $ httpParsedResponseAr;
}
Других решений пока нет …