Download the PHP package ttpryg/payment-engine without Composer
On this page you can find all versions of the php package ttpryg/payment-engine. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download ttpryg/payment-engine
More information about ttpryg/payment-engine
Files in ttpryg/payment-engine
Package payment-engine
Short Description Production-ready, framework-agnostic PHP 8.1+ Payment Engine with generic payable/payer references, gateway abstraction, idempotent webhook processing, and append-only audit trail.
License MIT
Informations about the package payment-engine
PaymentEngine Library (ttpryg/payment-engine)
ttpryg/payment-engine is a production-ready, framework-agnostic standalone PHP 8.1+ Payment Engine designed to manage payment lifecycles, polymorphic payable/payer references, gateway abstraction, idempotent webhook processing, partial/full refunds, and append-only audit histories without coupling to any specific framework or external domain.
π 1. Introduction
In modern microservices and modular monolithic architectures, handling payments requires strict separation of domain boundaries. A Payment Engine must be responsible for orchestrating payment attempts, validating state transitions, guaranteeing idempotency during webhook retries, and recording immutable audit logsβwithout possessing hardcoded dependencies on orders, shopping carts, product catalogs, or specific third-party payment gateway SDKs.
ttpryg/payment-engine decouples payment processing via a clean driver/adapter pattern (PaymentGatewayInterface) and generic references (PayableReference and PayerReference).
π 2. Features
- Framework Agnostic: Pure PHP 8.1+ with zero framework dependencies (works on Vanilla PHP, Slim, Laravel, Symfony, CodeIgniter).
- Polymorphic / Generic References: Decoupled from orders and users via
PayableReference(payable_type,payable_id) andPayerReference(payer_type,payer_id). - Strict Money Representation: Uses immutable
MoneyValue Object with integer values (representing lowest denomination/cents or integer units for IDR), eliminating floating-point rounding errors. - Provider-Agnostic Gateway Abstraction: Decouples payment gateway integration using
PaymentGatewayInterfaceandGatewayManager. - Built-in Gateway Drivers:
MockPaymentGateway: Predictable driver for unit tests, CI/CD, and local sandboxes.ManualTransferGateway: Built-in driver for manual bank transfers, cash on delivery (COD), or offline payments.
- Robust Webhook Idempotency: Prevents duplicate executions, double settlements, or duplicate history entries using gateway
event_idand SHA-256payload_fingerprint. - Strict State Machine: Enforces valid status transitions across the entire payment lifecycle (
pending,authorized,captured,completed,failed,cancelled,expired,partially_refunded,refunded). - Partial & Full Refunds: Verifies that refund requests never exceed the remaining refundable
paid_amount. - Append-Only Audit History: Tracks every critical transition and webhook with
actor_type,actor_id, and structuredmetadata. - PSR-14 Domain Events: Dispatches standardized domain events (
PaymentCreatedEvent,PaymentStatusChangedEvent,PaymentCompletedEvent,PaymentRefundedEvent, etc.). - Multiple Storage Drivers: Clean separation via PDO (MariaDB, MySQL, SQLite) & In-Memory drivers for ultra-fast unit testing.
π¦ 3. Installation
Install via Composer:
𧬠4. Domain Model
Value Objects
Money: Strictly integer-based amount (int $amount,string $currency = 'IDR'). Providesadd(),subtract(),multiply(),equals(),isGreaterThan(),isLessThan().PaymentNumber: Unique human-readable identifier (e.g.,PAY-20260925-A1B2C3).PayableReference: Generic reference to the billable entity (payable_type,payable_id).- Example:
new PayableReference('order', 'ORD-2026-001')ornew PayableReference('subscription', 'SUB-88').
- Example:
PayerReference: Generic reference to the customer/payer (payer_type,payer_id).
Entities
Payment: Core aggregate root representing the payment record, containing monetary balances (amount,fee,totalAmount,paidAmount,refundedAmount), status, and metadata.PaymentAttempt: Log of each payment attempt made against a gateway (gateway_provider,transaction_reference,status, raw request/response payloads).PaymentRefund: Detailed record of full or partial refunds issued against a completed payment.PaymentHistory: Immutable append-only audit trail capturing every status transition or webhook occurrence.WebhookEvent: Audit and deduplication log capturing inbound webhook deliveries with SHA-256 fingerprinting.
π 5. Payment Lifecycle & State Machine
- Invalid transitions (e.g. attempting to complete an already
CANCELLEDorFAILEDpayment) throwInvalidStatusTransitionException. - Idempotent transitions (calling
complete()on an alreadyCOMPLETEDpayment) result in a safe no-op without creating duplicate histories or events.
π 6. Gateway Driver Architecture
To add a new payment gateway (such as Midtrans, Xendit, Stripe, or DOKU), implement PaymentGatewayInterface:
Register drivers using GatewayManager:
π‘οΈ 7. Idempotent Webhook Processing
Webhooks sent by gateways are often redelivered multiple times. WebhookProcessorService prevents duplicate balance updates and duplicate domain events using:
- Gateway Event ID: Tracks unique delivery IDs supplied by the gateway.
- Payload Fingerprint: Computes SHA-256 hashes of the payload:
If a webhook with the same event_id or payload_fingerprint has already been processed, it returns immediately without firing duplicate events or inserting duplicate history entries.
π° 8. Partial & Full Refunds
Refunds are processed through PaymentRefundService:
If a refund request exceeds the remaining refundable amount, a RefundAmountExceededException is thrown.
ποΈ 9. Database Schema
Run the SQL script from database/schema.sql:
π 10. Quick Usage Example
π§ͺ 11. Testing
Run tests with PHPUnit:
Or using Docker Compose:
π 12. License
MIT License.