Update order value and cart items
You may sometimes need to update the cart when the payment session already exists. Updating the cart is an asynchronous action that includes the following steps:
- The user changes the items in the cart or the final order amount.
- The merchant updates the data on their server.
- The merchant updates the data in the payment session Yandex Pay.
The problem is that the user might start the payment process somewhere between Step 1 and Step 2, before the updated data has arrived. As a result, the user might click the button and open the Yandex Pay form with the old cart.
To avoid such a situation, updating the cart must lock the Yandex Pay button for the update period.
As an argument, the paymentSession.update
method accepts a function (which is immediately executed). As a result of this function, a Promise
is expected. The button is locked until the Promise
resolves.
Example
function onYaPayLoad() {
const YaPay = window.YaPay;
let activeSession = null;
// Payment details
const paymentData = {
env: YaPay.PaymentEnv.Sandbox,
version: 3,
currencyCode: YaPay.CurrencyCode.Rub,
merchantId: '<YOUR_MERCHANT_ID>',
cart: getNewCart(),
};
// Handler to obtain a payment token
function onPaymentSuccess(event) {
console.log(`OrderId — ${event.orderId}`);
}
// Payment error handler
function onPaymentError(event) {
console.log(`Payment error — ${event.reason}`);
}
// Payment cancellation handler
function onPaymentAbort(event) {}
// Create a payment session.
YaPay.createSession(paymentData, {
onSuccess: onPaymentSuccess,
onAbort: onPaymentAbort,
onError: onPaymentError,
})
.then(function (paymentSession) {
activeSession = paymentSession;
paymentSession.mountButton(document.querySelector('#button_container'), {
type: YaPay.ButtonType.Checkout,
theme: YaPay.ButtonTheme.Black,
width: YaPay.ButtonWidth.Auto,
});
})
.catch(function (err) {
// Couldn't create a payment session.
});
// Cart update emulation
// apiRequestPromise — API request promise to update the cart on the service
onOrderUpdate(function (apiRequestPromise) {
if (!activeSession) {
return console.log('Payment session is not created');
}
const newCart = getNewCart();
// Update the cart, locking the button
activeSession.update(async function () {
await apiRequestPromise;
return {
cart: newCart,
};
});
});
}
/**
* Collateral features for illustrative purposes
*/
function getNewCart() {
const randomInt = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min;
const price = 7990;
const count = randomInt(1, 20);
const total = (count * price).toFixed(2);
document.querySelector('#order_amount').innerHTML = Intl.NumberFormat('ru-RU', {
style: 'currency',
currency: 'RUB',
}).format(total);
return {
items: [{ productId: '3', total, quantity: { count } }],
};
}
function onOrderUpdate(cb) {
const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
const updateButton = document.querySelector('#update_order_button');
updateButton.addEventListener('click', function () {
// Emulate the request's Promise to update the cart on the server
const apiRequestPromise = wait(2000);
cb(apiRequestPromise);
});
}