BTCPay
Accept Bitcoin payment in your Medusa store
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.
1yarn add medusa-plugin-btcpay
Usage
Set up a Bitcoin PayServer instance, either self-hosted or via a trusted host.
In your environment file (Copy to clipboard.env
) define:
1234BTCPAY_URL=https://your-btcpayserver-instance.comBTCPAY_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 Copy to clipboardmedusa-config.ts
:
1234567891011121314151617181920module.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)
1yarn 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.
1234567const PaymentButton: React.FC<PaymentButtonProps> = ({cart,"data-testid": dataTestId,}) => {const [btcClicked, setBtcClicked] = useState(false)....}
Step 2.2 Then in the case
1234567case 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 Copy to clipboardsrc/lib/constants.tsx
:
123456789101112131415export 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 Copy to clipboardpayment-button/index.tsx
:
123456import { 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
1234567891011121314151617181920"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 () => {
Step 6. Configure Environment Variables in Frontend
Set the following environment variables for your storefront:
12NEXT_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:
1<your-host-url>/hooks/payment/btcpay_btcpay
Make sure you set the webhook secret to match your Copy to clipboard.env
Copy to clipboardBTCPAY_WEBHOOK_SECRET
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
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,
[YourName]
Lead Developer, Payment-BitcoinPayServer Provider