Skip to content
KrokoPay

For SaaS

Recurring billing your backend can follow

The hard part of charging for software is not the first payment. It is knowing, every month, who renewed, whose card failed and who canceled. KrokoPay turns each of those moments into a subscription status and a webhook event.

Pick a plan on the right: the request changes with it.

Rota Certa · choose your plan

Interactive demo
curl -X POST https://api.krokopay.app/v1/subscriptions \  -H "Authorization: Bearer kp_test_sk_4f9a2c7e1b8d4a6f9c3e5d7b" \  -H "Idempotency-Key: signup_cus_7Hq2LmN4pZx8Wd_starter" \  -H "Content-Type: application/json" \  -d '{    "customer_id": "cus_7Hq2LmN4pZx8Wd",    "price_id": "price_2Rc8StMnTh4Qa1",    "method": "card"  }'

Monthly or yearly is just a different price_id. Fictional prices set by the example business.

The month after the signup

Every billing moment has a name

No more guessing from bank statements. Each situation below changes the subscription status and sends one event; your app decides what that means for access.

  • What happened
    A customer subscribes
    Event and status
    subscription.createdActive
    What your app usually does
    Create the account and unlock the plan's features.
  • What happened
    The period renews and is paid
    Event and status
    subscription.renewedActive
    What your app usually does
    Extend access until the new period end.
  • What happened
    A renewal payment fails
    Event and status
    subscription.past_duePast due
    What your app usually does
    Show a banner asking to update the payment method.
  • What happened
    You pause the subscription
    Event and status
    subscription.pausedPaused
    What your app usually does
    Keep the data, limit access while paused.
  • What happened
    You resume it
    Event and status
    subscription.resumedActive
    What your app usually does
    Unlock the plan again from the next period.
  • What happened
    The subscription is canceled
    Event and status
    subscription.canceledCanceled
    What your app usually does
    Limit access at the end of the paid period.

See it happen

Play a subscription from signup to recovery

Pick a scenario and watch the status, the charges and the events of a fictional subscription move. It is the same model your backend receives.

  • Statuses: trialing, active, past_due, paused, canceled.
  • Pause and resume without losing the customer.
  • Everything also shows in your dashboard, no code needed to check.

Members club

Monthly plan · R$49.00/month

sub_5Hn2RtK8wPz4Bq
Current status
Active
Next charge
Dec 3, 2026

Subscription history

  1. Trial started

    Aug 20, 2026
    The customer subscribed with a card. No charge during the trial.subscription.created
  2. First charge paid

    Sep 3, 2026
    Trial over: R$49.00 charged and the subscription is active.charge.paid
  3. Renewed

    Oct 3, 2026
    R$49.00 charged for the new period.subscription.renewed
  4. Renewal declined

    Nov 3, 2026
    The card had insufficient funds. The subscription is past due.subscription.past_due
  5. Payment recovered

    Nov 5, 2026
    The customer updated the card and the renewal was paid.subscription.renewed

Integration

Three steps, one webhook

Create the subscription when the customer picks a plan, let the hosted checkout collect the card, and keep access in sync from a single endpoint.

  1. Create prices

    One price per plan and period, in the dashboard or via the API.

  2. Create the subscription

    POST /subscriptions with the customer and the chosen price.

  3. Listen to events

    Grant, warn or limit access from the subscription.* events.

Your webhook endpointJavaScript
export async function POST(request) {  const payload = await request.text();  const signature = request.headers.get("KrokoPay-Signature");  if (!verifySignature(payload, signature, process.env.KROKOPAY_WEBHOOK_SECRET)) {    return new Response(null, { status: 400 });  }  const event = JSON.parse(payload);  const subscription = event.data.object;​  switch (event.type) {    case "subscription.created":    case "subscription.renewed":    case "subscription.resumed":      await accounts.grantAccess(subscription.customer_id, subscription.current_period_end);      break;    case "subscription.past_due":      await accounts.showPaymentBanner(subscription.customer_id);      break;    case "subscription.paused":    case "subscription.canceled":      await accounts.limitAccess(subscription.customer_id);      break;  }  return new Response(null, { status: 200 });}

verifySignature stands for the signature check described in the webhooks docs. Contract proposal, subject to change.

Provisional API contract proposal — not an operational endpoint.

Webhooks docsTest environment

Transparency

What is ready and what is not yet

We prefer to show the gaps than to promise them away. If one of these blocks your launch, tell us.

Already in the product

  • Monthly and yearly prices per plan.
  • Statuses and webhook events for every lifecycle change.
  • Pause, resume and cancel from the dashboard or the API.
  • Test mode with test keys and fictional data.

Still being defined

  • Upgrades and downgrades with proration.To be announced
  • Automatic retry schedule after a failed renewal.To be announced
  • Renewal by Pix.To be announced
  • Fees and payout times.To be announced
See what is defined on pricing

Questions from SaaS teams

Short answers, including the ones that are still "not yet".

Did not find your question?

What is defined on pricingTalk to us

Yes. Create one price per period for each plan; the subscription points to the price the customer picked.

There is no plan-change action with proration yet. Today you cancel and create a new subscription; a proper change flow is to be announced.

The subscription moves to past_due and you receive subscription.past_due. The automatic retry schedule is to be announced.

Subscriptions are charged by card today. How a Pix renewal would work is still being defined.

No. The card is typed in KrokoPay's own checkout, so your servers never receive the card number.

Fees and payout times are still to be announced. The pricing page shows what is defined so far.

Not for now. The API is a provisional contract proposal, documented with cURL and plain fetch examples.

Start billing your first plan

Create your account, set up a test price and watch the events arrive.

No real payment is made.