Search for a command to run...
В этом руководстве вы узнаете, как ряд экспресс-оплаты витрины выбирает кнопки кошельков и как добавить кнопку платёжного провайдера.
Ряд стоит над формой оформления заказа. Каждая кнопка оплачивает весь заказ из окна своего кошелька. Покупатель выбирает там адрес, ряд отвечает доставкой и новым итогом, а стартер оформляет заказ, когда покупатель платит. В стартере реестр пуст, поэтому ряд ничего не показывает, пока вы не добавите в него кнопку платёжного плагина.
загружает платёжные провайдеры, включённые в регионе корзины, тот же список, что и у шага оплаты, и передаёт его в . Ряд оставляет кнопку, только если её запись в реестре подходит одному из этих провайдеров:
src/modules/checkout/components/express-checkout/index.tsx1const buttons = expressButtons.flatMap(({ match, Component }) => {2 const provider = availablePaymentMethods.find((method) => match(method.id))3 return provider && !unavailable.includes(provider.id)4 ? [{ providerId: provider.id, Component }]5 : []6 })
В реестре по одной записи на платёжный провайдер, и в стартере он пустой:
src/modules/checkout/components/express-checkout/registry.ts1/**2 * Express buttons above the checkout, one entry per payment provider. The row3 * shows an entry only when `match` accepts a provider enabled in the cart's4 * region. The starter ships without entries, so the row renders nothing until a5 * payment plugin's button is added here.6 */7export const expressButtons: {8 match: (providerId: string) => boolean9 Component: ComponentType<ExpressButtonProps>10}[] = []
Важно: кнопка может скрыть себя и после того, как ряд её показал. Если кошелёк недоступен покупателю, например не загрузился его скрипт, кнопка вызывает , и ряд её убирает. Когда кнопок не остаётся, ряд не показывает ничего, даже заголовка.
Все кнопки получают от ряда одни и те же свойства:
src/modules/checkout/components/express-checkout/registry.ts1export type ExpressButtonProps = {2 cart: HttpTypes.StoreCart3 /** The payment provider of the button, as enabled in the cart's region. */4 providerId: string5 /** The shipping option the checkout has selected, for the wallet's first quote. */6 shippingOptionId: string | null7 /** The wallet is not available to this customer, so the row hides the button. */8 onUnavailable: () => void9 onError: (error: ExpressCheckoutError | null) => void10 /** True while the wallet's payment turns into an order. */11 onBusy: (busy: boolean) => void12 /** Places the order once the wallet has paid. A placed order redirects. */13 placeOrder: () => Promise<void>14 /**15 * The wallet's window closed without an order. The cart may now hold the16 * wallet's address, so the row refreshes the checkout.17 */18 onClosed: () => void19}
С Medusa кнопка работает через Server Actions из . Ни одна из этих функций не сбрасывает кэш корзины, потому что окно кошелька ждёт каждого ответа, а сброс кэша заново отрисовывает всё оформление заказа внутри ответа функции. Ряд обновляет страницу один раз, через , когда окно уже закрыто.
| Функция | Что делает |
|---|---|
| Записывает в корзину адрес, переданный кошельком до оплаты, проверяет, что регион корзины доставляет в эту страну, и выбирает доставку. Оставляет вариант, выбранный при оформлении заказа, если он подходит, иначе берёт первый в порядке оформления заказа. Самовывоз и варианты с ценой по выбору покупателя пропускает. Возвращает новый итог, название и цену выбранного варианта, чтобы кошелёк показал стоимость доставки | |
| Сохраняет email, телефон и полный адрес, переданные кошельком после оплаты, и заново выбирает доставку. Если итог выше , суммы, одобренной покупателем в кошельке, возвращает отказ | |
| Создаёт платёжную сессию, которую оплачивает кошелёк, и возвращает её данные. С оставляет ожидающую сессию, в которой уже есть то же значение, например тот же заказ кошелька | |
| Заново отрисовывает оформление заказа с текущей корзиной |
Чтобы добавить кнопку платёжного провайдера:
Так добавляет свою кнопку пример витрины плагина PayPal:
src/modules/checkout/components/express-checkout/registry.ts1import { isPaypal } from "@lib/constants"2import PayPalExpressButton from "./buttons/paypal"34// ...56export const expressButtons: {7 match: (providerId: string) => boolean8 Component: ComponentType<ExpressButtonProps>9}[] = [10 { match: (providerId) => Boolean(isPaypal(providerId)), Component: PayPalExpressButton },11]
Кнопка целиком, со сменой адреса и проверкой одобренной суммы, описана в разделе Интеграция оплаты PayPal в витрину. Пример плагина Stripe добавляет в ряд Apple Pay, Google Pay и Link так же. Запись в реестре отбирает провайдеров функцией , а кнопка описана в разделе Интеграция платежей Stripe в витрину.
Ряд и его кнопки работают на с sandbox-ключами кошелька. Вебхуку кошелька, который оформляет заказ, если покупатель закрыл вкладку после оплаты, нужен бэкенд на публичном адресе. Примеры платёжных плагинов, например пример PayPal, поднимают его через туннель командой .