• Модуль интеграций
  • Сообщество
  • Блог
Документация
Плагины и интеграцииВсе расширения для Medusa от сообществаСтартерыЗапускайте проекты быстрее с готовыми решениями
ЭкспертыПодберите специалиста для разработки и развития вашего проекта на MedusaКейсыПосмотрите примеры Medusa в продакшене и успешные внедрения
Представляем готовый к продакшену Medusa DTC Starter от Gorgo

26 августа 2026 г. · Продукт

Gorgo снижает затраты на адаптацию Medusa к локальным рынкам.

Мы разрабатываем плагины интеграции, осуществляем поддержку и развиваем сообщество разработчиков на Medusa в Telegram.

  • Ресурсы Medusa
  • Плагины и интеграции
  • Модуль интеграций
  • Стартеры
  • Эксперты
  • Кейсы
  • Medusa Чат в Telegram
  • Medusa Новости в Telegram
  • Документация Gorgo
  • Связаться с нами
  • TelegramGitHub
Плагины
P

Peach payments

Неофициальный платёжный провайдер Peach Payments для Medusa v2

npm install medusa-payment-peach-payments
Категория
Платежи
Создано
Max-bissolati
Версия
0.1.5
Последнее обновление
4 недели назад
Ежемесячные загрузки
Загрузка данных
Звезды на Github
0
npmNPMGitHubGithub

An unofficial Peach Payments (Checkout V2) payment provider for Medusa v2. It generalizes a production-grade Medusa v2 Peach integration, carrying over the parts worth keeping: checkout creation, authorize-on-return completion with an amount-integrity check, webhook handling that re-confirms the outcome server-to-server before trusting it, and V1 HMAC refunds.

Not affiliated with, endorsed by, or supported by Peach Payments. A community plugin maintained independently. For Peach API questions that are not about this plugin's code, see developer.peachpayments.com.

Why reach for this instead of a quick custom provider

A payment provider is easy to write and easy to get subtly, expensively wrong. This one carries the guards you would want from any integration, made explicit:

  • Amount-integrity gate. cross-checks the amount Peach reports on against the amount the session was created for, and fails closed on any mismatch or a missing amount. A result code alone never completes an order.
  • Webhook re-confirmation. The webhook handler never acts on the notification body's claimed outcome or amount. It re-fetches by and treats that as the only source of truth, so the result is independent of anything in the (forgeable) notification.
  • Fail-closed result mapping. and (3DS "not participating" and "not enrolled") map to , not success. They are intermediate, not terminal; real Checkout V2 successes land on a terminal code.
  • Declined refunds are not silent. Peach returns HTTP 200 for a declined refund; the provider checks the result code and throws rather than reporting success.
  • Two independent completion paths (authorize-on-return and webhook), both converging on the same call, so a shopper who closes the tab before the redirect still gets their order.

Install

Requirements: Medusa v2 with and (peer deps, not bundled), Node.js 20+, and a Peach Payments merchant account with Checkout V2 access (plus a sandbox entity for testing).

Register

Payment providers in Medusa v2 go in the Payment module's array, not the top-level array. Always import the provider subpath. A bare package import is intentionally not exported.

The runtime provider id is . With that is , which is the your storefront selects and the segment Medusa uses for the webhook URL. For the full, typed option set read the JSDoc on :

All provider options (annotated) plus environment variables
Env varOptionNotes
or , default
secret
reaches the browser, not a secret
secret; webhook HMAC plus refund HMAC
storefront origin, no trailing slash
your webhook URL
return target after paying
hosted-redirect cancel target
or , default
fallback only, no ZAR default
fallback only

Webhooks

No custom route needed. Medusa auto-mounts for every registered provider. With , register this URL in the Peach Dashboard as your checkout's webhook endpoint (and set it as ):

https://your-backend.example.com/hooks/payment/pp_peach_peach

Peach surfaces a signing secret when you add the webhook; that becomes your . You do not need a body parser: the provider verifies the signature from the raw body when it is preserved, and reconstructs the signed message from Medusa's already-parsed body when it is not. Verification fails closed: an unverifiable webhook is ignored, never trusted. Scheme details: .

Refunds

Refunds use Peach's older V1 endpoint (), signed with the same HMAC key as webhooks, so is required even if you never receive a webhook. The refund body is flat, form-encoded key-value pairs (not nested JSON) with a V1 HMAC over the sorted keys. It is a genuinely different signing scheme from the checkout API, and an easy thing to trip over building from scratch. Refunds need the original transaction id (not the ); the provider stores it on the session after authorization and throws a clear error if it is missing rather than guessing.

Testing in sandbox

Set and use your sandbox entity. Peach's sandbox skips the success screen and OTP/challenge prompts for known test cards (any future expiry; CVV 3 digits for Visa/Mastercard, 4 for Amex):

SchemeCard numberOutcome
Visafrictionless success
Mastercardfrictionless success
Amexfrictionless success

Full list (challenge and decline scenarios): Peach's test and go-live reference.

Storefront integration

