This guide is for the tenant administrator responsible for enabling and configuring the ITBMS withholding agent module before AP clerks start posting payments.
Your tenant has been designated by the DGI as an ITBMS withholding agent under Resolución 201-8055 (or a successor resolution) and you need to enable CifraHQ's automated retention pipeline.
Foreign or non-Panama tenants do not need any configuration. Leave Designated ITBMS Withholding Agent off and the entire module stays inert.
Navigate to Accounting → ITBMS Withholdings (Settings). The first time you open the page, CifraHQ creates a default config row in your tenant database with sensible defaults (50% rate, OnPayment trigger, RT- certificate prefix).
Fill in the Agent Designation section:
| Field | What to enter |
|---|---|
| Designated ITBMS Withholding Agent | Toggle on |
| Designation Reference | The resolution that named you (e.g., "Resolución 201-8055 / 2026-2027") |
| Effective From | The start date of your designation period |
| Effective To | The end date of your designation period (typically biennial) |
The system honors the effective window: payments outside the window will not generate retentions, even if the agent flag is on.
| Field | DGI default | Notes |
|---|---|---|
| Retention Rate | 50% | The DGI-mandated rate. Override only if a future regulation changes it. |
| Trigger Event | On payment (DGI canonical) | When the retention is issued. The alternative ("On invoice post") is a Phase 2 option. |
| Require CPA Approval to Close | Off (toggle on if your annual revenue > USD 11,000) | When on, the monthly period close routes to a CPA user for approval. |
| Field | Notes |
|---|---|
| Certificate Prefix | Default RT-. Used as {prefix}{8-digit-zero-padded-sequence} (e.g., RT-00000001). |
| Next Certificate Number | Read-only. The engine increments this atomically under optimistic concurrency. |
| Automatically Email Certificate to Supplier | Toggle on if you want every issued certificate emailed when generated. |
The retention engine emits two-line Journal Entries against these accounts:
| Account | Used when |
|---|---|
| ITBMS Withheld Payable | You are the agent: CR this liability account when a retention is issued; DR when voided. Typically a 2-04-xx code in a Panama CoA. |
| ITBMS Withheld Receivable | You are a supplier registering a certificate received from your customer: DR this asset account when the certificate is matched. Typically a 1-04-xx code. |
If either account is unset, retentions still persist in the subledger but the corresponding Journal Entry is not posted. The Form 4331 monthly validation step will surface the gap.
New tenants get these accounts pre-created. As of CifraHQ 2.3.x, every new tenant's default Chart of Accounts now includes:
116000 - ITBMS Withheld Receivable(asset, ITBMS Retenido por Cobrar in Spanish)231500 - ITBMS Withheld Payable(liability, ITBMS Retenido por Pagar in Spanish)A backfill migration also runs against existing tenants on the first upgrade after 2.3.0: it inserts the two accounts if they're missing, and auto-binds them to the singleton
TenantWithholdingConfigrow when the FKs are still null. So on most tenants you'll find the two accounts already picked when you open Accounting → ITBMS Withholdings (Settings) for the first time. Verify they match your CoA conventions before going live - you can change to any other liability/asset account in the same category.
Once the agent flag is enabled, the Vendor detail page shows a new ITBMS Withholding section. For each vendor:
| Field | When to change it |
|---|---|
| Tax Domicile | Default Panama. Set to United States, Mexico, Canada, or Other for foreign Vendors. |
| Subject to ITBMS withholding | Auto-managed: turns off when Tax Domicile is anything other than Panama. Override for special cases. |
| ITBMS Retention Rate Override | Leave blank to use the tenant default (50%). Set a value only for Vendors under a special regime that mandates a different rate. |
| Exemption Reason | None / Free Trade Zone / Special Regime / Small Taxpayer / Foreign / Other |
| Exemption Document Reference | The DGI resolution number that grants the exemption |
| Exemption Valid Until | The expiration of the exemption - the system warns when older than 365 days |
The fastest way to skip a vendor entirely is to set Tax Domicile correctly. A US (Miami) vendor with no ITBMS on the invoice would yield zero retention anyway, but the domicile setting makes the intent explicit.
After Setup, run this smoke test against a Panama vendor:
If steps 5–6 don't happen, see the troubleshooting section of the Withholding Agent Guide.
The Vendor detail page has a Verify Tax ID button next to the RUC field (mirrors the Customer page that has had this for years). Click it after you enter the supplier's RUC and CifraHQ will:
Panama for a Panamanian RUC, Other for foreign Vendors with a Cédula extranjera style ID)Why this matters for the withholding flow:
The same button is available from a vendor's Code lookup (/api/Vendor/VerifyTaxIdByCode?code=...), useful when you only have the vendor code from an imported CSV.
In rare cases - typically when a deploy lands mid-payment-posting or an external dependency (GL posting period missing, configured account suddenly invalid) trips the engine - you can end up with an ITBMSRetention row in Issued state that has no matching RetentionCertificate row. The Form 4331 close-validation step will block the period close until this is fixed.
CifraHQ ships with a one-shot recovery endpoint:
POST /api/RetentionCertificate/ReissueByPayment?paymentId={billPaymentId}
What it does:
(SourceDocId, PaymentId) tuple)RetentionCertificate rowCertificateDeliveryJob so the PDF gets generated, uploaded, and emailedThe endpoint is idempotent: calling it on a payment that already has a healthy certificate just Returns the existing certificate and does nothing else.
When to use it:
| Situation | Action |
|---|---|
| Form 4331 validation says "uncertified retention" | Run ReissueByPayment for each affected payment |
| Bill Payment shows posted but no Withholding Certificate panel, and you've waited 60+ seconds | Run ReissueByPayment |
| Mass recovery after an outage | Query ITBMSRetentions r LEFT JOIN RetentionCertificates c ON c.RetentionId = r.Id WHERE c.Id IS NULL, then call ReissueByPayment for each r.PaymentId |
The job state appears in /hangfire - successful runs leave a clear Audit Trail.
The certificate template is built programmatically in C# at seed time using the Stimulsoft .NET API and saved in XML format. This eliminates the entire class of "JSON template loaded fine in the designer but crashes the server-side render" problems that plagued earlier hand-rolled templates.
Once per tenant (and again after a CifraHQ version bump that ships an updated template):
POST /api/WithholdingTemplateSeeder/Seed
The endpoint Returns a JSON list of created/updated/skipped templates:
{
"Created": [],
"Updated": ["RetentionCertificate"],
"Skipped": []
}
PrintReports row existed for that nameIsCustom = false), so it was overwritten with the latest binaryIsCustom = true (someone customized the template in the Stimulsoft designer); the customization is left intactSafe to re-run any time - the new programmatic build always emits the same canonical XML bytes, so a re-seed never introduces a load-time crash on the .NET render path.
You can edit the seeded template in the Stimulsoft web designer (link on the PrintReports admin page). The designer saves your edits in JSON format, which is what the JS designer uses - and which the JS designer also loads back cleanly. The PDF render path stays robust because the data binding is the same in both formats; only the wire encoding changes.
If you ever upload a JSON template that the server-side renderer rejects with InvalidCastException - Unable to cast object of type 'JValue' to type 'JObject' (a known Stimulsoft .NET 2025.x quirk with hand-rolled JSON), re-run the seeder - it will replace the broken JSON with the canonical XML and your customizations will need to be reapplied through the designer.
You can only disable the Designated ITBMS Withholding Agent flag when there are no open (Issued or Draft) retentions in the current period. If retentions exist, close the current Form 4331 first.
This guard prevents orphaned certificates and protects the GL.
/settings/taxes/itbms-withholdings) - administrator roleWas this page helpful?