curl -X GET https://www.wiseyield.co/api/billing/invoices \
-H "Authorization: Bearer wy_YOUR_API_KEY"
const response = await fetch(
'https://www.wiseyield.co/api/billing/invoices',
{
headers: {
'Authorization': 'Bearer wy_YOUR_API_KEY'
}
}
);
const { invoices } = await response.json();
console.log(`${invoices.length} invoices found`);
invoices.forEach(invoice => {
console.log(`${invoice.invoiceNumber}: €${invoice.amount / 100} - ${invoice.status}`);
});
import requests
response = requests.get(
'https://www.wiseyield.co/api/billing/invoices',
headers={'Authorization': 'Bearer wy_YOUR_API_KEY'}
)
data = response.json()
invoices = data['invoices']
for invoice in invoices:
amount = invoice['amount'] / 100
print(f"{invoice['invoiceNumber']}: €{amount:.2f} - {invoice['status']}")
{
"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"
}
]
}
{
"invoices": []
}
{
"error": "Unauthorized"
}
{
"error": "Failed to fetch invoices"
}
Get Invoices
Get a list of billing invoices for the authenticated user
GET
/
api
/
billing
/
invoices
curl -X GET https://www.wiseyield.co/api/billing/invoices \
-H "Authorization: Bearer wy_YOUR_API_KEY"
const response = await fetch(
'https://www.wiseyield.co/api/billing/invoices',
{
headers: {
'Authorization': 'Bearer wy_YOUR_API_KEY'
}
}
);
const { invoices } = await response.json();
console.log(`${invoices.length} invoices found`);
invoices.forEach(invoice => {
console.log(`${invoice.invoiceNumber}: €${invoice.amount / 100} - ${invoice.status}`);
});
import requests
response = requests.get(
'https://www.wiseyield.co/api/billing/invoices',
headers={'Authorization': 'Bearer wy_YOUR_API_KEY'}
)
data = response.json()
invoices = data['invoices']
for invoice in invoices:
amount = invoice['amount'] / 100
print(f"{invoice['invoiceNumber']}: €{amount:.2f} - {invoice['status']}")
{
"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"
}
]
}
{
"invoices": []
}
{
"error": "Unauthorized"
}
{
"error": "Failed to fetch invoices"
}
Endpoint
GET https://www.wiseyield.co/api/billing/invoices
Authentication
Requires a valid API key withbilling:read scope.
Response
Returns an array of invoice objects (max 10 most recent).Show Invoice Object
Show Invoice Object
Unique invoice ID
User ID who owns this invoice
Dodo Payments payment ID
Dodo Payments customer ID
Associated subscription ID (if applicable)
Invoice amount in cents (e.g., 8900 = €89.00)
Currency code (e.g.,
usd, eur)Invoice status:
paid, open, void, uncollectibleURL to view/download invoice PDF
Human-readable invoice number (e.g.,
INV-0001)ISO 8601 datetime when billing period started
ISO 8601 datetime when billing period ended
ISO 8601 datetime when invoice was paid (null if unpaid)
ISO 8601 datetime when invoice was created
curl -X GET https://www.wiseyield.co/api/billing/invoices \
-H "Authorization: Bearer wy_YOUR_API_KEY"
const response = await fetch(
'https://www.wiseyield.co/api/billing/invoices',
{
headers: {
'Authorization': 'Bearer wy_YOUR_API_KEY'
}
}
);
const { invoices } = await response.json();
console.log(`${invoices.length} invoices found`);
invoices.forEach(invoice => {
console.log(`${invoice.invoiceNumber}: €${invoice.amount / 100} - ${invoice.status}`);
});
import requests
response = requests.get(
'https://www.wiseyield.co/api/billing/invoices',
headers={'Authorization': 'Bearer wy_YOUR_API_KEY'}
)
data = response.json()
invoices = data['invoices']
for invoice in invoices:
amount = invoice['amount'] / 100
print(f"{invoice['invoiceNumber']}: €{amount:.2f} - {invoice['status']}")
{
"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"
}
]
}
{
"invoices": []
}
{
"error": "Unauthorized"
}
{
"error": "Failed to fetch invoices"
}
Errors
Unauthorized - Missing or invalid API key
Internal Server Error - Failed to fetch invoices
Invoice Statuses
Limits
Response Limit: Returns maximum 10 most recent invoices, ordered bycreatedAt descending.
Time Range: No time limit - returns all historical invoices up to the limit.
Use Cases
Display Invoice History
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);
Check Last Payment
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()}`);
}
Calculate Total Spent
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)}`);
Check for Unpaid Invoices
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)`);
}
Best Practices
Display Currency: Always format
amount by dividing by 100 and showing currency symbol.Download Links: Use
invoiceUrl to allow users to download/view invoice PDFs.Date Formatting: Format
createdAt and paidAt for user’s locale.Status Badges: Show visual indicators (colors/icons) for different invoice statuses.
10 Invoice Limit: Endpoint returns max 10 invoices. For full history, direct users to Dodo Payments billing portal.
Amount in Cents:
amount field is in cents. Always divide by 100 before displaying to users.Invoice URLs: Invoice URLs may be temporary. Don’t cache them - fetch fresh on each page load.
Integration Examples
Invoice History Table
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>
);
}
Invoice Status Badge
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>
);
}
Invoice Summary Card
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>
);
}
Download All Invoices
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`);
}
Related Endpoints
- Get Subscription - GET current subscription status
- Create Checkout Session - POST to start subscription
- Create Portal Session - POST to manage subscription
- Get Usage - GET current usage metrics
⌘I