Zenso Docs

AI agent integration spec

A complete contract block that can be copied into an AI coding agent or implementation ticket.

Copy this integration spec

Give this entire spec to your AI coding agent. It is framework-neutral and includes the request shapes, response shapes, webhook rules, and security constraints needed for a safe Hosted Checkout integration.

zenso-integration-spec.md

markdown

# Zenso Integration Spec

Use this file as context for an AI coding agent or engineering handoff.

## Product model

Zenso Hosted Checkout lets a merchant create a checkout session on their server, redirect the customer to Zenso, and fulfill the order from signed webhook events. Redirects improve customer experience. Webhooks are the authoritative server-side payment signal.

## API

Base URL: https://api.zenso.lk
Authentication: Authorization: Bearer $ZENSO_SECRET_KEY
Create requests should send an Idempotency-Key header.
Amounts are integers in the smallest currency unit. For LKR, Rs 30.00 is 3000.

Secret keys must only be used on the server. Never expose a Zenso secret key in browser JavaScript, mobile apps, or frontend environment variables.

## Create checkout session

POST /api/v1/checkout/sessions/

Headers:
Authorization: Bearer $ZENSO_SECRET_KEY
Content-Type: application/json
Idempotency-Key: order_123

Request:
{
  "amount": 3000,
  "currency": "LKR",
  "line_items": [
    {
      "name": "Invoice 1001",
      "amount": 3000,
      "quantity": 1,
      "currency": "LKR"
    }
  ],
  "customer": {
    "email": "customer@example.com",
    "name": "Jane Perera",
    "phone": "+94770000000"
  },
  "billing_details": {
    "first_name": "Jane",
    "last_name": "Perera",
    "email": "customer@example.com",
    "phone": "+94770000000",
    "address": {
      "line1": "123 Main Street",
      "city": "Colombo",
      "country": "LK"
    }
  },
  "success_url": "https://example.com/success",
  "cancel_url": "https://example.com/cancel",
  "metadata": {
    "order_id": "order_123"
  }
}

Response:
{
  "id": "cs_...",
  "object": "checkout_session",
  "status": "open",
  "payment_status": "unpaid",
  "checkout_url": "https://pay.zenso.lk/cs/cs_..."
}

Redirect the customer to checkout_url.

## Retrieve checkout session

GET /api/v1/checkout/sessions/{id}/

Use this for display or debugging. Do not use browser redirects as proof of payment.

## Create payment link

POST /api/v1/payment_links/

Request:
{
  "amount": 3000,
  "currency": "LKR",
  "description": "Invoice 1001",
  "metadata": {
    "order_id": "order_123"
  }
}

Response:
{
  "id": "plink_...",
  "object": "payment_link",
  "status": "active",
  "url": "https://pay.zenso.lk/pl/plink_..."
}

## Redirect behavior

After a successful payment, Zenso may redirect the customer to success_url with:
checkout_session_id=cs_...
payment_status=paid

This redirect is not authoritative. Fulfill orders only after verifying a signed webhook.

## Webhooks

Zenso signs webhook deliveries with:
Zenso-Signature: t=<timestamp>,v1=<hmac>

Verification:
1. Read the raw request body before JSON parsing.
2. Parse timestamp t and signature v1 from Zenso-Signature.
3. Compute HMAC-SHA256 using the webhook signing secret over timestamp + "." + rawBody.
4. Compare signatures with a constant-time comparison.
5. Reject stale timestamps.
6. Fulfill idempotently by event ID.

Events:
checkout.session.completed
payment_intent.succeeded
payment_intent.failed
charge.captured
charge.refunded

## Common errors

401: Missing, invalid, or revoked secret key.
403: Live payments are not approved or the key cannot perform the action.
400: Invalid request body. Check amount, currency, URLs, and customer fields.
429: Too many requests. Retry later with the same Idempotency-Key when appropriate.

OpenAPI

For machine-readable endpoint details, use https://api.zenso.lk/api/v1/openapi.json.