Developer Tools

Testing

Test your integration without calling PayMongo. The package fakes its whole API and ships realistic fixture payloads; these examples run in the Playground's own test suite.

  • Paymongo::fake() answers the endpoints the package calls from fixtures: creates echo the attributes you sent, retrievals echo the id you asked for. A path it does not know gets a PayMongo-style 404.
  • Pass URL patterns to Paymongo::fake() to stub a specific response. Stubs win over the catch-all.
  • Fixtures build full PayMongo payloads. Give them an explicit id so assertions stay deterministic, and wrap them in Fixtures::list() with hasMore to fake pagination.
  • Paymongo::assertSent() and Paymongo::assertNothingSent() inspect the requests the package made, and interoperate with Http::fake().
  • Error responses map to typed exceptions, so a stubbed 402 surfaces as PaymentDeclinedException just as a real decline would.

tests/Feature/PaymongoFakeExamplesTest.php

PHP
<?php

/*
 * These tests are shown on the Playground's Developer Tools "Testing" page as
 * examples of testing an integration with the package's fake and fixtures.
 * They run in this suite, so the examples a Visitor copies are known to pass.
 */

use Illuminate\Http\Client\Request;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Sleep;
use Luigel\Paymongo\Data\Refund;
use Luigel\Paymongo\Exceptions\PaymentDeclinedException;
use Luigel\Paymongo\Facades\Paymongo;
use Luigel\Paymongo\Testing\Fixtures;

it('fakes the whole PayMongo API and asserts on the request sent', function () {
    Paymongo::fake();

    $intent = Paymongo::paymentIntents()->create([
        'amount' => 10000,
        'currency' => 'PHP',
        'payment_method_allowed' => ['card'],
    ]);

    expect($intent->amount)->toBe(10000);

    Paymongo::assertSent(fn (Request $request): bool => $request->url() === 'https://api.paymongo.com/v1/payment_intents'
        && $request['data']['attributes']['amount'] === 10000);
});

it('stubs one endpoint with a fixture that has an explicit id', function () {
    Paymongo::fake([
        'api.paymongo.com/v1/payments/*' => Http::response(Fixtures::payment([
            'id' => 'pay_known_id',
            'status' => 'paid',
        ])),
    ]);

    $payment = Paymongo::payments()->retrieve('pay_known_id');

    expect($payment->id)->toBe('pay_known_id')
        ->and($payment->status?->value)->toBe('paid');
});

it('surfaces a declined card as a typed exception', function () {
    Paymongo::fake([
        'api.paymongo.com/v1/payment_intents/*/attach' => Http::response([
            'errors' => [['code' => 'card_declined', 'detail' => 'Your card was declined.']],
        ], 402),
    ]);

    Paymongo::paymentIntents()->attach('pi_test', 'pm_test');
})->throws(PaymentDeclinedException::class, 'Your card was declined.');

it('walks every page of a list lazily', function () {
    Paymongo::fake([
        'api.paymongo.com/v1/refunds?limit=2' => Http::response(Fixtures::list([
            Fixtures::refund(['id' => 'ref_1']),
            Fixtures::refund(['id' => 'ref_2']),
        ], hasMore: true)),
        'api.paymongo.com/v1/refunds?limit=2&after=ref_2' => Http::response(Fixtures::list([
            Fixtures::refund(['id' => 'ref_3']),
        ])),
    ]);

    $ids = Paymongo::refunds()->list(['limit' => 2])
        ->lazy()
        ->map(fn (Refund $refund): string => $refund->id)
        ->all();

    expect($ids)->toBe(['ref_1', 'ref_2', 'ref_3']);
});

it('retries a rate-limited request after the Retry-After delay', function () {
    Sleep::fake();

    Paymongo::fake([
        'api.paymongo.com/v1/payments/*' => Http::sequence()
            ->push(['errors' => [['code' => 'rate_limited', 'detail' => 'Too many requests.']]], 429, ['Retry-After' => '2'])
            ->push(Fixtures::payment(['id' => 'pay_after_retry'])),
    ]);

    $payment = Paymongo::payments()->retrieve('pay_after_retry');

    expect($payment->id)->toBe('pay_after_retry');

    Sleep::assertSleptTimes(1);
    Sleep::assertSequence([Sleep::for(2)->seconds()]);
});