PHPackages                             puntodev/paypal-fake - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Testing &amp; Quality](/categories/testing)
4. /
5. puntodev/paypal-fake

ActiveLibrary[Testing &amp; Quality](/categories/testing)

puntodev/paypal-fake
====================

Fake PayPal API Client for testing

0.0.1(1mo ago)03↑2900%MITPHPPHP &gt;=8.4 &lt;9.0CI passing

Since Mar 28Pushed 1mo agoCompare

[ Source](https://github.com/puntodev/paypal-fake)[ Packagist](https://packagist.org/packages/puntodev/paypal-fake)[ Docs](https://github.com/puntodev/paypal-fake)[ RSS](/packages/puntodev-paypal-fake/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (1)Dependencies (4)Versions (2)Used By (0)

paypal-fake
===========

[](#paypal-fake)

A fake PayPal API server for testing Laravel applications. It replaces the real `puntodev/paypal` client with a mock implementation that simulates the full checkout flow without hitting the PayPal API.

Installation
------------

[](#installation)

```
composer require --dev puntodev/paypal-fake
```

Activation
----------

[](#activation)

Set the environment variable in your `.env` or `phpunit.xml`:

```
PAYPAL_USE_FAKE=true

```

The service provider auto-registers and swaps the `PayPal` binding in the container with `PayPalFake`.

How It Works
------------

[](#how-it-works)

The library has four main components:

### PayPalFake

[](#paypalfake)

Extends `PayPal` and manages global test state. Stores orders in a file-based cache, records method calls for assertions, and provides a `reset()` method to clean up between tests.

### PayPalFakeApi

[](#paypalfakeapi)

Extends `PayPalApi` with mock implementations:

- `createOrder(array $order)` — Generates a fake order ID, stores it in cache, and returns the expected response structure.
- `findOrderById(string $id)` — Retrieves a stored order from cache.
- `captureOrder(string $orderId)` — Simulates payment capture. Throws a `RequestException` if the order was marked as declined.
- `verifyIpn(string $querystring)` — Always returns `'VERIFIED'`.

### FakeCheckoutController

[](#fakecheckoutcontroller)

Exposes HTTP routes that simulate PayPal's checkout UI:

MethodRouteDescriptionGET`/paypal-fake/checkout/{orderId}`Displays a styled checkout page with Approve, Decline, and Cancel buttonsPOST`/paypal-fake/checkout/{orderId}/approve`Simulates approval and posts a webhook to your appPOST`/paypal-fake/checkout/{orderId}/decline`Marks the order as declinedGET`/paypal-fake/checkout/{orderId}/cancel`Redirects to the order's cancel URL### PayPalFakeServiceProvider

[](#paypalfakeserviceprovider)

When `PAYPAL_USE_FAKE` is `true`, it binds `PayPalFake` as a singleton in place of `PayPal`, registers the checkout routes, and loads the Blade views.

Checkout Flow
-------------

[](#checkout-flow)

```
Your test creates an order via PayPalFakeApi::createOrder()
        ↓
Order is stored in file cache (300s TTL)
        ↓
Test or browser approves the order
        ↓
Webhook POSTed to /paypal/webhook/{providerId}
        ↓
Test captures payment via PayPalFakeApi::captureOrder()
        ↓
Assertions via PayPalFake::getCalls()

```

Usage
-----

[](#usage)

### Automated Tests

[](#automated-tests)

```
use Puntodev\PaymentsFake\PayPalFake;
use Puntodev\Payments\PayPal;
use Puntodev\Payments\OrderBuilder;

// Get the fake client
$client = app(PayPal::class)->defaultClient();

// Create an order
$order = (new OrderBuilder())
    ->currency('USD')
    ->amount(25.00)
    ->make();

$created = $client->createOrder($order);

// Capture the payment
$captured = $client->captureOrder($created['id']);

// Assert calls were made
$calls = PayPalFake::getCalls('createOrder');
$this->assertCount(1, $calls);

// Clean up
PayPalFake::reset();
```

### Manual Browser Testing

[](#manual-browser-testing)

Start your Laravel app with `PAYPAL_USE_FAKE=true` and navigate to `/paypal-fake/checkout/{orderId}` after creating an order. The checkout page lets you click Approve, Decline, or Cancel to test the full flow, including webhooks hitting your application.

### Test Helpers

[](#test-helpers)

MethodDescription`PayPalFake::storeOrder($id, $order)`Store an order in the fake cache`PayPalFake::getStoredOrder($id)`Retrieve a stored order`PayPalFake::markOrderAsDeclined($id)`Mark an order as declined`PayPalFake::isOrderDeclined($id)`Check if an order is declined`PayPalFake::recordCall($method, $args)`Record a method call`PayPalFake::getCalls($method)`Get recorded calls, optionally filtered by method`PayPalFake::reset()`Clear all stored state and recorded callsRequirements
------------

[](#requirements)

- PHP &gt;= 8.4
- Laravel 12+
- `puntodev/paypal` ^4.1.3

###  Health Score

37

—

LowBetter than 83% of packages

Maintenance90

Actively maintained with recent releases

Popularity4

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity41

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

45d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/7201db0e06c12ae2e12e1cf4ee5806b5b465dc538bee3cab6bfb1c0ec52e4dce?d=identicon)[Mariano Goldman](/maintainers/Mariano%20Goldman)

---

Top Contributors

[![marianogoldman](https://avatars.githubusercontent.com/u/959563?v=4)](https://github.com/marianogoldman "marianogoldman (2 commits)")

---

Tags

testingfakepaypalpuntodev

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/puntodev-paypal-fake/health.svg)

```
[![Health](https://phpackages.com/badges/puntodev-paypal-fake/health.svg)](https://phpackages.com/packages/puntodev-paypal-fake)
```

###  Alternatives

[timacdonald/log-fake

A drop in fake logger for testing with the Laravel framework.

4235.9M56](/packages/timacdonald-log-fake)[laracasts/testdummy

Easy test stubs

4671.4M36](/packages/laracasts-testdummy)[sti3bas/laravel-scout-array-driver

Array driver for Laravel Scout

971.5M3](/packages/sti3bas-laravel-scout-array-driver)[laravel-shift/factory-generator

Generate factories from existing models

49697.9k](/packages/laravel-shift-factory-generator)[luthfi/simple-crud-generator

A simple CRUD generator for Laravel 5.5 (and later) with Bootstrap 5.

17218.4k](/packages/luthfi-simple-crud-generator)[timacdonald/callable-fake

A testing utility that allows you to fake and capture invokations of a callable / Closure

4519.5k3](/packages/timacdonald-callable-fake)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
