Every month your bank sends you a statement, usually in PDF form, outlining all the transactions you made in that month. It shows your balance at the beginning and end of the month, that deposited birthday card check from your Aunt Jill 🤑, other deposits & withdrawals, and metadata such as the physical locations where you used an ATM. You've probably noticed that all other financial services you use such as credit cards, investment platforms, etc. also provide monthly financial statements with similar information in a similar format. A statement might look like this:
An example monthly financial statement we will generate with HTML and CSS below
What gives? Why do all these companies issue monthly financial statements? Because of regulation. Financial institutions are required to provide you a statement each month under the Electronic Fund Transfer Act (EFTA) / Regulation E (12 CFR Part 1005 to be specific). In this post, we'll dig into a few details in the EFTA, then show you how to generate compliant monthly statement PDFs with HTML, CSS, and React.
- The EFTA / Regulation E
- Periodic statements
- Required statement fields
- Generating monthly statement PDFs
- Key Takeaways
The Electronic Fund Transfer Act (EFTA) / Regulation E
The EFTA / Regulation E governs electronic transfers of assets made by "financial institutions." To the EFTA, a "financial institution" is any company that allows a customer to make electronic fund transfers defined as:
The term "electronic fund transfer" or "EFT" means any transfer of funds that is initiated through an electronic terminal, telephone, computer, or magnetic tape for the purpose of ordering, instructing, or authorizing a financial institution to debit or credit a consumer's account.
When the EFTA was passed in 1978, likely only a small percentage of institutions were making "electronic fund transfers" within this definition. In the modern world, and especially on the internet, every meaningful asset transaction is electronic and happens through an "electronic terminal." This applies to every online bank, investment platform, money transfer app, retirement product, and anything else dealing with other people's assets.
What about cryptocurrency? Turns out even crypto companies fall into the "financial institution" category based on a recent ruling in NY (Rider v. Uphold HQ Inc.). This ruling is New York-only for now, though it's safe to say that, long-term, all crypto companies will be viewed as "financial institutions" in the eyes of the EFTA.
So while there is a very specific EFTA definition of a financial institution (12 CFR 1005.2(i); I'm fun at parties), it is safe to assume that if you are transferring other people's money, cryptocurrency, or other assets in any way, your company is a "financial institution."
Periodic monthly statements
The EFTA covers a number of different rules for financial institutions: disclosures, liabilities, etc. But for the purposes of this post, we're most interested in section 1005.9 which describes periodic statements: you know, those monthly statements that your bank sends you each month.
The gist of 1005.9 is that if you are a financial institution — i.e. your company electronically transfers assets for a customer — you will need to provide a downloadable statement to that customer. Specifically, 1005.9(b) outlines that statements must be issued monthly so long as a transaction has occurred, and quarterly even if there have been no transactions.
Required financial statement PDF fields
The periodic statements section, 1005.9(b), also specifies a list of fields that must be in each financial statement PDF and on each transaction line item. You can obviously go nuts giving your customers extra information on your statements, but I'll just describe the minimum requirements below.
General statement information
A few straightforward account details need to be on each statement. If you've ever used a bank, these will be pretty familiar:
- The account number
- Fees. The amount of any fees assessed against the account during the statement period
- Account balances. The balance in the account at the beginning and at the close of the statement period.
- Address and telephone number for your company. The address and telephone number to be used for inquiries or notice of errors, preceded by "Direct inquiries to" or similar language.
- A telephone number (for your company) the consumer may call to ascertain whether preauthorized transfers to the consumer's account have occurred
Financial transaction report
Your statements need to report a list of all financial transactions. The policy says the following bits of information need to be shown for each transaction:
- The amount of the transfer
- The date the transfer was credited or debited to the consumer's account
- The type of transfer and type of account to or from which funds were transferred
- For a transfer initiated by the consumer at an electronic terminal (except for a deposit of cash or a check, draft, or similar paper instrument), the terminal location
- The name of any third party to or from whom funds were transferred
How to generate monthly financial statement PDFs
I'll assume if you've made it this far, your company probably falls under the "financial institution" definition, and will need to generate monthly statements for your customers.
To make this as easy as possible, we've created a EFTA-compliant monthly statement PDF template with both a plain HTML + CSS example, and a React + styled-components example. Check out the template GitHub repository at anvilco/html-pdf-financial-statement-template. Our goal with this template is to give you an easy starting point for your own company's statements, so feel free to fork it and copy code from the repo!
The rest of this post will show how to generate a statement that looks like the statement below. It has all the EFTA required fields, and it even looks pretty good! It's ready to be updated with your company's color palette 🎨
The monthly statement we will be generating from HTML and CSS
Steps for setting up
We'll use the Anvil HTML to PDF API to generate statement PDFs.
First, you'll need to get your API key by signing up for an Anvil account.
Once logged in, you will be directed to copy the API key from your organization’s API settings page. For more information see the getting started guide.
Generating PDFs from HTML
Generating PDFs is as simple as POST
ing your HTML and CSS to the Anvil PDF generation endpoint https://app.useanvil.com/api/v1/generate-pdf
. You send HTML and CSS, and the endpoint will respond with your newly generated PDF binary data ✨. Here's a quick curl
example to illustrate how simple it is:
curl \
-X POST \
-u <YOUR_API_KEY>: \
-H 'Content-Type: application/json' \
-d '{ "type": "html", "title": "World", "data": { "html": "<h1>HTML to PDF</h1>", "css": "h1 { color: purple; }" } }' \
https://app.useanvil.com/api/v1/generate-pdf > html-to.pdf
A curl example generating a PDF with HTML and CSS
For the remaining examples, we'll use the node-anvil API client. Generating PDFs with the node API client is simple as well:
import fs from 'fs'
import Anvil from '@anvilco/anvil'
const apiKey = <YOUR_API_KEY>
const client = new Anvil({ apiKey })
const { statusCode, data, errors } = await client.generatePDF({
type: 'html',
title: 'Hello World',
data: {
html: '<h1>HTML to PDF</h1>',
css: 'h1 { color: purple; }',
},
})
fs.writeFileSync('html-to.pdf', data, { encoding: null })
A JavaScript example generating a PDF with HTML and CSS
If you don't use node, JavaScript, or TypeScript, check out our other language-specific API clients.
Financial statement PDF from plain HTML & CSS
The monthly financial statement template contains a plain HTML and CSS files you can use to generate your PDF: statement.html and statement.css.
From the template repository, you can run generate-pdf.js via a simple command:
ANVIL_API_TOKEN=<YOURKEY> yarn generate-pdf:plain-html && open ./generate-plain-html.output.pdf
The basic gist of generate-pdf.js
is as follows:
import fs from 'fs'
import Anvil from '@anvilco/anvil'
const apiKey = <YOUR_API_KEY>
const client = new Anvil({ apiKey })
function buildHTMLToPDFPayload () {
const html = fs.readFileSync('./statement.html').toString()
const css =
fs.readFileSync('./statement.css').toString() +
fs.readFileSync('./statement-pdf.css').toString()
return {
type: 'html',
title: 'HTML Monthly Statement',
data: {
html,
css,
},
}
}
const exampleData = buildHTMLToPDFPayload()
const { statusCode, data, errors } = await client.generatePDF(exampleData)
fs.writeFileSync('monthly-statement.pdf', data, { encoding: null })
An example generating a statement PDF with HTML and CSS
Financial statement PDF from React + styled-components
The monthly statement template also contains a React statement example that is similarly easy to use.
From the template repo, you can run react-pdf/generate-pdf.js via:
ANVIL_API_TOKEN=your_token yarn generate-pdf:react && open ./generate-react.output.pdf
The basic gist to generate the statement from React is:
- Collect all styles from
styled-components
- Use
ReactDOMServer.renderToStaticMarkup
to render the statement components to HTML - Extract CSS from the collected styles
- Send generated HTML and CSS to Anvil's PDF generation endpoint
- Receive
baconPDF
import fs from 'fs'
import Anvil from '@anvilco/anvil'
import React from 'react'
import ReactDOMServer from 'react-dom/server'
import { ServerStyleSheet } from 'styled-components'
const apiKey = <YOUR_API_KEY>
const client = new Anvil({ apiKey })
function buildHTMLToPDFPayload () {
const sheet = new ServerStyleSheet()
const html = ReactDOMServer.renderToStaticMarkup(
sheet.collectStyles(<Statement />)
)
const css = sheet.instance.toString()
return {
type: 'html',
title: 'HTML Statement',
data: {
html,
css,
},
page: {
marginLeft: '60px',
marginRight: '60px',
},
}
}
const exampleData = buildHTMLToPDFPayload()
const { statusCode, data, errors } = await client.generatePDF(exampleData)
fs.writeFileSync('monthly-statement-react.pdf', data, { encoding: null })
An example generating a statement PDF from React and styled components
For more general-purpose information on using React to generate PDFs, see the step-by-step guide for creating PDFs with React.
Generate EFTA-compliant PDF statements with ease
Hopefully you now have a good idea of how the Electronic Fund Transfer Act works. If your company is a financial institution, you will need to provide monthly statements to your customers. The statement template described above should get you started in no time.
Here are a couple links to check out:
- EFTA / Regulation E (1005.9) detailing all the requirements for periodic statements.
- The monthly statement HTML template which provides an EFTA compliant monthly statement PDF template for financial institutions.
Key Takeaways
- Financial institutions must provide customers with monthly statements, and these statements must comply with the Electronic Fund Transfer Act (EFTA) and Regulation E.
- Key information on the statement includes transaction details, fees, and account summaries to ensure transparency and regulatory compliance.
- Developers can use HTML, CSS, and React to generate EFTA-compliant monthly financial statements efficiently, allowing for automation and scalability.
- Using modern web technologies to automate financial statement PDF generation can reduce manual effort and ensure accurate, compliant financial reporting.
Ready to simplify your financial statement process? Sign up for Anvil today and start generating EFTA-compliant statements.