Constra

Developer docs

Integrate payment operations into your product.

Constra payment operations API

Add agent-assisted payment flows to your application.

Constra gives product teams one operational layer for payment intents, provider callbacks, recovery actions, and audit trails. Start in simulator mode, validate the workflow with your application, then connect approved provider credentials when your pilot is ready.

Sandbox first
Provider adapters
Operator guardrails

Quickstart

Configure your app, not the Constra codebase.

Your application only needs a Constra API base URL, a workspace secret key, and a webhook secret. Provider credentials such as Daraja keys are configured inside Constra so your app does not have to own every rail-specific integration.

.env

bash

CONSTRA_API_BASE_URL=https://api.constra.online/v1
CONSTRA_SECRET_KEY=cs_test_your_workspace_secret
CONSTRA_WEBHOOK_SECRET=whsec_your_callback_secret
CONSTRA_DEFAULT_PROVIDER=mpesa
CONSTRA_ENVIRONMENT=sandbox

Create a workspace

Start with a sandbox workspace. It holds your API keys, provider settings, callback URLs, and audit trail.

Create payment intents

Your application sends amount, customer, provider, and reference data to Constra instead of talking to every rail directly.

Listen for events

Constra normalizes provider callbacks into stable events such as succeeded, failed, cancelled, timeout, or review_required.

Act with guardrails

Agents can draft recovery notes, retry suggestions, and operator summaries while deterministic APIs own execution.

Payment Intents

Create a payment intent

A payment intent is the source of truth for one attempted payment. It keeps the customer action, provider response, retry history, and agent review notes together under one id.

Idempotency required

Create intent

curl

curl -X POST https://api.constra.online/v1/payment-intents \
  -H "Authorization: Bearer cs_test_your_workspace_secret" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order_7429_deposit" \
  -d '{
    "amount": 1250,
    "currency": "KES",
    "provider": "mpesa",
    "customer": {
      "name": "Amina N.",
      "phone_number": "254700000000"
    },
    "reference": "order_7429",
    "description": "Solar home kit deposit",
    "agent_policy": "operator_review"
  }'

Response

json

{
  "id": "pi_01hx9k7s4v3p9e7m5n2",
  "status": "pending_user_action",
  "amount": 1250,
  "currency": "KES",
  "provider": "mpesa",
  "reference": "order_7429",
  "provider_action": {
    "type": "stk_push",
    "state": "sent_to_customer",
    "checkout_request_id": "ws_CO_120520261644291"
  },
  "next_action": "wait_for_callback"
}

Node.js

javascript

const response = await fetch("https://api.constra.online/v1/payment-intents", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CONSTRA_SECRET_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": "order_7429_deposit"
  },
  body: JSON.stringify({
    amount: 1250,
    currency: "KES",
    provider: "mpesa",
    customer: { phone_number: "254700000000" },
    reference: "order_7429",
    description: "Solar home kit deposit",
    agent_policy: "operator_review"
  })
});

const intent = await response.json();

Python

python

import os
import requests

response = requests.post(
    "https://api.constra.online/v1/payment-intents",
    headers={
        "Authorization": f"Bearer {os.environ['CONSTRA_SECRET_KEY']}",
        "Content-Type": "application/json",
        "Idempotency-Key": "order_7429_deposit",
    },
    json={
        "amount": 1250,
        "currency": "KES",
        "provider": "mpesa",
        "customer": {"phone_number": "254700000000"},
        "reference": "order_7429",
        "description": "Solar home kit deposit",
        "agent_policy": "operator_review",
    },
)

intent = response.json()

Callbacks

Receive normalized payment events

Provider callbacks are often inconsistent. Constra converts them into stable webhook events so your backend can react with simple, predictable handlers.

payment_intent.created

Constra accepted the request and created an auditable intent.

payment_intent.pending_user_action

A customer action is required, such as approving an STK push.

payment_intent.succeeded

The provider confirmed successful payment.

payment_intent.requires_recovery

The provider returned a recoverable issue such as cancellation or timeout.

payment_intent.failed

The provider returned a terminal failure or the attempt exhausted retries.

Webhook payload

json

{
  "id": "evt_01hx9m4b9s8n2",
  "type": "payment_intent.requires_recovery",
  "created_at": "2026-05-15T13:41:08Z",
  "data": {
    "payment_intent_id": "pi_01hx9k7s4v3p9e7m5n2",
    "status": "requires_recovery",
    "provider": "mpesa",
    "provider_result_code": "1032",
    "provider_result_desc": "Request cancelled by user.",
    "agent_note": "Customer cancelled the prompt. Offer retry or alternate payment timing."
  }
}

Verify signature

javascript

import crypto from "node:crypto";

export function verifyConstraWebhook(rawBody, signature, secret) {
  const digest = crypto
    .createHmac("sha256", secret)
    .update(rawBody)
    .digest("hex");

  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(digest)
  );
}

Agent Review

Use AI for recovery, not unchecked money movement.

Constra treats agents as operators with bounded tools. They can explain a failed callback, recommend a retry, prepare a dispute note, or ask for human approval. The deterministic backend still validates state, idempotency, provider credentials, and execution rules.

Safety boundary

No prompt, chat message, or generated answer should directly post funds. Constra converts agent suggestions into reviewable actions before a provider call is made.

Simulate a recoverable provider outcome

curl

curl -X POST https://api.constra.online/v1/payment-intents/pi_01hx9k7s4v3p9e7m5n2/simulate-callback \
  -H "Authorization: Bearer cs_test_your_workspace_secret" \
  -H "Content-Type: application/json" \
  -d '{
    "result_code": 1032,
    "result_desc": "Request cancelled by user."
  }'

API Reference

Sandbox API shape

The current simulator implements the core payment-intent and callback loop. The same resource shape is designed to support Daraja sandbox, Paystack test mode, and future provider adapters.

POST/v1/payment-intents

Create a new payment intent for mobile money, card, wallet, or another configured rail.

Simulator
GET/v1/payment-intents/{id}

Retrieve the latest state, provider reference, amount, customer, and recovery summary.

Simulator
GET/v1/payment-intents/{id}/events

Read the full event timeline for reconciliation, debugging, and audit review.

Simulator
POST/v1/payment-intents/{id}/simulate-callback

Apply a sandbox outcome such as success, cancellation, timeout, or insufficient funds.

Simulator
POST/v1/providers/mpesa/callback

Receive Daraja-style provider callbacks and map them into Constra payment events.

Sandbox rail
GET/v1/sandbox/overview

Return workspace stats, recent intents, callback volume, and operational activity.

Simulator

Go Live

Configure provider credentials when the rail is approved.

For M-Pesa, your team creates a Daraja app, adds the sandbox or production credentials into Constra, and points provider callbacks to the Constra callback URL for your workspace.

Recommended rollout path

1. Simulator: test product logic and operator workflows.

2. Provider sandbox: receive real provider payloads with no live settlement.

3. Pilot: route limited production transactions with monitoring and review.

Provider configuration

Provider

M-Pesa Daraja

Mode

Sandbox first, production after provider approval

Business Short Code

174379 for Daraja sandbox

Callback URL

Constra generates a provider callback URL for the workspace

Account Reference

Use your order id, invoice id, or customer reference

Credential Storage

Provider secrets stay server-side and move to Key Vault for Azure deployment

Ready to test the workflow

Open the sandbox dashboard and create an intent.

Open sandbox

Constra developer documentation.

Simulator docs use the same concepts as provider sandbox and pilot mode.