Transactions
A credit or debit from an Account is referred to as a Transaction, which has several metadata fields in our system, such as:
Name |
Description |
---|---|
AllTransactionType (Enum) |
0: Posted, 1: Memo, 2: Insufficient Funds |
TransactionID |
Unique identifier of the Transaction within this environment |
HostAccountID |
Which Account this Transaction relates to |
OfxTrnType |
ex: CREDIT |
StatementDescription |
ex. N9848 Q2 SOFTWAR DIR DEP 268904 10230 06/01/18 |
SignedTxnAmount |
ex. -123.23 |
Note
For a more complete list, check out the sample response at GetAccountHistoryByIdWindowed module
Unlike Accounts, Transactions do not come in to your extension as part of the initial data blob from HQ. Rather, you will have to go back to the database for subsequent information. We did this in one way in the Online Banking Form Tutorial during the Using HQ API step. In that case we used the GetAccountHistoryById module. That HQ endpoint gave us ALL transactions for a given AccountId.
However, there are many endpoints that HQ provides for transaction search. For instance, if you are looking for only transactions that match a pattern, or just a subset of the entire transaction history, one such option is the GetAccountHistoryByIdWindowed module. This endpoint is more powerful, but also more complicated to call. Let’s check out an example:
from dataclasses import dataclass
from datetime import datetime, timedelta
from q2_sdk.core.http_handlers.tecton_server_handler import Q2TectonServerRequestHandler
from q2_sdk.hq.hq_api.q2_api import GetAccountHistoryByIdWindowed
from q2_sdk.hq.models.hq_response import HqResponse
# This is a neat way to consolidate all the input parameters and only
# pass a single argument to _get_windowed_transactions
@dataclass
class HistoryParameters:
login_name: str
host_account_id: str
page_size: int = 100
page_number: int = 1
from_date: str = "1901-01-01"
to_date: str = None
@property
def from_as_str(self) -> str:
return self.from_date.strftime("%Y-%m-%d")
@property
def to_as_str(self) -> str:
return self.to_date.strftime("%Y-%m-%d")
# This handler is missing lots of properties and such, meant only to show
# how this type of call might be constructed
class MyGetTransactionHandler(Q2TectonServerRequestHandler):
async def default(self):
from_date = datetime.today() - timedelta(days=365) # Last 3 days
history_parameters = HistoryParameters(
'retail0', # login_name
5009, # host_account_id
from_date=from_date
)
hq_response = await self._get_windowed_transactions(history_parameters)
data = {
'transactions': []
}
if not hq_response.result_node.Data.AllHostTransactions.Transactions:
data = 'No transactions for the given inputs'
else:
for tran in hq_response.result_node.Data.AllHostTransactions.Transactions:
post_date = str(tran.PostDate)
transaction_amount = tran.SignedTxnAmount.pyval
data['transactions'].append(
{
'post_date': post_date,
'transaction_amount': transaction_amount
}
)
self.get_tecton_form('Transactions', )
return self.get_tecton_form(
"Transactions",
custom_template=data,
hide_submit_button=True
)
async def _get_windowed_transactions(self, history_parameters: HistoryParameters) -> HqResponse:
get_account_history = GetAccountHistoryByIdWindowed.ParamsObj(
self.logger, # logger
history_parameters.host_account_id, # host_account_id
history_parameters.page_size, # page_size
history_parameters.page_number, # page_number
True, # perform_history_lookup
False, # perform_memo_lookup
False, # perform_nsf_lookup
optional_filter=GetAccountHistoryByIdWindowed.OptionalFilter([
GetAccountHistoryByIdWindowed.FilterItem(
0, # is_or_operator_not_and
GetAccountHistoryByIdWindowed.Operand.GT, # Operand
0, # parens_before
0, # parens_after
field_name="PostDate",
comparison_value=history_parameters.from_as_str
),
GetAccountHistoryByIdWindowed.FilterItem(
0, # is_or_operator_not_and
GetAccountHistoryByIdWindowed.Operand.LT, # Operand
0, # parens_before
0, # parens_after
field_name="PostDate",
comparison_value=history_parameters.to_as_str
)
]),
optional_sort='',
hq_credentials=self.hq_credentials
)
results = await GetAccountHistoryByIdWindowed.execute(get_account_history)
return results
Assuming a database that has data for that account id (5009) and time range (365 days), the frontend will look something like this:

Generated Vs Host Transactions
The Q2 database makes a distinction between Transactions originating from the Q2 system vs those we learn about by pulling from the Banking Core.
Those that originate from Q2 (such as by using the Funds Transfer interface) are called Generated Transactions
,
living in the Q2_GeneratedTransaction
table. Those that start in the Core (such as debit card purchases) are called Host Transactions
,
living in the Q2_HostTransactionHistory
table. Generated Transactions also can have a subtype called a GT Flavor.