Является ли этот процесс платежным для пользователя надежным и безопасным? - PullRequest
2 голосов
/ 08 июня 2011

Я работаю над проектом, который требует, чтобы мое приложение платило пользователю за его счет PayPal, когда он просит об этом.

Вот как я это сделал до сих пор:

  1. (зарегистрированный) пользователь переходит на страницу оплаты, на которой перечисляются все его платежи (полученные или нет)
  2. Он вводит свою электронную почту Paypal и пароль своего приложения (мой) (для безопасности)
  3. Страница POST получает список всех Платежей, которые имеют статус = «НЕПОЛАДОК» для этого пользователя, и обновляет статус до «РАБОТАЮЩИЙ» (чтобы пользователь не обновлял страницу до завершения всего процесса и не отправлял ее повторно). сумма денег)
  4. Мы считаем общую сумму для оплаты в этом списке (простой for)
  5. Сумма отправляется в Paypal через PayPal Adaptive Payment API (запрос: PAY)
  6. Ответ проверяется, если он завершен, статус списка устанавливается на «ЗАВЕРШЕНО», если нет, список возвращается к «НЕПРАВИЛЬНО» (обновление SQL выполняется через WHERE id IN(x, y, z) в случае, если второй запрос на платеж имеет было сделано за это время.
  7. Затем пользователю отображается сообщение

Но мне нужна ваша помощь, я столкнулся с одной рискованной проблемой, которую я хотел бы избежать, и я бы знал, как вы поступите:

  • Если пользователь нажал кнопку «Обновить» на странице процесса, я не хочу отправлять ему дважды (или более) сумму (здесь работает «РАБОЧАЯ» блокировка, но что произойдет, если пользователь нажмет кнопку «Обновить», прежде чем я установлю замок?)
  • Редко возможно: что произойдет, если пользователь нажмет клавишу f5 после того, как будет сделана блокировка «РАБОТАЕТ», но до запроса к PayPal и получения нового платежа. Следуя тому, что я сделал, только один элемент (новый) будет получен и установлен на РАБОТУ, но все остальные предыдущие платежи будут стоить

Как бы вы сделали? Каков наилучший способ сделать его на 100% надежным?

Спасибо за вашу помощь

Примечание:

Шаги с 4 по 6 выполняются с помощью заданий PlayFramework , вызываемых с now() и awaiting() результатом

1 Ответ

2 голосов
/ 08 июня 2011

Вы можете:

  • предотвратить двойную публикацию через JQuery
  • использовать checkAuthenticity () метод для проверки запроса
  • выполнить GET-перенаправление после обработки POST (чтобы они не могли отправить одно и то же 2 раза, даже по ошибке)
  • сделать обработку платежей асинхронной (см. Ниже)

Для оплаты вместо вызова задания задайте идентификаторы платежей в очереди (или таблице в базе данных) и задание, которое запускается раз в минуту и ​​обрабатывает эту таблицу, если в ней есть какие-либо данные.Когда пользователь выполняет процедуру POST, вы перенаправляете на страницу, на которой говорится, что вы обрабатываете платежи, и будете уведомлять, если возникнет какая-либо проблема.Вы можете уведомить пользователя позже через предупреждение пользовательского интерфейса с помощью кометы или по почте.

Таким образом, вы не будете связывать запрос с обработкой, и у вас не будет проблем с многопоточностью / гонками, а также вы сможете обнаружить устаревшие запросы (платежи уже сделаны), если вы выполните последовательную обработку.

...