Back to Blog

Fintech Compliance Software: KYC, AML, PCI DSS, and SOC 2 for Financial Applications

Build compliant fintech software with KYC/AML workflows, PCI DSS card data handling, SOC 2 controls, and open banking integrations. Includes architecture diagra

Viprasol Tech Team
March 29, 2026
13 min read

Fintech Compliance Software: KYC, AML, PCI DSS, and SOC 2 for Financial Applications

Compliance is the primary reason fintech software costs more to build and maintain than a standard SaaS product. It's also the primary reason fintech products take longer to launch, and why cutting corners on compliance creates existential risk rather than just technical debt.

This guide covers the four compliance frameworks most relevant to financial software โ€” what each requires, how to implement the technical controls, and what it costs to do it properly.


The Compliance Stack for Fintech

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                    User Interface                   โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  KYC/KYB Layer     โ”‚  AML Screening  โ”‚  Fraud       โ”‚
โ”‚  (Identity verify) โ”‚  (Transaction)  โ”‚  Detection   โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚              Application Logic                      โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  PCI DSS Scope     โ”‚  Audit Logging  โ”‚  Encryption  โ”‚
โ”‚  (Card Data)       โ”‚  (Immutable)    โ”‚  at Rest/TLS โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚              SOC 2 Controls (Pervasive)             โ”‚
โ”‚  Access Control โ”‚ Monitoring โ”‚ Incident Response    โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Each layer has regulatory requirements, technical controls, and operational processes. The layers interact: your AML screening depends on having solid KYC data; your PCI scope depends on how you handle card data; your SOC 2 audit covers all of it.


KYC/KYB: Identity Verification

Know Your Customer (KYC) for individuals, Know Your Business (KYB) for companies โ€” these are the requirements to verify who you're doing business with before allowing financial activity.

