SOQ International Academy

← Documentation Home

FilPass & OpenCerts

Package: soq-filpass-opencerts - Permissions: 90190-90194 - Status: Implemented with mock adapter; production API pending FilPass documentation.

What This Module Does

FilPass adds an external verifiable credential layer on top of SOQ's existing internal certificate system. SOQ still creates its normal certificate first. When enabled, the observer creates one pending row in filpass_credentials; the scheduler later sends it to FilPass.

Checkout, quiz completion and course completion never call FilPass directly, so FilPass outages do not block learners.

Admin Screens

  • Settings (/admin/filpass): enable issuance, go-live date, environment, credentials, issuer name and template IDs.
  • Issuance log (/admin/filpass/logs): pending/issued/failed/revoked/expired rows, payload preview, retry, sync now and revoke.

Who Uses This Page

RoleWhat they doPermissions needed
System adminInstall seed, configure credentials, set issue date and template mapping.admin_filpass_settings
Operations adminCheck issuance log, preview payloads, run Sync now.admin_filpass_logs, optionally admin_filpass_retry
Compliance adminInvestigate revoked or expired credentials.admin_filpass_logs
Senior adminRevoke issued credentials.admin_filpass_revoke

Pre-processing: Set Up FilPass Before Touching SOQ

Do this with FilPass first, then copy the values into /admin/filpass. Keep sandbox and production values separate.

StepIn FilPassValue you need for SOQWhere it goes in SOQ
1Create or request the SOQ issuer/organization account.Legal issuer name, normally SOQ International Academy.Issuer name
2Request API access for the environment.Sandbox or production API base URL, without a trailing slash.API base URL
3Create an API application / integration credential.Preferred: API key / bearer token. Alternative: Client ID + Client secret.API key, or Client ID + Client secret
4Create credential templates for each SOQ certificate type.Template IDs for course, quiz, and bundle.Template IDs mapping
5Register SOQ callback/webhook endpoint.https://<your-soq-domain>/webhooks/filpassFilPass webhook/callback URL field
6Choose a webhook signing secret.A long random shared secret.Webhook secret
7Confirm lifecycle event payload.document_id or filpass_document_id, and status = revoked or expired.Webhook handling
8Confirm issuance response fields.document_id or id, and verification_url or verify_url.Issuance sync

SOQ posts to POST {API base URL}/credentials, reads GET {API base URL}/credentials/{document_id}, and revokes with POST {API base URL}/credentials/{document_id}/revoke.

Authentication is sent as Authorization: Bearer <API key> when API key is filled. If API key is empty, SOQ uses HTTP Basic Auth with Client ID + Client secret.

Webhook signature expected by SOQ: X-FilPass-Signature: sha256=<hex_hmac_sha256_of_raw_body_using_webhook_secret>.

Use the exact public HTTPS URL displayed under Webhook URL on /admin/filpass. For sandbox testing from a local machine, expose SOQ through HTTPS using a tunnel or staging domain and register that HTTPS URL in FilPass.

Before Enabling

  1. Database installed: filpass_credentials table exists.
  2. Seed installed: sections 90190-90194 exist and admin has permissions.
  3. Scheduler installed: server runs php artisan schedule:run every minute.
  4. Issue date decided: old certificates are not backfilled automatically.
  5. Template IDs ready: quiz, course and bundle template IDs are known.
  6. Environment selected: use mock for local/UAT without FilPass; use sandbox only after FilPass-side setup is complete.
  7. API credential saved: fill either API key or both Client ID and Client secret. Client ID is also required in sandbox/production mode.
  8. Webhook registered: {APP_URL}/webhooks/filpass with the same HMAC secret saved in SOQ.
  9. Response contract confirmed: FilPass issuance response includes document_id/id and verification_url/verify_url.
  10. Privacy reviewed: keep Include NRIC/FIN off for v1.

Field Guide

FieldRequired?What to enterWhat it affects
Enable FilPass issuanceYes for liveTurn on only after issue date and mapping are ready.New certificates can be queued.
Auto issue new certificatesUsually yesKeep on for automatic issuance.Observer creates pending rows.
Issue from dateYes when enabledGo-live date.Certificates before this date are ignored.
EnvironmentYesmock, sandbox, or production.Chooses mock or live client.
CredentialsLive/sandboxAPI base URL, Client ID/secret or API key.Authenticates FilPass API calls.
Webhook secretYes for webhookShared HMAC secret configured at FilPass.Verifies POST /webhooks/filpass.
Template IDsPer typeFilPass template ID for quiz, course and bundle.Missing mapping fails the row before API call.

