npm package: @igorppbr/medusa-v2-b2b-credit
Description: B2B Purchase Credit Module for Medusa V2
Author: Igor Ludgero Miura
Latest version: 1.0.1

<p align="center">
  <a href="https://www.medusajs.com">
    <picture>
      <img alt="Medusa logo" src="https://user-images.githubusercontent.com/59018053/229103726-e5b529a3-9b3f-4970-8a1f-c6af37f087bf.svg" width="200"/>
    </picture>
  </a>
</p>
<h1 align="center">
  Purchase Credit Plugin for Medusa B2B
</h1>

<h4 align="center">
  <a href="https://docs.medusajs.com">Medusa Documentation</a> |
  <a href="https://github.com/medusajs/b2b-starter-medusa">B2B Starter</a>
</h4>

<p align="center">
  <a href="https://github.com/medusajs/medusa/blob/master/CONTRIBUTING.md">
    <img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat" alt="PRs welcome!" />
  </a>
  <a href="https://www.linkedin.com/in/igor-ludgero-miura-26175263/">
    <img src="https://img.shields.io/badge/Follow%20on%20LinkedIn-blue?logo=linkedin" alt="Follow me on LinkedIn" />
  </a>
</p>

## Introduction

The **Purchase Credit Plugin** introduces a credit line system for B2B companies using Medusa. This is a common B2B commerce feature, allowing companies to place orders using a pre-approved credit line, and to replenish their balance upon payment. The plugin is designed to work seamlessly with the [Medusa B2B Starter](https://github.com/medusajs/b2b-starter-medusa) and its company/account modules.

**Key Features:**

- Assign and manage credit lines for companies.
- Allow companies to place orders using their available credit.
- Deduct credit when payments are captured.
- Restore credit to the company account in case of refunds.
- View credit usage and transaction history in the Medusa admin.
- Full integration with Medusa’s B2B modules and admin dashboard.

---

## Compatibility

This plugin is compatible with Medusa v2 (>= 2.4.0) and requires the B2B modules from the [Medusa B2B Starter](https://github.com/medusajs/b2b-starter-medusa).

---

## How It Works

### Credit Assignment

Admins can assign or adjust credit for each company via the Medusa admin panel. Each company has a credit balance, which can be increased or decreased as needed.

### Order Placement

Companies can use their available credit to place orders on the storefront. The system checks the company’s available credit before allowing the order to be placed.

### Credit Deduction

When a payment is captured (i.e., an order is confirmed and processed), the corresponding amount is deducted from the company’s credit balance automatically.

### Refunds

If an order is refunded, the credit is automatically restored to the company’s account, making it available for future purchases.

---

## Admin Features

In the Medusa admin dashboard, you can:

- **Add or adjust company credit balances:**
  - Navigate to the company profile and set or update the available credit.
- **View credit usage and transaction history:**
  - See a detailed log of all credit transactions (credits added, used, refunded, etc.) for each company.
- **Monitor outstanding credit and available balances:**
  - Quickly see which companies have outstanding balances and how much credit is available.

<br/>

<img alt="Admin Management Image 1" src="https://raw.githubusercontent.com/igorppbr/medusa-b2b-purchase-credit/master/images/1.png" />

<br/>

<img alt="Admin Management Image 2" src="https://raw.githubusercontent.com/igorppbr/medusa-b2b-purchase-credit/master/images/2.png" />

<br/>

<img alt="Admin Management Image 3" src="https://raw.githubusercontent.com/igorppbr/medusa-b2b-purchase-credit/master/images/3.png" />

<br/>

---

## Installation & Setup

### 1. Install the plugin

```bash
yarn add @igorppbr/medusa-v2-b2b-credit
```

### 2. Enable the plugin in your Medusa config

```js
// medusa-config.js or medusa-config.ts
plugins: [
  {
    resolve: "@igorppbr/medusa-v2-b2b-credit",
    options: {}
  },
  // ...other plugins
],
modules: {
  [Modules.PAYMENT]: {
      resolve: "@medusajs/medusa/payment",
      options: {
        providers: [
          {
            resolve: "@igorppbr/medusa-v2-b2b-credit/providers/b2b-credit",
            id: "b2b-credit",
            options: {
              debug: true // Show debug logs helpful to debug when credits are added and decreased
            }
          }
        ]
      }
    },
    // ...other modules
}
```

### 3. Ensure B2B modules are installed

This plugin requires the B2B modules from the [Medusa B2B Starter](https://github.com/medusajs/b2b-starter-medusa). Make sure you have these modules installed and configured.


### 4. Enabling on the storefront

<img alt="Payment method on the storefront" src="https://raw.githubusercontent.com/igorppbr/medusa-b2b-purchase-credit/master/images/4.png" />

<br/>

To just enabled and display this payment provider on the B2B storefront you can edit the file *src/lib/constants.tsx* on the NextJS storefront and add this:

```javascript

export const paymentInfoMap: Record<
  string,
  { title: string; icon: React.JSX.Element }
> = {
  // ... other payment methods
  'pp_b2b-credit_b2b-credit': {
    title: "B2B Credit",
    icon: <FilePlus />,
  }
}

export const isB2bCredit = (providerId?: string) => {
  return providerId?.startsWith("pp_b2b-credit")
}
```

This will add the B2B Credit payment method to the list of available payment methods on the checkout page.

Then on the file *src/modules/checkout/components/payment-button/index.tsx* we add this:

```javascript
import { isB2bCredit, isManual, isPaypal, isStripe } from "@/lib/constants"

switch (true) {
  // ... other payment modules
  case isB2bCredit(paymentSession?.provider_id):
      return (
        <B2bCreditPaymentButton
          notReady={notReady}
          cart={cart}
          data-testid={dataTestId}
        />
      )
}

const B2bCreditPaymentButton = ({
  notReady,
  cart,
}: {
  notReady: boolean
  cart: B2BCart
}) => {
  const [submitting, setSubmitting] = useState(false)
  const [errorMessage, setErrorMessage] = useState<string | null>(null)

  const onPaymentCompleted = async () => {
    await completeCart(cart)
      .catch((err) => {
        setErrorMessage(err.message)
      })
      .finally(() => {
        setSubmitting(false)
      })
  }

  const handlePayment = () => {
    setSubmitting(true)

    onPaymentCompleted()
  }

  return (
    <>
      <Button
        className="w-full"
        disabled={notReady}
        isLoading={submitting}
        onClick={handlePayment}
        size="large"
        data-testid="submit-order-button"
      >
        Place order using B2B Credits
      </Button>
      <ErrorMessage
        error={errorMessage}
        data-testid="b2b-credit-payment-error-message"
      />
    </>
  )
}
```

---

## Usage

1. **Assign credit to companies** in the admin panel.
2. **Companies use their credit** at checkout on the storefront.
3. **Credits are automatically managed**:
   - Deducted on payment capture.
   - Restored on refund.

---

## Example Workflow 1

1. **Admin assigns $10,000 credit** to Company A.
2. **Company A places an order** for $2,500 using their credit line.
3. **Order is captured:** $2,500 is deducted from Company A’s credit, leaving $7,500 available.
4. **Customer paid for the order:** The admin user will go and add $2,500 back to Company A’s credit, returning the balance to $10,000.

---

## Example Workflow 2

1. **Admin assigns $10,000 credit** to Company A.
2. **Company A places an order** for $2,500 using their credit line.
3. **Order is captured:** $2,500 is deducted from Company A’s credit, leaving $7,500 available.
4. **Order is refunded:** $2,500 is restored to Company A’s credit, returning the balance to $10,000.

---

## FAQ

**Q: Can I set different credit limits for different companies?**
A: Yes, each company can have its own credit limit and balance, managed via the admin panel.

**Q: What happens if a company tries to place an order exceeding their available credit?**
A: The order will be blocked until the company has sufficient credit.

**Q: Is credit usage tracked?**
A: Yes, all credit transactions (additions, deductions, refunds) are logged and viewable in the admin dashboard.

---

## Contributing

We welcome contributions to the FedEx Fulfillment Integration! If you have suggestions, improvements, or bug fixes, please follow these steps:

1. **Fork the Repository**  
   Create a personal copy of the repository by forking it on GitHub.

2. **Create a New Branch**  
   Create a new branch for your changes:
   ```bash
   git checkout -b my-feature-branch
   ```

3. **Make Your Changes**  
   Implement your changes in the codebase.

4. **Test Your Changes**  
   Ensure that your changes work as expected and do not break existing functionality.

5. **Submit a Pull Request**  
   Push your changes to your forked repository and submit a pull request to the main repository.

## Support / Contact

If you need help or have questions about the FedEx Fulfillment Integration, please reach out to us:

- **Email:** igorlmiura@gmail.com
- **GitHub Issues:** [Submit an issue](https://github.com/igorppbr/medusa-fedex-fulfillment/issues)