A secure proxy for Midtrans webhooks that validates signatures and routes notifications to downstream applications based on a custom identifier.
- Secure Verification: Validates the
signature_keyfrom Midtrans (SHA512 oforder_id+status_code+gross_amount+server_key) before processing. - Dynamic Routing: Inspects the incoming webhook payload for a matching identifier (default:
custom_field1) and forwards the request to the mapped destination. - Detailed Logging: Logs incoming requests, verification status, and forwarding results with timestamps and response times.
- Node.js (v14 or higher)
- A Midtrans Account (Sandbox or Production)
-
Clone the repository:
git clone <repository_url> cd midtrans-proxy
-
Install dependencies:
npm install
-
Copy the example environment file:
cp .env.example .env
-
Edit
.envand configure the following variables:Variable Description Example PORTPort for the proxy server to listen on. 5556MIDTRANS_SERVER_KEYYour Midtrans Server Key (found in Dashboard > Settings > Access Keys). SB-Mid-server-xxxxxxxxxMIDTRANS_IS_PRODUCTIONSet to truefor Production,falsefor Sandbox.falseTARGET_MAPPINGJSON object mapping identifiers to target Webhook URLs. {"rekaskill": "https://api.rekaskill.com/midtrans/webhook"}
To receive webhooks, you must configure the Notification URL in your Midtrans Dashboard.
- Login to Midtrans Dashboard (Sandbox or Production).
- Go to Settings > Configuration.
- Locate Notification Configuration.
- Add your proxy's URL to the Notification URL field:
Note: If testing locally, use a service like ngrok to expose your localhost (e.g.,
https://<your-proxy-domain.com>/webhookhttps://xxxx.ngrok.io/webhook).
- Transaction Creation: When creating a Snap transaction in your app, send a custom identifier in
custom_field1(or whichever field you configured logic for, currentlycustom_field1is hardcoded).{ "transaction_details": { "order_id": "order-101", "gross_amount": 10000 }, "custom_field1": "rekaskill" } - Notification: Midtrans sends a POST request to this proxy at
/webhook. - Verification: The proxy calculates the SHA512 signature and compares it with the
signature_keyin the payload. - Routing:
- The proxy reads
custom_field1from the payload (e.g., "rekaskill"). - It checks
TARGET_MAPPINGin.envfor the URL associated with "rekaskill".
- The proxy reads
- Forwarding: If a match is found, the verified payload is forwarded to the target URL.
- Start in development mode (auto-reload):
npm run dev
- Build and start for production:
npm run build npm start