定制 devmatchable/whop-php-sdk 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

devmatchable/whop-php-sdk

Composer 安装命令:

composer require devmatchable/whop-php-sdk

包简介

Framework-agnostic PHP SDK for the Whop API.

README 文档

README

CI PHP PHPStan

Warning

This package is in active development and is not yet ready for production use. The public API may change at any time before version 1.0.0 is released. Please do not depend on it in production projects until a stable release is published.

Framework-agnostic PHP client for the Whop API. Built on pure PSR interfaces (PSR-18 / PSR-17 / PSR-7) — drop it into any PHP 8.4+ project without pulling in a framework or opinionated HTTP stack.

Requirements

  • PHP 8.4+
  • A PSR-18 HTTP client and a PSR-7/17 implementation (your choice — see below)

Installation

composer require devmatchable/whop-php-sdk

The SDK declares only the PSR interface packages and php-http/discovery in its require block. Concrete HTTP implementations are not bundled — you pick what fits your stack.

Recommended: nyholm/psr7 (PSR-7 + PSR-17) paired with symfony/http-client (PSR-18) work well together:

composer require nyholm/psr7 symfony/http-client

Any other PSR-18 client (guzzlehttp/guzzle, etc.) and any PSR-7/17 implementation work as drop-in replacements.

Note

The SDK uses Symfony\Component\HttpClient\Psr18Client — the PSR-18 adapter shipped by symfony/http-client. This is intentionally different from Symfony's framework-native HttpClientInterface, which has a non-PSR shape and isn't compatible with this SDK (or any other PSR-18 consumer). The two interfaces ship from the same package but solve different problems: HttpClientInterface is for Symfony-native consumers; Psr18Client bridges the same underlying client to the PSR-18 standard the SDK type-hints against.

Quick start

use Matchable\Whop\WhopApiClient;
use Symfony\Component\HttpClient\Psr18Client;

$client = new WhopApiClient(
    httpClient: new Psr18Client(),
    apiKey: $_ENV['WHOP_API_KEY'],
);

// Methods that map to a typed DTO return it directly:
$company = $client->companies->get('biz_xxxxxxxx');
echo $company->name;

// Methods without a DTO return the decoded response array:
$list = $client->companies->list(['page' => 1]);

PSR-17 request and stream factories are auto-discovered at construction time via php-http/discovery when you omit them. Pass requestFactory: and streamFactory: explicitly if you want to control which implementation is used.

Error handling

Every failure surfaces as a WhopException — network problems, non-2xx responses, bad JSON, and shape mismatches all go through the same base type, so a single catch covers everything:

use Matchable\Whop\Exception\WhopException;

try {
    $payment = $client->payments->get('pay_xxxxxxxx');
} catch (WhopException $e) {
    // always safe to catch here
    echo $e->getMessage();
}

When you need to distinguish the failure mode, catch a specific subtype:

use Matchable\Whop\Exception\WhopApiException;
use Matchable\Whop\Exception\TransportException;
use Matchable\Whop\Exception\WhopException;

try {
    $payment = $client->payments->get('pay_xxxxxxxx');
} catch (WhopApiException $e) {
    // Non-2xx response from the Whop API
    echo $e->statusCode;       // int — HTTP status code
    print_r($e->responseBody); // array — decoded response body
} catch (TransportException $e) {
    // Network-level failure (DNS, connection refused, etc.)
    echo $e->getMessage();
} catch (WhopException $e) {
    // Anything else: SerializationException, MissingArgumentsException
    echo $e->getMessage();
}

The five concrete exception types:

Exception When it's thrown
WhopApiException The API returned an HTTP 4xx or 5xx response
TransportException A network-level PSR-18 failure (connection refused, timeout, etc.)
SerializationException The request body couldn't be JSON-encoded, or the response body couldn't be decoded
MissingArgumentsException A required field was absent or invalid when hydrating a typed DTO
WebhookVerificationException Webhook signature, timestamp, or header verification failed