KYC data collected:

  • Full legal name
  • Date of birth
  • Government-issued ID (passport, driver's license) โ€” document scan + liveness check
  • Address proof
  • SSN or equivalent national ID (for US)
  • Source of funds (for higher-risk customers)

The implementation choice: Build vs buy for identity verification.

ApproachVendorsCostBuild Time
API-based IDVPersona, Onfido, Jumio, Stripe Identity$1โ€“5 per verification2โ€“4 weeks integration
Self-builtTesseract OCR + face matching libraryEngineering + compliance overhead6โ€“12 months
Banking-as-a-ServiceUnit, Treasury Prime, SynapseBundled in BaaS pricing4โ€“8 weeks total

Build the KYC workflow, buy the identity verification engine. Building OCR + liveness detection is a compliance and fraud liability, not a competitive differentiator.

KYC status machine:

// types/kyc.ts
type KycStatus =
  | 'NOT_STARTED'
  | 'PENDING'           // User started, not submitted
  | 'SUBMITTED'         // Documents sent for review
  | 'MANUAL_REVIEW'     // Flagged for human review
  | 'APPROVED'
  | 'REJECTED'
  | 'EXPIRED';          // Re-verification required (typically every 1โ€“2 years)

interface KycRecord {
  id: string;
  userId: string;
  status: KycStatus;
  riskLevel: 'low' | 'medium' | 'high';
  verificationProvider: 'persona' | 'onfido' | 'manual';
  externalVerificationId?: string;
  documents: KycDocument[];
  reviewNotes?: string;
  approvedAt?: Date;
  expiresAt?: Date;
  createdAt: Date;
  updatedAt: Date;
}

// services/kyc.ts
export async function initiateKyc(userId: string): Promise<string> {
  // Create Persona inquiry
  const inquiry = await persona.inquiries.create({
    'inquiry-template-id': process.env.PERSONA_TEMPLATE_ID!,
    meta: { user_id: userId },
  });

  await db.kycRecord.create({
    data: {
      userId,
      status: 'PENDING',
      verificationProvider: 'persona',
      externalVerificationId: inquiry.id,
    },
  });

  return inquiry.attributes['session-token'];  // Pass to frontend SDK
}

// Handle Persona webhook
export async function handlePersonaWebhook(event: PersonaEvent) {
  const inquiry = event.data.attributes;
  const userId = event.data.attributes.meta?.user_id;

  const newStatus: KycStatus = 
    inquiry.status === 'approved' ? 'APPROVED' :
    inquiry.status === 'declined' ? 'REJECTED' :
    inquiry.status === 'needs_review' ? 'MANUAL_REVIEW' :
    'SUBMITTED';

  await db.kycRecord.updateMany({
    where: { externalVerificationId: event.data.id },
    data: {
      status: newStatus,
      riskLevel: mapRiskScore(inquiry['risk-score']),
      approvedAt: newStatus === 'APPROVED' ? new Date() : undefined,
      expiresAt: newStatus === 'APPROVED' 
        ? addYears(new Date(), 2) 
        : undefined,
    },
  });

  if (newStatus === 'APPROVED') {
    await enableFinancialFeatures(userId);
  }
}

๐Ÿค– Can This Strategy Be Automated?

In 2026, top traders run custom EAs โ€” not manual charts. We build MT4/MT5 Expert Advisors that execute your exact strategy 24/7, pass prop firm challenges, and eliminate emotional decisions.

  • Runs 24/7 โ€” no screen time, no missed entries
  • Prop-firm compliant (FTMO, MFF, TFT drawdown rules)
  • MyFXBook-verified backtest results included
  • From strategy brief to live EA in 2โ€“4 weeks

AML: Transaction Monitoring

Anti-Money Laundering (AML) requirements mandate that you screen customers against sanctions lists, monitor transactions for suspicious patterns, and file Suspicious Activity Reports (SARs) with FinCEN.

Sanctions screening (must happen at onboarding and on every transaction):

// services/sanctions.ts
import { OfacClient } from 'ofac-api-client';  // Or use Chainalysis, Elliptic, ComplyAdvantage

const ofac = new OfacClient({ apiKey: process.env.OFAC_API_KEY! });

interface SanctionsResult {
  clear: boolean;
  matches: SanctionsMatch[];
  screeningId: string;
}

export async function screenEntity(entity: {
  name: string;
  dateOfBirth?: string;
  country?: string;
  taxId?: string;
}): Promise<SanctionsResult> {
  const result = await ofac.search({
    name: entity.name,
    dob: entity.dateOfBirth,
    country: entity.country,
    minScore: 85,  // 85%+ match score triggers review
  });

  // Log every screening โ€” required for compliance audit
  const screening = await db.sanctionsScreening.create({
    data: {
      entityName: entity.name,
      clear: result.matches.length === 0,
      matchCount: result.matches.length,
      rawResult: result,
      screenedAt: new Date(),
    },
  });

  if (result.matches.length > 0) {
    await alertComplianceTeam(screening.id, result.matches);
  }

  return {
    clear: result.matches.length === 0,
    matches: result.matches,
    screeningId: screening.id,
  };
}

// Transaction monitoring rules
export async function assessTransactionRisk(transaction: {
  userId: string;
  amount: number;       // In cents
  type: 'deposit' | 'withdrawal' | 'transfer';
  counterparty?: string;
}): Promise<{ riskScore: number; flags: string[] }> {
  const flags: string[] = [];
  let riskScore = 0;

  // Rule 1: Large cash transactions (CTR threshold: $10,000)
  if (transaction.amount >= 1_000_000) {  // $10,000 in cents
    flags.push('CTR_THRESHOLD');
    riskScore += 40;
  }

  // Rule 2: Structuring detection (multiple transactions just below CTR threshold)
  const recentTotal = await getRecentTransactionTotal(
    transaction.userId,
    24  // hours
  );
  if (recentTotal + transaction.amount >= 950_000 && 
      transaction.amount < 1_000_000) {
    flags.push('POSSIBLE_STRUCTURING');
    riskScore += 60;
  }

  // Rule 3: Velocity โ€” too many transactions too fast
  const txCount = await getTransactionCount(transaction.userId, 1);  // 1 hour
  if (txCount > 10) {
    flags.push('HIGH_VELOCITY');
    riskScore += 30;
  }

  // Rule 4: Round amounts (often indicator of structured payments)
  if (transaction.amount % 100_000 === 0 && transaction.amount >= 500_000) {
    flags.push('ROUND_AMOUNT');
    riskScore += 10;
  }

  return { riskScore, flags };
}

SAR filing requirement: If a transaction is suspicious and exceeds $5,000 (or $2,000 for certain businesses), you must file a SAR with FinCEN within 30 days of detection. This is a regulatory obligation with criminal penalties for willful failure.


PCI DSS: Card Data Handling

PCI DSS (Payment Card Industry Data Security Standard) governs how you handle cardholder data. The most important rule: don't store card numbers (PAN). Let your payment processor handle it.

PCI scope reduction with Stripe Elements:

// โŒ NEVER do this โ€” storing raw card data puts you in full PCI scope
const card = {
  number: req.body.cardNumber,  // Never touch this
  expiry: req.body.expiry,
  cvv: req.body.cvv,
};

// โœ… Use tokenization โ€” card data never touches your server
// Frontend: Stripe Elements handles card input
// Your server receives only the PaymentMethod ID

// server/api/payment-methods.ts
export async function POST(request: Request) {
  const { paymentMethodId, userId } = await request.json();

  // Attach the payment method to a Stripe Customer
  const customer = await getOrCreateStripeCustomer(userId);
  
  await stripe.paymentMethods.attach(paymentMethodId, {
    customer: customer.stripeCustomerId,
  });

  // Store only the Stripe token reference โ€” not card data
  await db.paymentMethod.create({
    data: {
      userId,
      stripePaymentMethodId: paymentMethodId,  // Safe to store
      // NEVER store: card number, CVV, full expiry
    },
  });

  return Response.json({ success: true });
}

PCI compliance levels by transaction volume:

LevelAnnual TransactionsRequirement
Level 1> 6 millionAnnual QSA audit + quarterly network scans
Level 21โ€“6 millionAnnual SAQ + quarterly scans
Level 320,000โ€“1 million (e-commerce)Annual SAQ + quarterly scans
Level 4< 20,000 (e-commerce)Annual SAQ

Using Stripe/Braintree/Adyen without storing card data puts you in SAQ-A (the simplest questionnaire). Handling card data directly triggers SAQ-D or a full QSA audit.


๐Ÿ“ˆ Stop Trading Manually โ€” Let AI Do It

While you sleep, your EA keeps working. Viprasol builds prop-firm-compliant Expert Advisors with strict risk management, real backtests, and live deployment support.

  • No rule violations โ€” daily drawdown, max drawdown, consistency rules built in
  • Covers MT4, MT5, cTrader, and Python-based algos
  • 5.0โ˜… Upwork record โ€” 100% job success rate
  • Free strategy consultation before we write a single line

SOC 2: Trust Service Criteria

SOC 2 is an audit framework covering five trust criteria: Security, Availability, Processing Integrity, Confidentiality, and Privacy. Most B2B fintech customers require SOC 2 Type II certification.

SOC 2 technical controls to implement early:

// 1. Immutable audit logging โ€” every sensitive action logged
// services/auditLog.ts
export async function logAuditEvent(event: {
  actorId: string;
  actorType: 'user' | 'admin' | 'system';
  action: string;
  resourceType: string;
  resourceId: string;
  before?: unknown;
  after?: unknown;
  ipAddress?: string;
  userAgent?: string;
}) {
  // Write to append-only table โ€” no UPDATE/DELETE allowed
  await db.$executeRaw`
    INSERT INTO audit_log (
      actor_id, actor_type, action, resource_type, resource_id,
      before_state, after_state, ip_address, user_agent, occurred_at
    ) VALUES (
      ${event.actorId}, ${event.actorType}, ${event.action},
      ${event.resourceType}, ${event.resourceId},
      ${JSON.stringify(event.before)}, ${JSON.stringify(event.after)},
      ${event.ipAddress}, ${event.userAgent}, NOW()
    )
  `;
}

// Postgres: restrict DELETE on audit_log via row-level security
// CREATE POLICY audit_log_no_delete ON audit_log FOR DELETE USING (false);
# 2. Encryption at rest โ€” AWS RDS encryption config (Terraform)
resource "aws_db_instance" "primary" {
  engine                 = "postgres"
  engine_version         = "16.1"
  storage_encrypted      = true        # AES-256 encryption at rest
  kms_key_id            = aws_kms_key.rds.arn
  
  backup_retention_period = 30         # 30-day backups
  deletion_protection    = true        # Prevent accidental deletion
  
  # Enable enhanced monitoring
  monitoring_interval    = 60
  monitoring_role_arn    = aws_iam_role.rds_monitoring.arn
}

SOC 2 controls summary:

ControlImplementation
Access controlMFA for all admin access, RBAC, quarterly access reviews
EncryptionTLS 1.3 in transit, AES-256 at rest, KMS key management
Audit loggingImmutable audit trail for all sensitive operations
Vulnerability managementWeekly dependency scans, monthly pen tests
Incident responseDocumented IR plan, < 4h detection SLA
Change managementAll prod changes via PR + approval
Availability99.9% SLA, RTO < 4h, RPO < 1h

Compliance Cost Reality

ComplianceOne-Time BuildAnnual OngoingWho Does It
KYC integration (Persona)$15,000โ€“40,000$1โ€“5/verification + $2,000โ€“5,000/mo platformEngineering + Compliance
AML transaction monitoring$20,000โ€“60,000$500โ€“2,000/mo (self) or $2,000โ€“8,000/mo (vendor)Engineering + Compliance Officer
PCI SAQ-A (no card storage)$3,000โ€“8,000$1,000โ€“3,000/year (SAQ + scans)Engineering + Assessor
PCI Level 1/2 (storing cards)$100,000โ€“300,000$30,000โ€“100,000/year (QSA audit)QSA + Engineering
SOC 2 Type I$30,000โ€“80,000โ€”Auditor ($20โ€“50K) + Engineering
SOC 2 Type II$60,000โ€“150,000$30,000โ€“80,000/year renewalAuditor + ongoing controls

The compounding advantage of getting compliance right early: Companies that implement proper KYC, AML, and audit logging from day one spend 40โ€“60% less on their first SOC 2 audit than those who retrofit controls onto an existing system.


Working With Viprasol

We build fintech software with compliance requirements built into the architecture from the start โ€” not retrofitted before an audit. Our experience includes payment platforms, lending software, and investment tools with KYC, AML, PCI, and SOC 2 requirements.

We also help teams navigate the compliance landscape: determining which requirements apply, selecting vendors, and implementing technical controls that satisfy auditors while keeping the product moving.

โ†’ Talk to our fintech team about your compliance requirements.


See Also

Share this article:

About the Author

V

Viprasol Tech Team

Custom Software Development Specialists

The Viprasol Tech team specialises in algorithmic trading software, AI agent systems, and SaaS development. With 100+ projects delivered across MT4/MT5 EAs, fintech platforms, and production AI systems, the team brings deep technical experience to every engagement. Based in India, serving clients globally.

MT4/MT5 EA DevelopmentAI Agent SystemsSaaS DevelopmentAlgorithmic Trading

Ready to Automate Your Trading?

Get a custom Expert Advisor built by professionals with verified MyFXBook results.

Free consultation โ€ข No commitment โ€ข Response within 24 hours

Viprasol ยท Trading Software

Need a custom EA or trading bot built?

We specialise in MT4/MT5 Expert Advisor development โ€” prop-firm compliant, forward-tested before live, MyFXBook verifiable. 5.0โ˜… Upwork, 100% Job Success, 100+ projects shipped.