Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.trymaven.com/llms.txt

Use this file to discover all available pages before exploring further.

1

Set up your project

If you haven’t already: create an account, create an app, connect a gateway, and grab a test API key (mvn_test_*). Same setup as voice — gateway connections and API keys are shared.
2

Customize the widget (optional)

Open your app → Chat Payments tab in the dashboard. Set your colors, labels, and which fields to show (cardholder name, billing ZIP). Hit Save.These settings apply automatically to every session from this project. You can still override per-session via the API, but most merchants just set it once.
3

Server — create a session

When your chatbot is ready to collect payment, your backend calls:
curl https://api.trymaven.com/v1/widget-sessions \
  -H "Authorization: Bearer $MAVEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "project": "my-app",
    "gateway": "stripe",
    "amount_cents": 10000,
    "description": "Order #1234"
  }'
Response:
{
  "session_id": "8a7f3d2b-...",
  "widget_url": "https://api.trymaven.com/widget/8a7f3d2b-...",
  "expires_at": "2026-04-14T19:15:00Z"
}
Hand the session_id to your frontend — via WebSocket message, HTTP response, whatever your chatbot uses.
4

Frontend — load the SDK once

Add this once to your page, ideally before your chatbot renders:
<script src="https://api.trymaven.com/widget/v1/widget.js"></script>
This exposes a global Maven object with one method: createPayment().
5

Frontend — mount the widget when ready

When your chatbot receives the session_id, mount the widget into a <div> inside the chat message:
const payment = Maven.createPayment({
  sessionId: "<SESSION_FROM_YOUR_SERVER>",
  onSuccess: (result) => {
    // result = { transaction_id, card_brand, card_last4, amount_cents, currency, status }

    // Typical things to do here (all optional — Maven already shows
    // a green "Payment confirmed" screen inside the iframe):
    chatbot.sendMessage(`Paid — ${result.card_brand} •• ${result.card_last4}`);
    await db.orders.markPaid(orderId, result.transaction_id);
    // or: window.location = `/thanks?txn=${result.transaction_id}`;
  },
  onFailure: (error) => {
    // error = { error_code, error_message }
    chatbot.sendMessage(`Payment didn't go through: ${error.error_message}`);
  },
});

payment.mount("#chat-payment-slot");
The iframe appears inline. Customer types their card, hits pay. Your callbacks fire — onSuccess and onFailure are hooks into your app so you can continue the chatbot conversation, update your database, or redirect the customer. The widget itself handles the card form, charging, and the success/failure UI inside the iframe.
6

Handle webhook (recommended)

Configure a webhook URL on the project. Maven fires the same payment-success / payment-failed event for widget payments as it does for voice — with an additional source: "chat" field.See Webhooks for the full payload.

Common errors

POST /v1/widget-sessions can return these if something’s off in your setup:
StatusCodeWhat it meansFix
401Bad or missing API keyCheck the Authorization: Bearer mvn_test_... header
404project_not_foundProject slug doesn’t exist in your orgDouble-check the project value matches a slug in your dashboard
422gateway_not_connectedGateway isn’t connected for this envConnect the gateway in the dashboard (Gateways tab). Test keys need test credentials; live keys need live credentials.
422invalid_amountamount_cents is 0 or negative in charge modePass amount_cents > 0, or use mode: "tokenize" to save a card without charging
429Rate limitedBack off; defaults are 20 session creates/minute per IP
If the widget mounts but doesn’t render, check your browser console. The usual culprit is Maven is not defined — that means the <script src="…"> tag didn’t load. Hard-refresh and check the URL is reachable.

Test cards

Use these with your mvn_test_* key against a gateway in sandbox mode:
OutcomeNumberCVVExpiry
Success4242 4242 4242 4242Any 3 digitsAny future date
Declined4000 0000 0000 0002Any 3 digitsAny future date
Amex3782 822463 10005Any 4 digitsAny future date

Full example — vanilla JS chatbot

<!doctype html>
<html>
<body>
  <div id="chat">
    <!-- messages appended here -->
  </div>

  <script src="https://api.trymaven.com/widget/v1/widget.js"></script>
  <script>
    async function collectPayment(amount) {
      // 1. Ask your server to create the session
      const { sessionId } = await fetch("/api/create-payment-session", {
        method: "POST",
        body: JSON.stringify({ amount }),
      }).then(r => r.json());

      // 2. Add a chat bubble that will host the widget
      const bubble = document.createElement("div");
      bubble.className = "chat-message bot";
      bubble.innerHTML = `<div class="slot"></div>`;
      document.getElementById("chat").appendChild(bubble);

      // 3. Mount the widget into that bubble
      Maven.createPayment({
        sessionId,
        onSuccess: (result) => {
          addBotMessage(`Paid — ${result.card_brand} •• ${result.card_last4}`);
        },
        onFailure: (error) => {
          addBotMessage(`Payment failed: ${error.error_message}`);
        },
      }).mount(bubble.querySelector(".slot"));
    }
  </script>
</body>
</html>

Next

SDK Reference

Complete options, callbacks, and controller methods.

Customization

Theme, labels, fields, and sizing options.