Skip to main content

PDF Generator

Overview

The PDF Generator integration allows you to automatically generate a professional PDF shipping label when a customer submits a return request. The label is generated from a customizable HTML template, and can include both barcodes and QR codes for easy package tracking.


Step 1: Enable the PDF Generator Integration

  1. Go to your project’s Integrations page.
  2. Under “Out-of-the-Box Integrations,” check the box for PDF Generator (HTML Template).
  3. Click the ⚙️(gear) icon to configure your templates.

Step 2: Add a New Template

  1. In the PDF Generator Templates dialog, click Add New Template.
  2. Enter a Template Name (for example, productReturn).
  3. Paste your HTML template in the editor. You can use template variables such as {{ sender_name }}, {{ order_number }}, and more (see below for all supported variables).
  4. Click Save.

Tip: You can use the sample HTML template below as a starting point.


Step 3: Configure Your Return Flow

When your return form (Make_a_Return_of_a_product) is submitted, you must call the template_to_pdf function with:

  • templateName: "productReturn" (required—must match the name of your template)

  • context: A JSON object built from the submitted form data.

    • Hard code "barcode_number": "203865"
    • Hard code "qrcode_text": "https://ecom.ai12z.com/?id=203865"
    • Add any optional parameters (see below)

Example context

"context": {
"order_number": "ATLS-2410772",
"reason": "Boots are too small, need a larger size.",
"refund_exchange": "Exchange for Size 11",
"sender_name": "Jamie Thornton",
"sender_address": "1234 Aspen Way",
"sender_city_state_zip": "Stowe, VT 05672",
"barcode_number": "203865",
"qrcode_text": "https://ecom.ai12z.com/?id=203865"
}

Optional parameters:

  • exchange_product_for — e.g., "A different size", "A different color", "A different brand"
  • size
  • color
  • brand

Important: Use the actual values from the form for the context, except barcode_number and qrcode_text which should be hardcoded as shown above.


After generating the PDF, your system should return the download link to the user in the bot/chat interface.

Do not include any extra thank you or confirmation messages with the link—only the link itself should be sent, or the user will not see the download option.


Sample HTML Template

Here’s a ready-to-use HTML template. You can customize the logo, colors, and company information as needed:

<!doctype html>
<html>
<head>
<meta charset="UTF-8" />
<title>Return Shipping Label</title>
<style>
@import url("https://fonts.googleapis.com/css?family=Montserrat:700,400&display=swap");
body {
font-family: "Montserrat", Arial, sans-serif;
background: #f9fafc;
color: #222;
margin: 0;
padding: 0;
}
.label-container {
width: 600px;
margin: 32px auto;
background: #fff;
border-radius: 14px;
box-shadow: 0 6px 24px rgba(36, 71, 107, 0.1);
border: 1.5px solid #e3e9ef;
padding: 36px 38px 28px 38px;
}
.logo {
width: 120px;
margin-bottom: 20px;
}
h1 {
font-size: 2rem;
margin-bottom: 10px;
color: #23436d;
letter-spacing: 0.04em;
}
.section-title {
font-size: 1.14rem;
font-weight: bold;
color: #3777b6;
margin: 24px 0 10px 0;
letter-spacing: 0.02em;
}
.address-block {
font-size: 1.07rem;
margin-bottom: 12px;
}
.label-row {
display: flex;
justify-content: space-between;
margin-bottom: 24px;
}
.order-details {
background: #f3f6fb;
border-radius: 8px;
padding: 16px 20px;
margin-top: 16px;
font-size: 1.06rem;
}
.contact-section {
margin-top: 32px;
padding-top: 18px;
border-top: 1.5px solid #e3e9ef;
color: #23436d;
}
.contact-title {
font-weight: bold;
font-size: 1.08rem;
margin-bottom: 7px;
}
.contact-item {
margin: 2px 0 2px 0;
}
.tracking {
font-size: 1rem;
margin-top: 14px;
letter-spacing: 0.02em;
}
.code-row {
display: flex;
gap: 28px;
align-items: center;
justify-content: flex-start;
margin-top: 14px;
margin-bottom: 10px;
}
.code-block {
display: flex;
flex-direction: column;
align-items: center;
}
.barcode {
width: 320px;
height: 60px;
object-fit: contain;
}
.qrcode {
width: 70px;
height: 70px;
object-fit: contain;
}
.code-label {
font-size: 1.05rem;
letter-spacing: 0.14em;
color: #2a3d53;
margin-top: 4px;
text-align: center;
}
</style>
</head>
<body>
<div class="label-container">
<img
class="logo"
width="120"
height="40"
src="https://ai12z.com/wp-content/uploads/2023/12/AI12z_homepage_logo.png"
alt="Atlas Logo"
/>
<h1>Return Shipping Label</h1>
<div class="label-row">
<div>
<div class="section-title">From:</div>
<div class="address-block">
{{ sender_name }}<br />
{{ sender_address }}<br />
{{ sender_city_state_zip }}
</div>
</div>
<div>
<div class="section-title">To:</div>
<div class="address-block">
Atlas Returns Department<br />
123 Demo Street<br />
Boston, MA 02115
</div>
</div>
</div>
<div class="tracking">
<strong>Tracking #:</strong> {{ tracking_number or "—" }}
</div>
{% if barcode_img or qrcode_img %}
<div class="code-row">
{% if barcode_img %}
<div class="code-block">
<img class="barcode" src="{{ barcode_img }}" alt="Barcode" />
<div class="code-label">{{ barcode_number }}</div>
</div>
{% endif %} {% if qrcode_img %}
<div class="code-block">
<img class="qrcode" src="{{ qrcode_img }}" alt="QR Code" />
</div>
{% endif %}
</div>
{% endif %}
<div class="order-details">
<div><strong>Order Number:</strong> {{ order_number }}</div>
<div><strong>Reason:</strong> {{ reason }}</div>
<div><strong>Requested Action:</strong> {{ refund_exchange }}</div>
{% if exchange_product_for %}
<div>
<strong>Exchange Product For:</strong> {{ exchange_product_for }}
</div>
{% endif %} {% if size %}
<div><strong>Size:</strong> {{ size }}</div>
{% endif %} {% if color %}
<div><strong>Color:</strong> {{ color }}</div>
{% endif %} {% if brand %}
<div><strong>Brand:</strong> {{ brand }}</div>
{% endif %}
</div>
<div class="contact-section">
<div class="contact-title">Contact Info</div>
<div class="contact-item">
47 Tremont Street, Suite 300<br />Boston, MA 02108<br />United States
</div>
<div class="contact-item">contact@atlas.com</div>
<div class="contact-item">+1&nbsp;234&nbsp;567&nbsp;890</div>
</div>
</div>
</body>
</html>

