Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Php Sdk Laravel Package

wepay/php-sdk

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Check viability before anything else. WePay's public APIv2 was retired after the Chase acquisition; the SDK's last release was January 2017 and there is no maintainer. Confirm with WePay/Chase that your merchant account still has APIv2 access before writing a line of code. If it does, you are integrating against a frozen, legacy API with a legacy SDK.
  2. Install and pin the exact version — there will be no patches:
composer require wepay/php-sdk
composer show wepay/php-sdk   # note the resolved version and pin it in composer.json
  1. The SDK is all global WePay\* classes configured through static properties, so bootstrap it once in a provider rather than scattering WePayConfig::$... assignments in controllers:
// config/services.php
'wepay' => [
    'client_id'     => env('WEPAY_CLIENT_ID'),
    'client_secret' => env('WEPAY_CLIENT_SECRET'),
    'access_token'  => env('WEPAY_ACCESS_TOKEN'), // only for a single-merchant app
    'use_stage'     => env('WEPAY_STAGE', false),
],

// app/Providers/AppServiceProvider.php (boot)
\WePay\WePayConfig::$clientId     = config('services.wepay.client_id');
\WePay\WePayConfig::$clientSecret = config('services.wepay.client_secret');
\WePay\WePayConfig::$accessToken  = config('services.wepay.access_token');
\WePay\WePayConfig::$useStage     = (bool) config('services.wepay.use_stage');
  1. First use case: create a checkout and confirm you can round-trip.
$wepay = new \WePay\WePay();

try {
    $checkout = $wepay->request('/checkout/create', [
        'account_id'        => $accountId,
        'amount'            => 49.00,           // dollars, not cents
        'short_description' => 'Order #1042',
        'type'              => 'goods',
        'payment_method'    => ['type' => 'credit_card'],
        'redirect_uri'      => route('wepay.return', $order),
        'callback_uri'      => route('wepay.ipn'),
    ]);
} catch (\WePay\WePayException $e) {
    report($e);
    // $e->getMessage() / $e->getErrorCode() — inspect the actual accessors in the package
}

Redirect the user to $checkout['checkout_uri'], and persist $checkout['checkout_id'] against the order.

Implementation Patterns

Wrap the SDK in your own gateway class. Never let new \WePay\WePay() leak into controllers or jobs. One WePayGateway (or interface + implementation) gives you a seam for fakes, retries, logging, and a clean migration path if the API is replaced:

class WePayGateway
{
    public function __construct(private \WePay\WePay $client) {}

    public function createCheckout(Order $order): array
    {
        $response = $this->client->request('/checkout/create', [...]);
        $order->update(['wepay_checkout_id' => $response['checkout_id']]);
        return $response;
    }
}

OAuth for marketplace/multi-merchant apps. Each merchant's access_token must be stored per account, and the static WePayConfig::$accessToken is only a default. Pass the token per call where the SDK supports it (the request() signature accepts an access token argument) or set it immediately before the call in a single-threaded request — never assume the static value is "yours".

// redirect
$url = 'https://wepayapi.com/v2/oauth2/authorize?' . http_build_query([
    'client_id' => config('services.wepay.client_id'),
    'redirect_uri' => route('wepay.callback'),
    'scope' => 'manage_accounts,collect_payments,view_user',
]);
// callback
$token = $wepay->request('/oauth2/token', [
    'code' => $request->code,
    'redirect_uri' => route('wepay.callback'),
    'client_id' => config('services.wepay.client_id'),
    'client_secret' => config('services.wepay.client_secret'),
]);

Treat IPNs as untrusted events. WePay's callback is a POST with resource IDs only. Push a job, then re-fetch the object via the API (/checkout/get) before mutating order state, and make the transition idempotent — the same checkout_id can arrive more than once. Also reconcile via polling for any checkout stuck in pending, because webhooks are not guaranteed.

Handle the two exception families separately. WePayException means the API rejected the call (map its error code to a user-facing message); network/cURL failures surface differently. Retry only the latter, with backoff, and only for idempotent GETs — the SDK has no retry logic and no idempotency keys, so a retried /checkout/create can double-charge.

Testing. There is no HTTP client abstraction and no Http::fake() hook, so test against your WePayGateway interface and bind a fake in the container. For integration-ish tests, subclass \WePay\WePay and override request() to return canned payloads.

Gotchas and Tips

  • Static config is global state. WePayConfig leaks across tests and across tenants in the same process (queue workers, Octane). Reset every property in setUp()/tearDown() and avoid touching it outside the bootstrap provider.
  • Abandoned package. No PHP 8.x guarantees, no security patches, no PSR-7/Guzzle. composer audit will not help you. Run the test suite on the PHP version you deploy; watch for deprecations on first boot.
  • Amounts are decimal dollars in floats. The SDK and API speak 49.00, not 4900. Persist cents in your DB and convert at the boundary, or you will accumulate rounding drift.
  • Stage vs production. useStage = true points at stage.wepayapi.com. A production deploy with the env flag flipped is a silent, hard-to-spot bug — assert on the base URL in a smoke test.
  • Never log client_secret or access_token. Exception messages and any raw request dumps you add can carry them. Redact before report().
  • Set an explicit timeout. The SDK's default is short and cURL's is unbounded in places; pass a timeout through request() and set sane curl options via the config class for the rest.
  • Extension points are limited to subclassing \WePay\WePay, mutating the static config before construction, and injecting via the constructor. There is no middleware, no event hooks, no logger — build your own request logging around the gateway wrapper.
  • Don't build a new feature on this. If the integration is greenfield, prototype the call with curl/Http:: against the documented endpoint first; you may find you only need three endpoints and can own a 60-line client instead of inheriting an unmaintained dependency.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core