Skip to main content

Add Unit Tests to Your Payments Service

Build a test-writing playbook for payment processing and have Devin cover charge flows, refund logic, and webhook handlers with comprehensive unit tests.
AuthorCognition
CategoryCode Quality
FeaturesPlaybooks
1

Write a payments-specific test playbook

A playbook encodes your team’s testing conventions so Devin writes tests the way your engineers do. Payment code has unique concerns — idempotency, currency precision, gateway retries, PCI-safe mocking — so a payments-focused playbook catches issues a generic one would miss.Option 1: Write the playbook yourself. Go to Settings > Playbooks > Create playbook and define your standards:Option 2: Let Advanced Devin create the playbook for you. Describe your testing conventions and Advanced Devin will generate a complete playbook:Then add your best existing test file (e.g., src/services/__tests__/UserService.test.ts) as a Knowledge entry so Devin has a concrete example of your team’s style.
2

Identify untested payment code

Before pointing Devin at specific files, find where the gaps are in your payment modules. Ask Devin to run your coverage tool and surface the worst offenders:Devin runs the suite in its terminal, parses the coverage report, and gives you a prioritized list:
File                                | Lines | Uncovered functions
------------------------------------|-------|------------------------------
src/services/PaymentService.ts      |  34%  | processCharge, issueRefund, handleWebhook
src/services/SubscriptionService.ts |  41%  | renewSubscription, cancelTrial, proratePlan
src/services/InvoiceService.ts      |  52%  | generateInvoice, applyPromoCode, calculateTax
src/services/PayoutService.ts       |  58%  | initiateTransfer, reconcileSettlement
3

Have Devin write tests for PaymentService

Start a new session, attach your payments test playbook (you’ll see a blue pill confirming it’s attached), and tell Devin which module to cover:Devin reads the module, studies your existing tests for patterns, writes a comprehensive test file following your playbook, and runs it:
PASS src/services/__tests__/PaymentService.test.ts
  PaymentService
    processCharge
      ✓ charges a valid credit card and returns a receipt (14ms)
      ✓ uses integer cents to avoid floating-point errors (6ms)
      ✓ rejects duplicate charges with the same idempotency key (5ms)
      ✓ retries on Stripe gateway timeout up to 3 times (18ms)
      ✓ throws InsufficientFundsError for declined cards (4ms)
    issueRefund
      ✓ refunds full amount for a completed charge (8ms)
      ✓ refunds partial amount in cents when specified (6ms)
      ✓ prevents refund exceeding the original charge amount (3ms)
      ✓ throws AlreadyRefundedError on duplicate refund attempts (4ms)
    handleWebhook
      ✓ processes charge.succeeded events and updates order status (7ms)
      ✓ processes charge.refunded events and credits the customer (6ms)
      ✓ verifies Stripe webhook signature before processing (3ms)
      ✓ ignores unrecognized event types without error (2ms)

Coverage: 94% lines | 91% branches | 100% functions
Devin opens a PR with the test file and a coverage summary in the description.
4

Work through the remaining payment modules

Review the first PR. If the mock strategy or assertion style isn’t quite right, update your playbook before running it on more modules — one round of feedback saves you from correcting the same issue across multiple PRs.Then work down your gap list:To go faster, use Advanced Devin to launch parallel sessions — one per payment module — all following the same playbook. Or schedule a weekly session that finds any payment modules that have dropped below your coverage threshold and writes tests for them automatically.