├── .github └── workflows │ ├── style.yml │ └── tests.yml ├── .gitignore ├── .php-cs-fixer.php ├── LICENSE ├── README.md ├── composer.json ├── phpunit.xml ├── src ├── Api │ ├── Client.php │ ├── Request │ │ ├── BaselinkerConnect.php │ │ ├── CourierShipments.php │ │ ├── ExternalStorages.php │ │ ├── OrderReturns.php │ │ ├── Orders.php │ │ └── ProductCatalog.php │ └── Response │ │ ├── BaselinkerException.php │ │ ├── HasResponse.php │ │ └── Response.php ├── Baselinker.php └── Config.php └── tests ├── Api └── Response │ ├── BaselinkerExceptionTest.php │ └── ResponseTest.php ├── BaselinkerTest.php └── ConfigTest.php /.github/workflows/style.yml: -------------------------------------------------------------------------------- 1 | name: style 2 | 3 | on: 4 | pull_request: 5 | push: 6 | branches: 7 | - master 8 | - '*.x' 9 | 10 | jobs: 11 | style: 12 | runs-on: ubuntu-22.04 13 | 14 | steps: 15 | - name: Checkout code 16 | uses: actions/checkout@v4 17 | 18 | - name: Setup PHP 19 | uses: shivammathur/setup-php@v2 20 | with: 21 | php-version: 8.1 22 | tools: composer:v2 23 | coverage: none 24 | 25 | - name: Install dependencies 26 | uses: nick-invision/retry@v3 27 | with: 28 | timeout_minutes: 5 29 | max_attempts: 5 30 | command: composer install --no-interaction --no-progress 31 | 32 | - name: Run PHP CS Fixer 33 | run: vendor/bin/php-cs-fixer check -v 34 | -------------------------------------------------------------------------------- /.github/workflows/tests.yml: -------------------------------------------------------------------------------- 1 | name: tests 2 | 3 | on: 4 | pull_request: 5 | push: 6 | branches: 7 | - master 8 | - '*.x' 9 | 10 | jobs: 11 | tests: 12 | runs-on: ubuntu-22.04 13 | 14 | strategy: 15 | matrix: 16 | php: [8.1, 8.2, 8.3, 8.4] 17 | 18 | name: PHP ${{ matrix.php }} 19 | 20 | steps: 21 | - name: Checkout code 22 | uses: actions/checkout@v4 23 | 24 | - name: Setup PHP 25 | uses: shivammathur/setup-php@v2 26 | with: 27 | php-version: ${{ matrix.php }} 28 | tools: composer:v2 29 | coverage: none 30 | 31 | - name: Install composer dependencies 32 | uses: nick-invision/retry@v3 33 | with: 34 | timeout_minutes: 5 35 | max_attempts: 5 36 | command: composer install --no-interaction --no-progress 37 | 38 | - name: Execute tests 39 | run: vendor/bin/phpunit 40 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Folders 2 | /vendor 3 | 4 | # Files 5 | .php-cs-fixer.cache 6 | .phpunit.result.cache 7 | composer.lock 8 | -------------------------------------------------------------------------------- /.php-cs-fixer.php: -------------------------------------------------------------------------------- 1 | in(__DIR__) 8 | ->name('*.php') 9 | ->ignoreDotFiles(true) 10 | ->ignoreVCS(true) 11 | ->exclude(['vendor']); 12 | 13 | return (new Config()) 14 | ->setRules([ 15 | '@PSR12' => true, 16 | 'align_multiline_comment' => true, 17 | 'array_indentation' => true, 18 | 'array_syntax' => ['syntax' => 'short'], 19 | 'binary_operator_spaces' => true, 20 | 'blank_line_before_statement' => true, 21 | 'cast_spaces' => true, 22 | 'class_attributes_separation' => true, 23 | 'clean_namespace' => true, 24 | 'concat_space' => ['spacing' => 'one'], 25 | 'echo_tag_syntax' => true, 26 | 'explicit_indirect_variable' => true, 27 | 'explicit_string_variable' => true, 28 | 'fully_qualified_strict_types' => true, 29 | 'general_phpdoc_annotation_remove' => true, 30 | 'heredoc_indentation' => false, 31 | 'increment_style' => ['style' => 'post'], 32 | 'lambda_not_used_import' => true, 33 | 'linebreak_after_opening_tag' => true, 34 | 'list_syntax' => true, 35 | 'magic_constant_casing' => true, 36 | 'magic_method_casing' => true, 37 | 'method_chaining_indentation' => true, 38 | 'multiline_comment_opening_closing' => true, 39 | 'multiline_whitespace_before_semicolons' => true, 40 | 'native_function_casing' => true, 41 | 'native_type_declaration_casing' => true, 42 | 'new_with_parentheses' => ['anonymous_class' => false, 'named_class' => true], 43 | 'no_alternative_syntax' => true, 44 | 'no_empty_phpdoc' => true, 45 | 'no_empty_statement' => true, 46 | 'no_extra_blank_lines' => true, 47 | 'no_leading_namespace_whitespace' => true, 48 | 'no_mixed_echo_print' => true, 49 | 'no_multiline_whitespace_around_double_arrow' => true, 50 | 'no_null_property_initialization' => true, 51 | 'no_short_bool_cast' => true, 52 | 'no_singleline_whitespace_before_semicolons' => true, 53 | 'no_spaces_around_offset' => true, 54 | 'no_trailing_comma_in_singleline' => true, 55 | 'no_unneeded_braces' => true, 56 | 'no_unneeded_control_parentheses' => true, 57 | 'no_unneeded_import_alias' => true, 58 | 'no_unused_imports' => true, 59 | 'no_useless_else' => true, 60 | 'no_useless_return' => true, 61 | 'no_whitespace_before_comma_in_array' => true, 62 | 'normalize_index_brace' => true, 63 | 'nullable_type_declaration_for_default_null_value' => true, 64 | 'object_operator_without_whitespace' => true, 65 | 'operator_linebreak' => true, 66 | 'ordered_class_elements' => ['order' => ['use_trait', 'case', 'constant_public', 'constant_protected', 'constant_private', 'property', 'construct', 'destruct']], 67 | 'ordered_imports' => ['sort_algorithm' => 'alpha'], 68 | 'php_unit_fqcn_annotation' => true, 69 | 'php_unit_method_casing' => true, 70 | 'phpdoc_add_missing_param_annotation' => true, 71 | 'phpdoc_align' => ['align' => 'left'], 72 | 'phpdoc_line_span' => true, 73 | 'phpdoc_no_useless_inheritdoc' => true, 74 | 'phpdoc_order' => ['order' => ['param', 'return', 'throws']], 75 | 'phpdoc_return_self_reference' => true, 76 | 'phpdoc_scalar' => true, 77 | 'phpdoc_single_line_var_spacing' => true, 78 | 'phpdoc_summary' => true, 79 | 'phpdoc_tag_casing' => true, 80 | 'phpdoc_to_comment' => true, 81 | 'phpdoc_trim' => true, 82 | 'phpdoc_trim_consecutive_blank_line_separation' => true, 83 | 'phpdoc_types' => true, 84 | 'phpdoc_types_order' => ['null_adjustment' => 'always_last', 'sort_algorithm' => 'none'], 85 | 'phpdoc_var_annotation_correct_order' => true, 86 | 'phpdoc_var_without_name' => true, 87 | 'protected_to_private' => true, 88 | 'return_assignment' => true, 89 | 'semicolon_after_instruction' => true, 90 | 'simple_to_complex_string_variable' => true, 91 | 'single_line_comment_spacing' => true, 92 | 'single_line_comment_style' => true, 93 | 'single_line_empty_body' => true, 94 | 'single_quote' => true, 95 | 'space_after_semicolon' => true, 96 | 'standardize_not_equals' => true, 97 | 'ternary_to_null_coalescing' => true, 98 | 'trailing_comma_in_multiline' => ['elements' => ['arrays', 'match']], 99 | 'trim_array_spaces' => true, 100 | 'type_declaration_spaces' => true, 101 | 'types_spaces' => ['space' => 'single'], 102 | 'whitespace_after_comma_in_array' => true, 103 | 'yoda_style' => false, 104 | ]) 105 | ->setFinder($finder); 106 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Mateusz Nastalski 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BaseLinker PHP library 2 | 3 | PHP wrapper for [baselinker.com](https://baselinker.com/). 4 | 5 | ## Requirements 6 | 7 | - PHP >=8.1 8 | 9 | ## Installation 10 | 11 | ```shell script 12 | composer require mnastalski/baselinker-php 13 | ``` 14 | 15 | ## Usage 16 | 17 | ### Creating an instance 18 | 19 | ```php 20 | use Baselinker\Baselinker; 21 | 22 | $baselinker = new Baselinker('[API token]'); 23 | ``` 24 | 25 | ### Creating a request 26 | 27 | ```php 28 | $response = $baselinker->orders()->getOrders([ 29 | 'date_from' => 1609506671, 30 | 'get_unconfirmed_orders' => true, 31 | ]); 32 | 33 | $response->toArray(); 34 | 35 | /* 36 | [ 37 | 'status' => 'SUCCESS', 38 | 'orders' => [ 39 | [ 40 | 'order_id' => '123456', 41 | ... 42 | ], 43 | ... 44 | ] 45 | ] 46 | */ 47 | 48 | $orders = $response->getParameter('orders'); 49 | 50 | /* 51 | [ 52 | [ 53 | 'order_id' => '123456', 54 | ... 55 | ], 56 | ... 57 | ] 58 | */ 59 | ``` 60 | 61 | ## API Documentation 62 | 63 | [https://api.baselinker.com/](https://api.baselinker.com/) 64 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mnastalski/baselinker-php", 3 | "description": "BaseLinker PHP library", 4 | "keywords": [ 5 | "baselinker" 6 | ], 7 | "type": "library", 8 | "license": "MIT", 9 | "homepage": "https://github.com/mnastalski/baselinker-php", 10 | "authors": [ 11 | { 12 | "name": "Mateusz Nastalski", 13 | "homepage": "https://nastalski.pl" 14 | } 15 | ], 16 | "require": { 17 | "php": "^8.1", 18 | "ext-json": "*", 19 | "guzzlehttp/guzzle": "^7.5" 20 | }, 21 | "require-dev": { 22 | "friendsofphp/php-cs-fixer": "^3.34", 23 | "phpunit/phpunit": "^10.0" 24 | }, 25 | "autoload": { 26 | "psr-4": { 27 | "Baselinker\\": "src/" 28 | } 29 | }, 30 | "autoload-dev": { 31 | "psr-4": { 32 | "Baselinker\\Tests\\": "tests/" 33 | } 34 | }, 35 | "config": { 36 | "sort-packages": true 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | ./tests 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/Api/Client.php: -------------------------------------------------------------------------------- 1 | client()->post('connector.php', [ 24 | RequestOptions::HEADERS => [ 25 | 'X-BLToken' => $this->config->token(), 26 | ], 27 | RequestOptions::FORM_PARAMS => [ 28 | 'method' => $function, 29 | 'parameters' => json_encode($parameters), 30 | ], 31 | ]); 32 | } 33 | 34 | protected function client(): ClientInterface 35 | { 36 | if ($this->client) { 37 | return $this->client; 38 | } 39 | 40 | return $this->client = new GuzzleClient([ 41 | 'base_uri' => $this->getApiUrl(), 42 | RequestOptions::CONNECT_TIMEOUT => 10, 43 | RequestOptions::TIMEOUT => 30, 44 | ]); 45 | } 46 | 47 | private function getApiUrl(): string 48 | { 49 | return self::URL_LIVE; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/Api/Request/BaselinkerConnect.php: -------------------------------------------------------------------------------- 1 | post('getConnectIntegrations') 14 | ); 15 | } 16 | 17 | public function getConnectIntegrationContractors(int $connectIntegrationId): Response 18 | { 19 | return new Response( 20 | $this->post('getConnectIntegrationContractors', [ 21 | 'connect_integration_id' => $connectIntegrationId, 22 | ]) 23 | ); 24 | } 25 | 26 | public function getConnectContractorCreditHistory(int $connectContractorId): Response 27 | { 28 | return new Response( 29 | $this->post('getConnectContractorCreditHistory', [ 30 | 'connect_contractor_id' => $connectContractorId, 31 | ]) 32 | ); 33 | } 34 | 35 | public function addConnectContractorCredit(int $connectContractorId, float $amount, string $message): Response 36 | { 37 | return new Response( 38 | $this->post('addConnectContractorCredit', [ 39 | 'connect_contractor_id' => $connectContractorId, 40 | 'amount' => $amount, 41 | 'message' => $message, 42 | ]) 43 | ); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/Api/Request/CourierShipments.php: -------------------------------------------------------------------------------- 1 | post('createPackage', [ 14 | 'order_id' => $orderId, 15 | 'courier_code' => $courierCode, 16 | 'fields' => $fields, 17 | 'packages' => $packages, 18 | 'account_id' => $accountId, 19 | ]) 20 | ); 21 | } 22 | 23 | public function createPackageManual(int $orderId, string $courierCode, string $packageNumber, int $pickupDate, bool $returnShipment = false): Response 24 | { 25 | return new Response( 26 | $this->post('createPackageManual', [ 27 | 'order_id' => $orderId, 28 | 'courier_code' => $courierCode, 29 | 'package_number' => $packageNumber, 30 | 'pickup_date' => $pickupDate, 31 | 'return_shipment' => $returnShipment, 32 | ]) 33 | ); 34 | } 35 | 36 | public function getCouriersList(): Response 37 | { 38 | return new Response( 39 | $this->post('getCouriersList') 40 | ); 41 | } 42 | 43 | public function getCourierFields(string $courierCode): Response 44 | { 45 | return new Response( 46 | $this->post('getCourierFields', [ 47 | 'courier_code' => $courierCode, 48 | ]) 49 | ); 50 | } 51 | 52 | public function getCourierServices(string $courierCode, string $packageNumber, array $fields, array $packages, ?int $accountId = null): Response 53 | { 54 | return new Response( 55 | $this->post('getCourierServices', [ 56 | 'courier_code' => $courierCode, 57 | 'package_number' => $packageNumber, 58 | 'fields' => $fields, 59 | 'packages' => $packages, 60 | 'account_id' => $accountId, 61 | ]) 62 | ); 63 | } 64 | 65 | public function getCourierAccounts(string $courierCode): Response 66 | { 67 | return new Response( 68 | $this->post('getCourierAccounts', [ 69 | 'courier_code' => $courierCode, 70 | ]) 71 | ); 72 | } 73 | 74 | public function getLabel(string $courierCode, array $data): Response 75 | { 76 | $data['courier_code'] = $courierCode; 77 | 78 | return new Response( 79 | $this->post('getLabel', $data) 80 | ); 81 | } 82 | 83 | public function getProtocol(string $courierCode, array $data, int $accountId): Response 84 | { 85 | $data['courier_code'] = $courierCode; 86 | $data['account_id'] = $accountId; 87 | 88 | return new Response( 89 | $this->post('getProtocol', $data) 90 | ); 91 | } 92 | 93 | public function getOrderPackages(int $orderId): Response 94 | { 95 | return new Response( 96 | $this->post('getOrderPackages', [ 97 | 'order_id' => $orderId, 98 | ]) 99 | ); 100 | } 101 | 102 | public function getCourierPackagesStatusHistory(array $packageIds): Response 103 | { 104 | return new Response( 105 | $this->post('getCourierPackagesStatusHistory', [ 106 | 'package_ids' => $packageIds, 107 | ]) 108 | ); 109 | } 110 | 111 | public function deleteCourierPackage(string $courierCode, array $data, bool $forceDelete = false): Response 112 | { 113 | $data['courier_code'] = $courierCode; 114 | $data['force_delete'] = $forceDelete; 115 | 116 | return new Response( 117 | $this->post('deleteCourierPackage', $data) 118 | ); 119 | } 120 | 121 | public function requestParcelPickup(string $courierCode, array $data, int $accountId, array $fields = []): Response 122 | { 123 | $data['courier_code'] = $courierCode; 124 | $data['account_id'] = $accountId; 125 | $data['fields'] = $fields; 126 | 127 | return new Response( 128 | $this->post('requestParcelPickup', $data) 129 | ); 130 | } 131 | 132 | public function getRequestParcelPickupFields(string $courierCode): Response 133 | { 134 | return new Response( 135 | $this->post('getRequestParcelPickupFields', [ 136 | 'courier_code' => $courierCode, 137 | ]) 138 | ); 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /src/Api/Request/ExternalStorages.php: -------------------------------------------------------------------------------- 1 | post('getExternalStoragesList') 14 | ); 15 | } 16 | 17 | public function getExternalStorageCategories(string $storageId): Response 18 | { 19 | return new Response( 20 | $this->post('getExternalStorageCategories', [ 21 | 'storage_id' => $storageId, 22 | ]) 23 | ); 24 | } 25 | 26 | public function getExternalStorageProductsData(string $storageId, array $products): Response 27 | { 28 | return new Response( 29 | $this->post('getExternalStorageProductsData', [ 30 | 'storage_id' => $storageId, 31 | 'products' => $products, 32 | ]) 33 | ); 34 | } 35 | 36 | public function getExternalStorageProductsList(string $storageId, array $filters = [], ?int $page = null): Response 37 | { 38 | $filters['storage_id'] = $storageId; 39 | $filters['page'] = $page; 40 | 41 | return new Response( 42 | $this->post('getExternalStorageProductsList', $filters) 43 | ); 44 | } 45 | 46 | public function getExternalStorageProductsQuantity(string $storageId, ?int $page = null): Response 47 | { 48 | return new Response( 49 | $this->post('getExternalStorageProductsQuantity', [ 50 | 'storage_id' => $storageId, 51 | 'page' => $page, 52 | ]) 53 | ); 54 | } 55 | 56 | public function getExternalStorageProductsPrices(string $storageId, ?int $page = null): Response 57 | { 58 | return new Response( 59 | $this->post('getExternalStorageProductsPrices', [ 60 | 'storage_id' => $storageId, 61 | 'page' => $page, 62 | ]) 63 | ); 64 | } 65 | 66 | public function updateExternalStorageProductsQuantity(string $storageId, array $products): Response 67 | { 68 | return new Response( 69 | $this->post('updateExternalStorageProductsQuantity', [ 70 | 'storage_id' => $storageId, 71 | 'products' => $products, 72 | ]) 73 | ); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/Api/Request/OrderReturns.php: -------------------------------------------------------------------------------- 1 | post('getOrderReturnJournalList', [ 14 | 'last_log_id' => $lastLogId, 15 | 'logs_types' => $logsTypes, 16 | 'return_id' => $returnId, 17 | ]) 18 | ); 19 | } 20 | 21 | public function addOrderReturn(array $data): Response 22 | { 23 | return new Response( 24 | $this->post('addOrderReturn', $data) 25 | ); 26 | } 27 | 28 | public function getOrderReturnExtraFields(): Response 29 | { 30 | return new Response( 31 | $this->post('getOrderReturnExtraFields') 32 | ); 33 | } 34 | 35 | public function getOrderReturns(array $data): Response 36 | { 37 | return new Response( 38 | $this->post('getOrderReturns', $data) 39 | ); 40 | } 41 | 42 | public function getOrderReturnStatusList(): Response 43 | { 44 | return new Response( 45 | $this->post('getOrderReturnStatusList') 46 | ); 47 | } 48 | 49 | public function getOrderReturnPaymentsHistory(int $returnId, bool $showFullHistory = false): Response 50 | { 51 | return new Response( 52 | $this->post('getOrderReturnPaymentsHistory', [ 53 | 'return_id' => $returnId, 54 | 'show_full_history' => $showFullHistory, 55 | ]) 56 | ); 57 | } 58 | 59 | public function setOrderReturnFields(int $returnId, array $data): Response 60 | { 61 | $data['return_id'] = $returnId; 62 | 63 | return new Response( 64 | $this->post('setOrderReturnFields', $data) 65 | ); 66 | } 67 | 68 | public function addOrderReturnProduct(int $returnId, array $data): Response 69 | { 70 | $data['return_id'] = $returnId; 71 | 72 | return new Response( 73 | $this->post('addOrderReturnProduct', $data) 74 | ); 75 | } 76 | 77 | public function setOrderReturnProductFields(int $returnId, int $orderReturnProductId, array $data): Response 78 | { 79 | $data['return_id'] = $returnId; 80 | $data['order_return_product_id'] = $orderReturnProductId; 81 | 82 | return new Response( 83 | $this->post('setOrderReturnProductFields', $data) 84 | ); 85 | } 86 | 87 | public function deleteOrderReturnProduct(int $returnId, int $orderReturnProductId): Response 88 | { 89 | return new Response( 90 | $this->post('deleteOrderReturnProduct', [ 91 | 'return_id' => $returnId, 92 | 'order_return_product_id' => $orderReturnProductId, 93 | ]) 94 | ); 95 | } 96 | 97 | public function setOrderReturnRefund(int $returnId, float $orderRefundDone, int $refundDate, string $refundComment, ?string $externalRefundId = null): Response 98 | { 99 | return new Response( 100 | $this->post('setOrderReturnRefund', [ 101 | 'return_id' => $returnId, 102 | 'order_refund_done' => $orderRefundDone, 103 | 'refund_date' => $refundDate, 104 | 'refund_comment' => $refundComment, 105 | 'external_refund_id' => $externalRefundId, 106 | ]) 107 | ); 108 | } 109 | 110 | public function getOrderReturnReasonsList(): Response 111 | { 112 | return new Response( 113 | $this->post('getOrderReturnReasonsList') 114 | ); 115 | } 116 | 117 | public function setOrderReturnStatus(int $returnId, int $statusId): Response 118 | { 119 | return new Response( 120 | $this->post('setOrderReturnStatus', [ 121 | 'return_id' => $returnId, 122 | 'status_id' => $statusId, 123 | ]) 124 | ); 125 | } 126 | 127 | public function setOrderReturnStatuses(array $returnIds, int $statusId): Response 128 | { 129 | return new Response( 130 | $this->post('setOrderReturnStatuses', [ 131 | 'return_ids' => $returnIds, 132 | 'status_id' => $statusId, 133 | ]) 134 | ); 135 | } 136 | 137 | public function runOrderReturnMacroTrigger(int $returnId, int $triggerId): Response 138 | { 139 | return new Response( 140 | $this->post('runOrderReturnMacroTrigger', [ 141 | 'return_id' => $returnId, 142 | 'trigger_id' => $triggerId, 143 | ]) 144 | ); 145 | } 146 | 147 | public function getOrderReturnProductStatuses(): Response 148 | { 149 | return new Response( 150 | $this->post('getOrderReturnProductStatuses') 151 | ); 152 | } 153 | } 154 | -------------------------------------------------------------------------------- /src/Api/Request/Orders.php: -------------------------------------------------------------------------------- 1 | post('getJournalList', [ 14 | 'last_log_id' => $lastLogId, 15 | 'logs_types' => $logsTypes, 16 | 'order_id' => $orderId, 17 | ]) 18 | ); 19 | } 20 | 21 | public function addOrder(array $data): Response 22 | { 23 | return new Response( 24 | $this->post('addOrder', $data) 25 | ); 26 | } 27 | 28 | public function getOrderSources(): Response 29 | { 30 | return new Response( 31 | $this->post('getOrderSources') 32 | ); 33 | } 34 | 35 | public function getOrderExtraFields(): Response 36 | { 37 | return new Response( 38 | $this->post('getOrderExtraFields') 39 | ); 40 | } 41 | 42 | public function getOrders(array $data): Response 43 | { 44 | return new Response( 45 | $this->post('getOrders', $data) 46 | ); 47 | } 48 | 49 | public function getOrderTransactionDetails(int $orderId): Response 50 | { 51 | return new Response( 52 | $this->post('getOrderTransactionDetails', [ 53 | 'order_id' => $orderId, 54 | ]) 55 | ); 56 | } 57 | 58 | public function getOrderTransactionData(int $orderId): Response 59 | { 60 | return new Response( 61 | $this->post('getOrderTransactionData', [ 62 | 'order_id' => $orderId, 63 | ]) 64 | ); 65 | } 66 | 67 | public function getOrdersByEmail(string $email): Response 68 | { 69 | return new Response( 70 | $this->post('getOrdersByEmail', [ 71 | 'email' => $email, 72 | ]) 73 | ); 74 | } 75 | 76 | public function getOrdersByPhone(string $phone): Response 77 | { 78 | return new Response( 79 | $this->post('getOrdersByPhone', [ 80 | 'phone' => $phone, 81 | ]) 82 | ); 83 | } 84 | 85 | public function addInvoice(int $orderId, int $seriesId, $vatRate = null): Response 86 | { 87 | return new Response( 88 | $this->post('addInvoice', [ 89 | 'order_id' => $orderId, 90 | 'series_id' => $seriesId, 91 | 'vat_rate' => $vatRate, 92 | ]) 93 | ); 94 | } 95 | 96 | public function getInvoices(array $data): Response 97 | { 98 | return new Response( 99 | $this->post('getInvoices', $data) 100 | ); 101 | } 102 | 103 | public function getSeries(): Response 104 | { 105 | return new Response( 106 | $this->post('getSeries') 107 | ); 108 | } 109 | 110 | public function getOrderStatusList(): Response 111 | { 112 | return new Response( 113 | $this->post('getOrderStatusList') 114 | ); 115 | } 116 | 117 | public function getOrderPaymentsHistory(int $orderId, bool $showFullHistory = false): Response 118 | { 119 | return new Response( 120 | $this->post('getOrderPaymentsHistory', [ 121 | 'order_id' => $orderId, 122 | 'show_full_history' => $showFullHistory, 123 | ]) 124 | ); 125 | } 126 | 127 | public function getOrderPickPackHistory(int $orderId, ?int $actionType = null): Response 128 | { 129 | return new Response( 130 | $this->post('getOrderPickPackHistory', [ 131 | 'order_id' => $orderId, 132 | 'action_type' => $actionType, 133 | ]) 134 | ); 135 | } 136 | 137 | public function getNewReceipts(int $seriesId): Response 138 | { 139 | return new Response( 140 | $this->post('getNewReceipts', [ 141 | 'series_id' => $seriesId, 142 | ]) 143 | ); 144 | } 145 | 146 | public function getReceipt(array $data): Response 147 | { 148 | return new Response( 149 | $this->post('getReceipt', $data) 150 | ); 151 | } 152 | 153 | public function setOrderFields(array $data): Response 154 | { 155 | return new Response( 156 | $this->post('setOrderFields', $data) 157 | ); 158 | } 159 | 160 | public function addOrderProduct(array $data): Response 161 | { 162 | return new Response( 163 | $this->post('addOrderProduct', $data) 164 | ); 165 | } 166 | 167 | public function setOrderProductFields(array $data): Response 168 | { 169 | return new Response( 170 | $this->post('setOrderProductFields', $data) 171 | ); 172 | } 173 | 174 | public function deleteOrderProduct(int $orderId, int $orderProductId): Response 175 | { 176 | return new Response( 177 | $this->post('deleteOrderProduct', [ 178 | 'order_id' => $orderId, 179 | 'order_product_id' => $orderProductId, 180 | ]) 181 | ); 182 | } 183 | 184 | public function setOrderPayment(int $orderId, float $paymentDone, ?int $paymentDate = null, ?string $paymentComment = null, ?string $externalPaymentId = null): Response 185 | { 186 | return new Response( 187 | $this->post('setOrderPayment', [ 188 | 'order_id' => $orderId, 189 | 'payment_done' => $paymentDone, 190 | 'payment_date' => $paymentDate, 191 | 'payment_comment' => $paymentComment, 192 | 'external_payment_id' => $externalPaymentId, 193 | ]) 194 | ); 195 | } 196 | 197 | public function setOrderStatus(int $orderId, int $statusId): Response 198 | { 199 | return new Response( 200 | $this->post('setOrderStatus', [ 201 | 'order_id' => $orderId, 202 | 'status_id' => $statusId, 203 | ]) 204 | ); 205 | } 206 | 207 | public function setOrderStatuses(array $orderIds, int $statusId): Response 208 | { 209 | return new Response( 210 | $this->post('setOrderStatuses', [ 211 | 'order_ids' => $orderIds, 212 | 'status_id' => $statusId, 213 | ]) 214 | ); 215 | } 216 | 217 | public function setOrderReceipt(int $receiptId, string $receiptNr, int $date, bool $printerError = false, ?string $printerName = null): Response 218 | { 219 | return new Response( 220 | $this->post('setOrderReceipt', [ 221 | 'order_id' => $receiptId, 222 | 'receipt_nr' => $receiptNr, 223 | 'date' => $date, 224 | 'printer_error' => $printerError, 225 | 'printer_name' => $printerName, 226 | ]) 227 | ); 228 | } 229 | 230 | public function addOrderInvoiceFile(int $invoiceId, string $file, string $externalInvoiceNumber): Response 231 | { 232 | return new Response( 233 | $this->post('addOrderInvoiceFile', [ 234 | 'invoice_id' => $invoiceId, 235 | 'file' => $file, 236 | 'external_invoice_number' => $externalInvoiceNumber, 237 | ]) 238 | ); 239 | } 240 | 241 | public function addOrderReceiptFile(int $receiptId, string $file, string $externalReceiptNumber): Response 242 | { 243 | return new Response( 244 | $this->post('addOrderInvoiceFile', [ 245 | 'receipt_id' => $receiptId, 246 | 'file' => $file, 247 | 'external_receipt_number' => $externalReceiptNumber, 248 | ]) 249 | ); 250 | } 251 | 252 | public function getInvoiceFile(int $invoiceId): Response 253 | { 254 | return new Response( 255 | $this->post('getInvoiceFile', [ 256 | 'invoice_id' => $invoiceId, 257 | ]) 258 | ); 259 | } 260 | 261 | public function runOrderMacroTrigger(int $orderId, int $triggerId): Response 262 | { 263 | return new Response( 264 | $this->post('runOrderMacroTrigger', [ 265 | 'order_id' => $orderId, 266 | 'trigger_id' => $triggerId, 267 | ]) 268 | ); 269 | } 270 | } 271 | -------------------------------------------------------------------------------- /src/Api/Request/ProductCatalog.php: -------------------------------------------------------------------------------- 1 | post('addInventoryPriceGroup', [ 14 | 'name' => $name, 15 | 'description' => $description, 16 | 'currency' => $currency, 17 | ]) 18 | ); 19 | } 20 | 21 | public function updateInventoryPriceGroup(int $priceGroupId, string $name, ?string $description = null, string $currency = 'PLN'): Response 22 | { 23 | return new Response( 24 | $this->post('addInventoryPriceGroup', [ 25 | 'price_group_id' => $priceGroupId, 26 | 'name' => $name, 27 | 'description' => $description, 28 | 'currency' => $currency, 29 | ]) 30 | ); 31 | } 32 | 33 | public function deleteInventoryPriceGroup(int $priceGroupId): Response 34 | { 35 | return new Response( 36 | $this->post('deleteInventoryPriceGroup', [ 37 | 'price_group_id' => $priceGroupId, 38 | ]) 39 | ); 40 | } 41 | 42 | public function getInventoryPriceGroups(): Response 43 | { 44 | return new Response( 45 | $this->post('getInventoryPriceGroups') 46 | ); 47 | } 48 | 49 | public function addInventoryWarehouse(string $name, ?string $description = null, bool $stockEdition = true): Response 50 | { 51 | return new Response( 52 | $this->post('addInventoryWarehouse', [ 53 | 'name' => $name, 54 | 'description' => $description, 55 | 'stock_edition' => $stockEdition, 56 | ]) 57 | ); 58 | } 59 | 60 | public function updateInventoryWarehouse(int $warehouseId, string $name, ?string $description = null, bool $stockEdition = true): Response 61 | { 62 | return new Response( 63 | $this->post('addInventoryWarehouse', [ 64 | 'warehouse_id' => $warehouseId, 65 | 'name' => $name, 66 | 'description' => $description, 67 | 'stock_edition' => $stockEdition, 68 | ]) 69 | ); 70 | } 71 | 72 | public function deleteInventoryWarehouse(int $warehouseId): Response 73 | { 74 | return new Response( 75 | $this->post('deleteInventoryWarehouse', [ 76 | 'warehouse_id' => $warehouseId, 77 | ]) 78 | ); 79 | } 80 | 81 | public function getInventoryWarehouses(): Response 82 | { 83 | return new Response( 84 | $this->post('getInventoryWarehouses') 85 | ); 86 | } 87 | 88 | public function addInventory(array $data): Response 89 | { 90 | return new Response( 91 | $this->post('addInventory', $data) 92 | ); 93 | } 94 | 95 | public function deleteInventory(int $inventoryId): Response 96 | { 97 | return new Response( 98 | $this->post('deleteInventory', [ 99 | 'inventory_id' => $inventoryId, 100 | ]) 101 | ); 102 | } 103 | 104 | public function getInventories(): Response 105 | { 106 | return new Response( 107 | $this->post('getInventories') 108 | ); 109 | } 110 | 111 | public function addInventoryCategory(string $name, int $parentId = 0, ?int $inventoryId = null): Response 112 | { 113 | return new Response( 114 | $this->post('addInventoryCategory', [ 115 | 'name' => $name, 116 | 'parent_id' => $parentId, 117 | 'inventory_id' => $inventoryId, 118 | ]) 119 | ); 120 | } 121 | 122 | public function updateInventoryCategory(int $categoryId, string $name, int $parentId = 0): Response 123 | { 124 | return new Response( 125 | $this->post('addInventoryCategory', [ 126 | 'category_id' => $categoryId, 127 | 'name' => $name, 128 | 'parent_id' => $parentId, 129 | ]) 130 | ); 131 | } 132 | 133 | public function deleteInventoryCategory(int $categoryId): Response 134 | { 135 | return new Response( 136 | $this->post('deleteInventoryCategory', [ 137 | 'category_id' => $categoryId, 138 | ]) 139 | ); 140 | } 141 | 142 | public function getInventoryCategories(?int $inventoryId = null): Response 143 | { 144 | return new Response( 145 | $this->post('getInventoryCategories', [ 146 | 'inventory_id' => $inventoryId, 147 | ]) 148 | ); 149 | } 150 | 151 | public function addInventoryManufacturer(string $name): Response 152 | { 153 | return new Response( 154 | $this->post('addInventoryManufacturer', [ 155 | 'name' => $name, 156 | ]) 157 | ); 158 | } 159 | 160 | public function updateInventoryManufacturer(int $manufacturerId, string $name): Response 161 | { 162 | return new Response( 163 | $this->post('addInventoryManufacturer', [ 164 | 'manufacturer_id' => $manufacturerId, 165 | 'name' => $name, 166 | ]) 167 | ); 168 | } 169 | 170 | public function deleteInventoryManufacturer(int $manufacturerId): Response 171 | { 172 | return new Response( 173 | $this->post('deleteInventoryManufacturer', [ 174 | 'manufacturer_id' => $manufacturerId, 175 | ]) 176 | ); 177 | } 178 | 179 | public function getInventoryManufacturers(): Response 180 | { 181 | return new Response( 182 | $this->post('getInventoryManufacturers') 183 | ); 184 | } 185 | 186 | public function getInventoryExtraFields(): Response 187 | { 188 | return new Response( 189 | $this->post('getInventoryExtraFields') 190 | ); 191 | } 192 | 193 | public function getInventoryIntegrations(int $inventoryId): Response 194 | { 195 | return new Response( 196 | $this->post('getInventoryIntegrations', [ 197 | 'inventory_id' => $inventoryId, 198 | ]) 199 | ); 200 | } 201 | 202 | public function getInventoryAvailableTextFieldKeys(int $inventoryId): Response 203 | { 204 | return new Response( 205 | $this->post('getInventoryIntegrations', [ 206 | 'inventory_id' => $inventoryId, 207 | ]) 208 | ); 209 | } 210 | 211 | public function addInventoryProduct(array $data): Response 212 | { 213 | return new Response( 214 | $this->post('addInventoryProduct', $data) 215 | ); 216 | } 217 | 218 | public function updateInventoryProduct(int $productId, array $data): Response 219 | { 220 | $data['product_id'] = $productId; 221 | 222 | return new Response( 223 | $this->post('addInventoryProduct', $data) 224 | ); 225 | } 226 | 227 | public function deleteInventoryProduct(int $productId): Response 228 | { 229 | return new Response( 230 | $this->post('deleteInventoryProduct', [ 231 | 'product_id' => $productId, 232 | ]) 233 | ); 234 | } 235 | 236 | public function getInventoryProductsData( 237 | int $inventoryId, 238 | array $products = [], 239 | ?bool $includeErpUnits = null, 240 | ?bool $includeWmsUnits = null, 241 | ?bool $includeAdditionalEans = null 242 | ): Response { 243 | return new Response( 244 | $this->post('getInventoryProductsData', [ 245 | 'inventory_id' => $inventoryId, 246 | 'products' => $products, 247 | 'include_erp_units' => $includeErpUnits, 248 | 'include_wms_units' => $includeWmsUnits, 249 | 'include_additional_eans' => $includeAdditionalEans, 250 | ]) 251 | ); 252 | } 253 | 254 | public function getInventoryProductsList(int $inventoryId, array $filters = []): Response 255 | { 256 | $filters['inventory_id'] = $inventoryId; 257 | 258 | return new Response( 259 | $this->post('getInventoryProductsList', $filters) 260 | ); 261 | } 262 | 263 | public function getInventoryProductsStock(int $inventoryId, ?int $page = null): Response 264 | { 265 | return new Response( 266 | $this->post('getInventoryProductsStock', [ 267 | 'inventory_id' => $inventoryId, 268 | 'page' => $page, 269 | ]) 270 | ); 271 | } 272 | 273 | public function updateInventoryProductsStock(int $inventoryId, array $products = []): Response 274 | { 275 | return new Response( 276 | $this->post('updateInventoryProductsStock', [ 277 | 'inventory_id' => $inventoryId, 278 | 'products' => $products, 279 | ]) 280 | ); 281 | } 282 | 283 | public function getInventoryProductsPrices(int $inventoryId, ?int $page = null): Response 284 | { 285 | return new Response( 286 | $this->post('getInventoryProductsPrices', [ 287 | 'inventory_id' => $inventoryId, 288 | 'page' => $page, 289 | ]) 290 | ); 291 | } 292 | 293 | public function updateInventoryProductsPrices(int $inventoryId, array $products): Response 294 | { 295 | return new Response( 296 | $this->post('updateInventoryProductsPrices', [ 297 | 'inventory_id' => $inventoryId, 298 | 'products' => $products, 299 | ]) 300 | ); 301 | } 302 | 303 | public function getInventoryProductLogs(int $productId, array $filters = []): Response 304 | { 305 | $filters['product_id'] = $productId; 306 | 307 | return new Response( 308 | $this->post('getInventoryProductLogs', $filters) 309 | ); 310 | } 311 | 312 | public function runProductMacroTrigger(int $productId, int $triggerId): Response 313 | { 314 | return new Response( 315 | $this->post('runProductMacroTrigger', [ 316 | 'product_id' => $productId, 317 | 'trigger_id' => $triggerId, 318 | ]) 319 | ); 320 | } 321 | } 322 | -------------------------------------------------------------------------------- /src/Api/Response/BaselinkerException.php: -------------------------------------------------------------------------------- 1 | response = $response; 20 | $this->responseCode = $this->getParameter('error_code'); 21 | $this->responseMessage = $this->getParameter('error_message'); 22 | 23 | parent::__construct("[{$this->responseCode}] {$this->responseMessage}"); 24 | } 25 | 26 | public function responseCode(): string 27 | { 28 | return $this->responseCode; 29 | } 30 | 31 | public function responseMessage(): string 32 | { 33 | return $this->responseMessage; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Api/Response/HasResponse.php: -------------------------------------------------------------------------------- 1 | response; 18 | } 19 | 20 | public function contents(): string 21 | { 22 | if ($this->contents) { 23 | return $this->contents; 24 | } 25 | 26 | return $this->contents = (string) $this->response->getBody(); 27 | } 28 | 29 | public function toArray(): array 30 | { 31 | if ($this->array) { 32 | return $this->array; 33 | } 34 | 35 | $array = json_decode($this->contents(), true); 36 | 37 | if (json_last_error() !== JSON_ERROR_NONE) { 38 | $array = []; 39 | } 40 | 41 | return $this->array = $array; 42 | } 43 | 44 | public function getParameter(string $parameter): mixed 45 | { 46 | return $this->toArray()[$parameter]; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Api/Response/Response.php: -------------------------------------------------------------------------------- 1 | response = $response; 15 | 16 | if ($this->hasError()) { 17 | throw new BaselinkerException($this->response); 18 | } 19 | } 20 | 21 | private function hasError(): bool 22 | { 23 | $status = $this->getParameter('status'); 24 | 25 | return strtolower($status) !== 'success'; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Baselinker.php: -------------------------------------------------------------------------------- 1 | config = new Config($token); 19 | } 20 | 21 | public function productCatalog(): ProductCatalog 22 | { 23 | return new ProductCatalog($this->config); 24 | } 25 | 26 | public function externalStorages(): ExternalStorages 27 | { 28 | return new ExternalStorages($this->config); 29 | } 30 | 31 | public function orders(): Orders 32 | { 33 | return new Orders($this->config); 34 | } 35 | 36 | public function orderReturns(): OrderReturns 37 | { 38 | return new OrderReturns($this->config); 39 | } 40 | 41 | public function courierShipments(): CourierShipments 42 | { 43 | return new CourierShipments($this->config); 44 | } 45 | 46 | public function baselinkerConnect(): BaselinkerConnect 47 | { 48 | return new BaselinkerConnect($this->config); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/Config.php: -------------------------------------------------------------------------------- 1 | token; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /tests/Api/Response/BaselinkerExceptionTest.php: -------------------------------------------------------------------------------- 1 | 'ERROR', 16 | 'error_code' => 'CODE', 17 | 'error_message' => 'Message', 18 | ])); 19 | 20 | $exception = new BaselinkerException($response); 21 | 22 | $this->assertInstanceOf(ResponseInterface::class, $exception->response()); 23 | 24 | $this->assertEquals('{"status":"ERROR","error_code":"CODE","error_message":"Message"}', $exception->contents()); 25 | 26 | $this->assertEquals([ 27 | 'status' => 'ERROR', 28 | 'error_code' => 'CODE', 29 | 'error_message' => 'Message', 30 | ], $exception->toArray()); 31 | 32 | $this->assertEquals('CODE', $exception->getParameter('error_code')); 33 | 34 | $this->assertEquals('CODE', $exception->responseCode()); 35 | $this->assertEquals('Message', $exception->responseMessage()); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /tests/Api/Response/ResponseTest.php: -------------------------------------------------------------------------------- 1 | 'SUCCESS', 17 | 'list' => [ 18 | 'foo' => 'bar', 19 | ], 20 | ]); 21 | 22 | $response = new Response( 23 | new GuzzleResponse(200, [], $body) 24 | ); 25 | 26 | $this->assertInstanceOf(ResponseInterface::class, $response->response()); 27 | 28 | $this->assertEquals('{"status":"SUCCESS","list":{"foo":"bar"}}', $response->contents()); 29 | 30 | $this->assertEquals([ 31 | 'status' => 'SUCCESS', 32 | 'list' => [ 33 | 'foo' => 'bar', 34 | ], 35 | ], $response->toArray()); 36 | 37 | $this->assertEquals([ 38 | 'foo' => 'bar', 39 | ], $response->getParameter('list')); 40 | } 41 | 42 | public function testWithErrorThrowsException(): void 43 | { 44 | $body = json_encode([ 45 | 'status' => 'ERROR', 46 | 'error_code' => 'CODE', 47 | 'error_message' => 'Message', 48 | ]); 49 | 50 | $this->expectException(BaselinkerException::class); 51 | $this->expectExceptionMessage('[CODE] Message'); 52 | 53 | new Response( 54 | new GuzzleResponse(200, [], $body) 55 | ); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /tests/BaselinkerTest.php: -------------------------------------------------------------------------------- 1 | productCatalog(); 21 | 22 | $this->assertInstanceOf(ProductCatalog::class, $productCatalog); 23 | } 24 | 25 | public function testExternalStorages(): void 26 | { 27 | $baselinker = new Baselinker('token'); 28 | 29 | $externalStorages = $baselinker->externalStorages(); 30 | 31 | $this->assertInstanceOf(ExternalStorages::class, $externalStorages); 32 | } 33 | 34 | public function testOrders(): void 35 | { 36 | $baselinker = new Baselinker('token'); 37 | 38 | $orders = $baselinker->orders(); 39 | 40 | $this->assertInstanceOf(Orders::class, $orders); 41 | } 42 | 43 | public function testOrderReturns(): void 44 | { 45 | $baselinker = new Baselinker('token'); 46 | 47 | $orderReturns = $baselinker->orderReturns(); 48 | 49 | $this->assertInstanceOf(OrderReturns::class, $orderReturns); 50 | } 51 | 52 | public function testCourierShipments(): void 53 | { 54 | $baselinker = new Baselinker('token'); 55 | 56 | $courierShipments = $baselinker->courierShipments(); 57 | 58 | $this->assertInstanceOf(CourierShipments::class, $courierShipments); 59 | } 60 | 61 | public function testBaselinkerConnect(): void 62 | { 63 | $baselinker = new Baselinker('token'); 64 | 65 | $baselinkerConnect = $baselinker->baselinkerConnect(); 66 | 67 | $this->assertInstanceOf(BaselinkerConnect::class, $baselinkerConnect); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /tests/ConfigTest.php: -------------------------------------------------------------------------------- 1 | assertEquals('foo', $config->token()); 15 | } 16 | } 17 | --------------------------------------------------------------------------------