Overview
Icon for PayU

PayU

Enable payments with PayU

Medusa PayU Payment Plugin

A seamless PayU India integration for Medusa v2.

This plugin enables a redirect-based checkout flow with PayU, complete with robust webhook handling to automatically verify and capture transactions even if the user drops off during the redirect.

Installation

yarn add medusa-payu-payment-plugin

Configuration

First, add your PayU credentials to your Copy to clipboard.env file:

# Required
PAYU_MERCHANT_KEY="your_merchant_key"
PAYU_MERCHANT_SALT="your_merchant_salt" # Note: This plugin uses Salt V1 for hashing!
PAYU_ENVIRONMENT="test" # or "production"
# Optional Base URLs (used to build the redirect URLs dynamically based on context)
STOREFRONT_URL="http://localhost:8000"
# PAYU_REDIRECT_URL="/order/confirmed"
# PAYU_REDIRECT_FAILURE_URL="/checkout"

Next, configure the plugin in your Copy to clipboardmedusa-config.ts:

import { defineConfig } from "@medusajs/framework/utils"
export default defineConfig({
modules: [
{
resolve: "@medusajs/medusa/payment",
options: {
providers: [
{
resolve: "medusa-payu-payment-plugin/providers/payu",
id: "payu",
options: {
merchantKey: process.env.PAYU_MERCHANT_KEY,
merchantSalt: process.env.PAYU_MERCHANT_SALT,
environment: process.env.PAYU_ENVIRONMENT || "test",
},
},
],
},
},

Finally, make sure you go into your Medusa Admin → Settings → Regions and add Copy to clipboardpayu as a payment provider to your Indian region.

Frontend Integration

PayU requires a redirect-based flow. Because MedusaJS's Copy to clipboardinitiatePayment doesn't directly redirect the user natively, the plugin generates the required raw signature hashes and returns them in the Copy to clipboardform_data attribute of the payment session.

You are expected to construct a hidden HTML form using this data and automatically submit it on the frontend to execute the redirect.

PayU requires Copy to clipboardfirstname, Copy to clipboardemail, and Copy to clipboardphone. The plugin automatically attempts to extract this from the Medusa cart's shipping/billing address. To avoid errors, you can explicitly pass Copy to clipboardshipping_address_phone (and ideally Copy to clipboardcart_id and Copy to clipboardcustomer_id for tracking) in the data payload when initializing standard payment sessions on the frontend.

Example in React/Next.js

"use client"
function PayUPaymentButton({ cart }) {
const handlePayment = async () => {
const paymentSession = cart.payment_collection?.payment_sessions?.find(
(session) => session.provider_id === "pp_payu_payu"
)
if (!paymentSession?.data?.form_data) return;
const { form_data, paymentUrl } = paymentSession.data
// Create a hidden form to POST to PayU
const form = document.createElement("form")
form.method = "POST"
form.action = paymentUrl
Object.entries(form_data).forEach(([key, value]) => {
const input = document.createElement("input")
input.type = "hidden"

Webhooks (Critical for Production)

Users often close the browser before completing the redirect back to the store. Setting up Server-to-Server callbacks ensures Medusa captures the payment regardless.

  1. Go to your PayU Dashboard → Webhooks.
  2. Add your webhook URL: Copy to clipboardhttps://your-medusa-backend.com/hooks/payment/payu_payu

The plugin handles reverse SHA-512 verification automatically to ensure incoming webhooks are strictly from PayU and have not been tampered with.

Development & Local Testing

If you want to modify this plugin locally:

# Build the plugin
yarn build
# Push to local yalc store
npx yalc push

Then in your main Medusa project:

npx yalc add medusa-payu-payment-plugin
yarn install

When using Copy to clipboardtest environment, use PayU's standard test cards (e.g., Copy to clipboard4012 0010 3844 3335, CVV: Copy to clipboard123, any future expiry). Note that for webhook testing locally, you will need a tunneling service like ngrok to expose your local Medusa instance to PayU's webhook dispatcher.

You may also like

Browse all integrations

Build your own

Develop your own custom integration

Build your own integration with our API to speed up your processes. Make your integration available via npm for it to be shared in our Library with the broader Medusa community.

gift card interface

Ready to build your custom commerce setup?