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-cardsbraintree-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_settlement → settled transition with simulated settlement in sandbox.
When to use
Authoring
Setup
Get sandbox credentials at braintreepayments.com/sandbox (opens in new window) - merchant ID + public + private keys.
Install
npm install braintree
pip install braintreeInitialize
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):
| Card | Behaviour |
|---|---|
| 4111 1111 1111 1111 | Authorized + settled |
| 5555 5555 5555 4444 | Authorized + settled (Mastercard) |
| 4000 1111 1111 1115 | Processor declined (general) |
| 4000 0000 0000 0002 | Processor declined |
| 4000 0000 0000 1109 | 3DS frictionless |
| 4000 0000 0000 1091 | 3DS challenge |
By amount:
| Amount | Behaviour |
|---|---|
| $2000.00 | Processor declined (insufficient funds) |
| $2999.00 | Fraud failure |
| $3000.00 | Bank 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 testCI 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-pattern | Why it fails | Fix |
|---|---|---|
| Use prod credentials in tests | Real charges | Sandbox-only |
Skip submitForSettlement: true | Transaction stays in authorized state | Set explicitly |
| Test refund without settlement | Refund requires settled state | Settle first via testing API |
| Hardcoded amounts ignoring magic values | Trip amount-based behaviours unexpectedly | Document amount-vs-behaviour |
Use fake-valid-nonce in production code path | Sandbox-only | Real nonces from Drop-in |
| Skip webhook signature validation | Spoof risk | gateway.webhookNotification.parse validates |
| Long-polling settled-state in tests | Slow | gateway.testing.settle synchronously |
| Test only success path | Decline / fraud / bank-failure paths matter | Test amount-based magic values |
Limitations
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.