From feaf773f2da8d80fde78f9ffecfc8cb507b6fb02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A0=D1=83=D1=81=D0=BB=D0=B0=D0=BD=20=D0=9B=D0=B0=D1=82?= =?UTF-8?q?=D1=8B=D0=BF=D0=BE=D0=B2?= Date: Sun, 14 Jun 2026 16:16:55 +0400 Subject: [PATCH] fix(invoice): auto-select worker's coinpay wallet when poster creates invoice Fixes #478. When the poster initiates an invoice on behalf of the worker, the frontend no longer forces the poster to select a CoinPay receiving wallet (which they wouldn't have access to). The backend API now automatically falls back to selecting the worker's CoinPay wallet matching the gig's payment coin. --- src/app/api/gigs/[id]/invoice/route.ts | 28 ++++++++++++++--------- src/components/gigs/InvoiceButton.tsx | 31 +++++++++++++++++--------- 2 files changed, 38 insertions(+), 21 deletions(-) diff --git a/src/app/api/gigs/[id]/invoice/route.ts b/src/app/api/gigs/[id]/invoice/route.ts index e0f5414c..85e81cd7 100644 --- a/src/app/api/gigs/[id]/invoice/route.ts +++ b/src/app/api/gigs/[id]/invoice/route.ts @@ -313,16 +313,6 @@ export async function POST(request: NextRequest, { params }: { params: Promise<{ ); } - const selectedCurrency = preferredCoinToPaymentCurrency(payment_currency || null); - const selectedAddress = merchant_wallet_address?.trim() || ""; - - if (!selectedCurrency || !selectedAddress) { - return NextResponse.json( - { error: "Select a CoinPay receiving wallet before sending the invoice" }, - { status: 400 } - ); - } - const workerCoinpayToken = await getConnectedCoinpayAccessToken(workerId); if (!workerCoinpayToken) { return NextResponse.json( @@ -353,6 +343,24 @@ export async function POST(request: NextRequest, { params }: { params: Promise<{ ); } + let selectedCurrency = preferredCoinToPaymentCurrency(payment_currency || null); + let selectedAddress = merchant_wallet_address?.trim() || ""; + + if (!selectedCurrency || !selectedAddress) { + const gigCoin = preferredCoinToPaymentCurrency(gig.payment_coin || null); + const preferred = workerWallets.find((w) => w.currency === gigCoin) || workerWallets[0]; + + if (preferred) { + selectedCurrency = preferred.currency; + selectedAddress = preferred.address; + } else { + return NextResponse.json( + { error: "Select a CoinPay receiving wallet before sending the invoice" }, + { status: 400 } + ); + } + } + const selectedWallet = findCoinpayGlobalWallet( workerWallets, selectedCurrency, diff --git a/src/components/gigs/InvoiceButton.tsx b/src/components/gigs/InvoiceButton.tsx index 1d097bb2..91145a3c 100644 --- a/src/components/gigs/InvoiceButton.tsx +++ b/src/components/gigs/InvoiceButton.tsx @@ -234,12 +234,19 @@ export function InvoiceButton({ setIsCreating(true); setError(null); - const selectedWallet = - wallets.find((wallet) => walletKey(wallet) === selectedWalletKey) || null; - if (!selectedWallet) { - setError("Select a CoinPay receiving wallet"); - setIsCreating(false); - return; + let selectedWalletCurrency: string | undefined; + let selectedWalletAddress: string | undefined; + + if (isWorker) { + const selectedWallet = + wallets.find((wallet) => walletKey(wallet) === selectedWalletKey) || null; + if (!selectedWallet) { + setError("Select a CoinPay receiving wallet"); + setIsCreating(false); + return; + } + selectedWalletCurrency = selectedWallet.currency; + selectedWalletAddress = selectedWallet.address; } try { @@ -251,8 +258,8 @@ export function InvoiceButton({ items: lineItems, amount: total, currency: "USD", - payment_currency: selectedWallet.currency, - merchant_wallet_address: selectedWallet.address, + payment_currency: selectedWalletCurrency, + merchant_wallet_address: selectedWalletAddress, notes: notes || undefined, due_date: dueDate || undefined, pr_links: prLinks.length > 0 ? prLinks : undefined, @@ -844,7 +851,8 @@ function InvoiceForm({ /> -
+ {isWorker && ( +
)} -
+
+ )} {error &&

{error}

}