rapttor/whop-sdk-php

PHP SDK for the Whop API — payments, memberships, webhooks and more.

Installs: 0

Dependents: 0

Suggesters: 0

Security: 0

Stars: 0

Watchers: 0

Forks: 0

Open Issues: 0

pkg:composer/rapttor/whop-sdk-php

dev-master / 1.x-dev 2026-02-25 10:43 UTC

This package is auto-updated.

Last update: 2026-02-25 10:43:19 UTC


README

CI Latest Version PHP Version License

PHP 8.1+ SDK for the Whop API — payments, memberships, webhooks, and more.

Requirements

Requirement Version
PHP ^8.1
ext-curl *
ext-json *

Installation

composer require rapttor/whop-sdk-php

Quick start

use Rapttor\WhopSdk\WhopClient;

$client = new WhopClient(); // reads WHOP_API_KEY from env

Set your API key in the environment:

export WHOP_API_KEY="your_api_key_here"

Or pass it directly:

$client = new WhopClient(apiKey: 'your_api_key_here');

Usage

Payments

// List payments — returns a Page object
$page = $client->payments->list([
    'company_id' => 'biz_xxxxxxxxxxxxxx',
    'per_page'   => 10,
]);

foreach ($page->getData() as $payment) {
    echo $payment['id'] . PHP_EOL;
}

// Auto-paginate through ALL pages
foreach ($client->payments->list(['company_id' => 'biz_xxxxxxxxxxxxxx']) as $payment) {
    echo $payment['id'] . PHP_EOL;
}

// Retrieve a single payment
$payment = $client->payments->retrieve('pay_xxxxxxxxxxxxxx', 'biz_xxxxxxxxxxxxxx');

Members

foreach ($client->members->list(['company_id' => 'biz_xxxxxxxxxxxxxx']) as $member) {
    echo $member['id'] . PHP_EOL;
}

$member = $client->members->retrieve('mber_xxxxxxxxxxxxx', 'biz_xxxxxxxxxxxxxx');

$client->members->update('mber_xxxxxxxxxxxxx', 'biz_xxxxxxxxxxxxxx', [
    'metadata' => ['tier' => 'gold'],
]);

Memberships

$membership = $client->memberships->create('biz_xxxxxxxxxxxxxx', [
    'plan_id' => 'plan_xxxxxxxxxxxxxx',
    'user_id' => 'user_xxxxxxxxxxxxxx',
]);

$client->memberships->update($membership['id'], 'biz_xxxxxxxxxxxxxx', ['status' => 'active']);
$client->memberships->delete($membership['id'], 'biz_xxxxxxxxxxxxxx');

Invoices

$invoice = $client->invoices->create('biz_xxxxxxxxxxxxxx', [
    'collection_method' => 'send_invoice',
    'due_date'          => '2025-12-01T05:00:00.000Z',
    'member_id'         => 'mber_xxxxxxxxxxxxx',
    'plan'              => [],
    'product'           => ['title' => 'My Product'],
]);

$client->invoices->send($invoice['id'], 'biz_xxxxxxxxxxxxxx');
$client->invoices->void($invoice['id'], 'biz_xxxxxxxxxxxxxx');

Users

$me = $client->users->me();

// Verify a JWT issued by the Whop iframe / frontend
$result = $client->users->verifyToken($jwtFromFrontend);
$userId = $result['user_id'];

// Check access to an experience
$access = $client->users->checkAccess('exp_xxxxxxxxxxxxxx', ['user_id' => $userId]);

Webhooks

// Create a webhook endpoint
$webhook = $client->webhooks->create('biz_xxxxxxxxxxxxxx', [
    'url'    => 'https://yourapp.example.com/webhooks/whop',
    'events' => ['payment.completed', 'membership.created'],
]);

// Verify an incoming webhook (in your controller)
$payload   = (string) file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_WHOP_SIGNATURE'] ?? '';
$secret    = (string) getenv('WHOP_WEBHOOK_SECRET');

use Rapttor\WhopSdk\Resources\Webhooks;

if (!Webhooks::verifySignature($payload, $signature, $secret)) {
    http_response_code(401);
    exit;
}

$event = json_decode($payload, true);
// handle $event ...

