curl -X GET https://www.wiseyield.co/api/billing/invoices \
-H "Authorization: Bearer wy_YOUR_API_KEY"
{
"invoices": [
{
"id": "inv_abc123",
"userId": "user_xyz789",
"paymentId": "in_1234567890",
"customerId": "cus_9876543210",
"subscriptionId": "sub_abc123",
"amount": 8900,
"currency": "eur",
"status": "paid",
"invoiceUrl": "https://payments.dodopayments.com/invoices/inv_...",
"invoiceNumber": "INV-0042",
"periodStart": "2025-11-01T00:00:00.000Z",
"periodEnd": "2025-12-01T00:00:00.000Z",
"paidAt": "2025-11-01T10:05:00.000Z",
"createdAt": "2025-11-01T10:00:00.000Z"
},
{
"id": "inv_def456",
"userId": "user_xyz789",
"paymentId": "in_0987654321",
"customerId": "cus_9876543210",
"subscriptionId": "sub_abc123",
"amount": 8900,
"currency": "eur",
"status": "paid",
"invoiceUrl": "https://payments.dodopayments.com/invoices/inv_...",
"invoiceNumber": "INV-0041",
"periodStart": "2025-10-01T00:00:00.000Z",
"periodEnd": "2025-11-01T00:00:00.000Z",
"paidAt": "2025-10-01T10:05:00.000Z",
"createdAt": "2025-10-01T10:00:00.000Z"
}
]
}
Get a list of billing invoices for the authenticated user
curl -X GET https://www.wiseyield.co/api/billing/invoices \
-H "Authorization: Bearer wy_YOUR_API_KEY"
{
"invoices": [
{
"id": "inv_abc123",
"userId": "user_xyz789",
"paymentId": "in_1234567890",
"customerId": "cus_9876543210",
"subscriptionId": "sub_abc123",
"amount": 8900,
"currency": "eur",
"status": "paid",
"invoiceUrl": "https://payments.dodopayments.com/invoices/inv_...",
"invoiceNumber": "INV-0042",
"periodStart": "2025-11-01T00:00:00.000Z",
"periodEnd": "2025-12-01T00:00:00.000Z",
"paidAt": "2025-11-01T10:05:00.000Z",
"createdAt": "2025-11-01T10:00:00.000Z"
},
{
"id": "inv_def456",
"userId": "user_xyz789",
"paymentId": "in_0987654321",
"customerId": "cus_9876543210",
"subscriptionId": "sub_abc123",
"amount": 8900,
"currency": "eur",
"status": "paid",
"invoiceUrl": "https://payments.dodopayments.com/invoices/inv_...",
"invoiceNumber": "INV-0041",
"periodStart": "2025-10-01T00:00:00.000Z",
"periodEnd": "2025-11-01T00:00:00.000Z",
"paidAt": "2025-10-01T10:05:00.000Z",
"createdAt": "2025-10-01T10:00:00.000Z"
}
]
}
Documentation Index
Fetch the complete documentation index at: https://docs.wiseyield.co/llms.txt
Use this file to discover all available pages before exploring further.
GET https://www.wiseyield.co/api/billing/invoices
billing:read scope.
Show Invoice Object
usd, eur)paid, open, void, uncollectibleINV-0001)curl -X GET https://www.wiseyield.co/api/billing/invoices \
-H "Authorization: Bearer wy_YOUR_API_KEY"
{
"invoices": [
{
"id": "inv_abc123",
"userId": "user_xyz789",
"paymentId": "in_1234567890",
"customerId": "cus_9876543210",
"subscriptionId": "sub_abc123",
"amount": 8900,
"currency": "eur",
"status": "paid",
"invoiceUrl": "https://payments.dodopayments.com/invoices/inv_...",
"invoiceNumber": "INV-0042",
"periodStart": "2025-11-01T00:00:00.000Z",
"periodEnd": "2025-12-01T00:00:00.000Z",
"paidAt": "2025-11-01T10:05:00.000Z",
"createdAt": "2025-11-01T10:00:00.000Z"
},
{
"id": "inv_def456",
"userId": "user_xyz789",
"paymentId": "in_0987654321",
"customerId": "cus_9876543210",
"subscriptionId": "sub_abc123",
"amount": 8900,
"currency": "eur",
"status": "paid",
"invoiceUrl": "https://payments.dodopayments.com/invoices/inv_...",
"invoiceNumber": "INV-0041",
"periodStart": "2025-10-01T00:00:00.000Z",
"periodEnd": "2025-11-01T00:00:00.000Z",
"paidAt": "2025-10-01T10:05:00.000Z",
"createdAt": "2025-10-01T10:00:00.000Z"
}
]
}
createdAt descending.
Time Range: No time limit - returns all historical invoices up to the limit.
async function getInvoiceHistory() {
const response = await fetch('/api/billing/invoices', {
headers: { 'Authorization': `Bearer ${apiKey}` }
});
const { invoices } = await response.json();
return invoices.map(invoice => ({
id: invoice.id,
number: invoice.invoiceNumber,
amount: `€${(invoice.amount / 100).toFixed(2)}`,
status: invoice.status,
date: new Date(invoice.createdAt).toLocaleDateString(),
downloadUrl: invoice.invoiceUrl
}));
}
// Usage
const history = await getInvoiceHistory();
console.table(history);
async function getLastPayment() {
const response = await fetch('/api/billing/invoices', {
headers: { 'Authorization': `Bearer ${apiKey}` }
});
const { invoices } = await response.json();
const paidInvoices = invoices.filter(inv => inv.status === 'paid');
if (paidInvoices.length === 0) {
return null;
}
const latest = paidInvoices[0]; // Already sorted by createdAt desc
return {
amount: latest.amount / 100,
date: new Date(latest.paidAt),
invoiceNumber: latest.invoiceNumber
};
}
// Usage
const lastPayment = await getLastPayment();
if (lastPayment) {
console.log(`Last payment: €${lastPayment.amount} on ${lastPayment.date.toLocaleDateString()}`);
}
async function getTotalSpent() {
const response = await fetch('/api/billing/invoices', {
headers: { 'Authorization': `Bearer ${apiKey}` }
});
const { invoices } = await response.json();
const total = invoices
.filter(inv => inv.status === 'paid')
.reduce((sum, inv) => sum + inv.amount, 0);
return total / 100; // Convert cents to euros
}
// Usage
const totalSpent = await getTotalSpent();
console.log(`Total spent: €${totalSpent.toFixed(2)}`);
async function hasUnpaidInvoices() {
const response = await fetch('/api/billing/invoices', {
headers: { 'Authorization': `Bearer ${apiKey}` }
});
const { invoices } = await response.json();
const unpaid = invoices.filter(inv => inv.status === 'open');
return {
hasUnpaid: unpaid.length > 0,
count: unpaid.length,
unpaidInvoices: unpaid
};
}
// Usage
const { hasUnpaid, count, unpaidInvoices } = await hasUnpaidInvoices();
if (hasUnpaid) {
console.log(`You have ${count} unpaid invoice(s)`);
}
amount by dividing by 100 and showing currency symbol.invoiceUrl to allow users to download/view invoice PDFs.createdAt and paidAt for user’s locale.amount field is in cents. Always divide by 100 before displaying to users.function InvoiceHistoryTable() {
const [invoices, setInvoices] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
async function loadInvoices() {
try {
const response = await fetch('/api/billing/invoices', {
headers: { 'Authorization': `Bearer ${apiKey}` }
});
const { invoices } = await response.json();
setInvoices(invoices);
} finally {
setLoading(false);
}
}
loadInvoices();
}, []);
if (loading) return <div>Loading invoices...</div>;
if (invoices.length === 0) {
return <div>No invoices yet</div>;
}
return (
<table className="invoice-table">
<thead>
<tr>
<th>Invoice #</th>
<th>Date</th>
<th>Amount</th>
<th>Status</th>
<th>Download</th>
</tr>
</thead>
<tbody>
{invoices.map(invoice => (
<tr key={invoice.id}>
<td>{invoice.invoiceNumber}</td>
<td>{new Date(invoice.createdAt).toLocaleDateString()}</td>
<td>€{(invoice.amount / 100).toFixed(2)}</td>
<td>
<StatusBadge status={invoice.status} />
</td>
<td>
<a href={invoice.invoiceUrl} target="_blank" rel="noopener noreferrer">
Download PDF
</a>
</td>
</tr>
))}
</tbody>
</table>
);
}
function StatusBadge({ status }) {
const statusConfig = {
paid: { color: 'green', text: 'Paid', icon: '✓' },
open: { color: 'yellow', text: 'Pending', icon: '⏳' },
void: { color: 'gray', text: 'Void', icon: '✗' },
uncollectible: { color: 'red', text: 'Failed', icon: '!' },
};
const config = statusConfig[status] || statusConfig.open;
return (
<span className={`badge badge-${config.color}`}>
{config.icon} {config.text}
</span>
);
}
function InvoiceSummaryCard() {
const [summary, setSummary] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
async function loadSummary() {
const response = await fetch('/api/billing/invoices', {
headers: { 'Authorization': `Bearer ${apiKey}` }
});
const { invoices } = await response.json();
const paidInvoices = invoices.filter(inv => inv.status === 'paid');
const totalSpent = paidInvoices.reduce((sum, inv) => sum + inv.amount, 0) / 100;
setSummary({
totalInvoices: invoices.length,
totalPaid: paidInvoices.length,
totalSpent,
lastPayment: paidInvoices[0] || null
});
setLoading(false);
}
loadSummary();
}, []);
if (loading) return <div>Loading...</div>;
return (
<div className="summary-card">
<h3>Billing Summary</h3>
<div className="stats">
<div className="stat">
<label>Total Invoices</label>
<value>{summary.totalInvoices}</value>
</div>
<div className="stat">
<label>Total Spent</label>
<value>€{summary.totalSpent.toFixed(2)}</value>
</div>
{summary.lastPayment && (
<div className="stat">
<label>Last Payment</label>
<value>
€{(summary.lastPayment.amount / 100).toFixed(2)} on{' '}
{new Date(summary.lastPayment.paidAt).toLocaleDateString()}
</value>
</div>
)}
</div>
</div>
);
}
async function downloadAllInvoices() {
const response = await fetch('/api/billing/invoices', {
headers: { 'Authorization': `Bearer ${apiKey}` }
});
const { invoices } = await response.json();
// Open each invoice URL in new tab
invoices.forEach((invoice, index) => {
setTimeout(() => {
window.open(invoice.invoiceUrl, '_blank');
}, index * 500); // Stagger to avoid popup blocker
});
toast.success(`Opening ${invoices.length} invoice(s) in new tabs`);
}