Dev GuideAPI Reference
Dev GuideAPI ReferenceUser GuideGitHubNuGetDev CommunitySubmit a ticketLog In
GitHubNuGetDev CommunitySubmit a ticket

Custom PDF implementation

Describes an approach to creating custom PDF generation within the Optimizely Commerce Cloud platform.

Use Cases

  • A customer would like to generate a PDF that represents the current items in the cart, as this functionality is not in the base platform.
  • A customer would like to create a PDF that shows the top ten most purchased products for a given category.
  • A customer would like to create a PDF that shows a category’s marketing content.

Create a custom PDF

The create a custom PDF, a developer will need to modify a custom view template, modify a custom TypeScript controller and create a custom API controller.

Modify a custom view template

Add a line to your custom view template, where you want the end-user to trigger the PDF via a button or another action on the page. The getPdf() method will exists on your custom TypeScript controller.

Code Sample

<a href="#" ng-click="vm.getPdf()">View Cart as PDF</a>

Modify the TypeScript controller

Add your getPdf() method to your TypeScript controller, that facilitates calling out to your custom API controller.

Code Sample

getPdf() {
      let url = "/api/CustomCartV1/GetPdf";
      if (this.accessToken.exists()) {
        uri += "?access_token=" + encodeURIComponent(this.accessToken.get());
      }, "_blank");

Modify the custom API controller

Modify your custom API controller by adding a method to be called asynchronously.

Code Sample

    public HttpResponseMessage GetPdf()
      var pdfStream = new MemoryStream();
      string renderedHtml = this.GetPdfHtml();
      PdfGeneratorHelper.GeneratePdf(renderedHtml, pdfStream);
      var response = Request.CreateResponse(HttpStatusCode.OK);
      response.Content = new StreamContent(pdfStream);
      response.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("inline");
      response.Content.Headers.ContentDisposition.FileName = "ShoppingCart.pdf";
      response.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream");
      return response;

Implement your GetPdfHtml() method to return your PDF view as HTML. This method would be a member of the following API class:

Code Sample

[System.Web.Http.RoutePrefix("api/ CustomCartV1")]
    public class CustomCartController : BaseApiController

Code Sample

private string GetPdfHtml()
      var theme = this.UnitOfWork.GetRepository<Theme>().Get(SiteContext.Current.WebsiteDto.ThemeId);
      var themeSourceName = theme.ThemeSource == null
      ? (theme.IsSystemTheme ? "System" : "User")
      : theme.ThemeSource.Name;
      // Generate cart pdf html.
      var templatePath = $"~/frontendresources/{themeSourceName}/{theme.Name}/pdfviews/CartPdfTemplate.cshtml";
      var getByPathParameter = new GetByPathParameter { Path = templatePath };
      var getByPathResult =
    var cartModelJson = cartModel.ToJson(false);
    dynamic cartModelDynamic = cartModelJson.ToExpando();
      var viewHtml = getByPathResult.ThemeContentDto != null
      ? getByPathResult.ThemeContentDto.Content
      : string.Empty;
      var renderedViewHtml =
      this.EmailService.ParseTemplate(viewHtml, cartModelDynamic);
      return renderedViewHtml;

Add or modify the custom PDF view template

The custom template that represents the PDF view you’re presenting, needs to be in DotLiquid format and needs to be of the Razor view extension .cshtml. The template will also need to be located at the following location:

This path would resolve to the following structure in your project directory structure:
YourThemeProjectRoot/PdfViews/CartPdfTemplate.cshtml, but Configured Commerce will handle locating this for you with the Theme Content Provider.

Code Sample

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "">
<html xmlns="">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>[% translate 'Share Order' %]</title>
      body {
        font-family: Helvetica, Arial, Sans-Serif;
        font-size: 16px;
        color: #252525;
    [% if Model.LogoImagePath != null and Model.LogoImagePath != "" -%]
        <img src="[[Model.LogoImagePath]]" max-height="150" max-width="300" alt="Company Logo" />
    [% endif -%]