Skip to navigation

Debit-card and digital-wallet funding

View as Markdown

NinjaTrader Connect supports deposits from an approved saved debit card and from Apple Pay or Google Pay. Both flows use Stripe in the user’s client and NinjaTrader’s live REST API.

These endpoints are Live-only. Do not send them to the Demo base URL.

Prerequisites

Your integration needs:

  • a bearer access token for the user;
  • the user’s eligible live accountId, user ID, and the USD currencyId;
  • Stripe.js or an applicable Stripe client integration;
  • for the conditional saved-card fallback, a NinjaTrader-approved Dyneti browser SDK integration and client key provisioned for your allowed origins.

Call getStripeConfiguration to obtain the Stripe publishable key. Never send Stripe secret keys to the browser.

Complete the funding disclosures

Before either the saved-card or digital-wallet flow, the user must review and sign both funding disclosures:

  1. Form of Risk Disclosure and Customer Authorization
  2. Payment Processor Disclosure and Authorization

Both disclosures must be signed, but the signing order is not enforced. addStripeDebitCard and startStripeFunding reject requests when either disclosure is missing.

The disclosure-signing operation is not part of the supported Connect API contract. Direct a user who has not completed both disclosures through NinjaTrader’s hosted funding experience. See Embedding the Funding Page with an iframe, and resume the API flow only after the user completes both disclosures.

Check eligibility and limits

Call checkStripeFundingEligibility before either flow:

{
"accountId": 123456,
"currencyId": 1
}

Use the returned minimumAmount and maximumAmount for the amount UI. Do not hard-code them. To validate a specific deposit, repeat the request with amount.

Stop when errorText is non-empty.

Saved debit-card flow

  1. Use Stripe.js in the user’s browser to collect the billing details and create a Stripe PaymentMethod.
  2. Call addStripeDebitCard with the Stripe string PaymentMethod ID:
{
"accountId": 123456,
"stripePaymentMethodId": "pm_example"
}
  1. Inspect the response to choose the next step. Do not use errorText as the branch discriminator:
ResponseANI resultNext step
{}PassRegistration is complete; call stripeFundingMethodDependents to resolve the approved numeric ID
Contains last4, nameOnCard, and numeric stripeFundingMethodIdFallback requiredRun the Dyneti scan and call processDyScanResult

Resolve the ID after ANI approval

When addStripeDebitCard returns {}, call stripeFundingMethodDependents with the user’s ID:

GET /v1/stripeFundingMethod/deps?masterid=654321

Select the new record with status: Approved, then use its numeric id as fundingMethodId. Do not substitute Stripe’s pm_... identifier.

Complete conditional Dyneti verification

The Dyneti step is not part of every saved-card registration. Run it only when addStripeDebitCard returns the fallback fields.

Initialize the Dyneti SDK in your client with the returned nameOnCard, last4, and stripeFundingMethodId. After the SDK completes, submit only its scan ID and the NinjaTrader numeric method ID:

{
"stripeFundingMethodId": 98765,
"scanId": "9762363e-5d82-4bd3-9f7e-e0edb8be688b"
}

The browser-side SDK key starts the scan but is not part of this request. Do not reuse NinjaTrader dashboard credentials; contact your NinjaTrader partner representative for Dyneti enablement. NinjaTrader’s funding service holds a separate server-side Dyneti API credential and uses it to retrieve the scan result directly from Dyneti.

Continue only when processDyScanResult returns isVerified: true with no errorText.

Start the saved-card deposit

Call startStripeFunding with NinjaTrader’s approved numeric ID:

{
"accountId": 123456,
"amount": 250,
"currencyId": 1,
"fundingMethodId": 98765
}

Apple Pay or Google Pay flow

The wallet flow does not create a saved card and does not use ANI or Dyneti.

  1. Initialize Stripe with the publishable key.
  2. Use Stripe Express Checkout in the user’s client to create a confirmation token.
  3. Call startStripeFunding once for the deposit:
{
"accountId": 123456,
"amount": 250,
"currencyId": 1,
"stripeConfirmationToken": "ctoken_example",
"flowType": "WalletFunding"
}

The single call refers to the NinjaTrader deposit operation. Stripe client initialization, eligibility, and confirmation-token creation still happen first.

Handle responses and rate limits

The funding endpoints return business failures in an HTTP 200 response. Always inspect errorText. An empty startStripeFunding response is not proof that the deposit succeeded: successful, canceled, and other terminal Stripe outcomes can all return an empty body.

Before calling startStripeFunding, retrieve the account’s existing CashBalanceLog entries and record the highest id. After the call, poll that endpoint with the same accountId as masterid. Credit the deposit only after a newer entry appears with the requested currencyId, a positive delta equal to the deposit amount, and cashChangeType: FundTransaction. An empty response without that matching ledger entry is not confirmation; do not retry the charge blindly. If your integration cannot perform this reconciliation, use the NinjaTrader-hosted funding flow.

addStripeDebitCard and startStripeFunding are limited to 20 calls per rolling hour per IP, count every request, and use a 3-second penalty step.

Check every HTTP 200 body for p-ticket before interpreting it as a registration or deposit response. When p-captcha is absent or false, follow the penalty-ticket procedure.

If p-captcha is true, stop all API retries and do not retry with p-ticket. A server-side integration cannot solve the reCAPTCHA challenge. Direct the user to the NinjaTrader-hosted funding flow. If the hosted flow cannot be used, wait approximately one hour for the penalty count to clear before resuming API calls. Do not treat the penalty response as proof that a card was registered or a deposit was submitted.

Next steps

  • Use startStripeFunding for both approved saved cards and wallet confirmation tokens.
  • Do not use submitDebitCardFunding as the deposit operation.
  • If you prefer a NinjaTrader-hosted flow, see Embedding the Funding Page with an iframe.