Skip to main content
npayload is launching soon.
npayloadDocs
Solutions

npayload for Fintech

Payment events, compliance, encryption, audit trails, and exactly-once processing

The challenge

Financial systems operate under strict requirements that most messaging platforms were not designed for. Every transaction must be processed exactly once. Sensitive payment data must be encrypted in transit and at rest. Regulators require complete audit trails with the ability to replay events for compliance reviews. A single missed or duplicated event can mean lost money, failed reconciliation, or regulatory penalties.

Building this infrastructure in-house means solving cryptography, idempotency, ordered delivery, and audit logging before writing any business logic.

How npayload solves it

End-to-end encryption for sensitive data

With E2E encryption enabled, npayload cannot read your message payloads. Only your services with the correct keys can decrypt the data. Metadata remains visible for routing and monitoring, while payment details stay private.

E2E encrypted payment events
import { NPayload } from "@npayload/node";

const np = new NPayload({ apiKey: process.env.NPAYLOAD_API_KEY });

// Create an encrypted channel for payment events
const channel = await np.channels.create({
  name: "payments.processed",
  type: "standard",
  privacy: "e2e", // npayload never sees the payload
});

await np.messages.publish({
  channelId: channel.id,
  type: "payment.completed",
  payload: {
    transactionId: "txn_8f3k2m",
    amount: 15000,
    currency: "usd",
    cardLast4: "4242",
    merchantId: "merch_abc",
  },
});

For cases where you need npayload to route based on metadata but still protect the payload, use hybrid mode:

Hybrid encryption
const channel = await np.channels.create({
  name: "payments.sensitive",
  type: "standard",
  privacy: "hybrid", // Metadata visible, payload encrypted
});

Exactly-once processing with idempotency keys

Prevent duplicate charges and double-bookings with built-in idempotency. If a publish is retried due to a network issue, npayload deduplicates it automatically.

Idempotent payment processing
// The idempotency key ensures this event is processed exactly once,
// even if the publish call is retried.
await np.messages.publish({
  channelId: "payments.charges",
  type: "charge.initiated",
  idempotencyKey: `charge-${orderId}-${attemptId}`,
  payload: {
    orderId,
    amount: 9900,
    currency: "usd",
    customerId: "cus_xyz",
  },
});

Transactional publish for atomic operations

When a payment triggers multiple downstream actions (charge the card, update the ledger, send a receipt), all events publish atomically. Either all events are delivered or none are.

Atomic multi-service publish
await np.messages.publishTransactional([
  {
    channelId: "payments.ledger",
    type: "ledger.entry.created",
    payload: { accountId: "acc_123", amount: -9900, type: "debit" },
  },
  {
    channelId: "payments.fulfillment",
    type: "order.paid",
    payload: { orderId: "ord_456", paidAt: new Date().toISOString() },
  },
  {
    channelId: "notifications.receipts",
    type: "receipt.send",
    payload: { customerId: "cus_xyz", amount: 9900 },
  },
]);

Streams for audit trails and compliance replay

Streams provide an immutable, ordered log of every event. Compliance teams can replay events from any point in time for audits, investigations, or reconciliation.

Audit trail with streams
// Create a stream for compliance logging
const stream = await np.streams.create({
  name: "audit.payments",
  retentionDays: 2555, // 7 years for regulatory compliance
});

// Replay events from a specific point for audit
const events = await np.streams.consume({
  streamId: stream.id,
  fromOffset: auditStartOffset,
  maxMessages: 1000,
});

Dead letter queue for guaranteed recovery

When a downstream service fails to process a payment event, the message moves to a dead letter queue. Your team can inspect failed events, fix the issue, and replay them with full visibility.

DLQ inspection and replay
// List failed messages
const failed = await np.dlq.list({
  channelId: "payments.charges",
  limit: 50,
});

// After fixing the downstream issue, replay failed events
for (const message of failed) {
  await np.dlq.replay({ messageId: message.id });
}

Example: payment processing pipeline

Compliance features

FeatureHow it helps
End-to-end encryptionPayment data encrypted at rest and in transit. npayload cannot read payloads.
Hybrid encryptionRoute on metadata while keeping payloads private.
Idempotency keysPrevent duplicate transactions from retries or network issues.
Streams with configurable retentionImmutable audit logs with multi-year retention for regulatory requirements.
Transactional publishAtomic multi-service operations prevent partial state.
Dead letter queuesNo message is ever silently lost. Failed events are preserved for replay.
Message signingVerify message integrity and origin.
SOC 2 readinessSecurity controls aligned with SOC 2 Type II requirements.
GDPR complianceData residency controls with cross-region configuration.

Next steps

Was this page helpful?

On this page