├── .gitignore ├── README.md ├── composer.json ├── examples ├── Products │ ├── delete.php │ ├── get-products.php │ ├── get-single-product.php │ ├── get-single-variant.php │ ├── product-creation-array.php │ ├── product-creation-mixed.php │ ├── product-creation-oop.php │ ├── product-update.php │ ├── variant-create.php │ └── variant-update.php ├── orders.php ├── products.php └── shipping-rates.php └── src ├── Exceptions ├── PrintfulApiException.php ├── PrintfulException.php └── PrintfulSdkException.php ├── PrintfulApiClient.php ├── PrintfulMockupGenerator.php ├── PrintfulOrder.php ├── PrintfulProducts.php ├── PrintfulTaxRates.php ├── PrintfulWebhook.php └── Structures ├── AddressItem.php ├── BaseItem.php ├── CountryItem.php ├── File.php ├── Generator ├── GenerationResultItem.php ├── MockupExtraItem.php ├── MockupGenerationFile.php ├── MockupGenerationParameters.php ├── MockupItem.php ├── MockupList.php ├── MockupPositionItem.php ├── PrintfileItem.php ├── ProductPrintfiles.php ├── Templates │ ├── PlacementConflictItem.php │ ├── ProductTemplates.php │ ├── TemplateItem.php │ └── VariantTemplateMappingItem.php ├── VariantPlacementGroup.php └── VariantPrintfileItem.php ├── Order ├── GiftItem.php ├── Order.php ├── OrderCostGroup.php ├── OrderCostsItem.php ├── OrderCreationParameters.php ├── OrderItemCreationParameters.php ├── OrderItemOption.php ├── OrderLineItem.php ├── OrderList.php ├── PackingSlipItem.php ├── ProductVariant.php └── RecipientCreationParameters.php ├── Placements.php ├── Shipment ├── Shipment.php └── ShipmentItem.php ├── StateItem.php ├── Sync ├── Requests │ ├── SyncProductRequest.php │ ├── SyncVariantRequest.php │ ├── SyncVariantRequestFile.php │ └── SyncVariantRequestOption.php ├── Responses │ ├── SyncProductRequestResponse.php │ ├── SyncProductResponse.php │ ├── SyncProductsPagingResponse.php │ ├── SyncProductsResponse.php │ ├── SyncVariantOptionResponse.php │ ├── SyncVariantProductResponse.php │ └── SyncVariantResponse.php ├── SyncProductCreationParameters.php └── SyncProductUpdateParameters.php ├── TaxRateItem.php └── Webhook ├── WebhookItem.php └── WebhooksInfoItem.php /.gitignore: -------------------------------------------------------------------------------- 1 | vendor/ 2 | composer.lock 3 | .idea 4 | tests/Credentials.php -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Latest Stable Version](https://poser.pugx.org/printful/php-api-sdk/v/stable.svg)](https://packagist.org/packages/printful/php-api-sdk) 2 | [![Latest Unstable Version](https://poser.pugx.org/printful/php-api-sdk/v/unstable.svg)](https://packagist.org/packages/printful/php-api-sdk) 3 | 4 | # Printful API PHP wrapper 5 | 6 | Simple PHP wrapper class for work with Printful API. 7 | 8 | API endpoint documentation can be found here: https://www.printful.com/docs 9 | 10 | # Installation 11 | 12 | Using composer, run `composer require printful/php-api-sdk` 13 | 14 | Check out **example** and **test** directories for more specific usage examples. 15 | 16 | # OAuth 17 | [OAuth 2.0](https://developers.printful.com/docs/#section/Authentication:~:text=OAuth%202.0%20is%20the%20preferred%20way%20of%20doing%20authorization%20in%20Printful%20API.) 18 | is the preferred way of doing authorization in Printful API. Read more about how to acquire and 19 | use an access token in our docs: https://developers.printful.com/docs/#section/Authentication 20 | 21 | You can create an OAuth enabled APIClient using the following factory method: 22 | ```php 23 | ... 24 | use Printful\PrintfulApiClient; 25 | ... 26 | $client = PrintfulApiClient::createOauthClient('my-oauth-token') 27 | ``` 28 | 29 | You can still use the old store keys, like this: 30 | ```php 31 | ... 32 | use Printful\PrintfulApiClient; 33 | ... 34 | $client = PrintfulApiClient::createLegacyStoreKeyClient('my-legacy-store-key') 35 | ``` 36 | or, by using the constructor like this: 37 | ```php 38 | $client = new PrintfulApiClient($storeKey) 39 | ``` 40 | However, please note that legacy keys will be phased out on September 30th, 2022. 41 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "printful/php-api-sdk", 3 | "description": "Printful API wrapper", 4 | "type": "library", 5 | "authors": [ 6 | { 7 | "name": "Printful", 8 | "email": "dev@theprintful.com" 9 | } 10 | ], 11 | "require": { 12 | "php": ">=5.5.0", 13 | "ext-curl": "*", 14 | "ext-json": "*" 15 | }, 16 | "require-dev": { 17 | "phpunit/phpunit": "^5.7" 18 | }, 19 | "autoload": { 20 | "psr-4": { 21 | "Printful\\": "src/" 22 | } 23 | }, 24 | "autoload-dev": { 25 | "psr-4": { 26 | "Printful\\Tests\\": "tests/" 27 | } 28 | }, 29 | "minimum-stability": "stable" 30 | } 31 | -------------------------------------------------------------------------------- /examples/Products/delete.php: -------------------------------------------------------------------------------- 1 | deleteProduct($id); 35 | 36 | } catch (PrintfulApiException $e) { // API response status code was not successful 37 | echo 'Printful API Exception: ' . $e->getCode() . ' ' . $e->getMessage(); 38 | } catch (PrintfulException $e) { // API call failed 39 | echo 'Printful Exception: ' . $e->getMessage(); 40 | var_export($pf->getLastResponseRaw()); 41 | } 42 | 43 | // Delete variant example 44 | // Docs for this endpoint can be found here: https://www.printful.local/docs/products#actionDeleteVariant 45 | try { 46 | 47 | // variant id in Printful store, which we want to delete 48 | // remember that you can not delete products last variant, you should delete whole product instead 49 | $id = 1; 50 | 51 | // you can also use your external id 52 | // $externalId = 32142; 53 | // $id = '@'.$externalId; 54 | 55 | // create ApiClient 56 | $pf = new PrintfulApiClient($apiKey); 57 | 58 | // create Products Api object 59 | $productsApi = new PrintfulProducts($pf); 60 | 61 | $productsApi->deleteVariant($id); 62 | 63 | } catch (PrintfulApiException $e) { // API response status code was not successful 64 | echo 'Printful API Exception: ' . $e->getCode() . ' ' . $e->getMessage(); 65 | } catch (PrintfulException $e) { // API call failed 66 | echo 'Printful Exception: ' . $e->getMessage(); 67 | var_export($pf->getLastResponseRaw()); 68 | } -------------------------------------------------------------------------------- /examples/Products/get-products.php: -------------------------------------------------------------------------------- 1 | getProducts($offset, $limit); 33 | 34 | } catch (PrintfulApiException $e) { // API response status code was not successful 35 | echo 'Printful API Exception: ' . $e->getCode() . ' ' . $e->getMessage(); 36 | } catch (PrintfulException $e) { // API call failed 37 | echo 'Printful Exception: ' . $e->getMessage(); 38 | var_export($pf->getLastResponseRaw()); 39 | } 40 | -------------------------------------------------------------------------------- /examples/Products/get-single-product.php: -------------------------------------------------------------------------------- 1 | getProduct($productId); 32 | 33 | // actual product can be found $response->syncProduct 34 | // and its variants $response->syncVariants 35 | 36 | // product id in your store(saved with external_id) 37 | $externalProductId = 15946; 38 | 39 | // get product by external_id 40 | /** @var SyncProductRequestResponse $response */ 41 | $response = $productsApi->getProduct('@' . $externalProductId); 42 | 43 | // actual product can be found $response->syncProduct 44 | // and products variants $response->syncVariants 45 | 46 | } catch (PrintfulApiException $e) { // API response status code was not successful 47 | echo 'Printful API Exception: ' . $e->getCode() . ' ' . $e->getMessage(); 48 | } catch (PrintfulException $e) { // API call failed 49 | echo 'Printful Exception: ' . $e->getMessage(); 50 | var_export($pf->getLastResponseRaw()); 51 | } 52 | -------------------------------------------------------------------------------- /examples/Products/get-single-variant.php: -------------------------------------------------------------------------------- 1 | getProduct($variantId); 32 | 33 | 34 | // variant id in your store(saved with external_id) 35 | $externalVariantId = 15946; 36 | 37 | // get variant by external_id 38 | /** @var SyncVariantResponse $product */ 39 | $product = $productsApi->getProduct('@' . $externalVariantId); 40 | 41 | } catch (PrintfulApiException $e) { // API response status code was not successful 42 | echo 'Printful API Exception: ' . $e->getCode() . ' ' . $e->getMessage(); 43 | } catch (PrintfulException $e) { // API call failed 44 | echo 'Printful Exception: ' . $e->getMessage(); 45 | var_export($pf->getLastResponseRaw()); 46 | } 47 | -------------------------------------------------------------------------------- /examples/Products/product-creation-array.php: -------------------------------------------------------------------------------- 1 | [ 29 | 'external_id' => 1, // set id in my store for this product (optional) 30 | 'name' => 'My new shirt', 31 | 'thumbnail' => 'https://www.my-webshop.com/shirt.jpg', // set thumbnail url 32 | ], 33 | 'sync_variants' => [ // add sync variants 34 | [ 35 | 'external_id' => 1, // set id in my store for this variant (optional) 36 | 'retail_price' => 21.00, // set retail price that this item is sold for (optional) 37 | 'variant_id' => 4011, // set variant in from Printful Catalog(https://www.printful.com/docs/catalog) 38 | 'files' => [ 39 | [ 40 | 'url' => 'https://www.my-webshop.com/shirt.jpg', 41 | ], 42 | [ 43 | 'type' => 'back', // set print file placement on item. If not set, default placement for this product will be used 44 | 'id' => 1, // file id from my File library in Printful (https://www.printful.com/docs/files) 45 | ], 46 | ], 47 | 'options' => [ 48 | [ 49 | 'id' => 'embroidery_type', 50 | 'value' => 'flat' 51 | ], 52 | ], 53 | ], 54 | [ 55 | 'external_id' => 2, // set id in my store for this variant (optional) 56 | 'retail_price' => 21.00, // set retail price that this item is sold for (optional) 57 | 'variant_id' => 4012, // set variant in from Printful Catalog(https://www.printful.com/docs/catalog) 58 | 'files' => [ 59 | [ 60 | 'url' => 'https://www.my-webshop.com/shirt.jpg', 61 | ], 62 | [ 63 | 'type' => 'back', // set print file placement on item. If not set, default placement for this product will be used 64 | 'id' => 1, // file id from my File library in Printful (https://www.printful.com/docs/files) 65 | ], 66 | ], 67 | 'options' => [ 68 | [ 69 | 'id' => 'embroidery_type', 70 | 'value' => 'flat' 71 | ], 72 | ], 73 | ], 74 | 75 | ], 76 | ]; 77 | 78 | $creationParams = SyncProductCreationParameters::fromArray($data); 79 | 80 | $product = $productsApi->createProduct($creationParams); 81 | 82 | } catch (PrintfulApiException $e) { // API response status code was not successful 83 | echo 'Printful API Exception: ' . $e->getCode() . ' ' . $e->getMessage(); 84 | } catch (PrintfulSdkException $e) { // SDK did not call API 85 | echo 'Printful SDK Exception: ' . $e->getMessage(); 86 | } catch (PrintfulException $e) { // API call failed 87 | echo 'Printful Exception: ' . $e->getMessage(); 88 | var_export($pf->getLastResponseRaw()); 89 | } -------------------------------------------------------------------------------- /examples/Products/product-creation-mixed.php: -------------------------------------------------------------------------------- 1 | 1, // set id in my store for this product (optional) 32 | 'name' => 'My new shirt', // set product name 33 | 'thumbnail' => 'https://www.my-webshop.com/shirt.jpg', // // set thumbnail url (optional) 34 | ]); 35 | 36 | // create creationParams 37 | $creationParams = new SyncProductCreationParameters($productRequest); 38 | 39 | // create variant A (Bella + Canvas 3001, S, White) 40 | $syncVariantRequest = SyncVariantRequest::fromArray([ 41 | 'external_id' => 1, // set id in my store for this variant (optional) 42 | 'variant_id' => 4011, // set variant in from Printful Catalog(https://www.printful.com/docs/catalog) 43 | 'retail_price' => 21.00, // set retail price that this item is sold for (optional) 44 | 'files' => [ 45 | [ 46 | 'url' => 'https://www.my-webshop.com/shirt.jpg', 47 | ], 48 | [ 49 | 'type' => 'back', // set print file placement on item. If not set, default placement for this product will be used 50 | 'id' => 1, // file id from my File library in Printful (https://www.printful.com/docs/files) 51 | ], 52 | ], 53 | 'options' => [ 54 | [ 55 | 'id' => 'embroidery_type', 56 | 'value' => 'flat' 57 | ], 58 | ], 59 | ]); 60 | 61 | // add variant to creation params 62 | $creationParams->addSyncVariant($syncVariantRequest); 63 | 64 | // create variant B (Bella + Canvas 3001, M, White) 65 | $syncVariantRequest = SyncVariantRequest::fromArray([ 66 | 'external_id' => 2, // set id in my store for this variant (optional) 67 | 'variant_id' => 4012, // set variant in from Printful Catalog(https://www.printful.com/docs/catalog) 68 | 'retail_price' => 21.00, // set retail price that this item is sold for (optional) 69 | 'files' => [ 70 | [ 71 | 'url' => 'https://www.my-webshop.com/shirt.jpg', 72 | ], 73 | [ 74 | 'type' => 'back', // set print file placement on item. If not set, default placement for this product will be used 75 | 'id' => 1, // file id from my File library in Printful (https://www.printful.com/docs/files) 76 | ], 77 | ], 78 | 'options' => [ 79 | [ 80 | 'id' => 'embroidery_type', 81 | 'value' => 'flat' 82 | ], 83 | ], 84 | ]); 85 | 86 | // add variant to creation params 87 | $creationParams->addSyncVariant($syncVariantRequest); 88 | 89 | $product = $productsApi->createProduct($creationParams); 90 | 91 | } catch (PrintfulApiException $e) { // API response status code was not successful 92 | echo 'Printful API Exception: ' . $e->getCode() . ' ' . $e->getMessage(); 93 | } catch (PrintfulSdkException $e) { // SDK did not call API 94 | echo 'Printful SDK Exception: ' . $e->getMessage(); 95 | } catch (PrintfulException $e) { // API call failed 96 | echo 'Printful Exception: ' . $e->getMessage(); 97 | var_export($pf->getLastResponseRaw()); 98 | } -------------------------------------------------------------------------------- /examples/Products/product-creation-oop.php: -------------------------------------------------------------------------------- 1 | externalId = 1; 36 | 37 | // set product name 38 | $productRequest->name = 'My new shirt'; 39 | 40 | // set thumbnail url 41 | $productRequest->thumbnail = 'https://www.my-webshop.com/shirt.jpg'; 42 | 43 | // create creationParams 44 | $creationParams = new SyncProductCreationParameters($productRequest); 45 | 46 | // create variant 47 | $syncVariantRequest = new SyncVariantRequest; 48 | 49 | // set id in my store for this variant (optional) 50 | $syncVariantRequest->externalId = 1; 51 | 52 | // set variant in from Printful Catalog(https://www.printful.com/docs/catalog) 53 | $syncVariantRequest->variantId = 4011; // Bella + Canvas 3001, S, White 54 | 55 | // set retail price that this item is sold for (optional) 56 | $syncVariantRequest->retailPrice = 21.00; 57 | 58 | // create print file 59 | // $file->id or $file->url is required 60 | $file = new SyncVariantRequestFile(); 61 | 62 | // file id from my File library in Printful (https://www.printful.com/docs/files) 63 | // $file->id = 1; 64 | 65 | // set print file url 66 | $file->url = 'https://www.my-webshop.com/shirt.jpg'; 67 | 68 | // set print file placement on item. If not set, default placement for this product will be used 69 | $file->type = 'front'; 70 | 71 | // add print file to variant. You can add multiple files for single variant (type must be unique) 72 | $syncVariantRequest->addFile($file); 73 | 74 | // create variant option 75 | $option = new SyncVariantRequestOption; 76 | $option->id = 'embroidery_type'; 77 | $option->value = 'flat'; 78 | 79 | $syncVariantRequest->addOption($option); 80 | 81 | // add variant to creation params (you can create and add multiple variants) 82 | $creationParams->addSyncVariant($syncVariantRequest); 83 | 84 | $product = $productsApi->createProduct($creationParams); 85 | 86 | } catch (PrintfulApiException $e) { // API response status code was not successful 87 | echo 'Printful API Exception: ' . $e->getCode() . ' ' . $e->getMessage(); 88 | } catch (PrintfulSdkException $e) { // SDK did not call API 89 | echo 'Printful SDK Exception: ' . $e->getMessage(); 90 | } catch (PrintfulException $e) { // API call failed 91 | echo 'Printful Exception: ' . $e->getMessage(); 92 | var_export($pf->getLastResponseRaw()); 93 | } -------------------------------------------------------------------------------- /examples/Products/product-update.php: -------------------------------------------------------------------------------- 1 | name = 'My new shirt name'; 46 | 47 | // in this example we only need to update products info, so we omit variant list info 48 | $params->syncProduct = $productRequest; 49 | 50 | // preform update 51 | $product = $productsApi->updateProduct($productId, $params); 52 | 53 | } catch (PrintfulApiException $e) { // API response status code was not successful 54 | echo 'Printful API Exception: ' . $e->getCode() . ' ' . $e->getMessage(); 55 | } catch (PrintfulSdkException $e) { // SDK did not call API 56 | echo 'Printful SDK Exception: ' . $e->getMessage(); 57 | } catch (PrintfulException $e) { // API call failed 58 | echo 'Printful Exception: ' . $e->getMessage(); 59 | var_export($pf->getLastResponseRaw()); 60 | } 61 | 62 | // Example B 63 | try { 64 | 65 | // product id in Printful store, which we want to update 66 | $productId = 1; 67 | 68 | // create ApiClient 69 | $pf = new PrintfulApiClient($apiKey); 70 | 71 | // create Products Api object 72 | $productsApi = new PrintfulProducts($pf); 73 | 74 | // build product request from array 75 | $productRequest = SyncProductRequest::fromArray([ 76 | 'name' => 'My new shirt name', 77 | ]); 78 | 79 | $params = new SyncProductUpdateParameters; 80 | 81 | // in this example we only need to update products info, so we omit variant list info 82 | $params->syncProduct = $productRequest; 83 | 84 | // preform update 85 | $product = $productsApi->updateProduct($productId, $params); 86 | 87 | } catch (PrintfulApiException $e) { // API response status code was not successful 88 | echo 'Printful API Exception: ' . $e->getCode() . ' ' . $e->getMessage(); 89 | } catch (PrintfulSdkException $e) { // SDK did not call API 90 | echo 'Printful SDK Exception: ' . $e->getMessage(); 91 | } catch (PrintfulException $e) { // API call failed 92 | echo 'Printful Exception: ' . $e->getMessage(); 93 | var_export($pf->getLastResponseRaw()); 94 | } 95 | 96 | // Example C 97 | try { 98 | 99 | // product id in Printful store, which we want to update 100 | $productId = 1; 101 | 102 | // create ApiClient 103 | $pf = new PrintfulApiClient($apiKey); 104 | 105 | // create Products Api object 106 | $productsApi = new PrintfulProducts($pf); 107 | 108 | // build params from array 109 | $params = SyncProductUpdateParameters::fromArray([ 110 | 'sync_product' => [ 111 | 'name' => 'My new shirt name', 112 | ], 113 | ]); 114 | 115 | // preform update 116 | $product = $productsApi->updateProduct($productId, $params); 117 | 118 | } catch (PrintfulApiException $e) { // API response status code was not successful 119 | echo 'Printful API Exception: ' . $e->getCode() . ' ' . $e->getMessage(); 120 | } catch (PrintfulSdkException $e) { // SDK did not call API 121 | echo 'Printful SDK Exception: ' . $e->getMessage(); 122 | } catch (PrintfulException $e) { // API call failed 123 | echo 'Printful Exception: ' . $e->getMessage(); 124 | var_export($pf->getLastResponseRaw()); 125 | } -------------------------------------------------------------------------------- /examples/Products/variant-create.php: -------------------------------------------------------------------------------- 1 | 1, // set id in my store for this variant (optional) 38 | 'retail_price' => 21.00, // set retail price that this item is sold for (optional) 39 | 'variant_id' => 4011, // set variant in from Printful Catalog(https://www.printful.com/docs/catalog) 40 | 'files' => [ 41 | [ 42 | 'url' => 'https://www.my-webshop.com/shirt.jpg', 43 | ], 44 | [ 45 | 'type' => 'back', // set print file placement on item. If not set, default placement for this product will be used 46 | 'url' => 'https://www.my-webshop.com/shirt.jpg', 47 | ], 48 | ], 49 | 'options' => [ 50 | [ 51 | 'id' => 'embroidery_type', 52 | 'value' => 'flat', 53 | ], 54 | ], 55 | ]); 56 | 57 | $variant = $productsApi->createVariant($productId, $variantRequest); 58 | 59 | } catch (PrintfulApiException $e) { // API response status code was not successful 60 | echo 'Printful API Exception: ' . $e->getCode() . ' ' . $e->getMessage(); 61 | } catch (PrintfulSdkException $e) { // SDK did not call API 62 | echo 'Printful SDK Exception: ' . $e->getMessage(); 63 | } catch (PrintfulException $e) { // API call failed 64 | echo 'Printful Exception: ' . $e->getMessage(); 65 | var_export($pf->getLastResponseRaw()); 66 | } 67 | -------------------------------------------------------------------------------- /examples/Products/variant-update.php: -------------------------------------------------------------------------------- 1 | retailPrice = 22.00; 40 | 41 | $updatedVariant = $productsApi->updateVariant($variantId, $variantRequest); 42 | 43 | } catch (PrintfulApiException $e) { // API response status code was not successful 44 | echo 'Printful API Exception: ' . $e->getCode() . ' ' . $e->getMessage(); 45 | } catch (PrintfulSdkException $e) { // SDK did not call API 46 | echo 'Printful SDK Exception: ' . $e->getMessage(); 47 | } catch (PrintfulException $e) { // API call failed 48 | echo 'Printful Exception: ' . $e->getMessage(); 49 | var_export($pf->getLastResponseRaw()); 50 | } 51 | 52 | // Example B 53 | try { 54 | 55 | // variant id in Printful store, which we want to update 56 | $variantId = 1; 57 | 58 | // you can also use your external id 59 | // $externalId = 32142; 60 | // $variantId = '@'.$externalId; 61 | 62 | // create ApiClient 63 | $pf = new PrintfulApiClient($apiKey); 64 | 65 | // create Products Api object 66 | $productsApi = new PrintfulProducts($pf); 67 | 68 | // in this example we only update retail price, so we omit everything else 69 | $variantRequest = SyncVariantRequest::fromArray([ 70 | 'retail_price' => 22.00 71 | ]); 72 | 73 | $updatedVariant = $productsApi->updateVariant($variantId, $variantRequest); 74 | 75 | } catch (PrintfulApiException $e) { // API response status code was not successful 76 | echo 'Printful API Exception: ' . $e->getCode() . ' ' . $e->getMessage(); 77 | } catch (PrintfulSdkException $e) { // SDK did not call API 78 | echo 'Printful SDK Exception: ' . $e->getMessage(); 79 | } catch (PrintfulException $e) { // API call failed 80 | echo 'Printful Exception: ' . $e->getMessage(); 81 | var_export($pf->getLastResponseRaw()); 82 | } 83 | 84 | // Example C 85 | try { 86 | 87 | // variant id in Printful store, which we want to update 88 | $variantId = 1; 89 | 90 | // you can also use your external id 91 | // $externalId = 32142; 92 | // $variantId = '@'.$externalId; 93 | 94 | // create ApiClient 95 | $pf = new PrintfulApiClient($apiKey); 96 | 97 | // create Products Api object 98 | $productsApi = new PrintfulProducts($pf); 99 | 100 | // in this example we only update retail price and files, so we omit everything else 101 | $variantRequest = SyncVariantRequest::fromArray([ 102 | 'retail_price' => 22.00, 103 | 'files' => [ // if we provide `files`, we should mention all files. All missing files will be removed 104 | [ 105 | 'url' => 'https://www.my-webshop.com/shirt.jpg', 106 | ], 107 | [ 108 | 'type' => 'back', // set print file placement on item. If not set, default placement for this product will be used 109 | 'id' => 1, // file id from my File library in Printful (https://www.printful.com/docs/files) 110 | ], 111 | ] 112 | ]); 113 | 114 | $updatedVariant = $productsApi->updateVariant($variantId, $variantRequest); 115 | 116 | } catch (PrintfulApiException $e) { // API response status code was not successful 117 | echo 'Printful API Exception: ' . $e->getCode() . ' ' . $e->getMessage(); 118 | } catch (PrintfulSdkException $e) { // SDK did not call API 119 | echo 'Printful SDK Exception: ' . $e->getMessage(); 120 | } catch (PrintfulException $e) { // API call failed 121 | echo 'Printful Exception: ' . $e->getMessage(); 122 | var_export($pf->getLastResponseRaw()); 123 | } -------------------------------------------------------------------------------- /examples/orders.php: -------------------------------------------------------------------------------- 1 | get('orders', ['limit' => 10]); 19 | var_export($orders); 20 | // Get total number of items available from the previous request 21 | $items = $pf->getItemCount(); 22 | echo "Total orders " . $items; 23 | */ 24 | // ------------------------------- 25 | 26 | 27 | // ------------------------------- 28 | // Select order with ID 12345 (Replace with your order's ID) 29 | /* 30 | $order = $pf->get('orders/12345'); 31 | var_export($order); 32 | */ 33 | // ------------------------------- 34 | 35 | 36 | // ------------------------------- 37 | // Select order with External ID 9900999 (Replace with your order's External ID) 38 | /* 39 | $order = $pf->get('orders/@9900999'); 40 | var_export($order); 41 | */ 42 | // ------------------------------- 43 | 44 | 45 | // ------------------------------- 46 | // Confirm order with ID 12345 (Replace with your order's ID) 47 | /* 48 | $order = $pf->post('orders/12345/confirm'); 49 | var_export($order); 50 | */ 51 | // ------------------------------- 52 | 53 | 54 | // ------------------------------- 55 | // Cancel order with ID 12345 (Replace with your order's ID) 56 | /* 57 | $order = $pf->delete('orders/12345'); 58 | var_export($order); 59 | */ 60 | // ------------------------------- 61 | 62 | 63 | // ------------------------------- 64 | // Create an order 65 | /* 66 | $order = $pf->post('orders', [ 67 | 'recipient' => [ 68 | 'name' => 'John Doe', 69 | 'address1' => '172 W Street Ave #105', 70 | 'city' => 'Burbank', 71 | 'state_code' => 'CA', 72 | 'country_code' => 'US', 73 | 'zip' => '91502', 74 | ], 75 | 'items' => [ 76 | [ 77 | 'variant_id' => 1,//Small poster 78 | 'name' => 'Niagara Falls poster', //Display name 79 | 'retail_price' => '19.99', //Retail price for packing slip 80 | 'quantity' => 1, 81 | 'files' => [ 82 | [ 83 | 'url' => 'http://example.com/files/posters/poster_1.jpg', 84 | ], 85 | ], 86 | ], 87 | [ 88 | 'variant_id' => 1118, 89 | 'quantity' => 2, 90 | 'name' => 'Grand Canyon T-Shirt', //Display name 91 | 'retail_price' => '29.99', //Retail price for packing slip 92 | 'files' => [ 93 | [// Front print 94 | 'url' => 'http://example.com/files/tshirts/shirt_front.ai', 95 | ], 96 | [// Back print 97 | 'type' => 'back', 98 | 'url' => 'http://example.com/files/tshirts/shirt_back.ai', 99 | ], 100 | [// Mockup image 101 | 'type' => 'preview', 102 | 'url' => 'http://example.com/files/tshirts/shirt_mockup.jpg', 103 | ], 104 | ], 105 | 'options' => [// Additional options 106 | [ 107 | 'id' => 'remove_labels', 108 | 'value' => true, 109 | ], 110 | ], 111 | ], 112 | ], 113 | ]); 114 | var_export($order); 115 | */ 116 | // ------------------------------- 117 | 118 | // ------------------------------- 119 | // Create an order and confirm immediately 120 | /* 121 | $order = $pf->post('orders', 122 | [ 123 | 'recipient' => [ 124 | 'name' => 'John Doe', 125 | 'address1' => '172 W Street Ave #105', 126 | 'city' => 'Burbank', 127 | 'state_code' => 'CA', 128 | 'country_code' => 'US', 129 | 'zip' => '91502', 130 | ], 131 | 'items' => [ 132 | [ 133 | 'variant_id' => 1,// Small poster 134 | 'name' => 'Niagara Falls poster', // Display name 135 | 'retail_price' => '19.99', // Retail price for packing slip 136 | 'quantity' => 1, 137 | 'files' => [ 138 | [ 139 | 'url' => 'http://example.com/files/posters/poster_1.jpg', 140 | ], 141 | ], 142 | ], 143 | ], 144 | ], 145 | ['confirm' => 1] 146 | ); 147 | var_export($order); 148 | */ 149 | // ------------------------------- 150 | 151 | } catch (PrintfulApiException $e) { 152 | // API response status code was not successful 153 | echo 'Printful API Exception: ' . $e->getCode() . ' ' . $e->getMessage(); 154 | } catch (PrintfulException $e) { 155 | // API call failed 156 | echo 'Printful Exception: ' . $e->getMessage(); 157 | var_export($pf->getLastResponseRaw()); 158 | } 159 | -------------------------------------------------------------------------------- /examples/products.php: -------------------------------------------------------------------------------- 1 | get('store'); 17 | var_export($store); 18 | */ 19 | 20 | // Get product list 21 | /* 22 | $products = $pf->get('products'); 23 | var_export($products); 24 | */ 25 | 26 | // Get variants for product 10 27 | /* 28 | $variants = $pf->get('products/10'); 29 | var_export($variants); 30 | */ 31 | 32 | // Get information about Variant 1007 33 | /* 34 | $data = $pf->get('products/variant/1007'); 35 | var_export($data); 36 | */ 37 | 38 | } catch (PrintfulApiException $e) { //API response status code was not successful 39 | echo 'Printful API Exception: ' . $e->getCode() . ' ' . $e->getMessage(); 40 | } catch (PrintfulException $e) { //API call failed 41 | echo 'Printful Exception: ' . $e->getMessage(); 42 | var_export($pf->getLastResponseRaw()); 43 | } 44 | -------------------------------------------------------------------------------- /examples/shipping-rates.php: -------------------------------------------------------------------------------- 1 | post('shipping/rates', [ 17 | 'recipient' => [ 18 | 'country_code' => 'US', 19 | 'state_code' => 'CA', 20 | ], 21 | 'items' => [ 22 | ['variant_id' => 1, 'quantity' => 1], // Small poster 23 | ['variant_id' => 1118, 'quantity' => 2] // Alternative T-Shirt 24 | ], 25 | ]); 26 | var_export($rates); 27 | */ 28 | 29 | } catch (PrintfulApiException $e) { //API response status code was not successful 30 | echo 'Printful API Exception: ' . $e->getCode() . ' ' . $e->getMessage(); 31 | } catch (PrintfulException $e) { //API call failed 32 | echo 'Printful Exception: ' . $e->getMessage(); 33 | var_export($pf->getLastResponseRaw()); 34 | } 35 | -------------------------------------------------------------------------------- /src/Exceptions/PrintfulApiException.php: -------------------------------------------------------------------------------- 1 | legacyStoreKey = $type === self::TYPE_LEGACY_STORE_KEY ? $key : null; 61 | $this->oauthToken = $type === self::TYPE_OAUTH_TOKEN ? $key : null; 62 | } 63 | 64 | /** 65 | * @param string $oAuthToken 66 | * @throws PrintfulException 67 | */ 68 | public static function createOauthClient($oAuthToken) 69 | { 70 | return new self($oAuthToken, self::TYPE_OAUTH_TOKEN); 71 | } 72 | 73 | /** 74 | * @param string $legacyStoreKey 75 | * @throws PrintfulException 76 | */ 77 | public static function createLegacyStoreKeyClient($legacyStoreKey) 78 | { 79 | return new self($legacyStoreKey, self::TYPE_LEGACY_STORE_KEY); 80 | } 81 | 82 | /** 83 | * Returns total available item count from the last request if it supports paging (e.g order list) or null otherwise. 84 | * 85 | * @return int|null Item count 86 | */ 87 | public function getItemCount() 88 | { 89 | return isset($this->lastResponse['paging']['total']) ? $this->lastResponse['paging']['total'] : null; 90 | } 91 | 92 | /** 93 | * Perform a GET request to the API 94 | * @param string $path Request path (e.g. 'orders' or 'orders/123') 95 | * @param array $params Additional GET parameters as an associative array 96 | * @return mixed API response 97 | * @throws \Printful\Exceptions\PrintfulApiException if the API call status code is not in the 2xx range 98 | * @throws PrintfulException if the API call has failed or the response is invalid 99 | */ 100 | public function get($path, $params = []) 101 | { 102 | return $this->request('GET', $path, $params); 103 | } 104 | 105 | /** 106 | * Perform a DELETE request to the API 107 | * @param string $path Request path (e.g. 'orders' or 'orders/123') 108 | * @param array $params Additional GET parameters as an associative array 109 | * @return mixed API response 110 | * @throws \Printful\Exceptions\PrintfulApiException if the API call status code is not in the 2xx range 111 | * @throws \Printful\Exceptions\PrintfulException if the API call has failed or the response is invalid 112 | */ 113 | public function delete($path, $params = []) 114 | { 115 | return $this->request('DELETE', $path, $params); 116 | } 117 | 118 | /** 119 | * Perform a POST request to the API 120 | * @param string $path Request path (e.g. 'orders' or 'orders/123') 121 | * @param array $data Request body data as an associative array 122 | * @param array $params Additional GET parameters as an associative array 123 | * @return mixed API response 124 | * @throws \Printful\Exceptions\PrintfulApiException if the API call status code is not in the 2xx range 125 | * @throws PrintfulException if the API call has failed or the response is invalid 126 | */ 127 | public function post($path, $data = [], $params = []) 128 | { 129 | return $this->request('POST', $path, $params, $data); 130 | } 131 | 132 | /** 133 | * Perform a PUT request to the API 134 | * @param string $path Request path (e.g. 'orders' or 'orders/123') 135 | * @param array $data Request body data as an associative array 136 | * @param array $params Additional GET parameters as an associative array 137 | * @return mixed API response 138 | * @throws \Printful\Exceptions\PrintfulApiException if the API call status code is not in the 2xx range 139 | * @throws \Printful\Exceptions\PrintfulException if the API call has failed or the response is invalid 140 | */ 141 | public function put($path, $data = [], $params = []) 142 | { 143 | return $this->request('PUT', $path, $params, $data); 144 | } 145 | 146 | /** 147 | * Return raw response data from the last request 148 | * @return string|null Response data 149 | */ 150 | public function getLastResponseRaw() 151 | { 152 | return $this->lastResponseRaw; 153 | } 154 | 155 | /** 156 | * Return decoded response data from the last request 157 | * @return array|null Response data 158 | */ 159 | public function getLastResponse() 160 | { 161 | return $this->lastResponse; 162 | } 163 | 164 | /** 165 | * Internal request implementation 166 | * @param string $method POST, GET, etc. 167 | * @param string $path 168 | * @param array $params 169 | * @param mixed $data 170 | * @return 171 | * @throws \Printful\Exceptions\PrintfulApiException 172 | * @throws \Printful\Exceptions\PrintfulException 173 | */ 174 | private function request($method, $path, array $params = [], $data = null) 175 | { 176 | $this->lastResponseRaw = null; 177 | $this->lastResponse = null; 178 | 179 | $url = trim($path, '/'); 180 | 181 | if (!empty($params)) { 182 | $url .= '?' . http_build_query($params); 183 | } 184 | 185 | $curl = curl_init($this->url . $url); 186 | 187 | $this->setCredentials($curl); 188 | 189 | curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method); 190 | curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); 191 | curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); 192 | curl_setopt($curl, CURLOPT_MAXREDIRS, 3); 193 | 194 | curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, $this->curlConnectTimeout); 195 | curl_setopt($curl, CURLOPT_TIMEOUT, $this->curlTimeout); 196 | 197 | curl_setopt($curl, CURLOPT_USERAGENT, self::USER_AGENT); 198 | 199 | if ($data !== null) { 200 | curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data)); 201 | } 202 | 203 | $this->lastResponseRaw = curl_exec($curl); 204 | 205 | $errorNumber = curl_errno($curl); 206 | $error = curl_error($curl); 207 | curl_close($curl); 208 | 209 | if ($errorNumber) { 210 | throw new PrintfulException('CURL: ' . $error, $errorNumber); 211 | } 212 | 213 | $this->lastResponse = $response = json_decode($this->lastResponseRaw, true); 214 | 215 | if (!isset($response['code'], $response['result'])) { 216 | $e = new PrintfulException('Invalid API response'); 217 | $e->rawResponse = $this->lastResponseRaw; 218 | throw $e; 219 | } 220 | $status = (int)$response['code']; 221 | if ($status < 200 || $status >= 300) { 222 | $e = new PrintfulApiException((string)$response['result'], $status); 223 | $e->rawResponse = $this->lastResponseRaw; 224 | throw $e; 225 | } 226 | return $response['result']; 227 | } 228 | 229 | /** 230 | * @param resource $curl 231 | * @throws PrintfulException 232 | */ 233 | private function setCredentials($curl) 234 | { 235 | if ($this->oauthToken !== null) { 236 | curl_setopt($curl, CURLOPT_HTTPHEADER, ["Authorization: Bearer $this->oauthToken"]); 237 | } elseif ($this->legacyStoreKey !== null) { 238 | curl_setopt($curl, CURLOPT_USERPWD, $this->legacyStoreKey); 239 | } else { 240 | throw new PrintfulException('Either OAuth token or store key must be set to make this request.'); 241 | } 242 | } 243 | } -------------------------------------------------------------------------------- /src/PrintfulMockupGenerator.php: -------------------------------------------------------------------------------- 1 | printfulClient = $printfulClient; 28 | } 29 | 30 | /** 31 | * Get all available templates for specific printful product 32 | * 33 | * @param int $productId Printful product id 34 | * @param string|null $orientation Used for products with multiple orientations (e.g. wall art) {@see TemplateItem::ORIENTATION_HORIZONTAL} {@see TemplateItem::ORIENTATION_VERTICAL} 35 | * @return ProductPrintfiles 36 | * @throws Exceptions\PrintfulException 37 | */ 38 | public function getProductPrintfiles($productId, $orientation = null) 39 | { 40 | $query = []; 41 | 42 | if ($orientation) { 43 | $query['orientation'] = $orientation; 44 | } 45 | 46 | $raw = $this->printfulClient->get('mockup-generator/printfiles/' . $productId, $query); 47 | 48 | $productPrintfiles = new ProductPrintfiles; 49 | 50 | $productPrintfiles->productId = $raw['product_id']; 51 | $productPrintfiles->availablePlacements = $raw['available_placements']; 52 | $productPrintfiles->printfiles = []; 53 | $productPrintfiles->variantPrintfiles = []; 54 | 55 | foreach ($raw['printfiles'] as $v) { 56 | $printfileItem = PrintfileItem::fromArray($v); 57 | $productPrintfiles->printfiles[$printfileItem->printfileId] = $printfileItem; 58 | } 59 | 60 | foreach ($raw['variant_printfiles'] as $v) { 61 | $variantPrintfileItem = VariantPrintfileItem::fromArray($v); 62 | $productPrintfiles->variantPrintfiles[$variantPrintfileItem->variantId] = $variantPrintfileItem; 63 | } 64 | 65 | return $productPrintfiles; 66 | } 67 | 68 | /** 69 | * Merge variants in to unique printfile + placement groups. 70 | * This group can be used for positioning, that covers a list of variants 71 | * 72 | * @param ProductPrintfiles $productPrintfiles 73 | * @return VariantPlacementGroup[] 74 | */ 75 | public function groupPrintfiles(ProductPrintfiles $productPrintfiles) 76 | { 77 | $re = []; 78 | 79 | foreach ($productPrintfiles->variantPrintfiles as $v) { 80 | foreach ($v->placements as $k2 => $v2) { 81 | $key = $k2 . '|' . $v2; 82 | 83 | $item = isset($re[$key]) ? $re[$key] : new VariantPlacementGroup; 84 | $item->placement = $k2; 85 | $item->variantIds[] = $v->variantId; 86 | $item->printfile = $productPrintfiles->printfiles[$v2]; 87 | 88 | $re[$key] = $item; 89 | } 90 | } 91 | 92 | return array_values($re); 93 | } 94 | 95 | /** 96 | * Create an asynchronous generation task and return task that is in pending state 97 | * To retrieve the generation result use PrintfulMockupGenerator::getGenerationTask method. 98 | * 99 | * @param MockupGenerationParameters $parameters 100 | * @return GenerationResultItem Pending task 101 | * @throws Exceptions\PrintfulException 102 | * @see PrintfulMockupGenerator::getGenerationTask 103 | */ 104 | public function createGenerationTask(MockupGenerationParameters $parameters) 105 | { 106 | $data = $this->parametersToArray($parameters); 107 | 108 | $response = $this->printfulClient->post('/mockup-generator/create-task/' . $parameters->productId, $data); 109 | 110 | return GenerationResultItem::fromArray($response); 111 | } 112 | 113 | /** 114 | * Create a tasks and waits for it to be complete by periodically checking for result. 115 | * If the timeout is exceeded, latest task result is returned which will be in pending state. 116 | * 117 | * @param MockupGenerationParameters $parameters 118 | * @param int $maxSecondsWait Maximum amount of seconds to wait for the result 119 | * @param int $interval Interval before requesting task result 120 | * @return GenerationResultItem Completed or failed generation result 121 | * @throws Exceptions\PrintfulException 122 | */ 123 | public function createGenerationTaskAndWaitForResult( 124 | MockupGenerationParameters $parameters, 125 | $maxSecondsWait = 180, 126 | $interval = 5 127 | ) { 128 | $task = $this->createGenerationTask($parameters); 129 | 130 | for ($i = 0; $i < $maxSecondsWait / $interval; $i++) { 131 | sleep($interval); 132 | $task = $this->getGenerationTask($task->taskKey); 133 | if (!$task->isPending()) { 134 | break; 135 | } 136 | } 137 | 138 | return $task; 139 | } 140 | 141 | /** 142 | * Check for a generation task result 143 | * 144 | * @param string $tasKey 145 | * @return GenerationResultItem 146 | * @throws Exceptions\PrintfulException 147 | */ 148 | public function getGenerationTask($tasKey) 149 | { 150 | $response = $this->printfulClient->get('/mockup-generator/task/', [ 151 | 'task_key' => $tasKey, 152 | ]); 153 | 154 | return GenerationResultItem::fromArray($response); 155 | } 156 | 157 | /** 158 | * @param MockupGenerationParameters $parameters 159 | * @return array 160 | */ 161 | private function parametersToArray(MockupGenerationParameters $parameters) 162 | { 163 | $files = array_map(function (MockupGenerationFile $file) { 164 | $re = [ 165 | 'placement' => $file->placement, 166 | 'image_url' => $file->imageUrl, 167 | ]; 168 | 169 | if ($file->position) { 170 | $re['position'] = $file->position->toArray(); 171 | } 172 | 173 | return $re; 174 | }, $parameters->getFiles()); 175 | 176 | $data = [ 177 | 'variant_ids' => $parameters->variantIds, 178 | 'files' => $files, 179 | 'format' => $parameters->format, 180 | 'option_groups' => $parameters->optionGroups, 181 | 'product_options' => $parameters->productOptions, 182 | 'options' => $parameters->options, 183 | ]; 184 | 185 | return $data; 186 | } 187 | 188 | /** 189 | * Retrieve templates for given product. Resources returned may be used to create your own generator interface. 190 | * This includes background images and area positions. 191 | * 192 | * @param int $productId 193 | * @param string|null $orientation Used for products with multiple orientations (e.g. wall art) {@see TemplateItem::ORIENTATION_HORIZONTAL} {@see TemplateItem::ORIENTATION_VERTICAL} 194 | * @return ProductTemplates 195 | * @throws Exceptions\PrintfulApiException 196 | * @throws Exceptions\PrintfulException 197 | */ 198 | public function getProductTemplates($productId, $orientation = null) 199 | { 200 | $query = []; 201 | 202 | if ($orientation) { 203 | $query['orientation'] = $orientation; 204 | } 205 | 206 | $response = $this->printfulClient->get('/mockup-generator/templates/' . $productId, $query); 207 | 208 | $templates = new ProductTemplates; 209 | $templates->version = (int)$response['version']; 210 | $templates->minDpi = (int)$response['min_dpi']; 211 | 212 | $templates->variantMapping = array_map(function ($v) { 213 | return VariantTemplateMappingItem::fromArray($v); 214 | }, $response['variant_mapping']); 215 | 216 | $templates->templates = array_map(function ($v) { 217 | return TemplateItem::fromArray($v); 218 | }, $response['templates']); 219 | 220 | $templates->placementConflicts = array_map(function ($v) { 221 | $pc = new PlacementConflictItem; 222 | $pc->placement = $v['placement']; 223 | $pc->conflictingPlacements = $v['conflicts']; 224 | return $pc; 225 | }, $response['conflicting_placements']); 226 | 227 | return $templates; 228 | } 229 | } -------------------------------------------------------------------------------- /src/PrintfulOrder.php: -------------------------------------------------------------------------------- 1 | printfulClient = $printfulClient; 24 | } 25 | 26 | /** 27 | * @param OrderCreationParameters $parameters 28 | * @param bool $confirm - Automatically submit the newly created order for fulfillment (skip the Draft phase) 29 | * @return Order 30 | */ 31 | public function create(OrderCreationParameters $parameters, $confirm = false) 32 | { 33 | $request = $this->getRequestBodyFromParams($parameters); 34 | $params['confirm'] = $confirm; 35 | 36 | $raw = $this->printfulClient->post('orders', $request, $params); 37 | 38 | return Order::fromArray($raw); 39 | } 40 | 41 | /** 42 | * Updates unsubmitted order and optionally submits it for the fulfillment. 43 | * Post only the fields that need to be changed, not all required fields. 44 | * 45 | * @param OrderCreationParameters $parameters 46 | * @param string|int $orderId - Order ID (integer) or External ID (prefixed with @) 47 | * @param bool $confirm - Automatically submit the newly created order for fulfillment (skip the Draft phase) 48 | * @return Order 49 | */ 50 | public function update(OrderCreationParameters $parameters, $orderId, $confirm = false) 51 | { 52 | $request = $this->getRequestBodyFromParams($parameters); 53 | $params['confirm'] = $confirm; 54 | 55 | $raw = $this->printfulClient->put('orders/' . $orderId, $request, $params); 56 | return Order::fromArray($raw); 57 | } 58 | 59 | /** 60 | * Sets the order status to CANCELED 61 | * @param string|int $orderId - Order ID (integer) or External ID (prefixed with @) 62 | * @return Order 63 | */ 64 | public function cancel($orderId) 65 | { 66 | $raw = $this->printfulClient->delete('orders/' . $orderId); 67 | return Order::fromArray($raw); 68 | } 69 | 70 | /** 71 | * Approves for fulfillment an order that was saved as a draft 72 | * @param string|int $orderId - Order ID (integer) or External ID (prefixed with @) 73 | * @return Order 74 | */ 75 | public function confirm($orderId) 76 | { 77 | $raw = $this->printfulClient->post('orders/' . $orderId . '/confirm'); 78 | return Order::fromArray($raw); 79 | } 80 | 81 | /** 82 | * @param string|int $orderId - Order ID (integer) or External ID (prefixed with @) 83 | * @return Order 84 | */ 85 | private function getById($orderId) 86 | { 87 | $raw = $this->printfulClient->get('orders/' . $orderId); 88 | return Order::fromArray($raw); 89 | } 90 | 91 | /** 92 | * @param int $printfulId 93 | * @return Order 94 | */ 95 | public function getByPrintfulId($printfulId) 96 | { 97 | return $this->getById($printfulId); 98 | } 99 | 100 | /** 101 | * @param string $externalId 102 | * @return Order 103 | */ 104 | public function getByExternalId($externalId) 105 | { 106 | // Always remove possible @ symbol given by caller 107 | $id = '@' . ltrim($externalId, '@'); 108 | return $this->getById($id); 109 | } 110 | 111 | /** 112 | * @param int $offset 113 | * @param int $limit - Number of items per page (max 100) 114 | * @param null|string $status - Filter by order status 115 | * @return OrderList 116 | */ 117 | public function getList($offset = 0, $limit = 10, $status = null) 118 | { 119 | $params = [ 120 | 'offset' => $offset, 121 | 'limit' => $limit, 122 | 'status' => $status, 123 | ]; 124 | $rawOrders = $this->printfulClient->get('orders', $params); 125 | $total = $this->printfulClient->getItemCount(); 126 | 127 | return new OrderList($rawOrders, $total, $offset); 128 | } 129 | 130 | /** 131 | * @param OrderCreationParameters $parameters 132 | * @return OrderCostGroup 133 | * @throws Exceptions\PrintfulApiException 134 | * @throws Exceptions\PrintfulException 135 | */ 136 | public function estimateCosts(OrderCreationParameters $parameters) 137 | { 138 | $request = $this->getRequestBodyFromParams($parameters); 139 | 140 | $raw = $this->printfulClient->post('orders/estimate-costs', $request); 141 | 142 | return OrderCostGroup::fromArray($raw); 143 | } 144 | 145 | /** 146 | * Formats request body array from order creation parameters object 147 | * 148 | * @param OrderCreationParameters $parameters 149 | * @return array 150 | */ 151 | protected function getRequestBodyFromParams(OrderCreationParameters $parameters) 152 | { 153 | $request = [ 154 | 'external_id' => $parameters->externalId, 155 | 'shipping' => $parameters->shipping, 156 | 'recipient' => $parameters->getRecipient()->toArray(), 157 | 'retail_costs' => $parameters->getRetailCosts(), 158 | 'gift' => $parameters->getGift(), 159 | 'packing_slip' => $parameters->getPackingSlip(), 160 | 'currency' => $parameters->currency, 161 | ]; 162 | 163 | // Set order Items from given array of param objects 164 | $request['items'] = array_map(function (OrderItemCreationParameters $params) { 165 | return $params->toArray(); 166 | }, $parameters->getItems()); 167 | 168 | return $request; 169 | } 170 | } 171 | -------------------------------------------------------------------------------- /src/PrintfulProducts.php: -------------------------------------------------------------------------------- 1 | printfulClient = $printfulClient; 36 | } 37 | 38 | /** 39 | * Preforms GET SyncProducts request 40 | * 41 | * @param int $offset 42 | * @param int $limit 43 | * @return SyncProductsResponse 44 | * @throws Exceptions\PrintfulApiException 45 | * @throws Exceptions\PrintfulException 46 | */ 47 | public function getProducts($offset = 0, $limit = 20, $status = 'all', $search = '') 48 | { 49 | $requestData = [ 50 | 'offset' => (int)$offset, 51 | 'limit' => (int)$limit, 52 | 'status' => (string)$status, 53 | 'search' => (string)$search, 54 | ]; 55 | 56 | $response = $this->printfulClient->get(PrintfulProducts::ENDPOINT_PRODUCTS, $requestData); 57 | $lastResponse = $this->printfulClient->getLastResponse(); 58 | 59 | // as paging block is omitted in $response; 60 | $responseArray = [ 61 | 'result' => $response, 62 | 'paging' => $lastResponse['paging'], 63 | ]; 64 | $result = SyncProductsResponse::fromArray($responseArray); 65 | 66 | return $result; 67 | } 68 | 69 | /** 70 | * Preforms GET SyncProduct request 71 | * 72 | * @param $id 73 | * @return SyncProductRequestResponse 74 | * @throws Exceptions\PrintfulApiException 75 | * @throws Exceptions\PrintfulException 76 | */ 77 | public function getProduct($id) 78 | { 79 | $response = $this->printfulClient->get(PrintfulProducts::ENDPOINT_PRODUCTS . '/' . $id); 80 | $result = SyncProductRequestResponse::fromArray($response); 81 | 82 | return $result; 83 | } 84 | 85 | /** 86 | * Preforms GET SyncVariant request 87 | * 88 | * @param $id 89 | * @return SyncVariantResponse 90 | * @throws Exceptions\PrintfulApiException 91 | * @throws Exceptions\PrintfulException 92 | */ 93 | public function getVariant($id) 94 | { 95 | $response = $this->printfulClient->get(PrintfulProducts::ENDPOINT_VARIANTS . '/' . $id); 96 | $result = SyncVariantResponse::fromArray($response); 97 | 98 | return $result; 99 | } 100 | 101 | /** 102 | * Preforms POST SyncProduct request 103 | * 104 | * @param SyncProductCreationParameters $request 105 | * @return SyncProductResponse 106 | * @throws Exceptions\PrintfulApiException 107 | * @throws Exceptions\PrintfulSdkException 108 | * @throws Exceptions\PrintfulException 109 | */ 110 | public function createProduct(SyncProductCreationParameters $request) 111 | { 112 | $params = $request->toPostArray(); 113 | $result = $this->printfulClient->post(PrintfulProducts::ENDPOINT_PRODUCTS, $params); 114 | 115 | $syncProduct = SyncProductResponse::fromArray($result); 116 | 117 | return $syncProduct; 118 | } 119 | 120 | /** 121 | * Preforms POST SyncVariant request 122 | * 123 | * @param string $productId 124 | * @param SyncVariantRequest $syncVariantRequest 125 | * @return SyncVariantResponse 126 | * @throws Exceptions\PrintfulApiException 127 | * @throws Exceptions\PrintfulException 128 | * @throws Exceptions\PrintfulSdkException 129 | */ 130 | public function createVariant($productId, SyncVariantRequest $syncVariantRequest) 131 | { 132 | $params = $syncVariantRequest->toPostArray(); 133 | $result = $this->printfulClient->post(PrintfulProducts::ENDPOINT_PRODUCTS . '/' . $productId . '/variants', $params); 134 | 135 | $syncVariant = SyncVariantResponse::fromArray($result); 136 | 137 | return $syncVariant; 138 | } 139 | 140 | /** 141 | * Preforms PUT SyncProduct request 142 | * 143 | * @param string $productId 144 | * @param SyncProductUpdateParameters $request 145 | * @return SyncProductResponse 146 | * @throws Exceptions\PrintfulApiException 147 | * @throws Exceptions\PrintfulException 148 | * @throws Exceptions\PrintfulSdkException 149 | */ 150 | public function updateProduct($productId, SyncProductUpdateParameters $request) 151 | { 152 | $params = $request->toPutArray(); 153 | $result = $this->printfulClient->put(PrintfulProducts::ENDPOINT_PRODUCTS . '/' . $productId, $params); 154 | 155 | $syncProduct = SyncProductResponse::fromArray($result); 156 | 157 | return $syncProduct; 158 | } 159 | 160 | /** 161 | * Preforms PUT SyncVariant request 162 | * 163 | * @param string $variantId 164 | * @param SyncVariantRequest $request 165 | * @return SyncVariantResponse 166 | * @throws Exceptions\PrintfulApiException 167 | * @throws Exceptions\PrintfulException 168 | * @throws Exceptions\PrintfulSdkException 169 | */ 170 | public function updateVariant($variantId, SyncVariantRequest $request) 171 | { 172 | $params = $request->toPutArray(); 173 | $result = $this->printfulClient->put(PrintfulProducts::ENDPOINT_VARIANTS . '/' . $variantId, $params); 174 | 175 | $syncVariant = SyncVariantResponse::fromArray($result); 176 | 177 | return $syncVariant; 178 | } 179 | 180 | /** 181 | * Preforms DELETE SyncProduct request 182 | * 183 | * @param $productId 184 | * @return mixed 185 | * @throws Exceptions\PrintfulApiException 186 | * @throws Exceptions\PrintfulException 187 | */ 188 | public function deleteProduct($productId) 189 | { 190 | return $this->printfulClient->delete(PrintfulProducts::ENDPOINT_PRODUCTS . '/' . $productId); 191 | } 192 | 193 | /** 194 | * Preforms DELETE SyncVariant request 195 | * 196 | * @param $variantId 197 | * @return mixed 198 | * @throws Exceptions\PrintfulApiException 199 | * @throws Exceptions\PrintfulException 200 | */ 201 | public function deleteVariant($variantId) 202 | { 203 | return $this->printfulClient->delete(PrintfulProducts::ENDPOINT_VARIANTS . '/' . $variantId); 204 | } 205 | } 206 | -------------------------------------------------------------------------------- /src/PrintfulTaxRates.php: -------------------------------------------------------------------------------- 1 | printfulClient = $printfulClient; 22 | } 23 | 24 | /** 25 | * Get tax rate for given address 26 | * @param string $countryCode ISO country code 27 | * @param string $stateCode 28 | * @param string $city 29 | * @param string $zipCode 30 | * @return TaxRateItem 31 | */ 32 | public function getTaxRate($countryCode, $stateCode, $city, $zipCode) 33 | { 34 | $recipient = [ 35 | 'country_code' => $countryCode, 36 | 'state_code' => $stateCode, 37 | 'city' => $city, 38 | 'zip' => (string)$zipCode, 39 | ]; 40 | 41 | $requestData = ['recipient' => $recipient]; 42 | $raw = $this->printfulClient->post('tax/rates', $requestData); 43 | 44 | return TaxRateItem::fromArray($raw); 45 | } 46 | 47 | /** 48 | * Retrieve country list (with states) that requires sales tax calculation 49 | * @return CountryItem[] 50 | */ 51 | public function getTaxCountries() 52 | { 53 | $raw = $this->printfulClient->get('tax/countries'); 54 | $re = []; 55 | 56 | foreach ($raw as $v) { 57 | $country = CountryItem::fromArray($v); 58 | foreach ($v['states'] as $v1) { 59 | $country->states[] = StateItem::fromArray($v1); 60 | } 61 | $re[] = $country; 62 | } 63 | 64 | return $re; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/PrintfulWebhook.php: -------------------------------------------------------------------------------- 1 | printfulClient = $printfulClient; 21 | } 22 | 23 | /** 24 | * @return WebhooksInfoItem 25 | */ 26 | public function getRegisteredWebhooks() 27 | { 28 | $raw = $this->printfulClient->get('webhooks'); 29 | return WebhooksInfoItem::fromArray($raw); 30 | } 31 | 32 | /** 33 | * Allows to enable webhook URL for the store and select webhook event types that will be sent to this URL. 34 | * Only one webhook URL can be active for a store, so calling this method disables all existing webhook configuration 35 | * 36 | * @param string $url - Webhook URL that will receive store's event notifications 37 | * @param array $types - Array of enabled webhook event types 38 | * @param array $params - Array of parameters for enabled webhook event types 39 | * @return WebhooksInfoItem 40 | */ 41 | public function registerWebhooks($url, array $types, array $params = []) 42 | { 43 | $request = [ 44 | 'url' => $url, 45 | 'types' => $types, 46 | 'params' => $params, 47 | ]; 48 | $raw = $this->printfulClient->post('webhooks', $request); 49 | return WebhooksInfoItem::fromArray($raw); 50 | } 51 | 52 | /** 53 | * @return WebhooksInfoItem 54 | */ 55 | public function disableWebhooks() 56 | { 57 | $raw = $this->printfulClient->delete('webhooks'); 58 | return WebhooksInfoItem::fromArray($raw); 59 | 60 | } 61 | 62 | /** 63 | * @param array $raw 64 | * @return WebhookItem 65 | */ 66 | public function parseWebhook(array $raw) 67 | { 68 | return WebhookItem::fromArray($raw); 69 | } 70 | } -------------------------------------------------------------------------------- /src/Structures/AddressItem.php: -------------------------------------------------------------------------------- 1 | name = isset($raw['name']) ? $raw['name'] : null; 78 | $address->company = isset($raw['company']) ? $raw['company'] : null; 79 | $address->address1 = $raw['address1']; 80 | $address->address2 = isset($raw['address2']) ? $raw['address2'] : null; 81 | $address->city = $raw['city']; 82 | $address->stateCode = isset($raw['state_code']) ? $raw['state_code'] : null; 83 | $address->stateName = isset($raw['state_name']) ? $raw['state_name'] : null; 84 | $address->countryCode = $raw['country_code']; 85 | $address->countryName = isset($raw['country_name']) ? $raw['country_name'] : null; 86 | $address->zip = $raw['zip']; 87 | $address->phone = isset($raw['phone']) ? $raw['phone'] : null; 88 | $address->email = isset($raw['email']) ? $raw['email'] : null; 89 | 90 | return $address; 91 | } 92 | 93 | 94 | /** 95 | * @return array 96 | */ 97 | public function toArray() 98 | { 99 | return [ 100 | 'name' => $this->name, 101 | 'company' => $this->company, 102 | 'address1' => $this->address1, 103 | 'address2' => $this->address2, 104 | 'city' => $this->city, 105 | 'stateCode' => $this->stateCode, 106 | 'countryCode' => $this->countryCode, 107 | 'countryName' => $this->countryName, 108 | 'zip' => $this->zip, 109 | 'phone' => $this->phone, 110 | 'email' => $this->email, 111 | ]; 112 | } 113 | } -------------------------------------------------------------------------------- /src/Structures/BaseItem.php: -------------------------------------------------------------------------------- 1 | code = $raw['code']; 33 | $country->name = $raw['name']; 34 | 35 | return $country; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Structures/File.php: -------------------------------------------------------------------------------- 1 | id = (int)$raw['id']; 105 | $file->type = $raw['type']; 106 | $file->hash = $raw['hash']; 107 | $file->url = $raw['url']; 108 | $file->filename = $raw['filename']; 109 | $file->mimeType = $raw['mime_type']; 110 | $file->size = (int)$raw['size']; 111 | $file->width = (int)$raw['width']; 112 | $file->height = (int)$raw['height']; 113 | $file->dpi = (int)$raw['dpi']; 114 | $file->status = $raw['status']; 115 | $file->created = $raw['created']; 116 | $file->thumbnailUrl = $raw['thumbnail_url']; 117 | $file->previewUrl = $raw['preview_url']; 118 | $file->visible = (bool)$raw['visible']; 119 | 120 | return $file; 121 | } 122 | 123 | 124 | /** 125 | * @return array 126 | */ 127 | public function toArray() 128 | { 129 | return [ 130 | 'id' => $this->id, 131 | 'type' => $this->type, 132 | 'url' => $this->url, 133 | 'filename' => $this->filename, 134 | 'visible' => $this->visible, 135 | ]; 136 | } 137 | } -------------------------------------------------------------------------------- /src/Structures/Generator/GenerationResultItem.php: -------------------------------------------------------------------------------- 1 | status == self::STATUS_COMPLETED; 59 | } 60 | 61 | /** 62 | * @return bool 63 | */ 64 | public function isPending() 65 | { 66 | return $this->status == self::STATUS_PENDING; 67 | } 68 | 69 | /** 70 | * @return bool 71 | */ 72 | public function isFailed() 73 | { 74 | return $this->status == self::STATUS_FAILED; 75 | } 76 | 77 | /** 78 | * @param array|string $raw 79 | * @return GenerationResultItem 80 | */ 81 | public static function fromArray(array $raw) 82 | { 83 | $item = new GenerationResultItem; 84 | 85 | $item->taskKey = $raw['task_key']; 86 | $item->status = $raw['status']; 87 | 88 | if (isset($raw['error'])) { 89 | $item->error = $raw['error']; 90 | } 91 | 92 | if (!empty($raw['mockups'])) { 93 | $mockupList = new MockupList; 94 | $mockupList->mockups = array_map(function (array $rawMockup) { 95 | return MockupItem::fromArray($rawMockup); 96 | }, $raw['mockups']); 97 | $item->mockupList = $mockupList; 98 | } 99 | 100 | return $item; 101 | } 102 | } -------------------------------------------------------------------------------- /src/Structures/Generator/MockupExtraItem.php: -------------------------------------------------------------------------------- 1 | title = $raw['title']; 49 | $item->url = $raw['url']; 50 | $item->option = $raw['option']; 51 | $item->optionGroup = $raw['option_group']; 52 | 53 | return $item; 54 | } 55 | } -------------------------------------------------------------------------------- /src/Structures/Generator/MockupGenerationFile.php: -------------------------------------------------------------------------------- 1 | 'white']. 55 | * Depends on the product, available option list can be found here: 56 | * @see https://www.printful.com/docs/products#actionGet 57 | * 58 | * @var array 59 | */ 60 | public $productOptions = []; 61 | 62 | 63 | /** 64 | * Add a file for a specific placement 65 | * 66 | * Available placements are defined in Placement class 67 | * @see \Printful\Structures\Placements 68 | * 69 | * @param string $placement 70 | * @param $imageUrl 71 | * @param MockupPositionItem|null $position Optional position for image for generation. If position is not provided, image will be fitted or stretched over the area. 72 | * @return self 73 | */ 74 | public function addImageUrl($placement, $imageUrl, MockupPositionItem $position = null) 75 | { 76 | $file = new MockupGenerationFile; 77 | 78 | $file->placement = $placement; 79 | $file->imageUrl = $imageUrl; 80 | $file->position = $position; 81 | 82 | $this->files[] = $file; 83 | 84 | return $this; 85 | } 86 | 87 | /** 88 | * @return MockupGenerationFile[] 89 | */ 90 | public function getFiles() 91 | { 92 | return $this->files; 93 | } 94 | } -------------------------------------------------------------------------------- /src/Structures/Generator/MockupItem.php: -------------------------------------------------------------------------------- 1 | placement = $raw['placement']; 48 | $i->variantIds = $raw['variant_ids']; 49 | $i->mockupUrl = $raw['mockup_url']; 50 | 51 | if (!empty($raw['extra'])) { 52 | foreach ($raw['extra'] as $v) { 53 | $i->extraMockups[] = MockupExtraItem::fromArray($v); 54 | } 55 | } 56 | 57 | return $i; 58 | } 59 | } -------------------------------------------------------------------------------- /src/Structures/Generator/MockupList.php: -------------------------------------------------------------------------------- 1 | mockups, function (MockupItem $mockup) use ($variantId, $placement) { 27 | if ($placement && $mockup->placement !== $placement) { 28 | return false; 29 | } 30 | return in_array($variantId, $mockup->variantIds); 31 | }); 32 | } 33 | } -------------------------------------------------------------------------------- /src/Structures/Generator/MockupPositionItem.php: -------------------------------------------------------------------------------- 1 | width <= 0 || $this->height <= 0) { 53 | throw new PrintfulException('Invalid size given for position item (less or equals zero)'); 54 | } 55 | 56 | return [ 57 | 'area_width' => (float)$this->areaWidth, 58 | 'area_height' => (float)$this->areaHeight, 59 | 'width' => (float)$this->width, 60 | 'height' => (float)$this->height, 61 | 'top' => (float)$this->top, 62 | 'left' => (float)$this->left, 63 | ]; 64 | } 65 | } -------------------------------------------------------------------------------- /src/Structures/Generator/PrintfileItem.php: -------------------------------------------------------------------------------- 1 | printfileId = (int)$raw['printfile_id']; 76 | $item->width = (int)$raw['width']; 77 | $item->height = (int)$raw['height']; 78 | $item->dpi = (int)$raw['dpi']; 79 | $item->fillMode = $raw['fill_mode']; 80 | $item->canRotate = (bool)$raw['can_rotate']; 81 | 82 | return $item; 83 | } 84 | 85 | /** 86 | * Width / height ratio 87 | * @return float 88 | */ 89 | public function getRatio() 90 | { 91 | return $this->width / $this->height; 92 | } 93 | } -------------------------------------------------------------------------------- /src/Structures/Generator/ProductPrintfiles.php: -------------------------------------------------------------------------------- 1 | templateId = (int)$raw['template_id']; 114 | $item->imageUrl = $raw['image_url']; 115 | $item->isTemplateOnFront = (bool)$raw['is_template_on_front']; 116 | $item->backgroundUrl = $raw['background_url']; 117 | $item->backgroundColor = $raw['background_color']; 118 | $item->printfileId = (int)$raw['printfile_id']; 119 | $item->templateWidth = (int)$raw['template_width']; 120 | $item->templateHeight = (int)$raw['template_height']; 121 | $item->printAreaWidth = (int)$raw['print_area_width']; 122 | $item->printAreaHeight = (int)$raw['print_area_height']; 123 | $item->printAreaTop = (int)$raw['print_area_top']; 124 | $item->printAreaLeft = (int)$raw['print_area_left']; 125 | $item->orientation = (string)$raw['orientation']; 126 | 127 | return $item; 128 | } 129 | } -------------------------------------------------------------------------------- /src/Structures/Generator/Templates/VariantTemplateMappingItem.php: -------------------------------------------------------------------------------- 1 | templateId, ..] 22 | */ 23 | public $templates = []; 24 | 25 | /** 26 | * @param array $raw 27 | * @return VariantTemplateMappingItem 28 | */ 29 | public static function fromArray(array $raw) 30 | { 31 | $item = new self; 32 | $item->variantId = (int)$raw['variant_id']; 33 | 34 | foreach ($raw['templates'] as $v) { 35 | $item->templates[$v['placement']] = (int)$v['template_id']; 36 | } 37 | 38 | return $item; 39 | } 40 | } -------------------------------------------------------------------------------- /src/Structures/Generator/VariantPlacementGroup.php: -------------------------------------------------------------------------------- 1 | printfileId] 20 | */ 21 | public $placements = []; 22 | 23 | /** 24 | * Convert from raw response to item 25 | * 26 | * @param array $raw 27 | * @return VariantPrintfileItem 28 | */ 29 | public static function fromArray(array $raw) 30 | { 31 | $item = new self; 32 | 33 | $item->variantId = (int)$raw['variant_id']; 34 | $item->placements = $raw['placements']; 35 | 36 | return $item; 37 | } 38 | } -------------------------------------------------------------------------------- /src/Structures/Order/GiftItem.php: -------------------------------------------------------------------------------- 1 | subject = $raw['subject']; 29 | $gift->message = $raw['message']; 30 | 31 | return $gift; 32 | } 33 | 34 | /** 35 | * @return array 36 | */ 37 | public function toArray() 38 | { 39 | return [ 40 | 'subject' => $this->subject, 41 | 'message' => $this->message, 42 | ]; 43 | } 44 | 45 | } -------------------------------------------------------------------------------- /src/Structures/Order/Order.php: -------------------------------------------------------------------------------- 1 | id = (int)$raw['id']; 114 | $order->externalId = $raw['external_id']; 115 | $order->status = $raw['status']; 116 | $order->shipping = $raw['shipping']; 117 | $order->created = (int)$raw['created']; 118 | $order->updated = (int)$raw['updated']; 119 | $order->recipient = AddressItem::fromArray($raw['recipient']); 120 | $order->costs = OrderCostsItem::fromArray($raw['costs']); 121 | $order->retailCosts = OrderCostsItem::fromArray($raw['retail_costs']); 122 | $order->gift = isset($raw['gift']) ? GiftItem::fromArray($raw['gift']) : null; 123 | $order->packingSlip = isset($raw['packing_slip']) ? PackingSlipItem::fromArray($raw['packing_slip']) : null; 124 | 125 | foreach ($raw['items'] as $v) { 126 | $order->items[] = OrderLineItem::fromArray($v); 127 | } 128 | 129 | foreach ($raw['shipments'] as $v) { 130 | $order->shipments[] = Shipment::fromArray($v); 131 | } 132 | 133 | return $order; 134 | } 135 | 136 | /** 137 | * @return array 138 | */ 139 | public function toArray() 140 | { 141 | $items = []; 142 | foreach ($this->items as $v) { 143 | $items[] = $v->toArray(); 144 | } 145 | 146 | return [ 147 | 'id' => (int)$this->id, 148 | 'externalId' => $this->externalId, 149 | 'shipping' => $this->shipping, 150 | 'status' => $this->status, 151 | 'created' => $this->created, 152 | 'updated' => $this->updated, 153 | 'recipient' => $this->recipient->toArray(), 154 | 'items' => $items, 155 | 'retailPrice' => $this->retailCosts->toArray(), 156 | 'gift' => $this->gift ? $this->gift->toArray() : null, 157 | 'packingSlip' => $this->packingSlip ? $this->packingSlip->toArray() : null, 158 | 'currency' => $this->currency, 159 | ]; 160 | } 161 | } -------------------------------------------------------------------------------- /src/Structures/Order/OrderCostGroup.php: -------------------------------------------------------------------------------- 1 | printfulCosts = !empty($raw['costs']) ? OrderCostsItem::fromArray($raw['costs']) : null; 22 | $orderCosts->retailCosts = !empty($raw['retail_costs']) ? OrderCostsItem::fromArray($raw['retail_costs']) : null; 23 | 24 | return $orderCosts; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Structures/Order/OrderCostsItem.php: -------------------------------------------------------------------------------- 1 | subtotal = isset($raw['subtotal']) ? (float)$raw['subtotal'] : null; 67 | $costs->discount = isset($raw['discount']) ? (float)$raw['discount'] : null; 68 | $costs->shipping = isset($raw['shipping']) ? (float)$raw['shipping'] : null; 69 | $costs->tax = isset($raw['tax']) ? (float)$raw['tax'] : null; 70 | $costs->total = isset($raw['total']) ? (float)$raw['total'] : null; 71 | $costs->currency = isset($raw['currency']) ? $raw['currency'] : null; 72 | $costs->digitization = isset($raw['digitization']) ? (float)$raw['digitization'] : null; 73 | $costs->vat = isset($raw['vat']) ? (float)$raw['vat'] : null; 74 | 75 | return $costs; 76 | } 77 | 78 | /** 79 | * @return array 80 | */ 81 | public function toArray() 82 | { 83 | return [ 84 | 'discount' => $this->discount, 85 | 'shipping' => $this->shipping, 86 | 'tax' => $this->tax, 87 | 'subtotal' => $this->subtotal, 88 | 'total' => $this->total, 89 | 'currency' => $this->currency, 90 | 'digitization' => $this->digitization, 91 | 'vat' => $this->vat, 92 | ]; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/Structures/Order/OrderCreationParameters.php: -------------------------------------------------------------------------------- 1 | recipient = $parameters; 58 | } 59 | 60 | /** 61 | * @param OrderItemCreationParameters $parameters 62 | */ 63 | public function addItem(OrderItemCreationParameters $parameters) 64 | { 65 | $this->items[] = $parameters; 66 | } 67 | 68 | /** 69 | * Original retail costs in USD that are to be displayed on the packing slip for international shipments. 70 | * Retail costs are used only if every item in order contains the retail_price attribute. 71 | * 72 | * @param float $discount 73 | * @param float $shipping 74 | * @param float $tax 75 | */ 76 | public function addRetailCosts($discount, $shipping, $tax) 77 | { 78 | $this->retailCosts = [ 79 | 'discount' => $discount, 80 | 'shipping' => $shipping, 81 | 'tax' => $tax, 82 | ]; 83 | } 84 | 85 | /** 86 | * Add gift message 87 | * 88 | * @param string $subject 89 | * @param string $message 90 | */ 91 | public function addGift($subject, $message) 92 | { 93 | $this->gift = [ 94 | 'subject' => $subject, 95 | 'message' => $message, 96 | ]; 97 | } 98 | 99 | /** 100 | * Add custom packing slip for this order 101 | * 102 | * @param string $email 103 | * @param string $phone 104 | * @param string $message 105 | */ 106 | public function addPackingSlip($email, $phone, $message) 107 | { 108 | $this->packingSlip = [ 109 | 'email' => $email, 110 | 'phone' => $phone, 111 | 'message' => $message, 112 | ]; 113 | } 114 | 115 | /** 116 | * @return RecipientCreationParameters 117 | */ 118 | public function getRecipient() 119 | { 120 | return $this->recipient; 121 | } 122 | 123 | /** 124 | * @return OrderCreationParameters[] 125 | */ 126 | public function getItems() 127 | { 128 | return $this->items; 129 | } 130 | 131 | /** 132 | * @return array 133 | */ 134 | public function getRetailCosts() 135 | { 136 | return $this->retailCosts; 137 | } 138 | 139 | /** 140 | * @return array 141 | */ 142 | public function getGift() 143 | { 144 | return $this->gift; 145 | } 146 | 147 | /** 148 | * @return array 149 | */ 150 | public function getPackingSlip() 151 | { 152 | return $this->packingSlip; 153 | } 154 | } 155 | -------------------------------------------------------------------------------- /src/Structures/Order/OrderItemCreationParameters.php: -------------------------------------------------------------------------------- 1 | files[] = [ 64 | 'type' => $type, 65 | 'url' => $url, 66 | 'filename' => $filename, 67 | 'id' => $id, 68 | 'visible' => $isVisible, 69 | ]; 70 | } 71 | 72 | /** 73 | * @param string $id 74 | * @param string $value 75 | */ 76 | public function addOption($id, $value) 77 | { 78 | $this->options[] = [ 79 | 'id' => $id, 80 | 'value' => $value, 81 | ]; 82 | } 83 | 84 | /** 85 | * @return File[] 86 | */ 87 | public function getFiles() 88 | { 89 | return $this->files; 90 | } 91 | 92 | /** 93 | * @return OrderItemOption[] 94 | */ 95 | public function getOptions() 96 | { 97 | return $this->options; 98 | } 99 | 100 | /** 101 | * @return array 102 | */ 103 | public function toArray() 104 | { 105 | return [ 106 | 'external_id' => $this->externalId, 107 | 'variant_id' => $this->variantId, 108 | 'quantity' => $this->quantity, 109 | 'retail_price' => $this->retailPrice, 110 | 'name' => $this->name, 111 | 'sku' => $this->sku, 112 | 'files' => $this->files, 113 | 'options' => $this->options, 114 | ]; 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /src/Structures/Order/OrderItemOption.php: -------------------------------------------------------------------------------- 1 | id = $raw['id']; 29 | $option->value = $raw['value']; 30 | 31 | return $option; 32 | } 33 | 34 | /** 35 | * @return array 36 | */ 37 | public function toArray() 38 | { 39 | return [ 40 | 'id' => $this->id, 41 | 'value' => $this->value, 42 | ]; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Structures/Order/OrderLineItem.php: -------------------------------------------------------------------------------- 1 | id = (int)$raw['id']; 75 | $item->externalId = $raw['external_id']; 76 | $item->variantId = (int)$raw['variant_id']; 77 | $item->quantity = (int)$raw['quantity']; 78 | $item->price = (float)$raw['price']; 79 | $item->retailPrice = (float)$raw['retail_price']; 80 | $item->name = $raw['name']; 81 | $item->product = ProductVariant::fromArray($raw['product']); 82 | $item->sku = $raw['sku']; 83 | 84 | foreach ($raw['files'] as $v) { 85 | $item->files[] = File::fromArray($v); 86 | } 87 | 88 | foreach ($raw['options'] as $v) { 89 | $item->options[] = OrderItemOption::fromArray($v); 90 | } 91 | 92 | return $item; 93 | } 94 | 95 | 96 | /** 97 | * @return array 98 | */ 99 | public function toArray() 100 | { 101 | // Format Item print files 102 | $files = []; 103 | foreach ($this->files as $v) { 104 | $files[] = $v->toArray(); 105 | } 106 | 107 | $options = []; 108 | foreach ($this->options as $v) { 109 | $options[] = $v->toArray(); 110 | } 111 | 112 | return [ 113 | 'externalId' => $this->externalId, 114 | 'variantId' => $this->variantId, 115 | 'quantity' => $this->quantity, 116 | 'retailPrice' => (float)$this->retailPrice, 117 | 'name' => $this->name, 118 | 'sku' => $this->sku, 119 | 'options' => $options, 120 | 'files' => $files, 121 | ]; 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /src/Structures/Order/OrderList.php: -------------------------------------------------------------------------------- 1 | total = $total; 30 | $this->offset = $offset; 31 | 32 | foreach ($rawOrders as $v) { 33 | $this->orders[] = Order::fromArray($v); 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /src/Structures/Order/PackingSlipItem.php: -------------------------------------------------------------------------------- 1 | email = $raw['email']; 33 | $slip->phone = $raw['phone']; 34 | $slip->message = $raw['message']; 35 | 36 | return $slip; 37 | } 38 | 39 | /** 40 | * @return array 41 | */ 42 | public function toArray() 43 | { 44 | return [ 45 | 'email' => $this->email, 46 | 'phone' => $this->phone, 47 | 'message' => $this->message, 48 | ]; 49 | } 50 | 51 | } -------------------------------------------------------------------------------- /src/Structures/Order/ProductVariant.php: -------------------------------------------------------------------------------- 1 | variant_id = (int)$raw['variant_id']; 38 | $variant->product_id = (int)$raw['product_id']; 39 | $variant->image = $raw['image']; 40 | $variant->name = $raw['name']; 41 | 42 | return $variant; 43 | } 44 | 45 | /** 46 | * @return array 47 | */ 48 | public function toArray() 49 | { 50 | return [ 51 | 'variantId' => $this->variant_id, 52 | 'productId' => $this->product_id, 53 | 'image' => $this->image, 54 | 'name' => $this->name, 55 | ]; 56 | } 57 | } -------------------------------------------------------------------------------- /src/Structures/Order/RecipientCreationParameters.php: -------------------------------------------------------------------------------- 1 | $this->name, 74 | 'company' => $this->company, 75 | 'address1' => $this->address1, 76 | 'address2' => $this->address2, 77 | 'city' => $this->city, 78 | 'state_code' => $this->stateCode, 79 | 'state_name' => $this->stateName, 80 | 'country_code' => $this->countryCode, 81 | 'country_name' => $this->countryName, 82 | 'zip' => $this->zip, 83 | 'phone' => $this->phone, 84 | 'email' => $this->email, 85 | ]; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/Structures/Placements.php: -------------------------------------------------------------------------------- 1 | [ 99 | 'title' => 'Print file', 100 | 'conflictingTypes' => [], 101 | ], 102 | self::TYPE_FRONT => [ 103 | 'title' => 'Front print', 104 | 'conflictingTypes' => [], 105 | ], 106 | self::TYPE_BACK => [ 107 | 'title' => 'Back print', 108 | 'conflictingTypes' => [self::TYPE_LABEL_OUTSIDE], 109 | ], 110 | self::TYPE_EMBROIDERY_FRONT => [ 111 | 'title' => 'Front', 112 | 'conflictingTypes' => [], 113 | ], 114 | self::TYPE_EMBROIDERY_LEFT => [ 115 | 'title' => 'Left side', 116 | 'conflictingTypes' => [], 117 | ], 118 | self::TYPE_EMBROIDERY_RIGHT => [ 119 | 'title' => 'Right side', 120 | 'conflictingTypes' => [], 121 | ], 122 | self::TYPE_EMBROIDERY_BACK => [ 123 | 'title' => 'Back', 124 | 'conflictingTypes' => [], 125 | ], 126 | self::TYPE_EMBROIDERY_CHEST_LEFT => [ 127 | 'title' => 'Left chest', 128 | 'conflictingTypes' => [], 129 | ], 130 | self::TYPE_EMBROIDERY_APPAREL_FRONT => [ 131 | 'title' => 'Front', 132 | 'conflictingTypes' => [], 133 | ], 134 | self::TYPE_LABEL_INSIDE => [ 135 | 'title' => 'Inside label', 136 | 'conflictingTypes' => [self::TYPE_LABEL_OUTSIDE], 137 | ], 138 | self::TYPE_LABEL_OUTSIDE => [ 139 | 'title' => 'Outside label', 140 | 'conflictingTypes' => [self::TYPE_BACK, self::TYPE_LABEL_INSIDE], 141 | ], 142 | self::TYPE_SLEEVE_LEFT => [ 143 | 'title' => 'Left Sleeve', 144 | 'conflictingTypes' => [], 145 | ], 146 | self::TYPE_SLEEVE_RIGHT => [ 147 | 'title' => 'Right Sleeve', 148 | 'conflictingTypes' => [], 149 | ], 150 | self::TYPE_BELT_FRONT => [ 151 | 'title' => 'Front waist', 152 | 'conflictingTypes' => [], 153 | ], 154 | self::TYPE_BELT_BACK => [ 155 | 'title' => 'Back waist', 156 | 'conflictingTypes' => [], 157 | ], 158 | self::TYPE_TOP => [ 159 | 'title' => 'Top', 160 | 'conflictingTypes' => [], 161 | ], 162 | ]; 163 | 164 | /** 165 | * Check whether placement is valid 166 | * 167 | * @param string $placement 168 | * @return bool 169 | */ 170 | public static function isValid($placement) 171 | { 172 | return isset(self::$types[$placement]); 173 | } 174 | } -------------------------------------------------------------------------------- /src/Structures/Shipment/Shipment.php: -------------------------------------------------------------------------------- 1 | id = (int)$raw['id']; 63 | $item->carrier = $raw['carrier']; 64 | $item->service = $raw['service']; 65 | $item->trackingNumber = $raw['tracking_number']; 66 | $item->trackingUrl = $raw['tracking_url']; 67 | $item->created = $raw['created']; 68 | $item->shipDate = $raw['ship_date']; 69 | $item->reshipment = (bool)$raw['reshipment']; 70 | 71 | // Shipment Items 72 | foreach ($raw['items'] as $v) { 73 | $item->items[] = ShipmentItem::fromArray($v); 74 | } 75 | 76 | return $item; 77 | } 78 | 79 | /** 80 | * @return array 81 | */ 82 | public function toArray() 83 | { 84 | $re = [ 85 | 'id' => $this->id, 86 | 'carrier' => $this->carrier, 87 | 'service' => $this->service, 88 | 'trackingNumber' => $this->trackingNumber, 89 | 'trackingUrl' => $this->trackingUrl, 90 | 'created' => $this->created, 91 | 'shipDate' => $this->shipDate, 92 | 'reshipment' => $this->reshipment, 93 | ]; 94 | 95 | foreach ($this->items as $v) { 96 | $re['items'][] = $v->toArray(); 97 | } 98 | 99 | return $re; 100 | } 101 | } -------------------------------------------------------------------------------- /src/Structures/Shipment/ShipmentItem.php: -------------------------------------------------------------------------------- 1 | itemId = (int)$raw['item_id']; 28 | $item->quantity = (int)$raw['quantity']; 29 | 30 | return $item; 31 | } 32 | 33 | /** 34 | * @return array 35 | */ 36 | public function toArray() 37 | { 38 | return [ 39 | 'itemId' => $this->itemId, 40 | 'quantity' => $this->quantity, 41 | ]; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/Structures/StateItem.php: -------------------------------------------------------------------------------- 1 | code = $raw['code']; 31 | $item->name = $raw['name']; 32 | $item->isShippingTaxable = (bool)$raw['shipping_taxable']; 33 | 34 | return $item; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Structures/Sync/Requests/SyncProductRequest.php: -------------------------------------------------------------------------------- 1 | name = isset($array['name']) ? (string)$array['name'] : null; 27 | $syncProductRequest->thumbnail = isset($array['thumbnail']) ? (string)$array['thumbnail'] : null; 28 | $syncProductRequest->externalId = isset($array['external_id']) ? (string)$array['external_id'] : null; 29 | 30 | return $syncProductRequest; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Structures/Sync/Requests/SyncVariantRequest.php: -------------------------------------------------------------------------------- 1 | files)) { 35 | $this->files = []; 36 | } 37 | 38 | $this->files[] = $file; 39 | } 40 | 41 | /** 42 | * Returns SyncVariantRequestFile array added to SyncVariantRequest 43 | * 44 | * @return SyncVariantRequestFile[]|null 45 | */ 46 | public function getFiles() 47 | { 48 | return $this->files; 49 | } 50 | 51 | /** 52 | * Adds SyncVariantRequestOption to SyncVariantRequest 53 | * 54 | * @param SyncVariantRequestOption $option 55 | */ 56 | public function addOption(SyncVariantRequestOption $option) 57 | { 58 | if (is_null($this->options)) { 59 | $this->options = []; 60 | } 61 | 62 | $this->options[] = $option; 63 | } 64 | 65 | /** 66 | * Returns SyncVariantRequestOption array added to SyncVariantRequest 67 | * 68 | * @return SyncVariantRequestOption[]|null 69 | */ 70 | public function getOptions() 71 | { 72 | return $this->options; 73 | } 74 | 75 | /** 76 | * Builds SyncVariantRequest from array 77 | * 78 | * @param array $array 79 | * @return SyncVariantRequest 80 | */ 81 | public static function fromArray(array $array) 82 | { 83 | $syncVariantRequest = new SyncVariantRequest; 84 | 85 | $syncVariantRequest->externalId = isset($array['external_id']) ? (string)$array['external_id'] : null; 86 | $syncVariantRequest->variantId = isset($array['variant_id']) ? (int)$array['variant_id'] : null; 87 | $syncVariantRequest->retailPrice = isset($array['retail_price']) ? (float)$array['retail_price'] : null; 88 | 89 | $syncVariantRequestFiles = isset($array['files']) ? (array)$array['files'] : []; 90 | foreach ($syncVariantRequestFiles as $syncVariantRequestFile) { 91 | $file = SyncVariantRequestFile::fromArray($syncVariantRequestFile); 92 | $syncVariantRequest->addFile($file); 93 | } 94 | 95 | $syncVariantRequestOptions = isset($array['options']) ? (array)$array['options'] : []; 96 | foreach ($syncVariantRequestOptions as $syncVariantRequestOption) { 97 | $option = SyncVariantRequestOption::fromArray($syncVariantRequestOption); 98 | $syncVariantRequest->addOption($option); 99 | } 100 | 101 | return $syncVariantRequest; 102 | } 103 | 104 | /** 105 | * Builds POST request array 106 | * 107 | * @return array 108 | * @throws PrintfulSdkException 109 | */ 110 | public function toPostArray() 111 | { 112 | if (!$this->variantId) { 113 | throw new PrintfulSdkException('Missing variant_id'); 114 | } 115 | 116 | $files = $this->getFiles(); 117 | if (empty($files)) { 118 | throw new PrintfulSdkException('Missing files'); 119 | } 120 | 121 | $syncVariantParams = []; 122 | 123 | $syncVariantParams['external_id'] = $this->externalId; 124 | $syncVariantParams['retail_price'] = $this->retailPrice; 125 | $syncVariantParams['variant_id'] = $this->variantId; 126 | 127 | $syncVariantParams['files'] = []; 128 | foreach ($files as $file) { 129 | $syncVariantParams['files'][] = $file->toArray(); 130 | } 131 | 132 | $syncVariantParams['options'] = []; 133 | foreach ($this->getOptions() as $option) { 134 | $syncVariantParams['options'][] = $option->toArray(); 135 | } 136 | 137 | return $syncVariantParams; 138 | } 139 | 140 | /** 141 | * Builds PUT request array 142 | * 143 | * @return array 144 | * @throws PrintfulSdkException 145 | */ 146 | public function toPutArray() 147 | { 148 | $syncVariantParams = []; 149 | 150 | if (!is_null($this->externalId)) { 151 | $syncVariantParams['external_id'] = $this->externalId; 152 | } 153 | 154 | if (!is_null($this->retailPrice)) { 155 | $syncVariantParams['retail_price'] = $this->retailPrice; 156 | } 157 | 158 | if (!is_null($this->variantId)) { 159 | if (!$this->variantId) { 160 | throw new PrintfulSdkException('Variant id is required'); 161 | } 162 | 163 | $syncVariantParams['variant_id'] = $this->variantId; 164 | } 165 | 166 | $files = $this->getFiles(); 167 | if (!is_null($files)) { 168 | $syncVariantParams['files'] = []; 169 | foreach ($files as $file){ 170 | $syncVariantParams['files'][] = $file->toArray(); 171 | } 172 | } 173 | 174 | $options = $this->getOptions(); 175 | if (!is_null($options)) { 176 | $syncVariantParams['options'] = []; 177 | foreach ($options as $option) { 178 | $syncVariantParams['options'][] = $option->toArray(); 179 | } 180 | } 181 | 182 | return $syncVariantParams; 183 | } 184 | } 185 | -------------------------------------------------------------------------------- /src/Structures/Sync/Requests/SyncVariantRequestFile.php: -------------------------------------------------------------------------------- 1 | type = isset($array['type']) ? (string)$array['type'] : File::TYPE_DEFAULT; 30 | $file->id = isset($array['id']) ? (int)$array['id'] : null; 31 | $file->url = isset($array['url']) ? (string)$array['url'] : null; 32 | 33 | return $file; 34 | } 35 | 36 | /** 37 | * Builds array for request 38 | * 39 | * @return array 40 | * @throws PrintfulSdkException 41 | */ 42 | public function toArray() 43 | { 44 | $fileParam = []; 45 | 46 | if ($this->id && $this->url) { 47 | throw new PrintfulSdkException('Cannot specify both file id and url parameters'); 48 | } elseif (!$this->id && !$this->url) { 49 | throw new PrintfulSdkException('Must specify file id or url parameter'); 50 | } 51 | 52 | if ($this->id) { 53 | $fileParam['id'] = $this->id; 54 | } 55 | 56 | if ($this->url) { 57 | $fileParam['url'] = $this->url; 58 | } 59 | 60 | if ($this->type) { 61 | $fileParam['type'] = $this->type; 62 | } 63 | 64 | return $fileParam; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/Structures/Sync/Requests/SyncVariantRequestOption.php: -------------------------------------------------------------------------------- 1 | id = isset($array['id']) ? (string)$array['id'] : null; 24 | $option->value = isset($array['value']) ?: null; 25 | 26 | return $option; 27 | } 28 | 29 | /** 30 | * Builds array 31 | * 32 | * @return array 33 | */ 34 | public function toArray() 35 | { 36 | return [ 37 | 'key' => $this->id, 38 | 'value' => $this->value, 39 | ]; 40 | } 41 | } -------------------------------------------------------------------------------- /src/Structures/Sync/Responses/SyncProductRequestResponse.php: -------------------------------------------------------------------------------- 1 | syncProduct = SyncProductResponse::fromArray($productArray); 25 | 26 | $variantArray = $array['sync_variants']; 27 | foreach ($variantArray as $item) { 28 | $response->syncVariants[] = SyncVariantResponse::fromArray($item); 29 | } 30 | 31 | return $response; 32 | } 33 | } -------------------------------------------------------------------------------- /src/Structures/Sync/Responses/SyncProductResponse.php: -------------------------------------------------------------------------------- 1 | id = (int)$array['id']; 33 | $syncProduct->externalId = (string)$array['external_id']; 34 | $syncProduct->name = (string)$array['name']; 35 | $syncProduct->variants = (int)$array['variants']; 36 | $syncProduct->synced = (int)$array['synced']; 37 | 38 | return $syncProduct; 39 | } 40 | } -------------------------------------------------------------------------------- /src/Structures/Sync/Responses/SyncProductsPagingResponse.php: -------------------------------------------------------------------------------- 1 | total = (int)$array['total'] ?: 0; 27 | $paging->limit = (int)$array['limit'] ?: 0; 28 | $paging->offset = (int)$array['offset'] ?: 0; 29 | 30 | return $paging; 31 | } 32 | } -------------------------------------------------------------------------------- /src/Structures/Sync/Responses/SyncProductsResponse.php: -------------------------------------------------------------------------------- 1 | result[] = SyncProductResponse::fromArray($item); 26 | } 27 | 28 | $pagingArray = $array['paging'] ?: []; 29 | $response->paging = SyncProductsPagingResponse::fromArray($pagingArray); 30 | 31 | return $response; 32 | } 33 | } -------------------------------------------------------------------------------- /src/Structures/Sync/Responses/SyncVariantOptionResponse.php: -------------------------------------------------------------------------------- 1 | id = (string)$array['id']; 24 | $option->value = $array['value']; 25 | 26 | return $option; 27 | } 28 | } -------------------------------------------------------------------------------- /src/Structures/Sync/Responses/SyncVariantProductResponse.php: -------------------------------------------------------------------------------- 1 | variantId = (int)$array['variant_id'] ?: null; 30 | $syncVariantProduct->productId = (int)$array['product_id'] ?: null; 31 | $syncVariantProduct->image = (string)$array['image'] ?: ''; 32 | $syncVariantProduct->name = (string)$array['name'] ?: ''; 33 | 34 | return $syncVariantProduct; 35 | } 36 | } -------------------------------------------------------------------------------- /src/Structures/Sync/Responses/SyncVariantResponse.php: -------------------------------------------------------------------------------- 1 | id = (int)$array['id']; 54 | $variant->externalId = (string)$array['external_id']; 55 | $variant->syncProductId = (string)$array['sync_product_id']; 56 | $variant->name = (string)$array['name']; 57 | $variant->synced = (bool)$array['synced']; 58 | $variant->variantId = (int)$array['variant_id']; 59 | $variant->retailPrice = (float)$array['retail_price']; 60 | $variant->currency = (string)$array['currency']; 61 | $variant->product = SyncVariantProductResponse::fromArray($array['product']); 62 | 63 | $variantFiles = (array)$array['files'] ?: []; 64 | foreach ($variantFiles as $file) { 65 | $variant->files[] = File::fromArray($file); 66 | } 67 | 68 | $variantOptions = (array)$array['options'] ?: []; 69 | foreach ($variantOptions as $option) { 70 | $variant->options[] = SyncVariantOptionResponse::fromArray($option); 71 | } 72 | 73 | return $variant; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/Structures/Sync/SyncProductCreationParameters.php: -------------------------------------------------------------------------------- 1 | syncProduct = $syncProduct; 25 | } 26 | 27 | /** 28 | * Adds PostSyncVariant to PostSyncRequest 29 | * 30 | * @param SyncVariantRequest $syncVariant 31 | */ 32 | public function addSyncVariant(SyncVariantRequest $syncVariant) 33 | { 34 | $this->syncVariants[] = $syncVariant; 35 | } 36 | 37 | /** 38 | * Returns PostSyncVariants added to SyncProductCreationParameters 39 | * 40 | * @return SyncVariantRequest[] 41 | */ 42 | public function getVariants() 43 | { 44 | return $this->syncVariants; 45 | } 46 | 47 | /** 48 | * Returns SyncProductRequest 49 | * 50 | * @return SyncProductRequest 51 | */ 52 | public function getProduct() 53 | { 54 | return $this->syncProduct; 55 | } 56 | 57 | /** 58 | * Builds SyncProductCreationParameters from array 59 | * 60 | * @param array $array 61 | * @return SyncProductCreationParameters 62 | */ 63 | public static function fromArray(array $array) 64 | { 65 | $syncProductData = isset($array['sync_product']) ? (array)$array['sync_product'] : []; 66 | $syncProductRequest = SyncProductRequest::fromArray($syncProductData); 67 | 68 | $params = new SyncProductCreationParameters($syncProductRequest); 69 | 70 | $syncVariantData = isset($array['sync_variants']) ? (array)$array['sync_variants'] : []; 71 | foreach ($syncVariantData as $item) { 72 | $syncVariantRequest = SyncVariantRequest::fromArray($item); 73 | $params->addSyncVariant($syncVariantRequest); 74 | } 75 | 76 | return $params; 77 | } 78 | 79 | /** 80 | * Build POST request array 81 | * 82 | * @return array 83 | * @throws PrintfulSdkException 84 | */ 85 | public function toPostArray() 86 | { 87 | $params = []; 88 | 89 | $requestProduct = $this->getProduct(); 90 | $requestVariants = $this->getVariants(); 91 | $syncProductParams = []; 92 | 93 | if (empty($requestProduct->name)) { 94 | throw new PrintfulSdkException('Missing product name'); 95 | } 96 | 97 | if (empty($requestVariants)) { 98 | throw new PrintfulSdkException('No variants specified'); 99 | } 100 | 101 | $syncProductParams['name'] = $requestProduct->name; 102 | 103 | if (!empty($requestProduct->thumbnail)) { 104 | $syncProductParams['thumbnail'] = (string)$requestProduct->thumbnail; 105 | } 106 | 107 | if (!empty($requestProduct->externalId)) { 108 | $syncProductParams['external_id'] = (string)$requestProduct->externalId; 109 | } 110 | 111 | $params['sync_product'] = $syncProductParams; 112 | 113 | $params['sync_variants'] = []; 114 | foreach ($requestVariants as $variant) { 115 | $params['sync_variants'][] = $variant->toPostArray(); 116 | } 117 | 118 | return $params; 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /src/Structures/Sync/SyncProductUpdateParameters.php: -------------------------------------------------------------------------------- 1 | syncProduct = SyncProductRequest::fromArray($array['sync_product']); 29 | } 30 | 31 | if (isset($array['sync_variants'])) { 32 | foreach ($array['sync_variants'] as $item) { 33 | $syncVariantRequest = SyncVariantRequest::fromArray($item); 34 | $params->syncVariants[] = $syncVariantRequest; 35 | } 36 | } 37 | 38 | return $params; 39 | } 40 | 41 | /** 42 | * Builds PUT param array 43 | * 44 | * @return array 45 | * @throws PrintfulSdkException 46 | */ 47 | public function toPutArray() 48 | { 49 | $params = []; 50 | 51 | $requestSyncProduct = $this->syncProduct; 52 | $requestSyncVariants = $this->syncVariants; 53 | 54 | if (!$requestSyncProduct && !$requestSyncVariants) { 55 | throw new PrintfulSdkException('Nothing to update'); 56 | } 57 | 58 | if ($requestSyncProduct) { 59 | $syncProduct = []; 60 | 61 | if ($requestSyncProduct->name) { 62 | $syncProduct['name'] = $requestSyncProduct->name; 63 | } 64 | 65 | if ($requestSyncProduct->thumbnail) { 66 | $syncProduct['thumbnail'] = $requestSyncProduct->thumbnail; 67 | } 68 | 69 | if ($requestSyncProduct->externalId) { 70 | $syncProduct['external_id'] = $requestSyncProduct->externalId; 71 | } 72 | 73 | $params['sync_product'] = $syncProduct; 74 | } 75 | 76 | if ($requestSyncVariants) { 77 | $syncVariants = []; 78 | foreach ($requestSyncVariants as $requestSyncVariant) { 79 | $syncVariants[] = $requestSyncVariant->toPutArray(); 80 | } 81 | $params['sync_variants'] = $syncVariants; 82 | } 83 | 84 | return $params; 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/Structures/TaxRateItem.php: -------------------------------------------------------------------------------- 1 | rate = (float)$raw['rate']; 31 | $item->required = (bool)$raw['required']; 32 | $item->isShippingTaxable = (bool)$raw['shipping_taxable']; 33 | 34 | return $item; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Structures/Webhook/WebhookItem.php: -------------------------------------------------------------------------------- 1 | type = $raw['type']; 77 | $item->created = $raw['created']; 78 | $item->retries = $raw['retries']; 79 | $item->store = $raw['store']; 80 | $item->rawData = $raw['data']; 81 | 82 | if (isset($raw['data']['order'])) { 83 | $item->order = Order::fromArray($raw['data']['order']); 84 | } 85 | 86 | if (isset($raw['data']['shipment'])) { 87 | $item->shipment = Shipment::fromArray($raw['data']['shipment']); 88 | } 89 | 90 | if (isset($raw['data']['reason'])) { 91 | $item->reason = $raw['data']['reason']; 92 | } 93 | 94 | return $item; 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/Structures/Webhook/WebhooksInfoItem.php: -------------------------------------------------------------------------------- 1 | url = $raw['url']; 31 | $item->types = $raw['types']; 32 | $item->params = $raw['params']; 33 | 34 | return $item; 35 | } 36 | } 37 | --------------------------------------------------------------------------------