Medusa plugins
B

Btcpay

A plugin to receive for bitcoin payments in medusajss .

Need customizations for this plugin?

Get in touch
npm install medusa-plugin-btcpay
Category
other
Built by
medusa
Type
unknown
Last updated
1 month ago
Monthly downloads
72
Github stars
14

Support the Payment-BitcoinPayServer Provider – Power the Future of Medusa Commerce!

Dear Developers and E-commerce Pioneers,

Get ready to embrace the world of decentralized finance for your online stores with MedusaJS! We are excited to introduce the Payment-BitcoinPayServer provider – a community-driven project that brings the powerful Bitcoin PayServer gateway to our MedusaJS commerce stack.

What's in it for You:

🛡️ Secure & Sovereign Payments: Enable direct Bitcoin Network payments without relying on third-party payment processors.

🌍 Borderless Transactions: Serve a global audience with permissionless payments that know no borders.

🚀 Empower Open Commerce: By sponsoring this provider, you contribute to the Medusa community's growth, independence, and innovation!

Installation Made Simple

Use the package manager npm to install Payment-BitcoinPayServer.

yarn add medusa-plugin-btcpay

Usage

Set up a Bitcoin PayServer instance, either self-hosted or via a trusted host.

In your environment file () define:

BTCPAY_URL=https://your-btcpayserver-instance.com
BTCPAY_API_KEY=<your api key>
BTCPAY_STORE_ID=<your store id>
BTCPAY_WEBHOOK_SECRET=<your webhook secret>

You need to add the provider into your :

module.exports = defineConfig({
modules: [
...
{
resolve: "@medusajs/medusa/payment",
options: {
providers: [
...
{
resolve: "@yourorg/payment-btcpayserver",
id: "btcpayserver",
options: {
url: process.env.BTCPAY_URL,
apiKey: process.env.BTCPAY_API_KEY,
storeId: process.env.BTCPAY_STORE_ID,
webhookSecret: process.env.BTCPAY_WEBHOOK_SECRET,
},
},
...
],
},
},
...
]
})

Client Side Configuration

For your Medusa Next.js storefront, follow these steps:

Step 1. Install the Bitcoin Payment Button package

(optional - depends on your design)

yarn add react-btcpay-button

Step 2. Create the Bitcoin Payment Button Component in packages/storefront/src/modules/checkout/components/payment-button/index.tsx

Step 2.1 introduce a state variable to track clicks.

Step 2.2 Then in the case

case isBtcpay(paymentSession?.provider_id):
return (
<Button disabled={btcClicked} onClick={() => {setBtcClicked(true);
window.open(`${(paymentSession?.data as any).btc_invoice.checkoutLink}`)}}>
Pay with BtcPay
</Button>
)

Step 3. Extend Payment Constants

In :

export const isBtcpay = (providerId?: string) => {
return providerId?.startsWith("pp_btcpay")
}
export const paymentInfoMap: Record<
string,
{ title: string; icon: React.JSX.Element }
> = {
...
pp_btcpay_btcpay: {
title: "BtcPay",
icon: <CurrencyDollarSolid />,
},
...
}

Step 4. Hook Up the Payment Button

In :

import { BtcpayserverPaymentButton } from "./btcpayserver-payment-button"
...
case "btcpayserver":
return <BtcpayserverPaymentButton session={paymentSession} notReady={notReady} cart={cart} />

step 5 . Create a confirmation page to poll the server --

You can use any mechanism, but i'chosen long polling, coz its just simple. You could use websockets or any other call back mechanism.

processing/page.tsx

"use client";
import { useEffect } from "react";
import { useRouter } from "next/navigation";
import { useSearchParams } from "next/navigation";
import { sdk } from "@lib/config";
import axios from "axios";
const ProcessingPage = () => {
const router = useRouter();
const searchParams = useSearchParams();
const cart= searchParams.get("cart");
useEffect(() => {
let isCancelled = false;
const fetchData = async () => {
try {
const url = `${process.env.NEXT_PUBLIC_MEDUSA_BACKEND_URL}/checkout/is-paid?cart=${cart}`
console.log("Fetching data from URL:", url);
let response = await axios.get(url,{
headers: {
'content-type': 'application/json',
'x-publishable-api-key': process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
}
}) as any;
const result = await sdk.store.cart.complete(cart!) as {
order: {
id: string;
};
}
const redirectUrl = `/order/${result.order.id}/confirmed`
//const response = await fetch(`${process.env.NEXT_PUBLIC_MEDUSA_BACKEND_URL}/checkout/is-paid?cart=${cart}`);
/// const data = response.data;
if (!isCancelled && redirectUrl) {
router.push(redirectUrl);
}
} catch (error) {
if (!isCancelled) {
console.log("Error fetching data:", JSON.stringify(error));
}
} finally {
if (!isCancelled) {
setTimeout(fetchData, 5000); // Poll every 5 seconds
}
}
};
fetchData();
return () => {
isCancelled = true;
};
}, []);
return (
<div>
<h1>Processing...</h1>
<p>Please wait while we process your request.</p>
</div>
);
};
export default ProcessingPage;

Step 6. Configure Environment Variables in Frontend

Set the following environment variables for your storefront:

NEXT_PUBLIC_SHOP_NAME=<your shop name>
NEXT_PUBLIC_MEDUSA_BACKEND_URL=<your medusa store>

Setting Up BTCPay Server Webhook

In BTCPayServer, add a webhook with this URL:

<your-host-url>/hooks/payment/btcpay_btcpay

Make sure you set the webhook secret to match your value.

Contributing

Pull requests are welcome! For significant changes, please open an issue first to discuss improvements or new features.

Please ensure tests and documentation are updated appropriately.

License

MIT License

Untested Features

Some features exist but haven't been fully tested in client integration:

  • Refund support
  • Lightning Network (LNURL and other advanced flows)

Disclaimer

This project is community-driven and tested in limited scenarios. Bugs may occur; please raise issues or submit pull requests if you encounter any.

Support the Payment-BitcoinPayServer Provider – Fuel Open Commerce!

Dear Medusa Enthusiasts,

Thank you for your passion and energy for open e-commerce!
The Payment-BitcoinPayServer provider is an open-source project crafted to connect MedusaJS with the powerful Bitcoin payment ecosystem.

If you find this project useful, consider sponsoring it on GitHub to help maintain and expand it.
Your support makes a world of difference in creating decentralized, open, and innovative commerce for all.

Let's keep building the future together!

With gratitude,
SGFGOV
Lead Developer, Payment-BitcoinPayServer Provider