Skip to content

PayPal ​

English

Этот адаптер работает с PayPal Orders v2. Покупатель подтверждает оплату на странице PayPal, а потом ваш сервер списывает деньги. То, что покупатель вернулся на вашу страницу, оплату не доказывает.

Установка из npm ​

sh
npm install @checkout-kit/core @checkout-kit/runtime-browser @checkout-kit/provider-paypal

Пакет в npm · Все варианты установки

ts
import { defineProvider } from '@checkout-kit/core'
import type { PayPalConfig } from '@checkout-kit/provider-paypal'

const registration = defineProvider({
  id: 'paypal',
  config: { baseUrl: '/api' } satisfies PayPalConfig,
  load: () => import('@checkout-kit/provider-paypal'),
})

await checkout.pay({ input: { planId: 'starter' }, instrument: { kind: 'none' } })

На вашей странице ничего не вводится, поэтому инструмент — { kind: 'none' }.

Что должен делать ваш сервер ​

Ваш маршрутЧто делает
POST /paypal/orders с { planId }Создаёт заказ с ценой сервера и intent: CAPTURE.
GET /paypal/orders/:idЧитает заказ и состояние списания по нему.
POST /paypal/orders/:id/captureСписывает деньги по подтверждённому заказу. При повторе отправляет тот же id запроса.

Возвращайте PayPalOrder:

  • approveUrl — ссылка payer-action / approve от PayPal;
  • captureStatus берётся из purchase_units[].payments.captures[]. Если списаний несколько, сервер должен проверить, что вместе они покрывают ожидаемую сумму и валюту;
  • заказ со статусом COMPLETED, у которого списание в ожидании, отклонено или отсутствует, никогда не считается оплаченным.

Как адаптер защищает платёж ​

  • Перед списанием он заново читает заказ и списывает, только если заказ в статусе APPROVED.
  • Он не списывает повторно по уже завершённому заказу.
  • Токен возврата, который относится к другому заказу, отклоняется. Ваш сервер тоже должен проверять, что заказ принадлежит этому покупателю.
  • Создание и списание используют разные ключи идемпотентности. Передавайте их в PayPal как PayPal-Request-Id.
  • Поддельного API «отмены» нет: подтверждение в Orders v2 — не резервирование, которое можно аннулировать. Отмена оплаты лишь останавливает процесс в браузере; настоящее состояние платежа — на вашем сервере.

Настройка и тестирование ​

Укажите серверные переменные PAYPAL_CLIENT_ID / PAYPAL_CLIENT_SECRET из приложения PayPal в песочнице. Браузерный SDK не нужен. Используется перенаправление всей страницы и session storage из runtime. В руководстве по React показано, как заказ восстанавливается после возврата.

Ваш сервер возвращает PayPalOrder: id, сумму целым числом, валюту, статус, approveUrl, captureStatus.

Как понимаются статусы:

  • APPROVED — можно списывать;
  • списание завершено — успешно;
  • списание в ожидании — «в обработке»;
  • нет данных о списании — capture_unverified.

Проверяйте на сервере, что списание относится к заказу, а итоговая сумма и валюта правильные. Читайте заказ перед списанием и после потерянного ответа.

Тесты контракта используют сохранённые тестовые данные. Перед приёмом платежей проверьте подтверждение, списание и списание в ожидании на своём тестовом аккаунте. Подробнее — в README пакета и в разделе тестирование.

Сервер мерчанта · Восстановление · PayPal Orders v2

Apache-2.0 · Headless-движок, адаптеры провайдеров и запускаемые примеры.