Document Insights

MoneyThumb Integration — Troubleshooting Guide


This document covers the end-to-end MoneyThumb integration within Document Insights. It is intended for administrators, support engineers, and developers diagnosing issues in production or sandbox environments.


Integration Architecture Summary

The MoneyThumb integration follows an asynchronous, webhook-driven flow across five stages:

Stage

Component

Description

  1. Feature Check

PDFInsightRequestController

Validates Feature_Entitlement__c.PDF_Insights__c

  1. Application Creation

WS_PDFInsight.createApplication

Creates a MoneyThumb application via REST

  1. PDF Upload

QueueablePDFConvertWS_PDFInsight.convertMultipleStatements

Uploads PDFs in batches as multipart POST

  1. Webhook Receipt

Webhook_PDFInsightData (/getPDFInsights/*)

Receives async processing callbacks from MoneyThumb

  1. Analytics Retrieval

InvocableRetrievePDFAnalyticsWS_PDFInsight.retrieveScorecard

Fetches and stores structured analytics once all webhooks arrive


Prerequisites and Configuration Checklist

Before diagnosing any issue, verify the following are correctly configured in the org:

Custom Settings / Named Credentials

Setting

Location

Expected Value

Token_Endpoint__c

Custom Setting

MoneyThumb OAuth token URL

Create_Application_Endpoint__c

Custom Setting

MoneyThumb application creation URL

Convert_Multiple_PDF_Endpoint__c

Custom Setting

MoneyThumb PDF upload URL

Retrieve_PDF_Analytics_Endpoint__c

Custom Setting

MoneyThumb analytics retrieval URL

MoneyThumb username / password

Custom Setting or Named Credential

Valid API credentials

Feature_Entitlement__c.PDF_Insights__c

Custom Setting

Must be true

Remote Site Settings

Ensure all MoneyThumb endpoint domains are registered under Setup → Remote Site Settings. Missing entries cause callout failures with no descriptive error on the record.

Webhook URL Registration

The Salesforce webhook endpoint is:

https://<your-org-domain>.salesforce.com/services/apexrest/getPDFInsights/

This URL must be registered in MoneyThumb's portal as the callback URL for your application. If the webhook domain changes (e.g., after a sandbox refresh or org migration), analytics will never be retrieved.


Issue: Request Button Not Visible

Symptom: The "Request PDF Insight" button does not appear on the record page.

Root Cause 1 — Feature flag disabled PDFInsightRequestController.isFeatureEnabled() checks Feature_Entitlement__c.PDF_Insights__c. If this is false or the setting record does not exist, the entire component renders the "not entitled" error tile instead.

Resolution: Navigate to Setup → Custom Settings → Feature Entitlement and ensure PDF_Insights__c is checked for the relevant profile or org defaults.

Root Cause 2 — Record is itself a PDF_Insight__c showRequestButton() explicitly returns false when the current record's object type is PDF_Insight__c. This is by design — the button is suppressed on the insight record itself.

Root Cause 3 — ShowRequestSection metadata disabled If PDF_Insights__c is enabled but the button is still hidden, check the ShowRequestSection field in the relevant custom metadata. showRequestButton() reads this after the feature flag check.


Issue: Submission Fails Immediately (No PDF_Insight__c Created)

Symptom: Clicking submit produces an error toast or nothing happens, and no PDF_Insight__c record is created.

Diagnostic Steps:

  1. Open the browser developer console and check for JavaScript errors in PDFInsightRequestController.callPDFInsightService.

  2. Check Setup → Apex Jobs for any failed Queueable jobs (QueueablePDFConvert).

  3. Verify the user has Create permissions on PDF_Insight__c.

Root Cause 1 — No files selected callPDFInsightService receives a listSelectedFiles JSON payload. If no files are attached to the record or none are selected in the UI, the method has nothing to process.

Root Cause 2 — Duplicate detection reuse checkExistingPDFInsightRequest() may find an existing PDF_Insight__c for the same record within the configured reuse window. For MoneyThumb, if a record already has a PDF_Insight__c within the allowed duration, the existing record is reused rather than a new one created. Check if a PDF_Insight__c with Source = MoneyThumb already exists in a Processing or Completed state for the parent record.

Root Cause 3 — File size batching getListContentVersion() splits files into size-limited batches. If a single file exceeds the per-batch size limit, it may be excluded. Check ContentVersion.ContentSize for the files being submitted.


Issue: PDF_Insight__c Stuck in "Processing" Status

Symptom: The PDF_Insight__c record shows Status = Processing for an extended period with no update.

This is the most common MoneyThumb issue and almost always involves the webhook pathway.

Step 1 — Check Queueable_Count vs Webhook_Count

Navigate to the PDF_Insight__c record and inspect:

Field

Meaning

Queueable_Count__c

Number of PDF batches submitted to MoneyThumb

Webhook_Count__c

Number of webhook callbacks received so far

Analytics retrieval is only triggered when Webhook_Count == Queueable_Count. If Webhook_Count is lower, webhooks have not been received or have failed silently.

Step 2 — Check PDF_Insight_Item__c Records

Each successful webhook creates a PDF_Insight_Item__c child record. Query:

SELECT Id, Name, Status__c, CreatedDate 
FROM PDF_Insight_Item__c 
WHERE PDF_Insight__c = '<recordId>'

If no items exist, no webhooks have been processed. If items exist but the count is less than Queueable_Count, some webhooks are missing.

Step 3 — Verify Webhook Delivery

Check MoneyThumb portal: Confirm MoneyThumb shows the files as successfully processed on their end. If processing failed on the MoneyThumb side, no webhook is sent.

Check Salesforce REST logs: Enable API logging or use Setup → Event Monitoring to look for POST requests to /services/apexrest/getPDFInsights/. If no requests appear, the webhook URL is unreachable from MoneyThumb's servers.

Check Guest User permissions: The Webhook_PDFInsightData class is a @RestResource endpoint. The Site Guest User (or the connected app user) must have access to this Apex class. Go to Setup → Sites → [Your Site] → Public Access Settings → Apex Class Access and confirm Webhook_PDFInsightData is listed.

Step 4 — Manual Trigger

If webhooks are confirmed lost and cannot be retriggered, analytics can be fetched manually:

  1. From the PDF_Insight__c record, use the "Get Results" action (if surfaced in the UI), which calls WS_PDFInsight.getResults().

  2. Alternatively, run the following in Developer Console → Execute Anonymous:

InvocableRetrievePDFAnalytics.callPDFInsightService(new List<Id>{'<PDF_Insight__c Id>'});

This bypasses the webhook counter check and directly enqueues analytics retrieval.


Issue: Authentication Failure

Symptom: PDF_Insight__c shows Status = Failed with an error indicating auth failure. Apex debug logs show a 401 response from MoneyThumb.

Root Cause — Basic auth credentials invalid or expired

WS_PDFInsight.getAuthToken() constructs a Basic auth header using username:password stored in Custom Settings, encodes it as base64, and POSTs to Token_Endpoint__c.

Resolution:

  1. Navigate to the Custom Setting storing MoneyThumb credentials.

  2. Verify the username and password are current (MoneyThumb may rotate API keys).

  3. Test connectivity manually using Execute Anonymous:

WS_PDFInsight ws = new WS_PDFInsight();
String token = ws.getAuthToken();
System.debug('Token: ' + token);

A null or empty token means the auth request failed. Check the debug log for the raw HTTP response.


Issue: PDF Upload Fails (Status = Failed After Queueable Runs)

Symptom: The Queueable job completes but PDF_Insight__c status moves to Failed with no child PDF_Insight_Item__c records.

Diagnostic Steps:

  1. Check Setup → Apex Jobs — look for QueueablePDFConvert with status Failed or Completed. If Failed, expand the error message.

  2. Enable debug logging for the running user and reproduce — look for HTTP response codes from Convert_Multiple_PDF_Endpoint__c.

Common HTTP error codes and causes:

HTTP Code

Likely Cause

401

Token expired between createApplication and convertMultipleStatements — tokens are fetched fresh per job but check if MoneyThumb has rate limits on token issuance

413

File too large — though batching handles this, individual files approaching the batch limit may still exceed MoneyThumb's per-file maximum

400

Malformed multipart body — check that ContentVersion.FileExtension resolves correctly via HttpHexFormBuilder.resolveMimeType()

500

MoneyThumb-side error — check their status page

File type check: MoneyThumb only processes PDF files. If a non-PDF is uploaded (e.g., a PNG inadvertently selected), resolveMimeType may return an unexpected MIME type. Confirm all submitted files are valid PDFs.


Issue: Analytics Retrieval Runs But Child Records Are Missing

Symptom: PDF_Insight__c status reaches Completed but some expected child records are absent — e.g., Statement_Summary__c exists but Historical_Balance__c does not.

Root Cause — Partial data from MoneyThumb

WS_PDFInsight.retrieveScorecard() calls PDFAnalyticsParser to parse the scorecard response. Child records are only created if MoneyThumb returns data for the corresponding section. A missing section in the response means MoneyThumb could not extract that data from the PDF.

Diagnostic Steps:

  1. Check the raw API response if ConfigurationService.rawResponseFile() is enabled — look for a ContentVersion file attached to the PDF_Insight__c named Raw Response.

  2. In the raw JSON, check which sections (statement_summary, historical_balance, etc.) are present.

  3. If sections are missing: the uploaded PDF may be image-based (scanned) rather than text-based. MoneyThumb has reduced extraction accuracy on scanned documents.

Trigger-side aggregation:

PdfInsightTriggerHandler.storeAggregatedData() runs on PDF_Insight__c before update and aggregates values from Statement_Summary__c children onto the parent. If the parent fields appear blank even though Statement_Summary__c records exist, check whether the trigger is active (Setup → Apex Triggers → PdfInsightTrigger).


Issue: Income Analytics Tab Not Showing

Symptom: The Income Analytics tab is absent in viewPDFAnalytics for a Completed MoneyThumb record.

Root Cause:

PDFInsightRequestController.getChildData() only sets showIncomeAnalytics = true if Income_Insight__c records exist on the PDF_Insight__c. MoneyThumb does not produce income insights — this tab is exclusive to Ocrolus processing. This is expected behavior, not a defect.


Issue: Duplicate PDF_Insight__c Records Created

Symptom: Multiple PDF_Insight__c records with Source = MoneyThumb exist for the same parent record.

Root Cause:

checkExistingPDFInsightRequest() performs a reuse check before creating a new application. If the SOQL query for existing records returns no results (due to data visibility, FLS, or sharing rules), a new record is created even though one exists.

Resolution:

  1. Check sharing rules on PDF_Insight__c for the running user.

  2. If using with sharing, verify the querying user can see the existing records.

  3. Confirm FLS_Enforcement__c in ConfigurationService — if FLS enforcement is enabled, field-level access on the lookup and status fields must be granted.


Issue: Trigger Handler Errors on PDF_Insight__c

Symptom: Saving or updating a PDF_Insight__c record triggers a validation or DML error traced to PdfInsightTriggerHandler.

Key trigger operations and their failure modes:

Trigger Event

Method

Common Failure

Before Insert

updateParentLookup()

If currentRecordId does not start with 003 or 001, no lookup is set — not an error but can cause missing relationships

Before Update

updateStatus()

Aggregate queries on child objects — fails if user lacks access to Identity_Verification__c or Income_Insight__c

Before Update

storeAggregatedData()

Aggregate on Statement_Summary__c — fails if no Statement Summary records exist and null-checks are missing

After Update

populateParentFieldMapping()

JSON metadata config in ParentFieldMapping — misconfigured JSON causes a deserialize exception; check metadata for syntax errors

Before Delete

Cascade delete

If child record deletion fails (locked records, validation rules on children), the parent delete is blocked


Debugging Workflow (Quick Reference)

PDF_Insight__c Status = Processing (timeout)
│
├─ Check: Webhook_Count < Queueable_Count?
│   ├─ YES → Webhook not received
│   │         Check: Site Guest User Apex access
│   │         Check: Webhook URL registered in MoneyThumb portal
│   │         Check: Remote Site Settings for MoneyThumb domain
│   │         Workaround: Manual InvocableRetrievePDFAnalytics call
│   └─ NO  → Webhook received, analytics retrieval failed
│             Check: Apex Jobs for InvocableRetrievePDFAnalytics failure
│             Check: Retrieve_PDF_Analytics_Endpoint__c setting

PDF_Insight__c Status = Failed
│
├─ Failed immediately (no Item records) → Upload failed
│   Check: QueueablePDFConvert Apex Job error
│   Check: Auth token (getAuthToken debug)
│   Check: File type / size
│
└─ Failed after items exist → Analytics parse error
    Check: PDFAnalyticsParser debug log
    Check: Raw response ContentVersion on record


Relevant Apex Classes Reference

Class

Responsibility

PDFInsightRequestController

LWC controller — feature check, submission, data retrieval

WS_PDFInsight

All MoneyThumb HTTP callouts

QueueablePDFConvert

Async PDF upload, handles batching and chaining

Webhook_PDFInsightData

REST endpoint receiving MoneyThumb webhooks

InvocableRetrievePDFAnalytics

Triggers analytics retrieval post-webhook

PDFAnalyticsParser

Parses MoneyThumb scorecard response JSON

PdfInsightTriggerHandler

All trigger logic on PDF_Insight__c

HttpHexFormBuilder

Builds multipart form-data bodies for uploads


Relevant Objects Reference

Object

Role

PDF_Insight__c

Central record — one per submission, tracks status and counts

PDF_Insight_Item__c

Created per webhook received — confirms file processing

Statement_Summary__c

Monthly bank statement summary data

Historical_Balance__c

Daily balance trend data

Thumbprints__c

Fraud signal / anomaly flags

Transactions__c

Individual transaction records

Company__c

Company-level financial metadata

Monthly_Negative_Days__c

Days with negative balance per month