How The Queue Works

  1. A learner earns a normal SOQ certificate.
  2. The FilPass observer checks enabled, auto_issue and issue_from_date.
  3. If eligible, SOQ inserts one filpass_credentials row with status = pending.
  4. soq:filpass-sync runs every 5 minutes and processes pending plus retryable failed rows.
  5. Successful responses save document ID, verifier URL, PDF URL, OpenCerts hash and status = issued.
  6. Signed webhooks update rows to revoked or expired.

How To Enable In UAT

  1. Run php artisan migrate.
  2. Run php artisan soq:seed-filpass.
  3. Open /admin/filpass.
  4. Set Environment = mock.
  5. Set Issue from date = today.
  6. Fill template IDs such as mock_course, mock_quiz, mock_bundle.
  7. Turn on Enable FilPass issuance and Auto issue new certificates.
  8. Create a new SOQ certificate, then open /admin/filpass/logs and click Sync now.

UAT Script

StepActionExpected result
1Save mock settings.Settings saved; secrets are not displayed back.
2Complete a course or quiz as a student.Internal SOQ certificate can be downloaded.
3Open /admin/filpass/logs.A pending row appears for the certificate ID.
4Click Preview payload.Payload includes source, issuer, template, recipient and programme data.
5Click Sync now.Row becomes Issued with FP-MOCK-* document ID.
6Open learner achievements and public validation.FilPass status and verifier link are visible.

Daily Operations

  • Check /admin/filpass/logs for Failed rows during UAT and after go-live.
  • Preview payload after changing template IDs.
  • After a FilPass outage, retry one row first, then Retry all failed.
  • For learner complaints, search by certificate ID and compare internal certificate, FilPass row and verifier link.

Buttons And Actions

ActionWhat it doesSafe to repeat?
Preview payloadBuilds payload without calling FilPass.Yes
RetryResets a failed row to pending and attempts to 0.Yes, after fixing cause
Retry all failedResets all failed rows to pending.Use after known outage/config fix
Sync nowRuns soq:filpass-sync immediately.Yes
RevokeCalls FilPass revoke endpoint and marks row revoked.No, use with approval

Production Go-Live

Production requires official FilPass API documentation and credentials. Confirm endpoint paths, authentication, response fields, rate limits and webhook signature format before changing environment to production.

In FilPass production, create the SOQ issuer/integration credential and production templates, then register the exact webhook URL shown in SOQ: {PROD_URL}/webhooks/filpass.

In /admin/filpass, enter production API base URL, Client ID, and either API key or Client secret. Save the same webhook signing secret in both FilPass and SOQ.

Make sure php artisan schedule:run is installed every minute before running the first live certificate.

Do not switch config/soq_modules_pitch.php from coming_soon until the production FilPass credential flow has been tested with real credentials.

Status Meanings

StatusMeaningOperator action
PendingWaiting for cron or Sync now.Wait 5 minutes or click Sync now.
IssuedFilPass returned document ID and verifier URL.Verify external link.
FailedPayload, config or API error.Read error, fix config, Retry.
SkippedCertificate missing or intentionally not sent.Usually no action.
RevokedAdmin/API/webhook marked it revoked.Confirm reason and replacement policy.
ExpiredFilPass webhook marked it expired.Confirm if re-issuance is needed.

Incident Playbooks

Pending Rows Do Not Move

  1. Confirm scheduler is running: php artisan schedule:list.
  2. Click Sync now.
  3. Check module enabled, issue date and credential configuration.
  4. If the row is new, wait for the short settle window.

Webhook Returns 403

  1. Compare FilPass webhook secret with SOQ webhook_secret.
  2. Confirm FilPass signs the raw request body with HMAC SHA-256.
  3. Confirm header format: X-FilPass-Signature: sha256=<signature>.
  4. Rotate the secret if it may have leaked.

Troubleshooting

  • No row appears: module disabled, auto issue off, issue date in the future, or old certificate.
  • Template missing: fill template ID for the certificate type and retry.
  • Missing credentials: live/sandbox mode needs API base URL and credentials.
  • Webhook 403: signature does not match webhook_secret.

Security And Privacy Notes

  • Secrets are encrypted in soq_filpass_settings and never displayed back.
  • Changing APP_KEY makes encrypted secrets unreadable; re-enter FilPass secrets afterward.
  • The webhook route is CSRF-exempt but HMAC verification is mandatory.
  • v1 does not send NRIC/FIN. Do not repurpose identity scan uploads as plain identity numbers.

Quick Command Reference

php artisan soq:seed-filpass
php artisan soq:filpass-sync --limit=50
php artisan schedule:list
php artisan migrate:status --pending