Testland
Browse all skills & agents

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.

Install with skills.sh (any agent)

npx skills add testland/qa --skill braintree-test-cards
View source

braintree-test-cards

Overview

Per developer.paypal.com/braintree/docs/reference/general/testing (opens in new window), 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 (opens in new window) - 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 (opens in new window):

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 (opens in new window): 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 (opens in new window):

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

Related skills

3ds-test-flow-reference

Cross-gateway, protocol-level reference for 3-D Secure (3DS 2.x) test coverage. Covers the EMVCo frictionless / challenge / not-applicable flow paths, SCA under EU PSD2, and the per-PAN test cards for Stripe, Adyen, and Braintree. The gateway-specific wrappers (adyen-test-mode / stripe-test-cards-and-webhooks / braintree-test-cards) compose this skill for single-gateway work, so use one of those for a single-gateway query. Use this skill when designing multi-gateway 3DS test coverage, auditing a 3DS redirect round-trip, or investigating a challenge-flow regression that is not gateway-specific.

adyen-test-mode

Wraps Adyen test-mode patterns: test-API-key initialization, the canonical Adyen test cards (Visa 4111 1111 1111 1111; 5454 5454 5454 5454 3DS frictionless; 4917 6100 0000 0000 3DS 2 challenge), the per-flow result codes (Authorised / Refused / Pending / RedirectShopper / Error), the HMAC-SHA256 webhook validation, and notifications-vs-API duality (Adyen separates synchronous API calls from asynchronous notifications). Use when testing Adyen-integrated code.

chargeback-flow-test-author

Workflow-driven skill that builds the chargeback / dispute test suite: canonical reason codes (Visa 10.4 fraud, 13.1 services-not-provided; Mastercard MCC 4855), per-gateway dispute APIs (Stripe Disputes, Adyen Chargeback notifications, PayPal Disputes), the evidence-submission flow + window, and disposition outcomes (won / lost / accepted). Use when designing dispute coverage; for refunds use refund-test-matrix-builder, for webhook redelivery + idempotency use payment-webhook-replay, and for the lifecycle state model use payment-flow-states-reference.

payment-flow-states-reference

Pure-reference catalog of payment lifecycle state machines across Stripe, Adyen, PayPal, and Braintree: canonical states (created / requires_action / processing / succeeded / requires_capture / canceled / failed), authorisation vs capture, asynchronous webhook states, and refund / dispute / chargeback transitions. Use when designing tests for payment flows or auditing state-handling code; this is the state model, not a builder - to author suites on it use refund-test-matrix-builder (refunds), chargeback-flow-test-author (disputes), or payment-webhook-replay (webhook replay).

payment-webhook-replay

Workflow-driven skill that builds payment webhook replay + recovery tests. Covers the idempotency contract (every webhook handler must handle redelivery without side effects), the replay simulators (Stripe CLI `stripe trigger`, Adyen Customer Area resend, PayPal Webhook Simulator, Braintree webhook test), the signature-verification gauntlet (HMAC-SHA256 per gateway, expired-timestamps rejection), and the partial-failure recovery scenarios. Use when designing webhook robustness tests.

paypal-sandbox

Wraps PayPal Sandbox testing patterns: sandbox account creation (Business + Personal accounts in developer.paypal.com), the Orders v2 API (create / capture / refund), webhook event simulator (developer.paypal.com webhook simulator), sandbox-account-specific test cards, and the OAuth2 client-credentials flow for sandbox. Use when testing PayPal-integrated code.

pci-dss-scope-reference

Pure-reference catalog of PCI DSS v4.0 scope reduction techniques + the testable scope boundaries. Covers the SAQ levels (A through D, picked by how cardholder data flows), the PAN-storage prohibitions (only first-6 + last-4 retained; nothing else cleartext), the tokenization + hosted-fields scope-reduction patterns (Stripe Elements / Adyen Drop-in / Braintree Hosted Fields keep PAN off your servers), Network-Segmentation as PCI scope-reduction, and the testable behaviours the scope boundary creates. This is the catalog of WHY the boundary matters and what it makes testable - not a checker that verifies a given integration against the standard. Use when designing or auditing the PCI scope of a payment integration.

refund-test-matrix-builder

Workflow-driven skill that builds a refund test matrix from a payment-flow inventory: refund variants (full / partial / multiple-partials / over-refund / refund-on-disputed / refund-on-already-refunded), per-gateway nuances (Stripe, Adyen, PayPal, Braintree refund APIs), and timing variants (immediate / next-day / declined-by-bank), one test case per cell. Use for refund coverage on a new integration; for chargeback / dispute coverage use chargeback-flow-test-author, for webhook redelivery + idempotency use payment-webhook-replay, and for the state model use payment-flow-states-reference.

stripe-subscription-billing-test-author

Builds test suites for Stripe recurring-billing flows: trial-to-paid conversion, proration on plan upgrade and downgrade, dunning on failed renewal, cancel and reactivation, and the full subscription webhook event matrix (invoice.payment_failed, customer.subscription.updated, customer.subscription.deleted, invoice.paid). Uses Stripe Billing test clocks (POST /v1/test_helpers/test_clocks) to time-travel through billing cycles without calendar delay. Distinct from stripe-test-cards-and-webhooks (one-time PaymentIntents) and payment-webhook-replay (idempotency + replay robustness). Does not cover single-event CLI replay or handler idempotency testing (see payment-webhook-replay for those). Use when authoring tests for subscription or recurring-billing integrations.

stripe-test-cards-and-webhooks

Wraps Stripe API testing patterns: test-mode initialization, the canonical test cards (4242 success; 4000 0000 0000 0002 declined; 4000 0027 6000 3184 3DS challenge per 3ds-test-flow-reference), the Stripe CLI webhook flow (`stripe listen --forward-to`), the Stripe CLI fixture commands (`stripe trigger payment_intent.succeeded`), and the webhook signature verification (Stripe-Signature header + HMAC-SHA256). Use when testing Stripe-integrated code.