В настоящее время я занимаюсь разработкой аналогичного приложения для электронной коммерции с использованием узла js и MongoDB. Это не просто электронная коммерция, это приложение, в котором пользователь может накапливать баллы для обмена на товары и услуги, поэтому баллы можно зарабатывать и покупать.
Вся система использует протоколы двухфазной фиксации для обеспечения согласованности с БД, а при возникновении ошибки или запрещенного действия запускаются действия отката для восстановления состояния согласованности.
Моя команда спроектировала систему, используя этот подход, чтобы мы могли использовать скорость MongoDB в любом сценарии, делая приложение очень быстрым и предоставляя лучший UX, с помощью SPA, созданного с Angular 5 + Angular Universal.
В настоящее время мы внедряем платежную систему и пытаемся определить наилучший способ обработки платежа, проверить его и соответствующим образом обновить нашу базу данных, чтобы купленные продукты / услуги могли быть предоставлены авторизованным пользователям.
Мы подумываем об использовании Stripe для этого, создав клиентскую сторону токена и сохранив ее в корзине пользователя перед ее зарядкой, чтобы мы могли отслеживать неуспешные платежи и соответствующие действия, которые необходимо предпринять в каждом случае.
Мы подумали о следующей схеме корзины:
{
_id: USER'S MONGODB ID,
items: [
{
_id: ITEM'S MONGODB ID,
unitaryPrice: Number,
quantity: Number
}
],
totalPrice: Number,
totalItems: Number,
status: 'ACTIVE',
paymentInfo: {
creditCardAmount: Number (value to be paid in cash),
paymentToken: String (stripe token received from client),
fromUserBalance: Number (points used from user's balance: defined by user, if he/she wants to use points from their account and if balance is $gt 0 : creditCardAmount + fromUserBalance must be equal to totalPrice before proceeding to charge step)
}
}
И вот последовательность, которая должна произойти:
- Пользователь добавляет / удаляет товары в корзине
- Пользователь запускает процесс оформления заказа, при котором информация о кредитной карте отправляется в Stripe и получен токен
В случае успеха этот токен отправляется на наш сервер узлов, и корзина пользователя обновляется до:
{
статус: 'WAITING_PAYMENT',
Платежная информация: {
paymentToken: ПОЛОЖЕННЫЙ ЖЕЛЕЗ
}
}
После этого пользователь больше не может редактировать корзину, пока процесс оплаты не будет завершен
- В этой последовательности извлекается та же самая тележка и делается попытка зарядить токен Stripe
- В случае успеха корзина обновляется до {status: 'PAYMENT_SUCCEEDED'}
- При ошибке корзина возвращается к {status: 'ACTIVE' и токен $ unset}
- После успеха эта же корзина извлекается, и документ создается в другой коллекции с именем «истории покупки», в которой _id документа является токеном полосы, что делает его уникальным и предотвращает дублирование хронологических документов для той же корзины. В этом документе сохраняется вся информация о корзине, после чего корзина очищается.
- В этой истории покупок запускается подпрограмма, которая делает все продукты доступными для конечного пользователя
Вот и все, это механизм, о котором мы думали, чтобы сделать возможными платежи на нашем сайте.
Ребята, вы считаете это хорошим подходом? Есть ли какая-либо ошибка или пропущенный шаг в процессе? Помните, что каждый отдельный шаг происходит рекурсивно, чтобы гарантировать согласованность данных, используя двухфазные фиксации и обновляя документы, только если они соответствуют требуемым значениям ключей для каждого шага.
Я озабочен тем, что сбой системы происходит сразу после того, как токен чередуется, и моя корзина не обновлена до {status: 'PAYMENT_SUCCEEDED'}. В процессе восстановления я должен был бы зарядить его снова, и мне нужно было бы получить ответ, говорящий мне, что этот токен уже был успешно заряжен, чтобы я мог перейти к следующим шагам моей последовательности покупок. Предоставляет ли Stripe SDK это? Могу ли я проверить, был ли токен полосы уже успешно заряжен?