Template Rendering and Best Practices

Flexible Template System

The PDF Generator supports flexible template rendering that automatically adapts to different variable naming conventions. The system intelligently handles both clean variable names and field names with spaces or special characters.

Variable Naming Best Practices

sender_name, sender_address, order_number, barcode_number,
qrcode_text, shipping_address, order_date, product_sku,
customer_notes, exchange_product_for, tracking_number

❌ Avoid These Variable Names

"Sender Name", "order-number", "orderNumber", "Order#",
"Customer's Notes", "product/sku", "order.date"

Template Syntax Examples

Standard Templates (Direct Access)

<div>
<h1>Return Label for {{ sender_name }}</h1>
<p>Order: {{ order_number }}</p>
<p>Reason: {{ reason }}</p>

{% if tracking_number %}
<p>Tracking: {{ tracking_number }}</p>
{% endif %} {% if barcode_img %}
<img src="{{ barcode_img }}" alt="Barcode" />
<div>{{ barcode_number }}</div>
{% endif %}
</div>

Form Integration Templates (Context Access)

When integrating with forms that have field names with spaces, use context-based access:

<div>
<h1>Return Label for {{ context['Sender Name'] }}</h1>
<p>Order: {{ context.get('Order Number', 'N/A') }}</p>
<p>Reason: {{ context['Reason'] }}</p>

{% if context.get('Tracking Number') %}
<p>Tracking: {{ context['Tracking Number'] }}</p>
{% endif %} {% if context.get('barcode_img') %}
<img src="{{ context['barcode_img'] }}" alt="Barcode" />
<div>{{ context.get('Barcode Number', '') }}</div>
{% endif %}
</div>

Template Rendering Process

The system uses intelligent rendering that automatically selects the best approach:

try:
# Try direct variable access first (faster, cleaner)
rendered_html = Template(html_template).render(**context)
except TypeError:
# Fall back to context-based access (handles spaces in variable names)
rendered_html = Template(html_template).render(context=context)

When to Use Each Approach

Use Direct Access ({{ variable_name }}) when:

  • Creating new templates with clean variable names
  • You control the variable naming convention
  • Variable names follow snake_case convention

Use Context Access ({{ context['Variable Name'] }}) when:

  • Integrating with external forms or systems
  • Variable names contain spaces or special characters
  • Need graceful handling of missing variables with .get()

FAQ

Q: What variables can I use in the template? A: Any field you send in the context can be referenced with {{ field_name }} (direct access) or {{ context['Field Name'] }} (context access). Common fields: sender_name, order_number, barcode_number, qrcode_text, and any optional context parameter.

Q: Can I add more templates? A: Yes, you can add multiple templates and select the one to use by passing its name as the templateName parameter.

Q: What's the difference between {{ variable_name }} and {{ context['Variable Name'] }}? A: The first approach (direct access) is faster and cleaner but requires variable names without spaces. The second approach (context access) handles any variable name but is slightly slower. The system automatically tries both approaches.