Prood
ApplicationsDashboard

Integrations

Configure payment and service provider credentials per tenant in the dashboard.

The dashboard Integrations section lets merchants configure provider credentials that override environment-level defaults. Credentials are encrypted at rest and scoped per organization.

Integration list

Route: /integrations

Shows available providers grouped by category:

CategoryProviders
PaymentsStripe, Easypay, Ifthenpay
NotificationsResend, SMTP (UI only โ€” no runtime factory yet)
AnalyticsGoogle Analytics 4 (UI only)

Each provider card shows connection status (configured / not configured).

Provider configuration

Route: /integrations/[provider]

Dynamic form rendered from the provider registry in lib/providers.ts. Each provider defines its configurable fields:

Stripe

FieldEnv fallbackDescription
secretKeySTRIPE_SECRET_KEYServer-side secret key
webhookSecretSTRIPE_WEBHOOK_SECRETWebhook signing secret
publishableKeyNEXT_PUBLIC_STRIPE_PUBLISHABLE_KEYClient-side publishable key

Easypay

FieldEnv fallbackDescription
accountIdEASYPAY_ACCOUNT_IDEasypay account ID
apiKeyEASYPAY_API_KEYAPI key
baseUrlEASYPAY_BASE_URLAPI base URL (prod/sandbox)

Ifthenpay

FieldEnv fallbackDescription
antiPhishingKeyIFTHENPAY_ANTIPHISHING_KEYAnti-phishing key
mbKeyIFTHENPAY_MB_KEYMultibanco key
mbwayKeyIFTHENPAY_MBWAY_KEYMB WAY key
ccKeyIFTHENPAY_CC_KEYCredit card key

How credentials flow

Drag to pan ยท Scroll to zoom

Storage schema

CREATE TABLE integration_config (
  id          TEXT PRIMARY KEY,
  organization_id TEXT NOT NULL,
  provider    TEXT NOT NULL,  -- 'stripe', 'easypay', 'ifthenpay'
  config      JSONB NOT NULL, -- encrypted key-value pairs
  created_at  TIMESTAMPTZ,
  updated_at  TIMESTAMPTZ,
  UNIQUE (organization_id, provider)
);

Server actions

app/(dashboard)/integrations/actions.ts:

'use server'
export async function saveIntegration(provider: string, config: Record<string, string>) {
  return withActiveOrg(async (orgId) => {
    const encrypted = encryptConfig(config)
    await upsertIntegrationConfig(orgId, provider, encrypted)
  })
}

Security

  • Credentials encrypted with AES-256-GCM (enc:v1: prefix)
  • Encryption key: INTEGRATION_ENCRYPTION_KEY (dedicated key in production)
  • Dashboard decrypts on read for form display; never exposes raw secrets to client
  • Commerce layer decrypts when building providers at runtime
  • Plaintext values (no enc:v1: prefix) supported for dev/migration

On this page