A payment provider for Medusa.js 2.0 that accepts Solana cryptocurrency payments.
- Accept Solana (SOL) cryptocurrency payments in your Medusa store
- Convert cart totals from USD/EUR to SOL
- Display wallet address for payment
- Monitor the blockchain for payment confirmation
- Support for payment authorization, capture, and refund workflows
- Medusa.js 2.0 or higher
- Node.js 16 or higher
- A Solana wallet address
npm install medusa-payment-solanaAdd the following to your medusa-config.js or medusa-config.ts:
module.exports = defineConfig({
// ...
modules: [
// ...
{
resolve: "@medusajs/medusa/payment",
options: {
providers: [
{
resolve: "medusa-payment-solana",
id: "solana",
options: {
passPhrase: process.env.SOLANA_MNEMONIC,
rpcUrl: "https://api.testnet.solana.com", // Use mainnet for production
}
}
]
}
}
]
});Make sure to set the SOLANA_MNEMONIC environment variable in your .env file:
SOLANA_MNEMONIC="word word word word word word word word word word word word"
If you don't know what a mnemonic prhase is, or how to generate one you can use script node scripts/generatePassPhrase.js to get one. (DONT SHARE WITH ANYONE)
To monitor payments, create a file src/jobs/check-payments.ts with the following content:
import { checkPaymentsJob } from 'medusa-payment-solana'
// Export the job function
export default checkPaymentsJob
// Configure the job schedule
export const config = {
name: "check-solana-payments",
schedule: "*/5 * * * *", // Runs every 5 minutes
}This scheduled job will:
- Check for pending Solana payments
- Verify transactions on the Solana blockchain
- Automatically authorize and capture successful payments
- Place orders for completed payments
- Transfer funds to the cold storage wallet
The job runs independently of the storefront, ensuring orders are processed even if:
- The shopper leaves the website after payment
- The browser session ends
- The storefront experiences technical issues
When a payment is successfully captured:
- The order is automatically placed in Medusa
- The shopper receives an order confirmation email (if configured)
- Funds are transferred to the cold storage wallet
- Go to Settings > Regions
- Edit a region or create a new one
- In the Payment Providers section, enable "Solana"
- Save the region
When a customer reaches the checkout page, they will be able to select "Solana" as a payment method. The checkout will display:
- The total amount in SOL
- The wallet address to send the payment to
- Instructions for completing the payment
-
Initiate Payment: When a customer selects Solana as their payment method, the provider converts the cart total to SOL and generates a unique payment ID.
-
Display Payment Details: The storefront displays the Solana wallet address and the amount in SOL to be paid.
-
Monitor for Payment: This must be done using a scheduled job. Configure the
import { checkPaymentsJob } from 'medusa-payment-solana'to periodically check the blockchain for incoming transactions to the specified wallet address. -
Authorize Payment: Once a matching payment is detected, the payment is authorized.
-
Capture Payment: The payment is captured immediately when the payment is authorized. The funds are then transferred to the cold storage wallet.
-
Cold Storage Transfer: After capture, the funds are transferred from the one-time wallet to the configured cold storage wallet. The one-time wallet is emptied and will be closed automatically by the Solana network when its balance reaches zero.
- If the cold storage transfer fails, the payment is still marked as captured since the funds are safely in the one-time wallet
- Transfer failures are logged and can be monitored for manual intervention
- The system ensures customers receive their orders even if internal transfers encounter issues
The payment provider supports two currency conversion options:
-
Default Converter - Uses fixed exchange rates:
- 1 USD = 0.0075 SOL
- 1 EUR = 0.008 SOL
-
CoinGecko Converter - Uses real-time rates from CoinGecko API
To configure the currency converter, update your Medusa config:
{
resolve: "medusa-payment-solana",
options: {
walletAddress: process.env.SOLANA_MNEMONIC,
currencyConverter: {
provider: "coingecko", // or "default"
apiKey: process.env.COINGECK_API_KEY // Required for coingecko
}
}
}When using the CoinGecko provider:
- Set the COINGECK_API_KEY in your .env file
- Ensure your API key has sufficient permissions for the CoinGecko API
- Cache exchange rates to reduce API calls
- Implement error handling for API failures
- Monitor API usage to avoid rate limits
Here's a simple example of generating a QR code from paymentSession data, in a React Storefront:
import QRCode from "react-qr-code";
const paymentUrl = `solana:${paymentSession.data.solana_one_time_address}?amount=${paymentSession.data.sol_amount}`;
return (
<QRCode value={paymentUrl} />
);This will generate a QR code that wallets can scan to pre-fill the payment details.
npm run buildnpm testMIT