plutopay/plutopay-php

PlutoPay PHP SDK — accept card, ACH, terminal, and hosted-checkout payments.

Maintainers

Package info

github.com/PlutoPayUS/plutopay-php

Homepage

Documentation

pkg:composer/plutopay/plutopay-php

Transparency log

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v0.1.0 2026-07-11 05:16 UTC

This package is auto-updated.

Last update: 2026-07-11 07:12:20 UTC


README

The official PlutoPay SDK for PHP — accept card, ACH, terminal, and hosted-checkout payments. First-class for Laravel and WooCommerce merchants.

  • 📘 Docs: https://docs.plutopayus.com
  • 🧩 Typed methods for every endpoint, generated from the OpenAPI spec
  • 🔁 Automatic retries with backoff on 429 / 5xx
  • 🔐 Webhook signature verification helper
  • 💵 All amounts are integers in cents

Install

composer require plutopay/plutopay-php

Requires PHP 8.1+.

Quick start

use PlutoPay\Client;
use PlutoPay\Model\CreateTransactionRequest;

$pluto = new Client(getenv('PLUTOPAY_SECRET_KEY'));

$txn = $pluto->transactions->createPayment(
    new CreateTransactionRequest([
        'amount'   => 4750,          // $47.50 in cents
        'currency' => 'usd',
        'payment_method_type' => 'card',
        'description' => 'Order #1001',
    ]),
    'order_1001'                     // Idempotency-Key
);

echo $txn->getData()->getId();
echo $txn->getClientSecret();        // confirm client-side with the Payment Element

Using with Laravel

Config

Add your key to .env:

PLUTOPAY_SECRET_KEY=sk_live_...
PLUTOPAY_WEBHOOK_SECRET=whsec_...

config/services.php:

'plutopay' => [
    'secret'         => env('PLUTOPAY_SECRET_KEY'),
    'webhook_secret' => env('PLUTOPAY_WEBHOOK_SECRET'),
],

Bind the client as a singleton in AppServiceProvider::register():

use PlutoPay\Client;

$this->app->singleton(Client::class, fn () => new Client(config('services.plutopay.secret')));

Create a hosted checkout (controller)

use PlutoPay\Client;
use PlutoPay\Model\CreateCheckoutSessionRequest;

class CheckoutController extends Controller
{
    public function store(Request $request, Client $pluto)
    {
        $session = $pluto->checkout->createCheckoutSession(
            new CreateCheckoutSessionRequest([
                'amount'      => 4750,
                'currency'    => 'usd',
                'success_url' => route('thanks'),
                'cancel_url'  => route('cart'),
            ]),
            (string) Str::uuid()      // Idempotency-Key
        );

        return redirect($session->getData()->getUrl());
    }
}

Verify a webhook (route)

Use the raw request body — Laravel exposes it via $request->getContent():

use PlutoPay\Webhook;

Route::post('/webhooks/plutopay', function (Request $request) {
    try {
        $event = Webhook::constructEvent(
            $request->getContent(),
            $request->header('X-PlutoPay-Signature', ''),
            config('services.plutopay.webhook_secret'),
        );
    } catch (\RuntimeException $e) {
        return response('invalid signature', 400);
    }

    match ($event['type']) {
        'payment.succeeded' => /* fulfill the order */ null,
        default             => null,
    };

    return response('', 200);
})->withoutMiddleware(\App\Http\Middleware\VerifyCsrfToken::class);

Errors

Non-2xx responses throw PlutoPay\ApiException, which carries the canonical error envelope:

use PlutoPay\ApiException;

try {
    $pluto->transactions->createPayment($req);
} catch (ApiException $e) {
    $error = json_decode($e->getResponseBody(), true)['error'] ?? [];
    // $error['type'], $error['message'], $error['code'], $error['param']
    report($e);
}

Resources

$pluto->transactions, ->checkout, ->paymentLinks, ->refunds, ->terminal, ->customers, ->payouts, ->disputes, ->merchant, ->webhookEndpoints.

Regenerating

The API classes are generated from openapi.yaml (the single source of truth):

bash scripts/generate.sh

License

MIT