PHP Examples
Complete code examples for using the TakeTheme API with PHP.
Setup
Using cURL
<?php
class TakeThemeClient
{
private string $apiKey;
private string $baseUrl = 'https://api.taketheme.com/api/v1';
public function __construct(string $apiKey)
{
$this->apiKey = $apiKey;
}
public function request(string $method, string $endpoint, ?array $data = null): array
{
$ch = curl_init();
$url = $this->baseUrl . $endpoint;
$headers = [
'tt-api-key: ' . $this->apiKey,
'Content-Type: application/json',
];
curl_setopt_array($ch, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_CUSTOMREQUEST => $method,
]);
if ($data !== null) {
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
}
$response = curl_exec($ch);
$statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$result = json_decode($response, true);
if ($statusCode >= 400) {
throw new TakeThemeException($result, $statusCode);
}
return $result;
}
public function get(string $endpoint, array $params = []): array
{
if (!empty($params)) {
$endpoint .= '?' . http_build_query($params);
}
return $this->request('GET', $endpoint);
}
public function post(string $endpoint, array $data): array
{
return $this->request('POST', $endpoint, $data);
}
public function patch(string $endpoint, array $data): array
{
return $this->request('PATCH', $endpoint, $data);
}
public function delete(string $endpoint): void
{
$this->request('DELETE', $endpoint);
}
}
class TakeThemeException extends Exception
{
public int $status;
public ?string $code;
public function __construct(array $error, int $statusCode)
{
parent::__construct($error['message'] ?? $error['name'] ?? 'Unknown error');
$this->status = $error['status'] ?? $statusCode;
$this->code = $error['code'] ?? null; // Only present on some errors like rate limits
}
}
// Initialize
$client = new TakeThemeClient($_ENV['TAKETHEME_API_KEY']);
Using Guzzle
composer require guzzlehttp/guzzle
<?php
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
class TakeThemeGuzzleClient
{
private Client $http;
public function __construct(string $apiKey)
{
$this->http = new Client([
'base_uri' => 'https://api.taketheme.com/api/v1/',
'headers' => [
'tt-api-key' => $apiKey,
'Content-Type' => 'application/json',
],
]);
}
public function get(string $endpoint, array $params = []): array
{
$response = $this->http->get($endpoint, ['query' => $params]);
return json_decode($response->getBody(), true);
}
public function post(string $endpoint, array $data): array
{
$response = $this->http->post($endpoint, ['json' => $data]);
return json_decode($response->getBody(), true);
}
public function patch(string $endpoint, array $data): array
{
$response = $this->http->patch($endpoint, ['json' => $data]);
return json_decode($response->getBody(), true);
}
public function delete(string $endpoint): void
{
$this->http->delete($endpoint);
}
}
Products
List All Products
$response = $client->get('/products', ['limit' => 25]);
$products = $response['data'];
$pagination = $response['pagination'];
echo "Found {$pagination['total_count']} products\n";
foreach ($products as $product) {
echo "- {$product['title']} (\${$product['price']})\n";
}
Get a Single Product
$product = $client->get('/products/prod_abc123')['data'];
echo "{$product['title']}: {$product['description']}\n";
Create a Product
$newProduct = $client->post('/products', [
'title' => 'Premium Jacket',
'description' => 'Stylish winter jacket',
'price' => 149.99,
'currency' => 'USD',
'status' => 'active',
'variants' => [
['title' => 'Small', 'sku' => 'JACKET-S', 'price' => 149.99, 'inventory_quantity' => 30],
['title' => 'Medium', 'sku' => 'JACKET-M', 'price' => 149.99, 'inventory_quantity' => 50],
['title' => 'Large', 'sku' => 'JACKET-L', 'price' => 149.99, 'inventory_quantity' => 40],
],
'images' => [
['src' => 'https://example.com/jacket.jpg', 'alt' => 'Premium Jacket']
]
])['data'];
echo "Created product: {$newProduct['id']}\n";
Update a Product
$updated = $client->patch('/products/prod_abc123', [
'price' => 159.99,
'tags' => ['featured', 'winter-sale']
])['data'];
Delete a Product
$client->delete('/products/prod_abc123');
Orders
List Orders
// Recent pending orders
$orders = $client->get('/orders', [
'status' => 'pending',
'limit' => 50
])['data'];
// Orders from the last week
$weekAgo = (new DateTime('-7 days'))->format('c');
$recentOrders = $client->get('/orders', [
'created_at_min' => $weekAgo
])['data'];
Create an Order
$order = $client->post('/orders', [
'customer' => [
'email' => 'customer@example.com',
'first_name' => 'John',
'last_name' => 'Doe'
],
'line_items' => [
[
'variant_id' => 'var_abc123',
'quantity' => 2,
'price' => 29.99
]
],
'shipping_address' => [
'first_name' => 'John',
'last_name' => 'Doe',
'address1' => '123 Main Street',
'city' => 'New York',
'province' => 'NY',
'postal_code' => '10001',
'country' => 'US',
'phone' => '+1-555-123-4567'
],
'shipping_line' => [
'title' => 'Standard Shipping',
'price' => 5.99
]
])['data'];
echo "Order created: {$order['order_number']}\n";
Fulfill an Order
$fulfillment = $client->post("/orders/{$orderId}/fulfillments", [
'line_items' => [
['id' => 'li_abc123', 'quantity' => 2]
],
'tracking_number' => '1Z999AA10123456784',
'tracking_company' => 'UPS',
'notify_customer' => true
])['data'];
Cancel an Order
$cancelled = $client->post("/orders/{$orderId}/cancel", [
'reason' => 'customer_request',
'restock' => true,
'notify_customer' => true
])['data'];
Customers
Search Customers
// Find by email
$customers = $client->get('/customers', [
'email' => 'john@example.com'
])['data'];
// Find VIP customers
$vipCustomers = $client->get('/customers', [
'tags' => 'vip',
'orders_count_min' => 10
])['data'];
Create a Customer
$customer = $client->post('/customers', [
'email' => 'newcustomer@example.com',
'first_name' => 'Jane',
'last_name' => 'Smith',
'phone' => '+1-555-987-6543',
'addresses' => [
[
'address1' => '456 Oak Avenue',
'city' => 'Los Angeles',
'province' => 'CA',
'postal_code' => '90001',
'country' => 'US',
'default' => true
]
],
'tags' => ['newsletter', 'loyalty-program'],
'accepts_marketing' => true
])['data'];
Webhooks
Register a Webhook
$webhook = $client->post('/webhooks', [
'topic' => 'orders/created',
'address' => 'https://your-app.com/webhooks/orders',
'format' => 'json'
])['data'];
echo "Webhook registered: {$webhook['id']}\n";
Verify Webhook Signatures
<?php
function verifyWebhookSignature(string $payload, string $signature, string $secret): bool
{
$expected = base64_encode(hash_hmac('sha256', $payload, $secret, true));
return hash_equals($expected, $signature);
}
// Usage in webhook handler
$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_TAKETHEME_SIGNATURE'] ?? '';
$secret = $_ENV['TAKETHEME_WEBHOOK_SECRET'];
if (!verifyWebhookSignature($payload, $signature, $secret)) {
http_response_code(401);
exit('Invalid signature');
}
$event = json_decode($payload, true);
$orderNumber = $event['data']['order_number'];
// Process webhook...
echo "Order created: {$orderNumber}";
Pagination Helper
<?php
function paginate(TakeThemeClient $client, string $endpoint, array $params = []): Generator
{
$params['limit'] = 100;
$cursor = null;
do {
if ($cursor !== null) {
$params['cursor'] = $cursor;
$params['direction'] = 'next';
}
$response = $client->get($endpoint, $params);
$data = $response['data'];
$pagination = $response['pagination'];
foreach ($data as $item) {
yield $item;
}
$cursor = $pagination['next_cursor'] ?? null;
} while ($pagination['has_more'] ?? false);
}
// Usage
foreach (paginate($client, '/products') as $product) {
echo $product['title'] . "\n";
}
// Collect all products
$allProducts = iterator_to_array(paginate($client, '/products'));
echo "Total: " . count($allProducts) . " products\n";
Error Handling
<?php
class RateLimitException extends TakeThemeException
{
public int $retryAfter;
public function __construct(array $error, int $statusCode, int $retryAfter)
{
parent::__construct($error, $statusCode);
$this->retryAfter = $retryAfter;
}
}
function handleApiResponse(array $response, int $statusCode, array $headers): array
{
if ($statusCode >= 200 && $statusCode < 300) {
return $response;
}
switch ($statusCode) {
case 429:
$retryAfter = (int)($headers['Retry-After'] ?? 60);
throw new RateLimitException($response, $statusCode, $retryAfter);
default:
throw new TakeThemeException($response, $statusCode);
}
}
// Usage
try {
$client->post('/products', ['title' => '']); // Invalid
} catch (RateLimitException $e) {
echo "Rate limited. Retry after {$e->retryAfter} seconds\n";
sleep($e->retryAfter);
} catch (TakeThemeException $e) {
switch ($e->status) {
case 400:
echo "Validation error: {$e->getMessage()}\n";
break;
case 401:
echo "Authentication failed\n";
break;
case 403:
echo "Permission denied: {$e->getMessage()}\n";
break;
default:
echo "Error: {$e->getMessage()}\n";
}
}
Complete Example: Inventory Sync
<?php
require_once 'vendor/autoload.php';
$client = new TakeThemeClient($_ENV['TAKETHEME_API_KEY']);
function syncInventory(TakeThemeClient $client, string $csvFile): void
{
echo "Starting inventory sync...\n";
// Read CSV file
$handle = fopen($csvFile, 'r');
$headers = fgetcsv($handle);
$updated = 0;
$errors = 0;
while (($row = fgetcsv($handle)) !== false) {
$data = array_combine($headers, $row);
$sku = $data['sku'];
$quantity = (int)$data['quantity'];
try {
// Find variant by SKU
$variants = $client->get('/variants', ['sku' => $sku])['data'];
if (empty($variants)) {
echo "Variant not found: {$sku}\n";
$errors++;
continue;
}
$variantId = $variants[0]['id'];
// Update inventory
$client->post("/inventory/{$variantId}", [
'location_id' => 'loc_main',
'available' => $quantity
]);
echo "Updated {$sku}: {$quantity} units\n";
$updated++;
// Rate limit protection
usleep(100000); // 100ms
} catch (TakeThemeException $e) {
echo "Error updating {$sku}: {$e->getMessage()}\n";
$errors++;
}
}
fclose($handle);
echo "\nSync complete!\n";
echo "Updated: {$updated}\n";
echo "Errors: {$errors}\n";
}
// Run sync
syncInventory($client, 'inventory.csv');
Laravel Integration
<?php
namespace App\Services;
use Illuminate\Support\Facades\Http;
use Illuminate\Http\Client\Response;
class TakeThemeService
{
private string $baseUrl = 'https://api.taketheme.com/api/v1';
public function __construct(private string $apiKey)
{
}
private function request(): \Illuminate\Http\Client\PendingRequest
{
return Http::withToken($this->apiKey)
->baseUrl($this->baseUrl)
->acceptJson();
}
public function getProducts(array $params = []): array
{
return $this->request()
->get('/products', $params)
->throw()
->json('data');
}
public function createProduct(array $data): array
{
return $this->request()
->post('/products', $data)
->throw()
->json('data');
}
public function getOrder(string $id): array
{
return $this->request()
->get("/orders/{$id}")
->throw()
->json('data');
}
public function createOrder(array $data): array
{
return $this->request()
->post('/orders', $data)
->throw()
->json('data');
}
}
// Service provider
class TakeThemeServiceProvider extends ServiceProvider
{
public function register(): void
{
$this->app->singleton(TakeThemeService::class, function ($app) {
return new TakeThemeService(config('services.taketheme.api_key'));
});
}
}
// Usage in controller
class ProductController extends Controller
{
public function index(TakeThemeService $taketheme)
{
$products = $taketheme->getProducts(['limit' => 25]);
return view('products.index', compact('products'));
}
}