Skip to main content
With the Print.App WordPress plugin, every WooCommerce order line that has a design carries its project. This guide reads the project from a paid order, downloads its print-ready PDF and hands it to a print partner or fulfilment API. The example partner is a book printer such as the Lulu Print API.
To fetch files by hand instead, they are listed against each order in your WordPress admin: see How to access files.

1. Find the project on the order

The plugin stores the design on each order line as the item meta print_app_customization, an array that holds the projectId:
Lines without a design have no such meta.

2. Download the print-ready PDF

The PDF is at:
For other formats, swap pdf for png, jpeg or tiff in the host name.
  • It renders on request. The file is produced from the saved project when you ask for it, which takes a few seconds. Allow a generous timeout.
  • It answers with a redirect to a short-lived download link. Follow the redirect. wp_remote_get does so by default.
  • Download it once, when the order is paid, and keep your own copy. A later download reflects the project’s state at that later time.
  • The link works without a key. Treat it as confidential, and don’t publish it.
The PDF’s page size and settings come from the design. Set the size in the design’s pages, and choose the PDF version, colour profile and fonts with a PDF output profile.
To check from your server that the project is yours and finished before printing, call GET /v2/projects/{id} with a secret key. Its exports.pdf is the same link. See Verify a project before fulfilling.

3. Send the order to your print partner

This runs when an order becomes processing, which for most payment methods means it has been paid. It collects each cover PDF, stores a copy and creates one print job per order. Add it to a small plugin or your theme’s functions.php:
my_create_print_job is your own call to your partner’s API. A few things to decide for production:
  • Retries. If a download or the partner’s API fails, the hook stops without marking the order. Re-run it for that order later, for example with a scheduled action.
  • Storage. Media uploads are public URLs. The random file name keeps them unguessable, but you can also store the files privately and delete them once your partner has fetched them.
  • Idempotency. The _print_job_id check stops the same order being sent twice when its status changes again.

Example: personalised book covers with Lulu

A common case: customers personalise only the cover of a notebook or book, and the interior PDF is the same for every order.
1

Design the cover as the full spread

Lulu prints the cover from one PDF page holding the back cover, spine and front cover, plus bleed. Size the Print.App design to the cover dimensions Lulu gives for your trim size and page count. Your interior is fixed, so the spine width is fixed too.
2

Let customers change only the front

Lock the back-cover and spine elements with the object lock settings, so customers can only personalise the front.
3

Match Lulu's file requirements

Assign the design a PDF output profile that matches Lulu’s requirements, such as the PDF version and colour profile.
4

Create the print job

In my_create_print_job, create a Lulu print job with one line item per cover: the stored cover URL, your fixed interior PDF URL and your book’s product specification. Check Lulu’s API documentation for the exact request.
5

Test before you go live

Place a test order and run the cover through Lulu’s file validation. That confirms the spread size and spine are right for your book.

Why not the “Project created” webhook?

The Project created webhook fires the first time a project is saved. That can be an autosave, before the customer has finished and before any order exists. It’s useful for notifications, but for fulfilment start from the paid order as above.