Обновление стоимости и корзины
После создания платежной сессии иногда возникает необходимость обновить корзину.
Обычно обновление корзины — это асинхронное действие, которое по шагам выглядит так:
- Пользователь меняет состав корзины (или конечную сумму заказа).
- Продавец обновляет данные у себя на сервере.
- Продавец обновляет данные в платежной сессии Yandex Pay.
Проблема в том, что пользователь может начать процесс оплаты где-то между 1 и 2 пунктом, не дождавшись обновленных данных. Таким образом, он нажмет на кнопку и откроет форму Yandex Pay со старой корзиной.
Чтобы избежать подобной ситуации, нужно обновлять корзину с блокировкой кнопки Yandex Pay на время обновления.
Метод paymentSession.update
принимает в качестве аргумента функцию (которая тут же выполняется), результатом работы которой ожидается Promise
. Кнопка блокируется до резолва Promise
.
Пример
function onYaPayLoad() {
const YaPay = window.YaPay;
let activeSession = null;
// Данные платежа
const paymentData = {
env: YaPay.PaymentEnv.Sandbox,
version: 2,
countryCode: YaPay.CountryCode.Ru,
currencyCode: YaPay.CurrencyCode.Rub,
merchant: {
id: '<YOUR_MERCHANT_ID>',
name: 'test-merchant-name',
url: 'https://test-merchant-url.ru',
},
order: getNewOrder(),
paymentMethods: [
{
type: YaPay.PaymentMethodType.Card,
gateway: 'test-gateway',
gatewayMerchantId: 'test-gateway-merchant-id',
allowedAuthMethods: [YaPay.AllowedAuthMethod.PanOnly],
allowedCardNetworks: [
YaPay.AllowedCardNetwork.Visa,
YaPay.AllowedCardNetwork.Mastercard,
YaPay.AllowedCardNetwork.Mir,
YaPay.AllowedCardNetwork.Maestro,
YaPay.AllowedCardNetwork.VisaElectron,
],
},
],
};
// Обработчик на получение платежного токена
function onPaymentProcess(event) {
console.log(`Payment token — ${event.token}`);
}
// Обработчик на ошибки при оплате
function onPaymentError(event) {
console.log(`Payment error — ${event.reason}`);
}
// Обработчик на отмену оплаты
function onPaymentAbort(event) {}
// Создать платежную сессию.
YaPay.createSession(paymentData, {
onProcess: onPaymentProcess,
onAbort: onPaymentAbort,
onError: onPaymentError,
})
.then(function (paymentSession) {
activeSession = paymentSession;
paymentSession.mountButton(document.querySelector('#button_container'), {
type: YaPay.ButtonType.Pay,
theme: YaPay.ButtonTheme.Black,
width: YaPay.ButtonWidth.Auto,
});
})
.catch(function (err) {
// Не получилось создать платежную сессию.
});
// Эмуляция обновления корзины
// apiRequestPromise — Promise api-запроса на обновление корзины на сервисе
onOrderUpdate(function (apiRequestPromise) {
if (!activeSession) {
return console.log('Payment session is not created');
}
const newOrder = getNewOrder();
// Обновляем корзину с блокировкой кнопки
activeSession.update(async function () {
await apiRequestPromise;
return {
order: newOrder,
};
});
});
}
/**
* Сопроводительные функции для иллюстрации работы
*/
function getNewOrder() {
const randomInt = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min;
const node = document.querySelector('#order_amount');
const amount = randomInt(1000, 20000).toFixed(2);
node.innerHTML = Intl.NumberFormat('ru-RU', {
style: 'currency',
currency: 'RUB',
}).format(amount);
return {
id: `order-id-${Date.now()}`,
total: { amount },
};
}
function onOrderUpdate(cb) {
const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
const updateButton = document.querySelector('#update_order_button');
updateButton.addEventListener('click', function () {
// Эмуляция Promise'a запроса на обновление корзины на сервере
const apiRequestPromise = wait(2000);
cb(apiRequestPromise);
});
}