CtrlK
BlogDocsLog inGet started
Tessl Logo

testland/braintree-test-cards

Wraps Braintree (PayPal-owned) sandbox testing patterns: sandbox merchant credentials, Drop-in / Hosted Fields client-side patterns, the Transaction lifecycle (submitted_for_settlement → settled), Braintree's distinctive test-card behaviours (specific PANs trigger specific errors), and the webhook verification (Braintree Webhook Parser). Use when testing Braintree-integrated code.

80

Quality

100%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide

SecuritybySnyk

Medium

Suggest reviewing before use

Overview
Quality
Evals
Security
Files
name:
braintree-test-cards
description:
Wraps Braintree (PayPal-owned) sandbox testing patterns: sandbox merchant credentials, Drop-in / Hosted Fields client-side patterns, the Transaction lifecycle (submitted_for_settlement → settled), Braintree's distinctive test-card behaviours (specific PANs trigger specific errors), and the webhook verification (Braintree Webhook Parser). Use when testing Braintree-integrated code.

braintree-test-cards

Overview

Per developer.paypal.com/braintree/docs/reference/general/testing, the Braintree sandbox accepts the same API as production with deterministic test-card responses.

The notable distinction: Braintree's Transaction state machine includes an explicit submitted_for_settlementsettled transition with simulated settlement in sandbox.

When to use

  • Tests for code using Braintree.
  • Drop-in / Hosted Fields client-side flow tests.
  • 3DS tests per 3ds-test-flow-reference.

Authoring

Setup

Get sandbox credentials at braintreepayments.com/sandbox - merchant ID + public + private keys.

Install

npm install braintree
pip install braintree

Initialize

import braintree from 'braintree';

const gateway = new braintree.BraintreeGateway({
  environment: braintree.Environment.Sandbox,
  merchantId: process.env.BT_SANDBOX_MERCHANT_ID!,
  publicKey: process.env.BT_SANDBOX_PUBLIC_KEY!,
  privateKey: process.env.BT_SANDBOX_PRIVATE_KEY!,
});

Test cards

Per developer.paypal.com/braintree/docs/reference/general/testing/node:

CardBehaviour
4111 1111 1111 1111Authorized + settled
5555 5555 5555 4444Authorized + settled (Mastercard)
4000 1111 1111 1115Processor declined (general)
4000 0000 0000 0002Processor declined
4000 0000 0000 11093DS frictionless
4000 0000 0000 10913DS challenge

By amount:

AmountBehaviour
$2000.00Processor declined (insufficient funds)
$2999.00Fraud failure
$3000.00Bank failure

This amount-based behaviour is unique to Braintree.

Transaction

const result = await gateway.transaction.sale({
  amount: '10.00',
  paymentMethodNonce: 'fake-valid-nonce',  // From Braintree client SDK
  options: { submitForSettlement: true },
});

expect(result.success).toBe(true);
expect(result.transaction.status).toBe('submitted_for_settlement');

fake-valid-nonce is a sandbox-only nonce that represents a successful tokenization. Real flow uses Drop-in or Hosted Fields to produce a real nonce.

Settle in sandbox

Sandbox transactions don't auto-settle; you can force settlement via the testing API:

await gateway.testing.settle(transactionId);
const result = await gateway.transaction.find(transactionId);
expect(result.status).toBe('settled');

Per developer.paypal.com/braintree/docs/reference/general/testing/node#settle-transaction: the testing methods are sandbox-only.

Refund

const refundResult = await gateway.transaction.refund(transactionId);
expect(refundResult.transaction.type).toBe('credit');

Refunds can only happen after settlement; submit-for-settlement then settle (testing) then refund.

Webhook handling

Per developer.paypal.com/braintree/docs/guides/webhooks/parse/node:

const webhookNotification = await gateway.webhookNotification.parse(
  request.body.bt_signature,
  request.body.bt_payload,
);

expect(webhookNotification.kind).toBeDefined();
// e.g., 'transaction_settled', 'transaction_settlement_declined'

The parser validates the signature; an invalid one throws.

Drop-in / Hosted Fields flow

Client-side (browser):

braintree.dropin.create({
  authorization: clientToken,
  selector: '#dropin-container',
}, (err, instance) => {
  // ...
  instance.requestPaymentMethod((err, payload) => {
    // payload.nonce - send to server
    fetch('/api/checkout', { method: 'POST', body: JSON.stringify({ nonce: payload.nonce }) });
  });
});

Tests for this layer need Playwright + Drop-in's test mode.

Running

npm test

CI integration

jobs:
  braintree-tests:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5
      - uses: actions/setup-node@v4
      - run: npm ci && npm test
        env:
          BT_SANDBOX_MERCHANT_ID: ${{ secrets.BT_SANDBOX_MERCHANT_ID }}
          BT_SANDBOX_PUBLIC_KEY: ${{ secrets.BT_SANDBOX_PUBLIC_KEY }}
          BT_SANDBOX_PRIVATE_KEY: ${{ secrets.BT_SANDBOX_PRIVATE_KEY }}

Anti-patterns

Anti-patternWhy it failsFix
Use prod credentials in testsReal chargesSandbox-only
Skip submitForSettlement: trueTransaction stays in authorized stateSet explicitly
Test refund without settlementRefund requires settled stateSettle first via testing API
Hardcoded amounts ignoring magic valuesTrip amount-based behaviours unexpectedlyDocument amount-vs-behaviour
Use fake-valid-nonce in production code pathSandbox-onlyReal nonces from Drop-in
Skip webhook signature validationSpoof riskgateway.webhookNotification.parse validates
Long-polling settled-state in testsSlowgateway.testing.settle synchronously
Test only success pathDecline / fraud / bank-failure paths matterTest amount-based magic values

Limitations

  • Amount-based test behaviour is sandbox-specific. Production doesn't use these magic values.
  • Settlement is real-time in test via testing API. Prod settlement is overnight batch.
  • Drop-in / Hosted Fields require browser context. Server unit tests use fake nonces; full flow needs Playwright.
  • gateway.testing.* methods don't exist in production. Be deliberate about test-only code paths.

References

Workspace
testland
Visibility
Public
Created
Last updated
Publish Source
GitHub
Badge
testland/braintree-test-cards badge