Pagination

All list() methods return a Page<array> object.

// Iterate all items across every page automatically
foreach ($client->payments->list(['company_id' => 'biz_xxx']) as $payment) {
    // Pages are fetched on demand
}

// Manual control
$page = $client->payments->list(['company_id' => 'biz_xxx', 'per_page' => 5]);

while (true) {
    foreach ($page->getData() as $payment) { /* ... */ }

    if (!$page->hasNextPage()) break;
    $page = $page->getNextPage();
}

// Cursor info
$info = $page->nextPageInfo(); // ['after' => 'cursor_abc'] or null

Error handling

use Rapttor\WhopSdk\Exceptions\APIConnectionError;
use Rapttor\WhopSdk\Exceptions\APITimeoutError;
use Rapttor\WhopSdk\Exceptions\AuthenticationError;
use Rapttor\WhopSdk\Exceptions\BadRequestError;
use Rapttor\WhopSdk\Exceptions\NotFoundError;
use Rapttor\WhopSdk\Exceptions\PermissionDeniedError;
use Rapttor\WhopSdk\Exceptions\RateLimitError;
use Rapttor\WhopSdk\Exceptions\InternalServerError;
use Rapttor\WhopSdk\Exceptions\APIStatusError;

try {
    $payment = $client->payments->retrieve('pay_xxx', 'biz_xxx');
} catch (APITimeoutError $e) {
    // Request timed out (after automatic retries)
} catch (APIConnectionError $e) {
    // Could not reach the server
} catch (AuthenticationError $e) {
    // 401 — check your API key
} catch (NotFoundError $e) {
    // 404 — resource does not exist
} catch (RateLimitError $e) {
    // 429 — back off and retry
} catch (APIStatusError $e) {
    // Any other 4xx / 5xx
    echo "HTTP {$e->statusCode}: {$e->getMessage()}" . PHP_EOL;
}

Exception hierarchy

\RuntimeException
└── APIError
    ├── APIConnectionError
    │   └── APITimeoutError
    └── APIStatusError
        ├── BadRequestError          (400)
        ├── AuthenticationError      (401)
        ├── PermissionDeniedError    (403)
        ├── NotFoundError            (404)
        ├── UnprocessableEntityError (422)
        ├── RateLimitError           (429)
        └── InternalServerError      (5xx)

Retries & timeouts

Requests that fail due to connection errors, 408, 409, 429, or 5xx responses are automatically retried with exponential back-off (0.5 s → 1 s → 2 s …, capped at 8 s).

// Global defaults
$client = new WhopClient(
    maxRetries: 3,   // default: 2
    timeout:    30,  // default: 60 seconds
);

// Per-request override (returns a new client instance)
$client->withOptions(['max_retries' => 0, 'timeout' => 5])
       ->payments
       ->list(['company_id' => 'biz_xxx']);

Raw HTTP requests

For endpoints not yet covered by a resource class:

$data = $client->get('/v5/some/endpoint', ['query_param' => 'value']);
$data = $client->post('/v5/some/endpoint', ['key' => 'value']);
$data = $client->patch('/v5/some/endpoint', ['key' => 'value']);
$data = $client->delete('/v5/some/endpoint');

Available resources

Property Methods
$client->accessTokens list, create, delete
$client->apps list, retrieve, create, update
$client->checkoutConfigurations list, retrieve, create, update
$client->companies retrieve, update
$client->experiences list, retrieve
$client->invoices list, retrieve, create, send, void
$client->members list, retrieve, update
$client->memberships list, retrieve, create, update, delete
$client->payments list, retrieve
$client->plans list, retrieve, create, update
$client->products list, retrieve, create, update
$client->promoCodes list, retrieve, create, update, delete
$client->refunds list, retrieve, create
$client->reviews list, retrieve
$client->users me, retrieve, verifyToken, checkAccess
$client->webhooks list, retrieve, create, update, delete, verifySignature (static)

Development

composer install

composer cs        # Check PSR-12 code style
composer cs-fix    # Auto-fix code style
composer analyse   # PHPStan level 8
composer test      # PHPUnit

composer check     # Run all three in sequence

License

Apache-2.0 © rapttor