rc 1.0
This commit is contained in:
@@ -3,6 +3,8 @@ import { cookies } from 'next/headers'
|
||||
import pool from '@/lib/db'
|
||||
import { getNowPaymentsConfig } from '@/lib/nowpayments'
|
||||
import { ALLOWED_PAYMENT_CURRENCIES, isAllowedCurrency } from '@/lib/payment-currencies'
|
||||
import { getCountryFromIp, calculateShippingFee } from '@/lib/geolocation'
|
||||
import { getCurrencyForCountry, convertPriceForCountry } from '@/lib/currency'
|
||||
|
||||
// POST /api/payments/create-invoice - Create a NOWPayments payment
|
||||
// Note: Endpoint name kept as "create-invoice" for backward compatibility
|
||||
@@ -129,23 +131,38 @@ export async function POST(request: NextRequest) {
|
||||
)
|
||||
}
|
||||
|
||||
// Check if user has unlocked wholesale prices
|
||||
const [referralRows] = await pool.execute(
|
||||
'SELECT COUNT(*) as count FROM referrals WHERE referrer = ?',
|
||||
[buyer_id]
|
||||
)
|
||||
const referralCount = (referralRows as any[])[0]?.count || 0
|
||||
const isWholesaleUnlocked = referralCount >= 3
|
||||
// Check if user has unlocked wholesale prices (use transaction connection to avoid connection leak)
|
||||
const [referralRows] = await connection.execute(
|
||||
'SELECT COUNT(*) as count FROM referrals WHERE referrer = ?',
|
||||
[buyer_id]
|
||||
)
|
||||
const referralCount = (referralRows as any[])[0]?.count || 0
|
||||
const isWholesaleUnlocked = referralCount >= 3
|
||||
|
||||
// Calculate price
|
||||
// ppu is stored as integer where 1000 = $1.00, so divide by 1000 to get actual price
|
||||
// Get country from IP to determine currency
|
||||
const countryCode = await getCountryFromIp(request)
|
||||
const currency = getCurrencyForCountry(countryCode)
|
||||
|
||||
// Calculate price in EUR (database stores prices in EUR)
|
||||
// ppu is stored as integer where 1000 = 1.00 EUR, so divide by 1000 to get actual price
|
||||
// Assuming ppu is per gram
|
||||
const pricePerGram = drop.ppu / 1000
|
||||
const priceToUse = isWholesaleUnlocked ? pricePerGram * 0.76 : pricePerGram
|
||||
const priceAmount = size * priceToUse
|
||||
const pricePerGramEur = drop.ppu / 1000
|
||||
const priceToUseEur = isWholesaleUnlocked ? pricePerGramEur * 0.76 : pricePerGramEur
|
||||
const priceAmountEur = size * priceToUseEur
|
||||
|
||||
// Convert price to user's currency (CHF for Swiss, EUR for others)
|
||||
const priceAmount = convertPriceForCountry(priceAmountEur, countryCode)
|
||||
|
||||
// Calculate shipping fee (already in correct currency: CHF for CH, EUR for others)
|
||||
const shippingFee = calculateShippingFee(countryCode)
|
||||
|
||||
// Add shipping fee to total price
|
||||
const totalPriceAmount = priceAmount + shippingFee
|
||||
|
||||
// Round to 2 decimal places
|
||||
const roundedPriceAmount = Math.round(priceAmount * 100) / 100
|
||||
const roundedPriceAmount = Math.round(totalPriceAmount * 100) / 100
|
||||
const roundedShippingFee = Math.round(shippingFee * 100) / 100
|
||||
const roundedSubtotal = Math.round(priceAmount * 100) / 100
|
||||
|
||||
// Generate order ID
|
||||
const orderId = `SALE-${Date.now()}-${drop_id}-${buyer_id}`
|
||||
@@ -158,6 +175,10 @@ export async function POST(request: NextRequest) {
|
||||
// Get NOWPayments config (testnet or production)
|
||||
const nowPaymentsConfig = getNowPaymentsConfig()
|
||||
|
||||
// Use currency based on user location (CHF for Swiss, EUR for others)
|
||||
// Override the default currency from config with user's currency
|
||||
const priceCurrency = currency.toLowerCase()
|
||||
|
||||
// Calculate expiration time (10 minutes from now)
|
||||
const expiresAt = new Date()
|
||||
expiresAt.setMinutes(expiresAt.getMinutes() + 10)
|
||||
@@ -180,7 +201,7 @@ export async function POST(request: NextRequest) {
|
||||
},
|
||||
body: JSON.stringify({
|
||||
price_amount: roundedPriceAmount,
|
||||
price_currency: nowPaymentsConfig.currency,
|
||||
price_currency: priceCurrency, // CHF for Swiss users, EUR for others
|
||||
pay_currency: payCurrency, // Required: crypto currency (btc, eth, etc)
|
||||
order_id: orderId,
|
||||
order_description: `${drop.item} - ${size}g`,
|
||||
@@ -206,7 +227,7 @@ export async function POST(request: NextRequest) {
|
||||
// payment.payment_id is the NOWPayments payment ID
|
||||
await connection.execute(
|
||||
'INSERT INTO pending_orders (payment_id, order_id, drop_id, buyer_id, buyer_data_id, size, price_amount, price_currency, expires_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)',
|
||||
[payment.payment_id, orderId, drop_id, buyer_id, buyer_data_id, size, roundedPriceAmount, nowPaymentsConfig.currency, expiresAt]
|
||||
[payment.payment_id, orderId, drop_id, buyer_id, buyer_data_id, size, roundedPriceAmount, priceCurrency, expiresAt]
|
||||
)
|
||||
|
||||
// Commit transaction - inventory is now reserved
|
||||
@@ -220,8 +241,10 @@ export async function POST(request: NextRequest) {
|
||||
pay_address: payment.pay_address, // Address where customer sends payment
|
||||
pay_amount: payment.pay_amount, // Amount in crypto to pay
|
||||
pay_currency: payment.pay_currency, // Crypto currency
|
||||
price_amount: payment.price_amount, // Price in fiat
|
||||
price_currency: payment.price_currency, // Fiat currency
|
||||
price_amount: payment.price_amount, // Total price in fiat (includes shipping)
|
||||
price_currency: payment.price_currency, // Fiat currency (CHF or EUR)
|
||||
shipping_fee: roundedShippingFee, // Shipping fee in user's currency
|
||||
subtotal: roundedSubtotal, // Product price without shipping in user's currency
|
||||
order_id: orderId,
|
||||
payin_extra_id: payment.payin_extra_id, // Memo/tag for certain currencies (XRP, XLM, etc)
|
||||
expiration_estimate_date: payment.expiration_estimate_date, // When payment expires
|
||||
|
||||
Reference in New Issue
Block a user