certificados_academicos flow manages the purchase of academic certificates for students and graduates. It presents a structured form, resolves pricing from a level-by-format matrix, validates catalog entries, and stores all request metadata on the WooCommerce order.
Flow overview
| Property | Value |
|---|---|
| Flow ID | certificados_academicos |
| Class | UTB\ProductBuilder\Flows\CertificadosFlow |
| Shortcodes | [utb_cert_form], [utb_cert_catalog_modal] |
| Icon | dashicons-awards |
| AJAX endpoints | utb_get_certs, utb_cert_price |
Shortcodes
| Shortcode | Renders |
|---|---|
[utb_cert_form] | The certificate request form (includes program selector, certificate selector, quantity, and price display). |
[utb_cert_catalog_modal] | A modal overlay showing the full certificate catalog. |
AJAX endpoints
utb_get_certs
Returns a filtered list of certificates based on applicant type and academic level. Used by the frontend to repopulate the certificate selector when the user changes utb_tipo_cert or utb_nivel.
POST parameters:
| Parameter | Type | Description |
|---|---|---|
tipo | string | Applicant type: estudiantes or egresados |
nivel | string | Academic level: pregrado or posgrado |
utb_cert_price
Calculates the total price for a certificate selection. Requires nonce default.
POST parameters:
| Parameter | Type | Description |
|---|---|---|
nonce | string | WordPress nonce (default) |
cert_id | int | Certificate ID |
formato | string | digital or fisico |
nivel | string | pregrado or posgrado |
qty | int | Quantity (minimum 1) |
Certificate catalog
The catalog is stored inwp_utb_certificates and managed by CertificatesRepository.
Table columns:
| Column | Description |
|---|---|
id | Primary key |
slug | URL-safe identifier |
nombre | Display name |
tipo_usuario | Estudiante, Egresado, or Ambos |
descripcion | Optional description shown in the form |
sku | Billing SKU reference |
tiempo_expedicion | Estimated delivery time shown to the applicant |
qty_enabled | Whether multiple copies can be ordered (boolean) |
form_config_json | Optional per-certificate form field overrides (JSON) |
activo | Soft-delete flag |
Filtering by type and level
CertificatesRepository::get_by_tipo_and_nivel() applies a two-stage filter:
- SQL stage: Filters by
tipo_usuariowith flexible matching (egresado/egresados/ambos). - PHP stage: For each certificate returned, calls
CertificatePricesRepository::get_available_levels(). A certificate passes the level filter if:- Its price table has no explicit levels defined (agnostic/universal price), OR
- Its price table includes an entry matching the requested level.
Do not assign a level when creating a price entry for certificates that apply to all students regardless of level. Leaving the level blank allows the certificate to appear for both Pregrado and Posgrado applicants.
Quantity support
allows_quantity() determines whether a certificate supports ordering multiple copies. By default the plugin uses by_table mode: the qty_enabled column on the certificate record controls this. The legacy by_slug_patterns mode (matching slug patterns like contenidos-programaticos or certificado-de-notas) is available as a fallback configured via utb_pb_table_config['rules']['cert_qty_enabled_mode'].
Matrix pricing
Prices live inwp_utb_certificate_prices and are managed by CertificatePricesRepository.
Pricing dimensions:
| Dimension | Values |
|---|---|
certificate_id | Foreign key to wp_utb_certificates |
formato | digital or fisico |
nivel_code | pregrado, posgrado, general, or blank |
price_cop | Price in Colombian pesos |
get_price():
- Fetches all active price rows for the requested
certificate_idandformato, ordering exact format matches first. - If no level was requested, returns the first row.
- Iterates rows looking for a
nivel_codeofgeneral(matches any level) or an exact normalized level match. - Falls back to a
generalor emptynivel_coderow, then to the first row.
| Raw value | Normalized to |
|---|---|
postgrado, pos-grado | posgrado |
pre-grado | pregrado |
profesional, tecnico, tecnologia, tyt, tecnica, tecnologica | pregrado |
especializacion, maestria, doctorado | posgrado |
general or blank | applies to any level |
Programs catalog
Academic programs for the certificate form (distinct from CEP programs) are stored inwp_utb_programs and managed by ProgramsRepository. Programs can be filtered by nivel (pregrado or posgrado). The system_program_selector field type in the form config renders a <select> populated from this repository via DataSourceManager.
Managing the catalog from admin
Certificates, prices, and programs are managed through UTB Builder → Tablas Locales UTB in the WordPress admin. The admin interface exposes CRUD operations for:wp_utb_certificates— certificate records with type, description, delivery time, and quantity flag.wp_utb_certificate_prices— price matrix rows (certificate × format × level).wp_utb_programs— academic programs linked to certificates.
Default form configuration
CertificadosFlow::get_default_config() defines the canonical field schema:
FormConfigManager using the same priority chain as the CEP flow: product meta → linked certificate’s form_config_json → flow default.
Cart metadata fields
The following order item meta keys are written byprepare_cart_metadata():
| Meta key | Source |
|---|---|
_utb_cert_nombre | utb_nombre (form field) |
_utb_cert_apellido | utb_apellido |
_utb_cert_tipo_doc | utb_tipo_doc |
_utb_cert_documento | utb_documento |
_utb_cert_correo | utb_correo |
_utb_cert_telefono | utb_telefono |
_utb_cert_id_est | utb_id_est |
_utb_cert_modalidad | utb_modalidad |
_utb_cert_id | Certificate ID from wp_utb_certificates |
_utb_cert_nombre_cert | Certificate name |
_utb_cert_tipo_cert | utb_tipo_cert (egresados or estudiantes) |
_utb_cert_formato | utb_formato (digital or fisico) |
_utb_cert_nivel | utb_nivel (pregrado or posgrado) |
_utb_cert_qty | Quantity (minimum 1) |
_utb_cert_programa_id | Program ID from wp_utb_programs |
_utb_cert_programa_nombre | Program name |
_utb_cert_price_unit | Unit price in COP |
_utb_cert_price_total | Total price (unit × qty) in COP |
_utb_cert_form_json | Full POST data as JSON for audit purposes |
Server-side validation
validate_cart_data() runs these checks before adding to the cart:
- All required fields are present.
- Email format is valid.
- The selected program exists in
wp_utb_programs. - The selected certificate exists in
wp_utb_certificates. - The certificate’s available price levels include the selected
utb_nivel(unless the certificate has no level restrictions). - The certificate’s
tipo_usuariomatches the applicant type (egresados/estudiantes/ambos). - If quantity > 1, the certificate’s
qty_enabledflag is set (orforce_qty_enableis set in the field config). - Quantity does not exceed
max_qty(from field config or globalcert_qty_max_defaultoption, default 10). - If a field has
validate_role: true, the document is verified against Banner and the user’s role must match the certificate’stipo_usuario. - Policies checkbox is checked.
- The resolved price is greater than zero.
- Any
RulesEnginerules defined in the form config pass.