ai newsDo., 29. Okt.
EilmeldungGoogle Connected Apps Platform Preview Brings One MCP Path to Search and Gemini

Building a Stripe Direct Charges Feature with Agentic AI: From Intent to QA

There is plenty of discussion about whether AI makes developers faster. I’m more interested in a practical question: how can we use AI agents to build software that a team can responsibly ship? I recently worked on a Stripe Direct Charges integration for a client’s WordPress/Dokan marketplace. I us

dev.toDonnerstag 19:19 · 29.10.7 Min. Lesezeit
Bild: dev.to

There is plenty of discussion about whether AI makes developers faster. I’m more interested in a practical question: how can we use AI agents to build software that a team can responsibly ship?

I recently worked on a Stripe Direct Charges integration for a client’s WordPress/Dokan marketplace. I used Claude Code with workflows from Matt Pocock’s skills collection, documenting the decisions, implementation, reviews, and bugs along the way.

The agent handled much of the implementation and test writing, but I stayed involved in clarifying requirements, checking assumptions, reviewing changes, and verifying behaviour. For payment software, generating code is only one part of the job.

The client needed Stripe Direct Charges for a Dokan marketplace. The customer’s payment would be charged on the vendor’s connected Stripe account, with the vendor acting as merchant of record. The platform would collect its commission through a Stripe application fee.

The feature also needed configurable payout holds of 7, 14, 21, or 28 days, with payouts released through an admin-controlled process. Refunds had to return the appropriate commission; disputes needed to affect the hold lifecycle; saved cards had to work per vendor; and vendors needed to connect their accounts through Stripe’s hosted onboarding flow.

Before implementation, I spent about three hours clarifying what the client needed. “Use Stripe Direct Charges” is a technical direction, not a complete product specification. We still had to settle who was charged, how the platform collected commission, what a hold meant, and what happened if a vendor disconnected Stripe while funds were held.

Our role as developers and team leads is to work with the project manager to clarify the client’s requirements, resolve ambiguities, and make sure the agreed intent is clear before implementation begins. AI can surface questions, but a plausible answer is not an approved business decision.

I then used /grill-me with Fable 5.1. It asked one question at a time and suggested an answer that I could accept, reject, or refine. I answered 45 questions over more than two and a half hours.

The process made key choices explicit: direct charges rather than destination charges, application fees rather than a separate transfer, permitted hold durations, and how disputes affect holds before or after payout. I set one rule: one question per message, then wait for my answer. Bundled questions are easy to skim, leaving decisions undocumented.

Some questions cannot be answered reliably through discussion alone. We used Stripe test mode for a small technical spike to check the integration’s behaviour.

One important finding was that balance_transaction.net —the net amount after Stripe fees—may not be available immediately when a charge succeeds. The spike also checked how the pinned Stripe API version behaved with connected accounts.

The timing issue mattered. If a payout hold started before the net amount was known, the system risked telling a vendor that their held payout was $0.00.

When a design depends on external API behaviour or timing, run the smallest experiment that can answer the question. The result gives the spec and implementation evidence to work from.

After the requirements work, I used /to-spec to create a specification and /to-tickets to break it into ten vertical slices. They covered the module foundation and settings; vendor connection, onboarding, and webhooks; a single-vendor checkout guard; card checkout and commission; saved cards; payout holds and releases; refunds; disputes; admin views and controls; and lifecycle emails.

Each slice had its own scope and GitHub issue, giving the agent a bounded task instead of “build Stripe support.” Tickets specified expected behaviour, constraints, failure cases, testability, and what was out of scope. This step was quick because the hard product questions had already been addressed.

I used /to-implement with Opus 5.5 to work through the slices. The agent wrote implementation code and PHPUnit tests, with changes committed incrementally. This is where agentic development differs from asking a chatbot for a function: the agent works in the repository, follows a defined task, runs checks, and produces changes that can be inspected.

I also asked the agent to list known gaps, not just completed work.

