npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@codemind.ec/medusa-plugin-bank-transfer

v1.0.2

Published

Bank transfer payment provider for Medusa v2 — multi-account management, receipt uploads, and order payment tracking.

Readme

@codemind.ec/medusa-plugin-bank-transfer

Bank transfer payment provider for Medusa v2 — multi-account management, receipt uploads, image compression, and automated email notifications.

npm version Medusa v2 License: MIT


Features

  • Multiple bank accounts — create, update, reorder, and toggle active/inactive accounts via admin API.
  • Payment provider — full lifecycle: initiate → authorize → capture → refund → cancel.
  • Receipt upload — customers upload payment receipts (images/PDFs) from the storefront; images are automatically compressed (JPEG, 1600px max, quality 80).
  • Email notifications — automatic transactional emails to customer & admin on first receipt upload (requires a notification provider like Listmonk).
  • Admin UI widgets — manage bank accounts and view receipts directly in the Medusa admin dashboard.
  • Store API — public endpoint for active bank accounts (cached 5 min) and receipt upload.

Prerequisites

| Requirement | Version | |-------------|---------| | Node.js | >= 20 | | Medusa | >= 2.4.0 |


Installation

npm install @codemind.ec/medusa-plugin-bank-transfer
# or
pnpm add @codemind.ec/medusa-plugin-bank-transfer

Configuration

Add the plugin and its modules to your medusa-config.ts:

import { defineConfig } from "@medusajs/framework/utils"

export default defineConfig({
  // ...
  modules: [
    // Bank accounts module (CRUD de cuentas bancarias)
    {
      resolve: "@codemind.ec/medusa-plugin-bank-transfer/bank-accounts",
      definition: { isQueryable: true },
    },
    // Payment receipt module (comprobantes de pago)
    {
      resolve: "@codemind.ec/medusa-plugin-bank-transfer/payment-receipt",
      definition: { isQueryable: true },
    },
    // Payment provider
    {
      resolve: "@medusajs/medusa/payment",
      options: {
        providers: [
          {
            resolve: "@codemind.ec/medusa-plugin-bank-transfer/payment",
            id: "bank-transfer",
            options: {},
          },
        ],
      },
    },
  ],
  plugins: [
    {
      resolve: "@codemind.ec/medusa-plugin-bank-transfer",
      options: {},
    },
  ],
})

Nota: El plugin necesita tres registros en modules[] (bank-accounts, payment-receipt, y el payment provider) además de la entrada en plugins[] que carga admin UI, API routes y subscribers.

Environment Variables (optional)

These are used by the receipt-upload email templates:

| Variable | Description | Default | |----------|-------------|---------| | ADMIN_EMAIL | Admin email for receipt notifications | — | | BRAND_COLOR | Brand hex color for email templates | #049839 | | BRAND_LOGO | Logo URL for email headers | — | | STORE_URL | Storefront base URL | — | | BACKEND_URL | Medusa backend URL | — | | ADMIN_URL | Admin dashboard URL | — | | WHATSAPP_NUMBER | WhatsApp number shown in emails | — |


Architecture

Modules

bank-accounts

Manages bank account records customers reference when making transfers.

| Field | Type | Description | |-------|------|-------------| | id | string | Primary key | | bank_name | string | Bank name | | account_type | "savings" | "checking" | Account type | | account_number | string | Account number | | account_holder | string | Account holder name | | identification | string? | ID / tax number | | is_active | boolean | Active flag (default true) | | display_order | number | Sort order (default 0) | | metadata | JSON? | Extra data |

payment-receipt

Stores uploaded receipt files linked to payment collections and orders.

| Field | Type | Description | |-------|------|-------------| | id | string | Primary key | | payment_collection_id | string | Associated payment collection | | order_id | string? | Associated order | | file_url | string | Receipt file URL | | file_id | string? | File module reference | | original_filename | string? | Original upload name | | mime_type | string? | MIME type | | file_size | number? | File size in bytes | | uploaded_by | "customer" | "admin" | Upload source |

Payment Provider

Identifier: bank-transfer

| Lifecycle Method | Behavior | |-----------------|----------| | initiatePayment() | Creates session with status pending, reference PED-{sessionId} | | authorizePayment() | Transitions to authorized | | capturePayment() | Requires receipt_url in payment.data | | cancelPayment() | Sets status to canceled | | refundPayment() | Records refund_amount | | getPaymentStatus() | Evaluates timestamps: captured_at → canceled_at → authorized_at |


API Reference

Admin Routes

| Method | Endpoint | Description | |--------|----------|-------------| | POST | /admin/bank-accounts | Create a bank account | | GET | /admin/bank-accounts | List all accounts (sorted by display_order) | | GET | /admin/bank-accounts/:id | Get a single account | | PUT | /admin/bank-accounts/:id | Update an account (partial) | | DELETE | /admin/bank-accounts/:id | Delete an account | | POST | /admin/orders/:id/receipt | Admin receipt upload |

Store Routes

| Method | Endpoint | Description | |--------|----------|-------------| | GET | /store/bank-accounts | List active accounts (public, cached 5 min) | | POST | /store/orders/:id/receipt | Upload payment receipt (multipart, max 5 MB) | | POST | /store/payment-collections/:id/receipt | Upload receipt by payment collection |

Upload a Receipt

curl -X POST https://your-backend.com/store/orders/{order_id}/receipt \
  -H "Content-Type: multipart/form-data" \
  -F "[email protected]"

What happens on upload:

  1. If the file is an image, it's compressed to JPEG (1600 px max width, quality 80).
  2. The filename is sanitized (accents and special characters removed).
  3. The file is saved via Medusa's File module.
  4. order.metadata.receipt_url is updated.
  5. Each bank-transfer payment's data.receipt_url is updated.
  6. Events order.receipt_uploaded and payment.receipt_uploaded are emitted.

Events

| Event | Trigger | |-------|---------| | order.receipt_uploaded | First receipt upload for an order | | payment.receipt_uploaded | Receipt linked to a payment |

The built-in subscriber sends email notifications to both the customer and admin on the first upload, with exponential backoff retry (3 attempts).


TypeScript Exports

import type {
  BankAccountDTO,
  CreateBankAccountData,
  UpdateBankAccountData,
  PaymentReceiptDTO,
  CreatePaymentReceiptData,
} from "@codemind.ec/medusa-plugin-bank-transfer"

// Module re-exports
import BankAccountModule from "@codemind.ec/medusa-plugin-bank-transfer/modules/bank-accounts"
import PaymentReceiptModule from "@codemind.ec/medusa-plugin-bank-transfer/modules/payment-receipt"

// Workflows
import { workflows } from "@codemind.ec/medusa-plugin-bank-transfer/workflows"

Validation

All admin inputs are validated with Zod schemas:

  • bank_name — non-empty string
  • account_type"savings" or "checking"
  • account_number — non-empty string
  • account_holder — non-empty string
  • identification — optional string
  • is_active — optional boolean
  • display_order — optional number
  • metadata — optional JSON object

License

MIT — CodeMind