Уникальный идентификатор IPN PayPal
Я всегда предполагал, что txn_id
отправлено с сообщением IPN уникально. Рекомендации PayPal, похоже, поддерживают эту идею - https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_admin_IPNIntro
Избегайте дублирования сообщений IPN. Убедитесь, что вы еще не обработали транзакцию, идентифицированную идентификатором транзакции, возвращенным в сообщении IPN. Возможно, вам придется хранить идентификаторы транзакций, возвращаемые сообщениями IPN в файле или базе данных, чтобы вы могли проверять наличие дубликатов. Если идентификатор транзакции, отправленный PayPal, является дубликатом, вы не должны обрабатывать его снова.
Однако я обнаружил, что PayPal eCheck payment IPN отправляется дважды с тем же идентификатором транзакции. Однажды во время первоначального платежа с payment_status
как "Ожидание" и снова через пару дней, когда eCheck фактически обрабатывает с помощью payment_status
как "Завершено".
Я хочу хранить обе транзакции, но все равно хочу избежать дублирования. В IPN есть другое поле, называемое ipn_track_id
, и оно отличается для обеих транзакций, но я не могу найти документацию для него, кроме этого неопределенного описания:
Внутренний; только для использования МТС и DTS
Кто-нибудь использует ipn_track_id
для уникальной идентификации сообщений IPN?
Ответы
Ответ 1
ipn_track_id
не следует использовать; главным образом потому, что это для внутреннего использования только, как указано, и потому, что оно уникально для каждого сообщения IPN.
txn_id
уникален для каждой транзакции , а не для каждого сообщения IPN.
Это означает; одна транзакция может иметь несколько сообщений IPN. Например, eCheck, где он пойдет в состоянии "Ожидание" по умолчанию, и "Завершить" после удаления eCheck.
Но вы также можете увидеть развороты, отмененные аннулирования, открытые случаи и возврат к тому же txn_id
.
Псевдокод:
If not empty txn_id and txn_type = web_accept and payment_status = Completed
// New payment received; completed. May have been a transaction which was pending earlier.
Update database set payment_status = Completed and txn_id = $_POST['txn_id']
If not empty txn_id and txn_type = web_accept and payment_status = Pending
// New payment received; completed
Update database set payment_status = Pending and payment_reason = $_POST['pending_reason'] and txn_id = $_POST['txn_id']
Вы можете найти намного больше переменных IPN, перечисленных на https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_html_IPNandPDTVariables#id08CTB0S055Z
В принципе; PayPal создаст уникальный идентификатор транзакции продавца. Этот идентификатор трансакции может проходить через различные этапы, прежде чем "Завершено", поэтому вам нужно будет иметь возможность обрабатывать эти исключения.
Что касается примечания PayPal в документации: PayPal может повторно отправлять отдельные IPN-сообщения, если он сталкивается с ошибками во время доставки. Например, для вашего script требуется вернуть правильный HTTP-статус HTTP/1.1 200 OK, когда PayPal отправляет данные IPN на него.
Если вы не вернете ответ HTTP/1.1 200 OK, PayPal повторно отправит одни и те же данные до 16 раз для отдельного IPN-сообщения.
Примечание. Идентификатор транзакции продавца отличается от идентификатора трансформирования покупателя, так как это два разных действия (один дебет, один кредит).
Ответ 2
ipn_track_id не уникален для повторяющихся платежей. По крайней мере, для плана рассрочки это не так.
Когда клиент создает план рассрочки и если ваш план имеет первый платеж при оформлении заказа, вы получите 2 сообщения IPN с тем же ipn_track_id (пример ниже).
Первое уведомление "recurring_payment_profile_created" первого платежа "recurring_payment"
Созданный план IPN
[txn_type] => recurring_payment_profile_created
[recurring_payment_id] => I-57UAPHFJ3SBY
[product_name] => Risk-Free Trial
[time_created] => 06:24:39 Aug 15, 2013 PDT
[ipn_track_id] => bdd94fdee935a
Первый платеж IPN
[txn_type] => recurring_payment
[mc_gross] => 10.95
[shipping] => 0.00
[product_type] => 1
[time_created] => 06:24:39 Aug 15, 2013 PDT
[ipn_track_id] => bdd94fdee935a
Ответ 3
Не все сообщения IPN содержат $_POST ['txn_id'], поэтому, если вы только проверяете наличие txn_id, вы можете периодически перехватывать IPN-сообщения, где они не содержат этот ключ.
Ответ 4
В моем вызове PHP API я использую эти поля и сохраняю их в своей базе данных:
custom=xxxx
(или invoice=ZZZZZZ
)
тогда, когда ваша страница получает IPN, она должна проверять (из базы данных), если custom=xxxx
или etc...
Ответ 5
транзакции IPN уникальны, а также транзакции, которые изменяют платеж, генерируют новый txn_id. Например, возврат средств, поэтому рекомендуется хранить все txn_id, связанные с одной покупкой. На данный момент я не знаю, какие транзакции, кроме возмещений, генерируют новый txn_id, возможно, и обратные.