Skip to main content

Documentation Index

Fetch the complete documentation index at: https://danestvesllc-2b77d201.mintlify.app/llms.txt

Use this file to discover all available pages before exploring further.

Polar generates PDF invoices on demand for each order. Laravel Polar surfaces this through two methods on the Order model:
  • receiptUrl() — returns the PDF URL as a string, useful for embedding a link in a Blade view.
  • downloadInvoice() — returns a RedirectResponse that sends the customer’s browser directly to the PDF.
Invoice URLs are generated fresh on each request via the Polar API. They are not stored locally. The result is memoized on the Order instance (per request) so multiple calls within a single request won’t hit the API more than once.

Getting the invoice URL

Call receiptUrl() on any Order instance to get the URL of the generated PDF:
$url = $order->receiptUrl(); // ?string
The method returns null when the order has no polar_id or no associated customer. Otherwise it:
  1. Authenticates with Polar on behalf of the customer.
  2. Calls Polar’s generate-invoice endpoint.
  3. Extracts and returns the URL from the response.

Memoization

The result is cached on the Order instance for the lifetime of the request. Calling receiptUrl() twice on the same object only makes one API call:
$url1 = $order->receiptUrl(); // hits Polar API
$url2 = $order->receiptUrl(); // returned from in-memory cache
This means it is safe to call receiptUrl() in a loop over a list of orders within a single request, but each distinct Order instance will make its own API call.
The invoice URL is fetched fresh on each request (once per Order instance). If you need to persist it, save the string returned by receiptUrl() to your own database column.
Use receiptUrl() in a Blade view to conditionally render a download link:
@if ($order->receiptUrl())
    <a href="{{ $order->receiptUrl() }}" target="_blank">
        Download invoice
    </a>
@endif
Because the URL is memoized, calling $order->receiptUrl() twice in the same template does not trigger a second API request.

Redirecting to the invoice from a controller

Use downloadInvoice() to redirect the customer’s browser directly to the PDF. The method returns an Illuminate\Http\RedirectResponse:
use App\Models\Order;
use Illuminate\Http\Request;

Route::get('/orders/{order}/invoice', function (Request $request, Order $order) {
    // Authorize that the order belongs to this user
    abort_unless($order->billable->is($request->user()), 403);

    return $order->downloadInvoice();
});
downloadInvoice() calls receiptUrl() internally and throws a RuntimeException if no URL is available (for example, when the order has not yet been synced from Polar).
Always authorize that the order belongs to the authenticated user before calling downloadInvoice(). The URL it redirects to is a short-lived signed link, but the route itself must still be protected.

Full controller example

1

Define the route

Register a route that accepts an order ID and returns the invoice redirect:
// routes/web.php
Route::get('/orders/{order}/invoice', [OrderController::class, 'invoice'])
    ->middleware('auth');
2

Authorize and redirect in the controller

Fetch the order, confirm ownership, and return the redirect response:
// app/Http/Controllers/OrderController.php
use Danestves\LaravelPolar\Order;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;

public function invoice(Request $request, Order $order): RedirectResponse
{
    abort_unless($order->billable->is($request->user()), 403);

    return $order->downloadInvoice();
}
3

Link to the route in your view

Render a download link in the order history table:
<a href="{{ route('orders.invoice', $order) }}">
    Download invoice
</a>