A PHP wrapper for CodesWholesale API v3

Maintainers

Package info

github.com/fefrik/codeswholesale-v3

pkg:composer/codeswholesale-v3/sdk

Transparency log

Fund package maintenance!

fefrik

Statistics

Installs: 10

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v1.5.0 2026-07-31 13:49 UTC

README

🌍 Languages:
English | Česky

CodesWholesale PHP SDK

PHP SDK for working with the CodesWholesale API v3 (products, orders, license keys, synchronization, security).

Designed for real-world e‑commerce integrations and long-running background jobs.

βœ… PHP 8.3+ βœ… No framework required
βœ… Automatic OAuth authentication
βœ… Safe pagination (resume using continuation token)
βœ… Designed for long-running syncs and cron jobs

Support This Project ❀️

This project is free and open-source and will always remain so.

If it helps you save time or ship faster, you can support ongoing maintenance via GitHub Sponsors:

➑️ https://github.com/sponsors/fefrik

Thank you β€” even a small contribution keeps the project going! πŸš€

Requirements

  • PHP 8.3+
  • cURL extension
  • JSON extension

Installation

composer require codeswholesale-v3/sdk

Basic Usage

Creating the Client and SDK

use CodesWholesaleApi\Api\Client;
use CodesWholesaleApi\Config\Config;
use CodesWholesaleApi\Sdk\Sdk;
use CodesWholesaleApi\Storage\OAuth2\TokenSessionOAuthStorage;

$oauthStorage = new TokenSessionOAuthStorage();

$client = new Client(
    Config::live(),
    $oauthStorage,
    'CLIENT_ID',
    'CLIENT_SECRET'
);

$sdk = new Sdk($client);

Architecture Overview

Client
 └── Endpoint (Products, Orders, Codes, …)
       └── Resource (ProductItem, OrderItem, …)

Client

  • Handles HTTP communication, OAuth2, retries, and errors
  • Always returns stdClass

Endpoint

  • Represents a REST API group (/v3/products, /v3/orders, …)
  • Converts responses into Resource objects

Resource

  • Immutable DTO: input data and raw() are defensively copied
  • Strict typed getters; invalid API field types throw ResourceMappingException
  • DateTimeImmutable accessors preserve timezone information
  • Nested collections offer memory-efficient iterate*() generators
  • Stable values such as code type are represented by PHP enums
  • No filesystem or HTTP side effects

SDK Contents (by API area)

Products

  • List products (paged, resumable)
  • Fetch product details
  • Fetch product descriptions
  • Fetch product images
  • Safe synchronization for large catalogs (50k+ products)

Orders

  • Create orders
  • Fetch order history
  • Fetch order details
  • Extract license keys from completed orders

Codes (License Keys)

  • Fetch ordered license keys
  • Write image-based codes through ImageCodeWriter
  • Base64 image handling

Account

  • Fetch account balance
  • Fetch account details

Security

  • Fraud / risk checks
  • IP and domain reputation
  • Risk score evaluation

Metadata

  • Platforms
  • Regions
  • Languages
  • Territories

Products

Fetching a single page of products

$page = $sdk->products()->getPage([
    'updatedSince' => '2024-01-01T00:00:00Z'
]);

foreach ($page['items'] as $product) {
    echo $product->getName();
}

Iterating over all products

$sdk->products()->getAll(
    function (array $items) {
        foreach ($items as $product) {
            saveProduct($product);
        }
    }
);

Memory-efficient streaming

For large catalogs, prefer the generator. It keeps only the current API page in memory and yields one ProductItem at a time:

foreach ($sdk->products()->iterate(['updatedSince' => $lastSync]) as $product) {
    upsertProduct($product);
}

For resumable jobs, configure a ContinuationTokenStorageInterface and use iterateWithContinuationStorage(). A token is checkpointed only after the complete page has been consumed, so stopping the loop cannot skip products from the unfinished page.

Resource collections and dates

Array getters remain available for convenience. For larger nested collections, use their generator counterparts:

foreach ($order->iterateProducts() as $orderedProduct) {
    foreach ($orderedProduct->iterateCodes() as $code) {
        deliver($code);
    }
}

$releasedAt = $product->getReleaseDate(); // ?DateTimeImmutable

Product descriptions expose structured LocalizedTitleItem, FactSheetItem, PhotoItem, VideoItem, and ReleaseItem objects instead of untyped values. raw() returns a deep copy and cannot mutate the resource.

Image codes are written by a separate service:

use CodesWholesaleApi\Service\ImageCodeWriter;

$path = (new ImageCodeWriter())->write($code, $privateDirectory);

CodeItem::saveImageBase64() remains as a deprecated compatibility wrapper.

Product Synchronization (recommended)

Safe and resumable synchronization using continuation tokens.

$runner->runForSeconds(
    fn(ProductItem $p) => upsertProduct($p),
    30
);

βœ” Safe for web requests
βœ” Safe for cron jobs
βœ” Continues exactly where it stopped

Disclaimer

This is a community-maintained integration and not an official CodesWholesale product.

You must use your own CodesWholesale API key and account. All trademarks belong to their respective owners.