diff --git a/userguide/assets/img/invoice_templates/catalog_translation.png b/userguide/assets/img/invoice_templates/catalog_translation.png index 7199e5109..128f2b9a7 100644 Binary files a/userguide/assets/img/invoice_templates/catalog_translation.png and b/userguide/assets/img/invoice_templates/catalog_translation.png differ diff --git a/userguide/assets/img/invoice_templates/custom_invoice_template.png b/userguide/assets/img/invoice_templates/custom_invoice_template.png index 2b16fb561..47bcd6cc6 100644 Binary files a/userguide/assets/img/invoice_templates/custom_invoice_template.png and b/userguide/assets/img/invoice_templates/custom_invoice_template.png differ diff --git a/userguide/assets/img/invoice_templates/custom_invoice_translation.png b/userguide/assets/img/invoice_templates/custom_invoice_translation.png new file mode 100644 index 000000000..202866f7b Binary files /dev/null and b/userguide/assets/img/invoice_templates/custom_invoice_translation.png differ diff --git a/userguide/assets/img/invoice_templates/html-invoice.png b/userguide/assets/img/invoice_templates/html-invoice.png new file mode 100644 index 000000000..69b426d70 Binary files /dev/null and b/userguide/assets/img/invoice_templates/html-invoice.png differ diff --git a/userguide/assets/img/invoice_templates/invoice_html_config.png b/userguide/assets/img/invoice_templates/invoice_html_config.png deleted file mode 100644 index 081190b03..000000000 Binary files a/userguide/assets/img/invoice_templates/invoice_html_config.png and /dev/null differ diff --git a/userguide/assets/img/invoice_templates/view_html_invoice.png b/userguide/assets/img/invoice_templates/view_html_invoice.png index f7a0f24ab..a41b71cd0 100644 Binary files a/userguide/assets/img/invoice_templates/view_html_invoice.png and b/userguide/assets/img/invoice_templates/view_html_invoice.png differ diff --git a/userguide/tutorials/invoice_templates.adoc b/userguide/tutorials/invoice_templates.adoc index 456642632..33ca4dc77 100644 --- a/userguide/tutorials/invoice_templates.adoc +++ b/userguide/tutorials/invoice_templates.adoc @@ -1,153 +1,303 @@ = Invoice Templates -Kill Bill invoices can be rendered as HTML using our https://apidocs.killbill.io/#invoice-render-an-invoice-as-html[render HTML invoice API]. This can be useful, for instance, to show the invoices directly to your customer on the billing section of your website. This document explains how to configure custom invoice templates. +Kill Bill invoices can be rendered as HTML using the https://apidocs.killbill.io/#invoice-render-an-invoice-as-html[render HTML invoice API]. This can be useful, for instance, to show the invoices directly to your customer on the billing section of your website. This document explains how to configure custom invoice templates. == Invoice Template Configuration Overview Kill Bill uses the https://mustache.github.io/[mustache] engine for generating HTML invoices. -There are two main components while generating an HTML invoice: +There are three things you can customize when generating an HTML invoice: -* *A template*: This constitutes the body of the template. It includes static text as well as variables which are replaced at runtime by the https://mustache.github.io/[mustache] engine. +- **A template**: This constitutes the body of the template. It includes static text as well as variables which are replaced at runtime by the https://mustache.github.io/[mustache] engine. -* *A resource bundle*: This includes one or more files that specify translations corresponding to a locale. You can read the https://docs.killbill.io/latest/internationalization.html#_language_translations[Kill Bill Internationalization] document to know more about resource bundles. +- **Translation files**: This includes one or more files that specify translations corresponding to a locale. Invoice translations supply the text strings used in the invoice template itself — labels like "Invoice Date" or "Balance". You can read the https://docs.killbill.io/latest/internationalization.html#_language_translations[Kill Bill Internationalization] document to know more about resource bundles. -== Defaults +- **Branding information**: Company details, appearance/style, and logo, which can be set as a tenant-wide default and optionally overridden per template. -Kill Bill provides a https://github.com/killbill/killbill/blob/99f7102c83cefe892027f4ac0d1ab4da37dd517b/util/src/main/resources/org/killbill/billing/util/email/templates/HtmlInvoiceTemplate.mustache[default invoice template] which looks like this: +Kill Bill ships with a default template, translations, and branding out of the box — see below for how to customize any of them. -image::https://github.com/killbill/killbill-docs/raw/v3/userguide/assets/img/invoice_templates/invoice_html.png[align=center] +== Managing Templates, Translations & Branding via Aviate -However, users can upload their own custom templates. +While templates, translations, and branding information can all be uploaded directly via the Kill Bill API or Kaui, **https://aviate.killbill.io/[Aviate]** — the premium UI/plugin layer on top of Kill Bill — is the recommended way to manage all three. Aviate provides a guided experience with a live invoice preview, inheritance indicators, and inline validation. -In addition, Kill Bill also provides a https://github.com/killbill/killbill-email-notifications-plugin/tree/6fc76403233fd5be290841ee6fc9d728028892f0/src/main/resources/org/killbill/billing/plugin/notification/translations[default resource file]. This file contains translation strings corresponding to the https://github.com/killbill/killbill/blob/99f7102c83cefe892027f4ac0d1ab4da37dd517b/util/src/main/resources/org/killbill/billing/util/email/templates/HtmlInvoiceTemplate.mustache[default template] and the `en_US` locale. Users can also upload their own resource files. +[NOTE] +Before you can configure templates, translations, or branding via Aviate, the Kill Bill instance must first be added as a deployment. See https://docs.killbill.io/latest/aviate-deployment-management[Aviate Deployment Management] for details. -== Customizing Invoice Template +=== Organization-level branding -This section explains how you can upload your own invoice template/translation resource bundle. +1. Navigate to **Configuration → Settings** in Aviate. + +2. Set the tenant-wide defaults for company information and appearance (logo, primary brand color). These apply to all templates (invoices, emails, and quotes) by default, and can be overridden per template. + +//TODO - Add storylane demo + +=== Invoice-template-level template, branding, and translations + +Under **Configuration → Invoices**, configure the invoice template as follows: + +1. Override company information and appearance for this template only, if required. Fields are pre-filled from the organization-level settings, with an indicator showing which are inherited versus overridden. + +2. Customize style details such as text color, table heading background/text color, and table border color. + +3. Select the desired language from the translations drop-down and modify the translations as required. + +4. Use the live invoice preview panel to confirm your changes render as expected. + +5. Click **Save Template** to save the changes. + +6. Advanced users can also edit the underlying mustache template directly via **Advanced View**, instead of the structured fields in steps 1–3. This is not recommended unless you are familiar with the mustache template engine. + +//TODO - Add storylane demo + + + +== Managing Invoice Template, Translations & Branding via API/Kaui + +If you are not using Aviate, or need to script/automate these uploads, you can manage the template, translations, and branding directly through the Kill Bill API or Kaui, as described below. At a high-level, you need to execute the steps given below: -. Upload the invoice template -. Upload the translation for all the supported locales -. Upload the catalog translation for all the locales (if required) +1. Upload the invoice template -Let us look at each step in detail. +2. Upload the translation for all the supported locales -. Upload the invoice template: +3. Upload the catalog translation for all the locales (if required) -.. Create a file `$SOME_PATH_PREFIX/HtmlInvoiceTemplate.mustache` as follows: +4. Optionally, upload branding information via the API -+ +=== Step 1 - Upload Invoice Template -[source,bash] +1. Create a file `$SOME_PATH_PREFIX/HtmlInvoiceTemplate.mustache` as follows: ++ +[source,html] ---- + - - - - -

