Payment

Holding credits until
a payment settles

A stolen card buys credits that burn GPU hours before the chargeback lands. Stripe tells you whether the payment went through; Nolgard tells you how much compute to release before the money settles.

Decision trace

Example · first payment, 5 000 creditsHold
  1. Inputverify({action:'checkout'}) for user_42. Third card from this device today.
  2. Reason idscard_cycling
  3. Decisionlimit · payment.threeDS: true
  4. Credits1 500 now, 3 500 after 72 h · frozen on a dispute

What it does

ReasonCheckoutElsewhere
card_testingblock: failed payments ≥3/hour from one device or ≥10/hour from one network—
card_cyclinglimit: ≥3 distinct cards from one device in 24 h · 3-D Secure and a hold—
payment_fraudblock: early fraud warning or fraudulent dispute on this device or a linked account in 180 dayslimit · GET /v1/accounts/:id returns payment_fraud and revoke_credits
refund_seriallimit: ≥2 refunds or lost disputes by the same human in 180 dayslimit on the next free-trial signup

Thresholds are per site. A hold caps spend at its share of the purchased credits; a fraud warning or a fraudulent dispute freezes the account until an owner releases it in the Payments tab.

How it works

  1. Connect the webhook

    One endpoint in your Stripe dashboard and the whsec_… secret in site settings. No Stripe API key.

  2. Gate the button

    Nolgard.execute({ action: 'checkout' }) in the browser, then verify on the server before you create the session.

  3. Release in two parts

    On limit, release the hold share now and the rest after the hold expires. Chargebacks and refunds follow the person into the next trial.

Integration

const r = await nolgard.verify({
  token, action: 'checkout',
  account: { id: user.id },
  checkout: { credits: 5000 },
});
if (r.decision === 'block' || r.decision === 'shadow') return deny();

const session = await stripe.checkout.sessions.create({
  mode: 'payment', line_items, success_url, cancel_url,
  client_reference_id: r.ref,
  metadata: { nolgard_ref: r.ref, nolgard_account: user.id },
  payment_intent_data: {
    metadata: { nolgard_ref: r.ref, nolgard_account: user.id },
    ...(r.payment?.threeDS ? { payment_method_options: { card: { request_three_d_secure: 'any' } } } : {}),
  },
});

// r.payment.hold → { share: 0.3, hours: 72 }: release 1500 credits now, 3500 after 72 h.

Data stored

Limits