Powered by Arrowhead Advisory Group
Developers

Penumbra, inside your CRM.

Penumbra has no dashboard of its own. It's a headless engine you drop into the CRM your team already runs. One typed client over the full orchestration API: routing decisions, transactions, the chargeback fighter, settlement, ledger, and analytics. Request a sandbox key and the SDK comes with it.

90+
Client methods
1
Typed client
Any
CRM, via REST
1 day
Sandbox turnaround

Integrate in four steps

Penumbra runs server-side, behind your CRM. Your team never logs into a Penumbra dashboard; the engine pushes every decision into the tools you already use.

1
Request a sandbox key. You get an sk_test_… key and access to the @penumbra/integration client. No real money moves in sandbox.
2
Drop the client into your CRM or backend. createClient({ baseUrl, apiKey }). No React, no framework lock-in; it's a dependency-free client that runs in Node, an edge function, or any JS runtime.
3
Call the engine. Read transactions and the routing decision behind each charge, fight chargebacks, configure settlement, pull analytics. Render it in your CRM's own UI.
4
Flip to live. Swap sk_test_ for sk_live_. No code changes; environments are key-scoped.

The same first calls, typed in TypeScript or plain REST from any language:

import { createClient } from '@penumbra/integration';

const penumbra = createClient({
  baseUrl: 'https://api.penumbrahq.com/api/v1',
  apiKey: process.env.PENUMBRA_API_KEY, // sk_test_… from your sandbox
});

// Every charge, with the routing decision that picked the PSP
const { data } = await penumbra.getPayments({ limit: '25' });
for (const txn of data) {
  console.log(txn.psp_used, txn.routing_decision);
}

// Fight a chargeback: score it, draft the rebuttal, submit
const disputes = await penumbra.listDisputes();
await penumbra.scoreDispute(disputes.data[0].id);
const rebuttal = await penumbra.fightDispute(disputes.data[0].id);
curl https://api.penumbrahq.com/api/v1/payments?limit=25 \
  -H "Authorization: Bearer sk_test_..." \
  -H "Accept: application/json"
import os, requests

resp = requests.get(
    "https://api.penumbrahq.com/api/v1/payments",
    headers={"Authorization": f"Bearer {os.environ['PENUMBRA_API_KEY']}"},
    params={"limit": 25},
)

print(resp.json()["data"])

TypeScript-first today. The packaged client is TS/JS. Every endpoint is plain REST, so any language works now. See the API reference for the full client-library matrix.

What the client covers

One client, the whole orchestration surface. A few of the domains:

Routing & decisions

Every charge carries the routing_decision that chose its PSP: the "why this processor" narrative, in your CRM.

Transactions

List, filter, retrieve, refund, capture. getPayments(), getPayment(id).

Chargeback fighter

Score a dispute, draft the AI rebuttal, run image forensics, submit. scoreDispute · fightDispute.

Settlement & payouts

Per-merchant destinations, splits, batch settlement across bank, crypto, and forex rails.

Ledger

Double-entry, immutable. Balances, entries, journals, splits, all auditable.

Analytics

Approval rate, PSP comparison, decline heatmaps, value saved by routing, portfolio health.

Statements

Upload a processor statement; get the fee decomposition and savings back.

Onboarding

Initiate PSP-native boarding and poll the decision. Penumbra holds a thin identity record.

Webhooks

Subscribe to the Pen.v1 events; HMAC-signed, retried, 99.9% delivery SLO.

It runs inside your CRM

Penumbra ships native in Aquifer, our merchant-services CRM, and connects to the CRM you already run. The pattern is the same everywhere: the client runs server-side, behind your app, and your front-end renders the data in your own UI.

Server-side keys

The sk_ key lives on your backend, never in the browser. Your app proxies the calls.

No dashboard to adopt

There's no Penumbra app to log into. Transactions, disputes, and payouts surface in your CRM.

Sandbox then live

sk_test_ hits simulated processors; sk_live_ moves real money. Same code path.

Request sandbox access.

We'll review within one business day and send your sandbox key plus the integration client. Build the whole flow against simulated processors before a dollar moves.

Request sandbox access