Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/IvanchoDev89/maleku-system/llms.txt

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

Maleku System uses Stripe Checkout for all guest-facing payment flows. After creating a booking, the client application requests a Checkout Session from this API, then redirects the user to Stripe’s hosted payment page. On success, Stripe posts a webhook event that confirms the booking. The platform retains a 10% commission on every transaction via Stripe Connect.

POST /api/v1/stripe/checkout

Creates a Stripe Checkout Session for a pending booking. The session is tied to the authenticated user’s booking and includes the commission split configured on the vendor’s Stripe Connect account. Auth: Bearer token — must be the booking owner Rate limit: 10 requests/minute per IP
booking_id
string
required
UUID of a pending booking to pay for.
success_url
string
required
URL to redirect the user to after successful payment. Must belong to an allowed domain (see warning below).
cancel_url
string
required
URL to redirect the user to if they cancel checkout. Same domain restrictions apply.
Both success_url and cancel_url are validated against an allowlist of permitted hostnames to prevent open redirect attacks. Allowed hosts are derived from SITE_URL in settings (e.g. costaricatravel.dev, app.costaricatravel.dev) plus localhost / 127.0.0.1 for development. Requests with URLs on other domains are rejected with 422 Unprocessable Entity.
Example request
curl -X POST https://api.malekusystem.com/api/v1/stripe/checkout \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
  -H "Content-Type: application/json" \
  -d '{
    "booking_id": "c3d4e5f6-a7b8-9012-cdef-123456789012",
    "success_url": "https://app.costaricatravel.dev/bookings/c3d4e5f6/success",
    "cancel_url": "https://app.costaricatravel.dev/bookings/c3d4e5f6/cancel"
  }'
Response 200
{
  "session_id": "cs_live_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6",
  "checkout_url": "https://checkout.stripe.com/c/pay/cs_live_a1b2..."
}
Redirect the user to checkout_url immediately after receiving this response. The session expires after 24 hours. Error responses
StatusCause
404Booking not found
403Authenticated user does not own the booking
400Booking is not in pending status, or Stripe API error

POST /api/v1/stripe/webhook

Receives and processes event notifications from Stripe. This endpoint must be publicly reachable and registered in the Stripe Dashboard as a webhook endpoint. Auth: None — verified via Stripe-Signature header The raw request body is verified against STRIPE_WEBHOOK_SECRET using stripe.WebhookEvent.construct_from. Requests with a missing or invalid signature header are rejected with 400 Bad Request.

Idempotency

Every processed event ID is stored in the ProcessedWebhook table (event_id primary key, event_type, processed_at). Duplicate delivery of the same event is detected and returns {"status": "already_processed"} — preventing replay attacks and double-processing.

Handled events

EventAction
checkout.session.completedSets booking status = confirmed, stores stripe_payment_intent_id
payment_intent.succeededSets booking status = confirmed, sends payment receipt email
payment_intent.payment_failedSets booking status = cancelled
charge.refundedSets booking status = refunded, stripe_payment_status = "refunded"
All other event types are acknowledged with {"status": "ignored"} and logged at DEBUG level. Response 200 — always returned (even on processing errors) to prevent Stripe from retrying:
{
  "status": "checkout_completed",
  "session_id": "cs_live_a1b2c3d4...",
  "booking_id": "c3d4e5f6-a7b8-9012-cdef-123456789012"
}
The platform takes a 10% commission on every booking (STRIPE_COMMISSION_RATE = 0.10). This is deducted from the vendor payout automatically via Stripe Connect’s application_fee_amount. Individual vendors may have a custom commission_rate stored on their Vendor record; if set, it overrides the platform default.

Vendor Connect

Vendors must connect a Stripe account before they can receive payouts.

GET /api/v1/stripe/vendor/connect

Returns the current Stripe Connect status for the authenticated vendor. If no account exists, a new one is created and an onboarding URL is returned. Auth: Bearer token — Vendor role required Response 200VendorConnectResponse
{
  "account_id": "acct_1AbcDef2GhIjKlMn",
  "onboarding_url": "https://connect.stripe.com/setup/s/...",
  "status": "onboarding_required"
}
Possible status values:
ValueMeaning
connectedAccount is fully verified (charges_enabled and payouts_enabled are both true)
pending_verificationAccount exists but Stripe verification is incomplete
onboarding_requiredNew account created — vendor must visit onboarding_url
The underlying service functions (create_vendor_connect_account, get_connect_account_status) in stripe_service.py handle all Stripe API calls.

Refunds

POST /api/v1/stripe/bookings//refund

Issues a full or partial refund for a paid booking. Only vendors (for their own bookings) and admins may trigger refunds. Auth: Bearer token — Vendor or Admin Rate limit: 5 requests/minute per IP
amount
number
Refund amount in USD. If omitted, a full refund of booking.total_amount is issued.
reason
string
Optional reason string passed to Stripe (e.g. "customer_request", "duplicate").
Example request
curl -X POST https://api.malekusystem.com/api/v1/stripe/bookings/c3d4e5f6-a7b8-9012-cdef-123456789012/refund \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
  -H "Content-Type: application/json" \
  -d '{
    "reason": "customer_request"
  }'
Response 200RefundResponse
{
  "refund_id": "re_3AbcDef1GhIjKlMnOpQrStUv",
  "amount": 925.00,
  "status": "succeeded",
  "booking_status": "refunded"
}
When a full refund is processed, the booking’s status is automatically updated to refunded and stripe_payment_status is set to "refunded". Partial refunds do not change booking status.

Additional Endpoints

MethodPathAuthDescription
GET/api/v1/stripe/configPublicReturns publishable_key and default currency ("usd") for frontend Stripe.js initialization
GET/api/v1/stripe/bookings/{id}/payment-statusBearerChecks stripe_payment_status and booking.status — used by frontend after redirect from Stripe

Build docs developers (and LLMs) love