Three integration paths. One compliance engine.
Bank of CAT integrated the CAT compliance platform three ways: a REST API for their internal CRM, an embeddable iframe for their merchant portal, and an MCP server for their AI support chatbot. Every tab below hits real production endpoints — click 🚀 Use demo configuration to start.
Bank of CAT internal CRM — backed by the REST API
Bank of CAT staff log in here to see their merchants' PCI compliance posture. Every row is fetched live with GET /v1/merchants.
How much of your book is compliant, and what's expiring
Merchants under Bank of CAT
| Merchant | External ID | Status | |
|---|---|---|---|
{{ m.name }} {{ m.email }} |
{{ m.externalMerchantId || '—' }} |
{{ (m.effectiveStatus || m.complianceStatus || '').replace(/_/g, ' ') }}
{{ expiryNote(m) }}
|
|
| Loading… | |||
{{ e.body }}
{{ drill.merchant.name }}
Customer-facing portal — backed by the REST API
A merchant of Bank of CAT (e.g., City of CAT) walks through completing one SAQ per payment method. Every interaction is a real REST call — watch the log on the right.
- {{ i + 1 }}. {{ s }}
{{ heroMerchantName }} Annual payment-security check for {{ brand.companyName || 'your bank' }}
Let's get you compliant. First, tell us how your business takes card payments — in your own words. It takes about 15 minutes.
Your bank has your signed documents. Nothing else is needed until your next annual review, due {{ nextReviewDate }}.
We'll email you before anything expires.
What is this?
Businesses that accept cards complete a short annual security self-assessment (called PCI DSS) confirming they handle card details safely.
You complete one assessment for each way you take payments — in person, online, over the phone, and so on. Your answers generate the official documents your bank keeps on file.
We never ask for card numbers.
Your ways of taking payments
{{ showAddForm ? 'Add another way you take payments' : 'Tell us how you take card payments' }}
Describe it in plain language — the vendor, the device or website, and how a customer's card details flow. We never ask for card numbers.
Step 1 — Identify the merchant
Step 3 — AI determines your SAQ type
The AI reads your payment method description, grounds itself in PCI DSS v4.1 documentation, and tells you which SAQ applies — plus the qualifications you'll need to meet.
- • {{ q.question }} ({{ q.pciReference }})
or pick manually
Step 4 — {{ flow.saqType }} · Section {{ flow.sectionIdx + 1 }} of {{ flow.sectionList.length }}
Answer one combined question per requirement; the AI distributes your answer across all controls in that requirement.
Show all {{ currentSection.children.length }} sub-controls in this section
- {{ c.controlId }} {{ c.status }} — {{ (c.requirement || c.title || '').slice(0, 140) }}
Step 5 — Attestation of Compliance review
A few consolidated questions to fill the AoC cover sheet. Each maps to the same field your bank's auditor would expect: company info, address, acquirer/processor, locations that touch card data, and a brief business description. Any "Not In Place" controls flagged earlier will also need a remediation plan.
Step 6 — Sign & finalize
Type your full legal name and title. We'll render this in cursive on the AoC attestation page along with today's UTC timestamp.
{{ e.body.length > 600 ? e.body.slice(0,600) + '\n…' : e.body }}
Bank of CAT support chatbot — driven by the MCP server
A simulated AI assistant that walks the merchant through their entire PCI SAQ. Every step the bot takes is a real POST /mcp tool call — see the JSON-RPC traffic on the right. This is what you build when you embed the MCP server in your bank's existing chat copilot.
Start a conversation with the AI assistant.
It'll walk you through the entire SAQ via MCP tool calls.
{{ e.body.length > 700 ? e.body.slice(0,700) + '\n…' : e.body }}
Bank of CAT merchant portal — with the iframe embedded
Below is a mockup of bankofcat.com/merchants/compliance. The grey area inside the page is a live <iframe src="https://api.complianceassessmenttool.com/portal/embed?…"> rendered fresh from production. Watch the postMessage events below as the customer clicks through.
{{ embedSnippet }}
cat:ready · cat:payment-method-added
cat:saq-submitted · cat:all-complete
{{ JSON.stringify(e.payload, null, 2).slice(0, 400) }}
Your partners can drop the iframe into their existing merchant portal in 4 lines of HTML. No customer-facing rebuilds. No data leaving CAT's tenant boundary. Their merchant sees your bank's chrome but completes a real PCI SAQ behind the scenes.
Partner onboarding & cross-partner monitoring
Logged in as {{ admin.me?.name || admin.me?.id }} · {{ admin.me?.id }} · key prefix {{ admin.me?.apiKeyPrefix }}. {{ admin.me?.webhookSecretConfigured ? '✓' : '✗' }} webhookSecret configured.
When a bank or ISO submits at /signup, it shows up below as pending. Read the contact + use case, then click Approve. (For offline deals: have them submit the form themselves with "notes: closed via sales call" so the audit trail is intact.)
Approval mints a cat_live_… API key + webhook signing secret once. The yellow banner that appears has copy buttons — paste each into a one-time-view channel (1Password Send, Bitwarden Send) and email the link to the bank's contact. They are never recoverable after dismiss.
Select the new partner from the list (left column). Set their per-merchant fee + billing cycle (this provisions a Stripe subscription) and set their brand color / logo / support email. Click Generate Stripe quote to send them a signable PDF before they're charged.
If the bank wants to redirect their merchants to our portal and get them back when done, enable Platform redirect and add their hostnames to the allowlist. They then call POST /v1/merchants/:m/portal-link with a returnUrl; we validate it against this list. The "What to tell the bank's integration team" block has copy-pasteable instructions.
📖 Founder library
admin-only — never shared with partnersYour meeting prep, in one click. The pitch deck is intentionally shareable — present from it, then send the link as the leave-behind.
{{ admin.library.title }}
Partner applications
Self-serve signups from /signup awaiting your review.
{{ a.approvedPartnerId }} · approved by {{ a.reviewedBy }} on {{ fmtDate(a.reviewedAt) }}Approve "{{ admin.approveDialog.application.legalName }}"
This will mint a new partner record, a one-time-view API key, and a webhook signing secret. The plaintext credentials are shown once — be ready to deliver them via a secure channel.
Deny "{{ admin.denyDialog.application.legalName }}"
A denial reason is recorded on the application row. Be specific — the applicant can request reconsideration with new information.
⚠ One-time credential view — {{ admin.approval.application?.legalName }}
These credentials are shown exactly once. The easiest delivery: send the bank the claim link below — it renders the credentials one time, then self-destructs. They are not recoverable server-side — only the SHA-256 hash of the API key is stored.
Partners
Onboarding checklist · {{ admin.selectedPartnerId }}
-
{{ s.done ? '✓' : '○' }}
{{ s.label }} — {{ s.detail }}
Billing & Stripe · {{ admin.selectedPartnerId }}
{{ admin.billing.snapshot.billing?.status || 'not configured' }}Sets per-merchant pricing and billing cadence for this partner. Each completed SAQ posts a Stripe usage record automatically; Stripe rolls them up into one invoice per cycle and charges the bank's card on file. Generate a quote PDF before activating if you want the bank to sign off first.
{{ admin.billing.snapshot.billing?.stripeCustomerId || '—' }}{{ admin.billing.snapshot.subscription?.id || '—' }}Platform redirect (hand-off) · {{ admin.selectedPartnerId }}
{{ admin.handoff.config.enabled ? 'enabled' : 'disabled' }}When a bank wants to redirect their merchant to our portal and have us send the merchant back when finished, enable hand-off here and add the bank's hostnames to the allowlist. Their backend then calls POST /v1/merchants/{mid}/portal-link with returnUrl; we validate against this list and respond with a handoffUrl they 302-redirect to.
*.bank.example to allow any single-level subdomain. Empty list = accept any HTTPS URL (only safe for sandbox testing).returnUrl. Must be on the allowlist above.📘 What to tell the bank's integration team
1. Your portal's backend authenticates the merchant locally.
2. Backend calls (server-side, using your CAT API key):
POST https://api.complianceassessmenttool.com/v1/merchants/{mid}/portal-link
Body: { "returnUrl": "https://portal.bank.example/compliance/return" }
3. We respond with handoffUrl + sessionToken + expiresAt.
4. Your portal 302-redirects the merchant to handoffUrl.
5. Merchant completes the SAQ on our domain (with your branding).
6. We 302 them back to your returnUrl with query params:
?status=completed&merchantId=mrc_…&attemptId=att_…&saqType=SAQ%20A&orgCompliant=true
7. Your portal verifies the bound merchant session and updates UI / records completion.
You'll also receive saq.submitted + merchant.compliant webhooks at the URL on your partner record.
White-label branding · {{ admin.selectedPartnerId }}
{{ admin.branding.configured ? 'configured' : 'using defaults' }}Used inside iframe embeds and platform-redirect (hand-off) flows. The portal recolors its header, swaps in the bank's logo, and shows their support email so the merchant sees the bank's identity throughout the SAQ.
✉️ Sending domain · send merchant email as the bank · {{ admin.selectedPartnerId }}
{{ admin.emailDomain.config.status === 'verified' ? '✓ verified' : admin.emailDomain.config.status === 'failed' ? '✕ failed' : '⏳ waiting for DNS' }}When the bank publishes these DNS records, invites and completion emails send from their domain with aligned SPF + DKIM — their DMARC passes and merchants see a sender they trust. Recommend a dedicated subdomain (e.g. compliance.acmebank.com).
| Type | Host / Name | Value | Status | |
|---|---|---|---|---|
| {{ r.type }} | {{ r.name }} | {{ r.value }} | optional ✓ detected pending |
Merchant invites · Concierge launch · {{ admin.selectedPartnerId }}
Import the partner's merchant list and email every merchant a branded personal link (valid 30 days). The email carries the partner's logo, color and company name from the Branding panel above; the words below are customizable per partner. Placeholders {merchantName} and {partnerName} are substituted automatically.
Completed documents · sealed SAQ + AoC per attempt
Every assessment this partner's merchants have finished. Open the PDFs to verify the SAQ answers and AoC fields are filled correctly before the partner distributes them.
| Merchant | SAQ | Sealed | Signed by | Pipeline | Documents |
|---|---|---|---|---|---|
|
{{ d.merchantName }}
{{ d.externalMerchantId || d.merchantId }}
|
{{ d.saqType }} | {{ fmtDate(d.sealedAt) }} | {{ d.signatoryName || '—' }} | {{ d.pipeline || '—' }} |
Merchants under {{ admin.selectedPartnerId }} · {{ admin.merchants.length }} total
| Merchant | Status | Level | Invited | Created |
|---|---|---|---|---|
{{ m.name }} {{ m.id }} |
{{ m.complianceStatus || '—' }} | L{{ m.merchantLevel || '—' }} | {{ fmtDate(m.invite.sentAt) }} ×{{ m.invite.count }} no email | {{ fmtDate(m.createdAt) }} |
Audit events (most recent first) · {{ admin.audit.length }} shown
{{ e.actor }}
merchant: {{ e.merchantId }}
attempt: {{ e.attemptId }}