Backend-only. There is no npm storefront SDK because Peach's Checkout widget itself is a script-tag global, not a package. has reference React and Next.js code: reading the session off the cart, mounting the embedded widget, and handling the return redirect.

Limitations

  • Two-decimal currencies only. Amounts are formatted and compared at 2 decimals; zero-decimal (JPY) and three-decimal currencies are not supported, and magnitudes beyond roughly 9e13 minor units lose float precision.
  • No built-in ZAR default. Set yourself if you want a fallback.
  • No server-side cancel. Peach's V2 API cannot cancel a checkout; is a no-op and unpaid checkouts expire after 30 minutes.
  • Capture is a no-op for . Immediate-capture settles at Peach when the shopper pays. Pre-auth () capture and void use a separate Peach API this provider does not implement.

License

MIT. See . An independent, community-maintained project with no affiliation to Peach Payments. Use at your own risk and test thoroughly against your own Peach account before going live.

Еще в этой категории

Посмотреть все
Платежи
Braintree logo

Braintree

От Lambda Curry

Поддержка платежей и 3D Secure через Braintree

Загрузка данных
GitHubnpm
Платежи
Pay. logo

Pay.

От Webbers

Принимайте кредитные карты, цифровые платежи и купи сейчас, плати потом

Загрузка данных
GitHubnpm
Платежи
Mollie logo

Mollie

От Variable Vic

Легко принимайте мультивалютные платежи через Mollie

Загрузка данных
GitHubnpm
npm install medusa-payment-peach-payments
1import { defineConfig } from "@medusajs/framework/utils"
2
3module.exports = defineConfig({
4 modules: [
5 {
6 resolve: "@medusajs/medusa/payment",
7 options: {
8 providers: [
9 {
10 resolve: "medusa-payment-peach-payments/providers/peach",
11 id: "peach",
12 options: {
13 mode: process.env.PEACH_MODE, // "sandbox" | "production"
14 clientId: process.env.PEACH_CLIENT_ID,
15 clientSecret: process.env.PEACH_CLIENT_SECRET, // secret
16 merchantId: process.env.PEACH_MERCHANT_ID,
17 entityId: process.env.PEACH_ENTITY_ID, // semi-public (reaches the browser)
18 secretToken: process.env.PEACH_SECRET_TOKEN, // secret: webhook HMAC + refund HMAC
19 referer: process.env.PEACH_REFERER, // allowlisted storefront origin, no trailing slash
20 notificationUrl: process.env.PEACH_NOTIFICATION_URL,
21 shopperResultUrl: process.env.PEACH_SHOPPER_RESULT_URL,
22 defaultCurrency: process.env.PEACH_DEFAULT_CURRENCY, // no ZAR baked in, set it yourself
23 },
24 },
25 ],
26 },
27 },
28 ],
29})
import type { PeachOptions } from "medusa-payment-peach-payments/providers/peach"
1options: {
2 // "sandbox" or "production". Default "sandbox". Drives which Peach hosts the provider talks to.
3 mode: process.env.PEACH_MODE,
4
5 // OAuth credentials from the Peach Dashboard (Checkout API access).
6 clientId: process.env.PEACH_CLIENT_ID,
7 clientSecret: process.env.PEACH_CLIENT_SECRET, // secret
8 merchantId: process.env.PEACH_MERCHANT_ID,
9
10 // The Checkout entity id. Doubles as `authentication.entityId` and the SDK `key` the storefront
11 // passes to Checkout.initiate(), so it reaches the browser (semi-public), but do not commit it.
12 entityId: process.env.PEACH_ENTITY_ID,
13
14 // HMAC key for webhook verification AND the V1 refund endpoint. Required for refunds even if you
15 // never wire up webhooks.
16 secretToken: process.env.PEACH_SECRET_TOKEN, // secret
17
18 referer: process.env.PEACH_REFERER, // allowlisted storefront origin, no trailing slash
19 notificationUrl: process.env.PEACH_NOTIFICATION_URL, // your webhook URL (see Webhooks)
20 shopperResultUrl: process.env.PEACH_SHOPPER_RESULT_URL, // where the shopper returns after paying
21 cancelUrl: process.env.PEACH_CANCEL_URL, // hosted-redirect cancel target (not used by embedded)
22 paymentType: process.env.PEACH_PAYMENT_TYPE, // "DB" capture-now (default) or "PA" pre-auth
23 merchantName: process.env.PEACH_MERCHANT_NAME, // shown in the Peach checkout UI
24
25 // Fallback currency, used only when a session or refund carries none. No ZAR default: with neither
26 // a session currency nor a default set, the provider throws rather than guessing.
27 defaultCurrency: process.env.PEACH_DEFAULT_CURRENCY,
28 defaultCountryCode: process.env.PEACH_DEFAULT_COUNTRY_CODE, // ISO alpha-2 fallback, omitted if unset
29
30 // Optional per-result-code overrides, checked before the built-in map (code only, no env var):
31 // resultCodeOverrides: { "000.400.101": "authorized" }
32 // Overriding a decline or error code logs a warning once, since it loosens a fail-closed default.
33}