PayU
Accept payments with PayU
@sam-ael/medusa-plugin-payu
A production-focused PayU India payment provider plugin for Medusa v2 featuring redirect checkout flow, callback handling, and fraud-aware verification.
Medusa Website | Medusa Repository
Features
- Redirect-Based Checkout: Integrates seamlessly into Medusa payment sessions to route customers to the official PayU checkout portal.
- Secure Hash Verification: Automated generation of checkout hashes and reverse-hash verification for response validation.
- Robust Webhook Integration: Processes real-time transaction updates from PayU to handle capture and payment events.
- Timing-Attack Protection: Employs constant-time string comparison for webhook payload hash validation.
- Replay Protection: Prevents duplicate transaction/webhook submissions via an in-memory key deduplication store.
- Discrepancy Guards: Compares paid amounts against expected payment session amounts to flag underpayment attempts.
Prerequisites
- Node.js v18 or greater
- A Medusa v2 backend
- A PayU India merchant account with a Merchant Key and Merchant Salt
Installation
Run the following command to install the plugin in your Medusa project:
1yarn add @sam-ael/medusa-plugin-payu
Configuration
1. Register in Copy to clipboardmedusa-config.ts
Add the PayU provider under the payment module options in Copy to clipboardmedusa-config.ts:
12345678910111213141516171819const modules = [// ... other modules{resolve: "@medusajs/medusa/payment",options: {providers: [{resolve: "@sam-ael/medusa-plugin-payu/providers/payu",id: "payu",options: {merchantKey: process.env.PAYU_MERCHANT_KEY,merchantSalt: process.env.PAYU_MERCHANT_SALT,environment: process.env.PAYU_ENVIRONMENT || "test", // "test" or "production"},},],},},]
2. Environment Variables
Define the required credentials and options in your Copy to clipboard.env file:
12345678PAYU_MERCHANT_KEY=your_merchant_keyPAYU_MERCHANT_SALT=your_merchant_saltPAYU_ENVIRONMENT=testSTOREFRONT_URL=http://localhost:8000PAYU_REDIRECT_URL=/order/confirmedPAYU_REDIRECT_FAILURE_URL=/checkoutPAYU_API_TIMEOUT_MS=30000
Webhooks
This plugin exposes an inbound webhook endpoint to handle asynchronous payment updates sent by PayU.
Method Endpoint Description Copy to clipboardPOST Copy to clipboard/hooks/payment/payu_payu Processes incoming transaction updates, verifying authenticity using PayU response hashes.
Webhook Validation
- Hash Verification: Generates a SHA-512 comparison hash using your Copy to clipboard
PAYU_MERCHANT_SALTand incoming payload variables. It uses Copy to clipboardcrypto.timingSafeEqualto check validity. - Amount Discrepancy Check: Validates that the amount reported in the webhook matches the expected transaction amount (stored in Copy to clipboard
udf4). If underpaid, it sets the payment status to Copy to clipboardrequires_more. - Replay Guard: Dedupes requests matching the key pattern Copy to clipboard
${txnid}:${status}:${mihpayid}:${amount}within a 10-minute window.
Test the Plugin
- Set your backend to use Copy to clipboard
testmode (Copy to clipboardPAYU_ENVIRONMENT=test). - Implement a checkout page on your storefront that resolves a payment session using the Copy to clipboard
payuprovider ID. - Initiate checkout; you should be redirected to the PayU Sandbox page.
- Complete the test transaction using the test card details provided on PayU's developer documentation.
- PayU will redirect the client back to your storefront, and call the Copy to clipboard
/hooks/payment/payu_payuwebhook to complete/authorize the order payment in Medusa.
