Skip to navigation

Reconcile the funding outcome

View as Markdown

A startStripeFunding response doesn’t tell you whether NinjaTrader created the deposit or whether cash posted. Reconcile every attempt before you credit it. This page covers Debit-card funding and Wallet Pay Funding.

HTTP 200 doesn’t guarantee success. A successful deposit, a canceled deposit, and another terminal Stripe outcome can each return an empty body with no errorText, so don’t credit a deposit from the response alone.

Capture a baseline

Before you call startStripeFunding, call fundTransactionDependents with the account ID as masterid and record the highest id. For wallet funding, re-read it if the user waits a long time before selecting a wallet.

Identify the outcome

After the call, read fundTransactionDependents again. A newer incoming record with the requested amount and currency and fundPaymentType: DCR identifies this attempt’s outcome. The record’s existence doesn’t mean the deposit succeeded. Store its id and inspect its status:

  • Declined means the attempt failed. Close the marker as failed, and don’t treat the record as a deposit or account credit.
  • Pending and InTransit mean the attempt is still processing. Don’t treat it as a failure or an account credit, and keep the flow locked against a duplicate request.
  • An unexpected status isn’t proof of success. Continue tracking the known transaction, or contact NinjaTrader support.

While a deposit is Pending, Suspended, Locked, or InTransit, checkStripeFundingEligibility returns a lowered maximumAmount or a non-empty errorText. Wait for the deposit to settle instead of retrying.

Confirm the cash credited

A Pending DCR deposit has no immediate CashBalanceLog entry. An InTransit deposit can apply only the amount remaining under the account’s funds-in-transit cap, so the first positive ledger delta can be smaller than the deposit.

To identify the cash credited, read CashBalanceLog entries and match fundTransactionId to the DCR record. Don’t require delta to equal the full deposit amount.

A deposit the user starts separately needs a new baseline and, for wallet funding, a new wallet confirmation.

Handle rate limits and CAPTCHA

addStripeDebitCard and startStripeFunding have CAPTCHA enabled, so a penalty response includes p-captcha: true. For the limits, see Rate limits. For the fields and recovery, see Penalty tickets. Check every HTTP 200 body for p-ticket before you read it as a registration or deposit response.

A server-side integration can’t solve the reCAPTCHA, so don’t retry either endpoint with p-ticket. This table lists where funding differs from the general procedure:

ResponseDebit-card fundingWallet funding
p-ticket or p-captcha: trueStop. Wait about one hour for the endpoint’s count to clear. The funding handler didn’t run, so a penalty response doesn’t prove a card was registered or a deposit submitted.Stop. Discard the old ConfirmationToken and require a new user-initiated confirmation before a later attempt.
HTTP 429Make no NinjaTrader API calls for one hour.Make no NinjaTrader API calls for one hour.
Empty, missing, or timed outDon’t send another startStripeFunding request. Reconcile first.Keep the flow locked, and never resend the ConfirmationToken or send a second request. Reconcile first.

A CAPTCHA blocks retries of the triggering endpoint. It doesn’t block the read-only reconciliation endpoints. An HTTP 429 blocks every endpoint for the hour, and an earlier call resets the clock.

For debit cards, don’t call addStripeDebitCard again for a card that may already be registered. Read the funding methods first.

When the outcome can’t be established

A read that finds no matching DCR record doesn’t prove no deposit happened, and an empty, missing, or timed-out response proves nothing either. Never start a fresh API flow merely because reads found nothing. Keep the marker, use the NinjaTrader-hosted funding flow, or contact NinjaTrader support.

Keep a durable marker (wallet funding)

The in-memory confirmationInFlight and fundingRequestSent guards are lost on a page reload, a tab close, or a crash. To survive that, record a non-secret marker in your own durable storage, preferably server-side and keyed by the account. Write it, and wait until the write is confirmed, before you send startStripeFunding. The marker says a funding request was possibly sent. It holds:

  • the account
  • the amount
  • the baseline FundTransaction id
  • lastAttemptAt, updated before every funding-request attempt, not only the first
  • whether an HTTP 429 or a CAPTCHA demand was received, and when
  • a conservative lockoutUntil

The marker must not hold an access token, a ConfirmationToken, a Stripe secret, or any wallet data.

Check for the marker before you create any new flow. After a reload, honor lockoutUntil before making any API call when the marker records an HTTP 429. Then reconcile, and never resend the old token. A matching DCR record resolves the marker according to its status, as described in Identify the outcome. Without a matching record, keep the marker and use the hosted flow or contact NinjaTrader support.

Next steps