yarn install vendure-plugin-invoices
- Add the following config to your
vendure-config.ts
:
plugins: [
InvoicePlugin.init({
licenseKey: processs.env.LICENSE,
vendureHost: 'http://localhost:3106',
}),
AdminUiPlugin.init({
port: 3002,
route: 'admin',
app: compileUiExtensions({
outputPath: path.join(__dirname, '__admin-ui'),
extensions: [InvoicePlugin.ui],
}),
}),
];
- Run a migration, to add the Invoice and InvoiceConfig
entities to the database.
- Start Vendure and login to the admin dashboard
- Make sure you have the permission
AllowInvoicesPermission
- Go to
Sales > Invoices
.
- Unfold the
Settings
accordion.
- Check the checkbox to
Enable invoice generation
for the current channel on order placement.
- A default HTML template is set for you. Click the
Preview
button to view a sample PDF invoice.
If you are using Docker with node:16 or higher as base, you need to add this to your Dockerfile:
# PhantomJS fix https://github.com/bazelbuild/rules_closure/issues/351
ENV OPENSSL_CONF=/dev/null
Adding invoices to your order-confirmation email
Add the following link to your email template:
https://<your server>/invoices/e2e-default-channel/C7YH7WME4LTQNFRZ?email=hayden.zieme12@hotmail.com
.
When the customer clicks the link, the server will check if the ordercode
, channelCode
and customer emailaddress
match with the requested order. If so, it will return the invoice.
Google Storage strategy
This plugin also includes a strategy for storing invoices in Google Storage:
yarn add @google-cloud/storage
InvoicePlugin.init({
vendureHost: 'http://localhost:3050',
storageStrategy: new GoogleStorageInvoiceStrategy({
bucketName: 'bucketname',
}),
});
The strategy will use the projectId and credentials in from your environment, which is useful for Google Cloud Run or
Cloud Functions.
However, if you want to run it locally or on a custom environment, you need to pass a keyFile to the plugin. This is
needed to generate signedUrls, which are used to give customers temporary access to a file on Storage. More info about
locally using signedUrls: https://github.com/googleapis/nodejs-storage/issues/360
import {
InvoicePlugin,
GoogleStorageInvoiceStrategy,
} from 'vendure-plugin-invoices';
InvoicePlugin.init({
vendureHost: 'http://localhost:3050',
storageStrategy: new GoogleStorageInvoiceStrategy({
bucketName: 'bucketname',
storageOptions: {
keyFilename: 'key.json',
},
}),
});
Amazon S3 Storage strategy
This plugin also includes a strategy for storing invoices on Amazon S3.
yarn add aws-sdk
import { InvoicePlugin, S3StorageStrategy } from 'vendure-plugin-invoices';
InvoicePlugin.init({
vendureHost: 'http://localhost:3050',
storageStrategy: new S3StorageStrategy({
expiresInSeconds: 360,
}),
});
Custom file storage
Implement your own strategy for storing invoices by implementing one of these interfaces:
Remote storage strategy
RemoteStorageStrategy
for storing PDF files on an external platform like Google Cloud or S3. It redirects the user to
a public/authorized URL for the user to download the invoice PDF.
import { RemoteStorageStrategy, zipFiles } from 'vendure-plugin-invoices';
export class YourRemoteStrategy implements RemoteStorageStrategy {
async save(
tmpFile: string,
invoiceNumber: number,
channelToken: string
): Promise<string> {
return 'unique-reference';
}
async getPublicUrl(invoice: InvoiceEntity): Promise<string> {
return 'https://your-signed-url/invoice.pdf';
}
async streamMultiple(
invoices: InvoiceEntity[],
res: Response
): Promise<ReadStream> {
const zipped = zipFiles(files);
return createReadStream(zipped);
}
}
Local file storage
LocalFileStrategy
streams the invoice through the Vendure service to the user.
import { LocalStorageStrategy, zipFiles } from 'vendure-plugin-invoices';
export class YourLocalStrategy implements LocalStorageStrategy {
async save(tmpFile: string, invoiceNumber: number, channelToken: string) {
return 'new/path.pdf';
}
async streamMultiple(
invoices: InvoiceEntity[],
res: Response
): Promise<ReadStream> {
const zipFile = await zipFiles(files);
return createReadStream(zipFile);
}
async streamFile(invoice: InvoiceEntity, res: Response): Promise<ReadStream> {
return createReadStream(invoice.storageReference);
}
}
Custom invoice numbering and custom data
Implement the DataStrategy
to pass custom data to your template or generate custom invoice numbers:
export class DefaultDataStrategy implements DataStrategy {
async getData({
ctx,
injector,
order,
latestInvoiceNumber,
}: DataFnInput): Promise<InvoiceData> {
return {
invoiceNumber: String(Math.floor(Math.random() * 90000) + 10000),
customerEmail: 'just used for admin display',
order,
someCustomField: '2022',
};
}
}
You can access this data in your HTML template using Handlebars.js:
<h1>{{ someCustomField }}</h1>