Passing tests were evidence, not proof. A green suite cannot establish that the business rule is right, every event ordering is covered, or every third-party response is understood.

I used /code-review for two separate reviews: one checked the changes against repository conventions and code-level concerns; the other checked them against the agreed specification. Both matter. Code can follow every convention and still implement the wrong behaviour.

Early reviews found an incorrect default hold duration, dispute handling that could write a note after payout, and redundant webhook-signature verification. After fixes, the review ran again.

It also connected back to the Stripe spike: because the net amount could arrive asynchronously, a hold notification could say $0.00. A Stripe test-mode run confirmed the scenario, and the implementation was changed to announce the hold only once the amount is known.

We connected a vendor sandbox account, then asked agent to ran a webhook listener, placed a test order, used a QA-only override to shorten the hold duration, and observed the payout flow in Stripe test mode.

That exercise exposed a race condition. The customer’s browser return from Stripe and the payment_intent.succeeded webhook could both attempt to complete the same order. The unit tests had passed because they did not exercise two competing requests at once. Fixed the issue by checking the order-completion state under a lock.

We also added Playwright end-to-end coverage for important money paths: checkout through payout hold and release, an admin refund, and a dispute. These tests used Stripe test mode and real webhooks.

After opening the PR, I had the agent rerun the automated suites and draft manual test cases for scenarios that needed human judgement. I worked through them myself; the agent can organise the cases, but I remain responsible for telling the client what works.

Unit tests cover isolated rules, integration tests cover component interactions, Stripe test mode checks external behaviour, and browser testing plus QA examine the user-facing flow.

A real-browser walkthrough covered vendor onboarding, checkout, a declined card, payout holds, release, refunds, and disputes. It included screenshots and notes so another engineer or QA tester could see what was exercised and what happened.

The walkthrough found four more bugs that the automated tests had missed:

We fixed the four defects, added tests, and checked the relevant paths again in the browser. Automated tests are only as good as the scenarios they cover; walking through the feature as a user can expose mismatches between intended and actual behaviour.

I used /pr to prepare a pull request description explaining what changed, why it changed, how it had been tested, and what remained open. A good PR explains the behaviour, the decisions it depends on, the checks run, and what remains before merge or release.

The build log’s recorded snapshot lists 20 commits, 121 PHPUnit tests, and three end-to-end specs. Those numbers indicate the size of the work and the verification effort at that recorded point; they do not establish correctness or production readiness by themselves. Test counts are meaningful only alongside an understanding of what the tests exercise.

The PR was still in QA in the documented project state. The build log records that CI had not yet run and review follow-ups remained open: untranslated ledger and error strings, an email-template exception, tracked refactoring, and a seed CLI test that failed in large test batches. These are part of the delivery status, not details to hide behind an implementation-complete label.

Implementation progress, QA sign-off, and production release are different milestones. The agent can help prepare and verify a change, but it cannot declare its own work ready for release. Outstanding findings must be addressed, required checks must pass, and the team must make the release decision based on the evidence.

The agent did much of the typing, generated tests, helped organise reviews, and prepared documentation. My effort shifted toward clarifying intent, choosing between alternatives, testing assumptions, and verifying behaviour.

That does not remove the developer from the process. An agent needs context, bounded tasks, useful checks, and explicit completion criteria; otherwise, it can produce plausible code while leaving the important questions unanswered.

The principles I’m taking forward are practical:

I’m not sharing this project as a benchmark or as proof that AI makes every feature faster. It is one real implementation, with evidence of what worked, bugs that still had to be found, and release checks that remained open.

A structured workflow helped us clarify requirements, test assumptions, review small slices against both standards and intent, and validate the result through Stripe and a real browser.

The question I want to ask is not simply, “Can AI write this feature?” It is: Can we give an agent enough context to implement a well-defined change, verify its behaviour through multiple layers, make the remaining gaps visible, and bring the work to a point where humans can responsibly decide whether it is ready to ship?

Quelle: dev.to (dev.to). Original öffnen