Skip to content

Checkout sessions: take investments from your server

Create a session with a fixed or suggested amount, redirect the investor, bring them back to your site when done and reconcile with reference and metadata.

9 min read4 chaptersFor foundersIntermediateUpdated Oct 17, 2026

Chapter 1The flow

  1. Your server creates the sessionPOST /v1/checkout/sessions with your secret key.
  2. You redirect the investor to session.urlIt is their investment page, with amount and email prefilled.
  3. The investor signs in, accepts and signsLike any investment.
  4. They return to your success_urlWith ?sesion=cs_…&inversion=….
  5. Your webhook firescheckout.session.completed and investment.confirmed, with your reference.

Chapter 2Creating the session

curl https://xvxhouuprjsmpfiwxkzz.supabase.co/functions/v1/api/v1/checkout/sessions \
  -H "Authorization: Bearer $KROWS_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-1234" \
  -d '{
    "amount": 250,
    "email": "investor@email.com",
    "reference": "order-1234",
    "metadata": { "campaign": "autumn" },
    "success_url": "https://yoursite.com/thanks",
    "cancel_url": "https://yoursite.com/invest"
  }'
FieldDescription
amountnumber, optionalFixed amount in USDC (at least 1, up to 2 decimals, not above the goal). The investor cannot change it.
suggested_amountnumber, optionalProposed amount the investor can change. Use one or the other, not both.
emailstring, optionalPrefills the investor’s email on the page.
referencestring, optionalYour identifier (order, user…), up to 200 characters. Returned in the investment and webhooks.
metadataobject, optionalUp to 20 keys and 2,000 characters. Returned as-is, untranslated.
success_urlURL, optionalWhere the investor goes when done. We append sesion and inversion as query parameters.
cancel_urlURL, optional“Go back” button if the session expired or was already paid.
Idempotency-Keyheader, recommendedUp to 100 characters. Repeating the request with the same key returns the same session.

Chapter 3Statuses and expiry

openCan be paid. Expires after 24 hours.
completeInvested. investment has the id and completed_at the date.
expiredExpired, or you closed it with POST /v1/checkout/sessions/:id/expire.

If the investor opens a completed or expired session, they see “This payment is already completed” or “This payment link has expired” and a button to your cancel_url.

Chapter 4In a window, without leaving your site

If you open the investment page in a window with ?v=1, when it finishes it notifies your page via postMessage (public investment data only). Always check the origin:

// Open the investment page in a window and hear back when it completes
const w = window.open('https://checkout.krows.app/aurora-solar?v=1', 'krows', 'width=480,height=760');
window.addEventListener('message', (e) => {
  if (e.origin !== 'https://checkout.krows.app') return;
  if (e.data?.tipo === 'krows:inversion') {
    // { tipo, slug, modo, id, importe, tokens, explorador } — public data only
    console.log('New investment', e.data.id, e.data.importe);
  }
});

To grant something valuable (access, product), trust the signed webhook, not the browser message.

Was this helpful?