{{text.invoiceTitle}}

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Insert image here - - -
- {{text.invoiceDate}}{{invoice.formattedInvoiceDate}}
- {{text.invoiceNumber}}{{invoice.invoiceNumber}}
{{text.companyName}}{{text.accountOwnerName}}{{account.name}}
{{text.companyAddress}} - - {{account.email}}
{{text.companyCityProvincePostalCode}} - - {{account.phone}}
{{text.companyCountry}} - - -
<{{text.companyUrl}} - - -
-
-
-
- - - - {{#invoice.invoiceItems}} - - - + + + {{text.invoiceTitle}} + + + +
+ +
{{text.invoiceItemBundleName}} - {{text.invoiceItemDescription}} - {{text.invoiceItemServicePeriod}} - {{text.invoiceItemAmount}} -
{{description}}{{planName}}
+ + + + + + + + + + + + {{#invoice.invoiceItems}} + - + + - {{/invoice.invoiceItems}} - - - - - - - - - - - - - - -
+ + + + + + +
+ + + {{text.invoiceTitle}} INV#{{invoice.invoiceNumber}}
+ {{text.invoiceDate}}{{invoice.formattedInvoiceDate}} +
+
+ + + + + + +
+ {{company.companyName}}
+ {{company.companyAddress}}
+ {{company.companyCityProvincePostalCode}}
+ {{company.companyCountry}} +
+ {{#account.name}}{{account.name}}
{{/account.name}} + {{#account.companyName}}{{account.companyName}}
{{/account.companyName}} + {{#account.address1}}{{account.address1}}
{{/account.address1}} + {{#account.city}}{{account.city}}{{#account.stateOrProvince}}, {{account.stateOrProvince}}{{/account.stateOrProvince}} {{account.postalCode}}
{{/account.city}} + {{account.country}} +
+
{{text.invoiceItemServicePeriod}}{{text.invoiceItemDescription}}{{text.invoiceItemAmount}}
{{formattedStartDate}}{{#formattedEndDate}} - {{formattedEndDate}}{{/formattedEndDate}}{{invoice.currency}} {{amount}}{{prettyPlanName}}{{formattedAmount}}
-
- {{text.invoiceAmount}}{{invoice.chargedAmount}}
- {{text.invoiceAmountPaid}}{{invoice.paidAmount}}
- {{text.invoiceBalance}}{{invoice.balance}}
- + {{/invoice.invoiceItems}} + + + + {{text.invoiceAmount}}{{invoice.formattedChargedAmount}} + + + + + {{text.invoiceAmountPaid}}{{invoice.formattedPaidAmount}} + + + + + {{text.invoiceBalance}}{{invoice.formattedBalance}} + + + + ---- - + - -.. Upload the file via the following `cURL` command: - +2. Upload the file either via API call or Kaui. ++ +a. To upload via API, execute the following `cURL` command: + - [source,bash] ---- -curl -v \ + curl -v \ -u admin:password \ -H "X-Killbill-ApiKey: bob" \ -H "X-Killbill-ApiSecret: lazar" \ @@ -157,26 +307,16 @@ curl -v \ --data-binary @$SOME_PATH_PREFIX/HtmlInvoiceTemplate.mustache \ http://127.0.0.1:8080/1.0/kb/invoices/template ---- - + - -.. Alternatively, you can upload this file via Kaui by going to your admin tenant page (`InvoiceTemplate`) tab: - +b. To upload via Kaui, go to `InvoiceTemplate` tab on the admin tenant page: + - image::https://github.com/killbill/killbill-docs/raw/v3/userguide/assets/img/invoice_templates/custom_invoice_template.png[align=center] -+ - -. Upload the invoice translation for the desired locale. For instance, in order to upload the translation for the locale `fr_FR`: - -+ - -.. Create a file `$SOME_PATH_PREFIX/InvoiceTranslation_fr_FR.properties` as follows: +=== Step 2- Upload Invoice Translations +1. Create a properties file for the desired locale (for example `fr_FR`) as follows: + - -[source,bash] +[source,properties] ---- invoiceEmailSubject=Nouvelle Facture invoiceTitle=FACTURE @@ -185,15 +325,8 @@ invoiceNumber=Facture # invoiceAmount=Montant à payer invoiceAmountPaid=Montant payé invoiceBalance=Nouveau montant - accountOwnerName=Chauffeur -companyName=Killbill, Inc. -companyAddress=P.O. Box 1234 -companyCityProvincePostalCode=Springfield -companyCountry=USA -companyUrl=http://kill-bill.org - invoiceItemBundleName=Armes invoiceItemDescription=Description invoiceItemServicePeriod=Période de facturation @@ -202,13 +335,11 @@ invoiceItemAmount=Montant processedPaymentCurrency=(*) Le payment à été payé en processedPaymentRate=Le taux de conversion est ---- - + - -.. Upload the file via the following `cURL` command: - +2. Upload the file either via API call or Kaui. ++ +a. To upload via API, execute the following `cURL` command: + - [source,bash] ---- curl -v \ @@ -221,40 +352,31 @@ curl -v \ --data-binary @$SOME_PATH_PREFIX/InvoiceTranslation_fr_FR.properties \ http://127.0.0.1:8080/1.0/kb/invoices/translation/fr_FR ---- - + - -.. Alternatively, you can upload this file via Kaui by going to your admin tenant page (`InvoiceTranslation`) tab: - +b. To upload via Kaui go to the `InvoiceTranslation` tab on the admin tenant page: + -image::https://github.com/killbill/killbill-docs/raw/v3/userguide/assets/img/invoice_templates/invoice_html_config.png[align=center] - +image::https://github.com/killbill/killbill-docs/raw/v3/userguide/assets/img/invoice_templates/custom_invoice_translation.png[align=center] + - Additional resource files can be uploaded for different locales as required. -+ - -. In addition to the invoice template translation, you can also upload a catalog translation file. +=== Step 3 - Upload Catalog Translations -+ +Catalog translations are different from invoice translations covered above. While invoice translations supply the text strings used in the invoice template itself, catalog translations supply the localized names of catalog entities, such as plan names (e.g. `Gold plan` translated as `Plan Or` in French), which are then substituted into the rendered invoice. -.. Create a catalog translation for locale `fr_FR` as follows: +Catalog translations are optional. If you don't upload one for a given locale, the invoice falls back to the plan names as defined in the catalog. +1. Create a catalog translation for the desired locale (for example `fr_FR`) as follows: + - -[source,bash] +[source, properties] ---- gold-monthly = plan Or mensuel ---- - + - -.. Upload the file via the following `cURL` command: - +2. Upload the file via API call or Kaui. ++ +a. To upload via API, execute the following `cURL` command: + - [source,bash] ---- curl -v \ @@ -267,25 +389,114 @@ curl -v \ --data-binary @$SOME_PATH_PREFIX/CatalogTranslation_fr_FR.properties \ http://127.0.0.1:8080/1.0/kb/invoices/catalogTranslation/fr_FR ---- - + +b. Alternatively, you can upload this file via Kaui by going to your admin tenant page (`CatalogTranslation`) tab: ++ +image::https://github.com/killbill/killbill-docs/raw/v3/userguide/assets/img/invoice_templates/catalog_translation.png[align=center] -.. Alternatively, you can upload this file via Kaui by going to your admin tenant page (`CatalogTranslation`) tab: +=== Step 4 - Upload Branding Information -+ +Branding fields (company info, style, logo) can be set directly using the https://apidocs.killbill.io/tenant.html#add-a-per-tenant-user-key-value[per-tenant user key/value endpoint]. -image::https://github.com/killbill/killbill-docs/raw/v3/userguide/assets/img/invoice_templates/catalog_translation.png[align=center] +Refer to the following table for the keys: + +| Key | Description | +|---|---| +| `COMPANY_INFO` | Organization-level (global default) company information | +| `LOGO_INFO` | Organization-level (global default) logo | +| `BRAND_INFO` | Organization-level (global default) style/brand information. Only accepts the `tableHeadingBgColor` field. | +| `INVOICE_TEMPLATE_COMPANY_INFO` | Invoice-template-level company information (overrides `COMPANY_INFO`) | +| `INVOICE_TEMPLATE_LOGO_INFO` | Invoice-template-level logo (overrides `LOGO_INFO`) | +| `INVOICE_TEMPLATE_BRAND_INFO` | Invoice-template-level style/brand information (overrides `BRAND_INFO`). Accepts all 4 fields: `textColor`, `tableBorderColor`, `tableHeadingBgColor`, `tableHeadingTextColor`. | -+ -. Generate an HTML invoice. +Each type of information is sent as a JSON payload. To override any of the three at the invoice-template level instead of organization-wide, use the corresponding `INVOICE_TEMPLATE_*` key instead. +1. Company information is uploaded to the `COMPANY_INFO` key (or `INVOICE_TEMPLATE_COMPANY_INFO` for a template-level override) as follows: ++ +a. Define the JSON payload: ++ +[source, json] +---- +{"companyName":"CloudSprout","companyAddress":"East Street","companyCityProvincePostalCode":"New York","companyCountry":"United States","companyUrl":"cloudsprout.com"} +---- ++ +b. Upload the payload via the following `cURL` command: ++ +[source,bash] +---- +curl -v \ + -X POST \ + -u admin:password \ + -H "X-Killbill-ApiKey: bob" \ + -H "X-Killbill-ApiSecret: lazar" \ + -H "Content-Type: application/json" \ + -H 'X-Killbill-CreatedBy: admin' \ + -d '{"companyName":"CloudSprout","companyAddress":"East Street","companyCityProvincePostalCode":"New York","companyCountry":"United States","companyUrl":"cloudsprout.com"}' \ + http://127.0.0.1:8080/1.0/kb/tenants/userKeyValue/COMPANY_INFO +---- ++ +2. Style/brand information is uploaded to the `BRAND_INFO` key (or `INVOICE_TEMPLATE_BRAND_INFO` for a template-level override) as follows: ++ +a. Define the JSON payload: ++ +[source, json] +---- +{"textColor":"red","tableBorderColor":"blue","tableHeadingBgColor":"yellow","tableHeadingTextColor":"green"} +---- ++ +b. Upload the payload via the following `cURL` command: ++ +[source,bash] +---- +curl -v \ + -X POST \ + -u admin:password \ + -H "X-Killbill-ApiKey: bob" \ + -H "X-Killbill-ApiSecret: lazar" \ + -H "Content-Type: application/json" \ + -H 'X-Killbill-CreatedBy: admin' \ + -d '{"textColor":"red","tableBorderColor":"blue","tableHeadingBgColor":"yellow","tableHeadingTextColor":"green"}' \ + http://127.0.0.1:8080/1.0/kb/tenants/userKeyValue/INVOICE_TEMPLATE_BRAND_INFO +---- ++ +[NOTE] +Note: `BRAND_INFO` only accepts the `tableHeadingBgColor` field — the other style fields (`textColor`, `tableBorderColor`, `tableHeadingTextColor`) are only available at the invoice-template level, via `INVOICE_TEMPLATE_BRAND_INFO`. ++ +3. The logo is uploaded to the `LOGO_INFO` key (or `INVOICE_TEMPLATE_LOGO_INFO` for a template-level override) as a base64-encoded data URI: ++ +a. Define the JSON payload: ++ +[source, json] +---- +{"logo":"data:image/png;base64,/9j/4AAQSk..."} +---- + +b. Upload the payload via the following `cURL` command: ++ +[source,bash] +---- +curl -v \ + -X POST \ + -u admin:password \ + -H "X-Killbill-ApiKey: bob" \ + -H "X-Killbill-ApiSecret: lazar" \ + -H "Content-Type: application/json" \ + -H 'X-Killbill-CreatedBy: admin' \ + -d '{"logo":"data:image/png;base64,/9j/4AAQSk..."}' \ + http://127.0.0.1:8080/1.0/kb/tenants/userKeyValue/LOGO_INFO +---- -.. Execute the following `cURL` command: +== Testing Your Changes -+ +No matter how you configure your template, translations, or branding, you'll want to confirm the changes render as expected before using them in production. + +If you configured things via Aviate, use the live invoice preview panel in the template editor — it reflects your changes as you make them, without needing to generate a separate invoice. + +If you configured things via the API or Kaui, generate an HTML invoice to verify the result: +1. Execute the following `cURL` command: ++ [source,bash] ---- curl -v \ @@ -296,14 +507,14 @@ curl -v \ -H 'X-Killbill-CreatedBy: admin' \ "http://127.0.0.1:8080/1.0/kb/invoices/1785b3d5-24b3-4d17-94ce-310aeb74bc63/html" ---- - + - -.. Alternatively, you can generate the HTML invoice via `Invoices` tab in Kaui: - +2. Alternatively, you can generate the HTML invoice via the `Invoices` tab in Kaui: + - image::https://github.com/killbill/killbill-docs/raw/v3/userguide/assets/img/invoice_templates/view_html_invoice.png[align=center] ++ +This displays the invoice in a new browser tab, which you can then inspect to confirm your changes. ++ +image::https://github.com/killbill/killbill-docs/raw/v3/userguide/assets/img/invoice_templates/html_invoice.png[align=center] == Customizing Invoice Data @@ -311,13 +522,8 @@ Sometimes, you may need to customize the data in the invoice (add additional fie == Further Information -* https://docs.killbill.io/latest/internationalization.html[_Kill Bill Internationalization_] - -* https://apidocs.killbill.io/#invoice-translation[_Invoice Translation Slate Documentation_] - -* https://apidocs.killbill.io/#invoice-render-an-invoice-as-html[_Invoice Generation Slate Documentation_] - - - +- https://docs.killbill.io/latest/internationalization.html[*Kill Bill Internationalization*] +- https://apidocs.killbill.io/#invoice-translation[*Invoice Translation Slate Documentation*] +- https://apidocs.killbill.io/#invoice-render-an-invoice-as-html[*Invoice Generation Slate Documentation*]