WhopApiException exposes two public readonly properties: statusCode (int) and responseBody (array).

Configuration

The full constructor signature:

public function __construct(
    ClientInterface $httpClient,           // PSR-18 client — required
    string $apiKey,                        // Whop API key — required
    string $baseUrl = 'https://api.whop.com/api/v1',  // production default
    ?RequestFactoryInterface $requestFactory = null,   // auto-discovered when null
    ?StreamFactoryInterface $streamFactory = null,     // auto-discovered when null
)

To target the Whop sandbox instead of production, pass the sandbox base URL:

$client = new WhopApiClient(
    httpClient: new Psr18Client(),
    apiKey: $_ENV['WHOP_SANDBOX_API_KEY'],
    baseUrl: 'https://sandbox-api.whop.com/api/v1',
);

If requestFactory or streamFactory is omitted and no PSR-17 implementation is installed, the constructor throws Http\Discovery\Exception\NotFoundException at construction time.

Webhook verification

WebhookVerifier implements the Standard Webhooks specification. Both whsec_ (production) and ws_ (sandbox) secret formats are supported — construct it with whichever secret is configured in your Whop dashboard:

use Matchable\Whop\Exception\WebhookVerificationException;
use Matchable\Whop\Webhook\WebhookVerifier;

$verifier = new WebhookVerifier(webhookSecret: $_ENV['WHOP_WEBHOOK_SECRET']);

// From raw body and headers:
try {
    $verifier->verify($rawBody, $requestHeaders);
} catch (WebhookVerificationException $e) {
    // signature mismatch, stale timestamp, or missing headers
    http_response_code(400);
    exit;
}

// From a PSR-7 request object:
$verifier->verifyRequest($psr7Request);

$requestHeaders is a case-insensitive array mapping header names to values. The verifier checks for webhook-id, webhook-timestamp, and webhook-signature and enforces a 5-minute timestamp tolerance.

Resources

Access the API through resource properties on $client. Each method returns a typed DTO where one exists, otherwise the raw decoded array:

$company  = $client->companies->get('biz_xxxxxxxx');    // Company DTO
$payment  = $client->payments->get('pay_xxxxxxxx');     // Payment DTO
$refund   = $client->payments->refund('pay_xxxxxxxx');  // RefundResponse DTO
$list     = $client->payments->list(['page' => 1]);     // array

The SDK covers the full Whop API surface across 57 resource groups. Per-endpoint method signatures and response shapes are documented in the GitHub Wiki.

A quick map of what's available:

Group Properties
Core $companies, $accountLinks, $files, $accessTokens, $authorizedUsers, $users, $members, $webhooks
Payments & Billing $payments, $checkouts, $plans, $products, $memberships, $refunds, $invoices, $promoCodes, $paymentMethods, $setupIntents
Platform & Finance $transfers, $feeMarkups, $topups, $withdrawals, $ledgerAccounts, $payoutAccounts, $payoutMethods
Disputes $disputes, $disputeAlerts, $resolutionCenter
Commerce $shipments, $leads, $entries, $reviews, $affiliates, $stats
Experiences & Courses $experiences, $courses, $courseChapters, $courseLessons, $courseLessonInteractions, $courseStudents
Communication $chatChannels, $dmChannels, $dmMembers, $messages, $reactions, $forums, $forumPosts, $supportChannels, $notifications
Advertising $adCampaigns, $adGroups, $ads
Apps & AI $apps, $appBuilds, $aiChats, $tokenTransactions
Verifications $verifications

Development

composer test       # PHPUnit
composer stan       # PHPStan
composer cs         # PHP-CS-Fixer dry-run
composer cs:fix     # PHP-CS-Fixer apply
composer infection  # Infection mutation testing

License

MIT — see LICENSE.

统计信息

  • 总下载量: 33
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 2
  • 依赖项目数: 2
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-05-15

承接程序开发

PHP开发

VUE

Vue开发

前端开发

小程序开发

公众号开发

系统定制

数据库设计

云部署

网站建设

安全加固