PrintNowPrintNowDocs
PDF Engine

Merge Engine

How PrintNow assembles individual product pages into final order PDFs using local and remote merge services.

The Merge Engine is responsible for turning individual product page PDFs into final, print-ready order files. When a customer places an order, the merge engine renders each product's design into PDF pages via PNPDF, assembles them into a single file per product, and delivers the output to Azure Blob Storage for download and fulfillment.

PrintNow supports two merge paths — a local in-process merge and a remote Azure-hosted service — selected automatically by configuration.

Merge Flow

When an order is placed through the storefront checkout, the merge engine is triggered:

  1. Order submitted — the checkout API initiates the merge.
  2. Merge path selected — the system checks MergeServiceClient.ShouldBeUsed() to determine local or remote processing.
  3. Product rendering — for each product in the order, PdfManager renders the design into PDF pages using PNPDF.
  4. Page assembly — individual pages are assembled into a single PDF per product.
  5. Completion — status is updated, notification emails are sent, and print MIS integrations (Presswise, OneFlow, SiteFlow) are triggered.

Local vs. Remote Merge

Local Merge

The local merge runs as an in-process background thread on the web server:

  • MergeManager queues merge operations and runs them on a background thread with below-normal priority.
  • OrderMerge iterates through all products in the order, creating a ProductMerge for each.
  • ProductMerge calls PdfManager.Export() or PdfManager.ExportSinglePages() to generate output.
  • Completion handlers execute synchronously after the merge finishes (e.g., Presswise submission).

This path is used for local file system deployments or when the remote service is not configured.

Remote Merge (Azure Service)

The remote merge offloads PDF processing to a dedicated Azure service for improved performance and scalability:

  • MergeServiceClient submits a MergeJobRequest to the remote service with a callback URL.
  • The remote service processes the merge asynchronously.
  • On completion, the service calls the MergeCompleteHandler webhook at /api/merge-complete.
  • The webhook validates the request (API key + storefront identity), then triggers print MIS submission.

This path is used for Azure-hosted deployments where files reside in Blob Storage. It prevents the web server from being bottlenecked by CPU-intensive PDF operations.

Merge Job Request

When submitting a remote merge, the following parameters are sent:

FieldDescription
JobTypeThe merge type: OrderMerge (all products in an order) or ProductMerge (single product).
OrderIdThe order being merged.
OrderProductIdSpecific product to merge (for product-level merges).
StorefrontIdThe tenant storefront.
LicenseIdLicense key for stock photo purchases (DepositPhotos) during merge.
OutputPathRoot directory for merged PDF output.
CompileOutputWhen true, generates a single multi-page PDF. When false, generates individual page files that are assembled into a final PDF.
LargeFormatEnables page sizes larger than 18 inches.
MultiPageEnables multi-page product output.
AvantiEnables Avanti print MIS integration with XML manifest output.
CallbackUrlThe webhook URL called when the merge completes.

Export Modes

PdfManager supports two export modes:

Compiled Export

PdfManager.Export() renders all product pages into a single multi-page PDF returned as a MemoryStream. This is the preferred mode when the deployment supports in-memory processing.

Single Page Export

PdfManager.ExportSinglePages() writes individual files named P{productId}.{pageNumber}.pdf to the output directory. After all pages are written, the individual page files are assembled into a final P{productId}.pdf.

Merge Status

Each product in an order tracks its merge progress through four states:

StatusValueDescription
Not Merged0The product has not been merged yet. The order was just placed or the merge has not started.
Currently Merging1The merge is in progress. PdfManager is rendering pages and assembling the output.
Merge Complete2The merge finished successfully. The final PDF is available for download.
Merge Error3The merge failed. Check the error log for details.

The merge status can be polled via the storefront endpoint ~/mergestatus.ashx?p={productId}&t=json.

Output Structure

Merged files are organized by order and product:

Orders Directory/
├── Order {orderId}/
│   ├── Order {orderId}.xml          (optional order detail file)
│   ├── Product {productId}/
│   │   ├── P{productId}.pdf         (final merged PDF)
│   │   └── DataList.csv             (if variable data product)
│   └── Product {productId}({index})/
│       └── P{productId}.pdf         (duplicate product in same order)

Special Product Types

The merge engine handles several product types differently:

Product TypeMerge Behavior
StandardRenders product design via PdfManager, exports as compiled or single-page PDF.
Photo RetouchCopies the pre-rendered retouched image directly to the output directory.
BookMerges separate cover and interior page PDFs into a single output.
Static / Print on DemandUses a pre-generated PDF file if available, bypassing the rendering pipeline.
Data ListExports CSV data (LeadsPlease, AccuZip) alongside the merged PDF for variable data printing.

Post-Merge Integrations

After a successful merge, the engine triggers:

  • Download Ready Email — notifies the customer that their order files are ready (configurable per storefront).
  • Presswise — submits the order to the Presswise print MIS for production scheduling.
  • OneFlow / SiteFlow — alternative print MIS integrations.
  • Avanti — compiles merged files into an Avanti-compatible hot folder structure with XML manifest.
  • Order Detail Output — generates XML, JSON, or CSV order detail files (configurable format).
  • PDF Engine — overview of the PNPDF library powering PDF generation
  • Admin Remerge — trigger and monitor remerges from the admin UI
  • Orders — order management and fulfillment
  • Error Log — diagnose merge failures

On this page