PHP backend case study

Payment Adapter

Context: a payment module with one contract for multiple gateways. The problem is duplicate event processing, inconsistent statuses, and hard debugging across charge, refund, and webhook replay.

Case study

Technical scope

Some repositories are private until the work is closed. Project scope, technical decisions, and operating scenarios are described on the page. I can discuss the code during a technical conversation.

01

Problem

  • Checkout code needs one payment boundary instead of direct coupling to a specific provider implementation.
  • The main risks are repeated payment attempts, inconsistent statuses, untrusted callbacks, and missing visibility into payment attempts.
02

Technical decision

  • Shared gateway port, Money VO, normalized payment result, HMAC webhook, idempotent side effects, and an audit log for payment attempts.
  • The gateway interface separates application logic from provider-specific details.
  • The service layer centralizes payment operations, callback handling, replay protection, and attempt history.
03

Result

  • The project shows how to reduce double-processing risk and leave a diagnostic trail for disputed payment cases.
  • Shared gateway contract with two provider-style adapters.
  • Payment, refund, replay-handling, and callback-validation scenarios.
  • ShopFlow order-to-payment mapping plus attempt and callback audit trails.
04

Stack

  • PHP / Adapter / Webhook / Audit
  • composer install
  • composer demo-all
  • composer webhook-demo