├── .styleci.yml ├── src ├── Exceptions │ └── BillingoApiException.php ├── BillingoApiV3WrapperFacade.php ├── BillingoApiV3WrapperServiceProvider.php ├── Traits │ └── ProcessErrorsTrait.php ├── BillingoApiV3Wrapper.php └── Services │ └── BillingoApiV3Service.php ├── config └── config.php ├── LICENSE.md ├── composer.json ├── CONTRIBUTING.md └── README.md /.styleci.yml: -------------------------------------------------------------------------------- 1 | preset: laravel 2 | 3 | disabled: 4 | - single_class_element_per_statement 5 | -------------------------------------------------------------------------------- /src/Exceptions/BillingoApiException.php: -------------------------------------------------------------------------------- 1 | env('BILLINGO_API_KEY', 'YOUR_API_KEY'), 9 | 10 | ]; 11 | -------------------------------------------------------------------------------- /src/BillingoApiV3WrapperFacade.php: -------------------------------------------------------------------------------- 1 | app->runningInConsole()) { 18 | $this->publishes([ 19 | __DIR__ . '/../config/config.php' => config_path('billingo-api-v3-wrapper.php'), 20 | ], 'billingo-config'); 21 | } 22 | } 23 | 24 | /** 25 | * Register the application services. 26 | */ 27 | public function register() 28 | { 29 | // Automatically apply the package configuration 30 | $this->mergeConfigFrom(__DIR__ . '/../config/config.php', 'billingo-api-v3-wrapper'); 31 | 32 | // Register the main class to use with the facade 33 | $this->app->singleton('billingo-api-v3-wrapper', function () { 34 | return new BillingoApiV3Wrapper; 35 | }); 36 | } 37 | 38 | /** 39 | * Get the services provided by the provider. 40 | * 41 | * @return array 42 | */ 43 | public function provides() 44 | { 45 | return [BillingoApiV3Wrapper::class]; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Traits/ProcessErrorsTrait.php: -------------------------------------------------------------------------------- 1 | error = $error; 25 | 26 | return $this; 27 | } 28 | 29 | /** 30 | * Get error message response 31 | * 32 | * @return string 33 | */ 34 | public function response(): string 35 | { 36 | if ($this->isJson($this->error)) { 37 | return \json_encode(\json_decode($this->getJsonFromErrorString(), true), JSON_FORCE_OBJECT); 38 | } 39 | 40 | return $this->error; 41 | } 42 | 43 | /** 44 | * Get json from error string 45 | * 46 | * @return string 47 | */ 48 | public function getJsonFromErrorString(): string 49 | { 50 | return substr( 51 | $this->error, 52 | strpos($this->error, "{"), 53 | strpos($this->error, "}") 54 | ); 55 | } 56 | 57 | /** 58 | * Check that error string is json encoded 59 | * 60 | * @param string $error 61 | * 62 | * @return bool 63 | */ 64 | public function isJson(string $error): bool 65 | { 66 | json_decode($error); 67 | return json_last_error() === JSON_ERROR_NONE; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "deviddev/billingo-api-v3-wrapper", 3 | "description": "This is a simple Laravel wrapper for Billingo (billingo.hu) API V3 SwaggerHUB PHP SDK.", 4 | "keywords": [ 5 | "laravel", 6 | "billingo", 7 | "API", 8 | "wrapper", 9 | "V3" 10 | ], 11 | "homepage": "https://github.com/deviddev/billingo-api-v3-wrapper", 12 | "type": "library", 13 | "license": "MIT", 14 | "authors": [ 15 | { 16 | "name": "David Molnar", 17 | "email": "david@codespot.hu" 18 | } 19 | ], 20 | "require": { 21 | "php": "^8.2", 22 | "illuminate/support": "^11|^12", 23 | "deviddev/billingo-api-v3-php-sdk": "^v0.3.0" 24 | }, 25 | "require-dev": { 26 | "orchestra/testbench": "^9.0|^10.0", 27 | "phpunit/phpunit": "^11.0" 28 | }, 29 | "autoload": { 30 | "psr-4": { 31 | "Deviddev\\BillingoApiV3Wrapper\\": "src" 32 | } 33 | }, 34 | "autoload-dev": { 35 | "psr-4": { 36 | "Deviddev\\BillingoApiV3Wrapper\\Tests\\": "tests" 37 | } 38 | }, 39 | "scripts": { 40 | "test": "vendor/bin/phpunit", 41 | "test-win": "vendor\\bin\\phpunit", 42 | "test-coverage": "vendor/bin/phpunit --coverage-html coverage", 43 | "test-coverage-win": "vendor\\bin\\phpunit --coverage-html coverage" 44 | }, 45 | "config": { 46 | "sort-packages": true 47 | }, 48 | "extra": { 49 | "laravel": { 50 | "providers": [ 51 | "Deviddev\\BillingoApiV3Wrapper\\BillingoApiV3WrapperServiceProvider" 52 | ], 53 | "aliases": { 54 | "BillingoApiV3Wrapper": "Deviddev\\BillingoApiV3Wrapper\\BillingoApiV3WrapperFacade" 55 | } 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Contributions are **welcome** and will be fully **credited**. 4 | 5 | Please read and understand the contribution guide before creating an issue or pull request. 6 | 7 | ## Etiquette 8 | 9 | This project is open source, and as such, the maintainers give their free time to build and maintain the source code 10 | held within. They make the code freely available in the hope that it will be of use to other developers. It would be 11 | extremely unfair for them to suffer abuse or anger for their hard work. 12 | 13 | Please be considerate towards maintainers when raising issues or presenting pull requests. Let's show the 14 | world that developers are civilized and selfless people. 15 | 16 | It's the duty of the maintainer to ensure that all submissions to the project are of sufficient 17 | quality to benefit the project. Many developers have different skillsets, strengths, and weaknesses. Respect the maintainer's decision, and do not be upset or abusive if your submission is not used. 18 | 19 | ## Viability 20 | 21 | When requesting or submitting new features, first consider whether it might be useful to others. Open 22 | source projects are used by many developers, who may have entirely different needs to your own. Think about 23 | whether or not your feature is likely to be used by other users of the project. 24 | 25 | ## Procedure 26 | 27 | Before filing an issue: 28 | 29 | - Attempt to replicate the problem, to ensure that it wasn't a coincidental incident. 30 | - Check to make sure your feature suggestion isn't already present within the project. 31 | - Check the pull requests tab to ensure that the bug doesn't have a fix in progress. 32 | - Check the pull requests tab to ensure that the feature isn't already in progress. 33 | 34 | Before submitting a pull request: 35 | 36 | - Check the codebase to ensure that your feature doesn't already exist. 37 | - Check the pull requests to ensure that another person hasn't already submitted the feature or fix. 38 | 39 | ## Requirements 40 | 41 | If the project maintainer has any additional requirements, you will find them listed here. 42 | 43 | - **[PSR-2 Coding Standard](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md)** - The easiest way to apply the conventions is to install [PHP Code Sniffer](https://pear.php.net/package/PHP_CodeSniffer). 44 | 45 | - **Add tests!** - Your patch won't be accepted if it doesn't have tests. 46 | 47 | - **Document any change in behaviour** - Make sure the `README.md` and any other relevant documentation are kept up-to-date. 48 | 49 | - **Consider our release cycle** - We try to follow [SemVer v2.0.0](https://semver.org/). Randomly breaking public APIs is not an option. 50 | 51 | - **One pull request per feature** - If you want to do more than one thing, send multiple pull requests. 52 | 53 | - **Send coherent history** - Make sure each individual commit in your pull request is meaningful. If you had to make multiple intermediate commits while developing, please [squash them](https://www.git-scm.com/book/en/v2/Git-Tools-Rewriting-History#Changing-Multiple-Commit-Messages) before submitting. 54 | 55 | **Happy coding**! 56 | -------------------------------------------------------------------------------- /src/BillingoApiV3Wrapper.php: -------------------------------------------------------------------------------- 1 | createResponse('cancel', [$id], true); 55 | 56 | return $this; 57 | } 58 | 59 | /** 60 | * Check valid tax number 61 | * 62 | * @param string $tax_number 63 | * 64 | * @return self 65 | */ 66 | public function checkTaxNumber(string $taxNumber): self 67 | { 68 | $this->createResponse('checkTaxNumber', [$taxNumber]); 69 | 70 | return $this; 71 | } 72 | 73 | /** 74 | * Call create$apiName method 75 | * 76 | * @throws Exception (methodExists) 77 | * @return self 78 | */ 79 | public function create(): self 80 | { 81 | $this->createResponse('create', [$this->model], true); 82 | 83 | return $this; 84 | } 85 | 86 | /** 87 | * Call createReceipt method 88 | * 89 | * @throws Exception (methodExists) 90 | * @return self 91 | */ 92 | public function createReceipt(): self 93 | { 94 | $this->createResponse('createReceipt', [$this->model], true); 95 | 96 | return $this; 97 | } 98 | 99 | /** 100 | * Create invoice from proforma 101 | * 102 | * @param integer $id 103 | * 104 | * @return self 105 | */ 106 | public function createInvoiceFromProforma(int $id): self 107 | { 108 | $this->createResponse('createDocumentFromProforma', [$id]); 109 | 110 | return $this; 111 | } 112 | 113 | /** 114 | * Create invoice from draft 115 | * 116 | * @param integer $id 117 | * 118 | * @return self 119 | */ 120 | public function createInvoiceFromDraft(int $id): self 121 | { 122 | $this->createResponse('createDocumentFromDraft', [$id]); 123 | 124 | return $this; 125 | } 126 | 127 | /** 128 | * Create receipt from draft 129 | * 130 | * @param integer $id 131 | * 132 | * @return self 133 | */ 134 | public function createReceiptFromDraft(int $id): self 135 | { 136 | $this->createResponse('createReceiptFromDraft', [$id]); 137 | 138 | return $this; 139 | } 140 | 141 | /** 142 | * Delete delete$apiName method 143 | * 144 | * @param integer $id 145 | * 146 | * @return self 147 | */ 148 | public function delete(int $id): self 149 | { 150 | $this->createResponse('delete', [$id], true); 151 | 152 | return $this; 153 | } 154 | 155 | /** 156 | * Delete payment 157 | * 158 | * @param integer $id 159 | * 160 | * @return self 161 | */ 162 | public function deletePayment(int $id): self 163 | { 164 | $this->createResponse('deletePayment', [$id]); 165 | 166 | return $this; 167 | } 168 | 169 | /** 170 | * Download document 171 | * 172 | * @param integer $id 173 | * 174 | * @return string 175 | */ 176 | public function downloadInvoice(int $id, string $path = null, string $extension = null): self 177 | { 178 | $filename = $id . ($extension ?? $this->extension); 179 | $this->createResponse('download', [$id], true); 180 | 181 | Storage::put( 182 | ($path ?? $this->downloadPath) . $filename, 183 | $this->response[0] 184 | ); 185 | 186 | $this->response = [ 187 | 'path' => ($path ?? $this->downloadPath) . $filename, 188 | 'status' => $this->withHttpInfo ? $this->response[1] : null, 189 | ]; 190 | 191 | return $this; 192 | } 193 | 194 | /** 195 | * Get get$apiName method 196 | * 197 | * @param integer $id 198 | * 199 | * @return self 200 | */ 201 | public function get(int $id): self 202 | { 203 | $this->createResponse('get', [$id], true); 204 | 205 | return $this; 206 | } 207 | 208 | /** 209 | * Get invoice public url 210 | * 211 | * @param integer $id 212 | * 213 | * @return self 214 | */ 215 | public function getPublicUrl(int $id): self 216 | { 217 | $this->createResponse('getPublicUrl', [$id]); 218 | 219 | return $this; 220 | } 221 | 222 | /** 223 | * Call list$apiName method 224 | * 225 | * @param array $conditions 226 | * 227 | * @return self 228 | */ 229 | public function list(array $conditions): self 230 | { 231 | $this->createResponse( 232 | 'list', 233 | array_diff_key($conditions, array_diff_key($conditions, array_flip($this->allowed_parameters))), 234 | true 235 | ); 236 | 237 | return $this; 238 | } 239 | 240 | /** 241 | * Call get$apiName method 242 | * 243 | * @param integer $id 244 | * 245 | * @return self 246 | */ 247 | public function update(int $id): self 248 | { 249 | $this->createResponse('update', [$this->model, $id], true); 250 | 251 | return $this; 252 | } 253 | 254 | /** 255 | * Send invoice in email 256 | * 257 | * @param integer $id 258 | * 259 | * @return self 260 | */ 261 | public function sendInvoice(int $id): self 262 | { 263 | $this->createResponse('send', [$id], true); 264 | 265 | return $this; 266 | } 267 | 268 | /** 269 | * Send invoice in email 270 | * 271 | * @param integer $id 272 | * 273 | * @return self 274 | */ 275 | public function getOnlineSzamlaStatus(int $id): self 276 | { 277 | $this->createResponse('getOnlineSzamlaStatus', [$id]); 278 | 279 | return $this; 280 | } 281 | } 282 | -------------------------------------------------------------------------------- /src/Services/BillingoApiV3Service.php: -------------------------------------------------------------------------------- 1 | config = SwaggerConfig::getDefaultConfiguration() 80 | ->setApiKey('X-API-KEY', $this->isLaravel() ? config('billingo-api-v3-wrapper.api_key') : $apiKey); 81 | } 82 | 83 | /** 84 | * Check that the environment is Laravel 85 | * 86 | * @return boolean 87 | */ 88 | protected function isLaravel(): bool 89 | { 90 | return \function_exists('app') && app() instanceof \Illuminate\Foundation\Application; 91 | } 92 | 93 | /** 94 | * Check if given class is exists. 95 | * 96 | * @param string $className 97 | * 98 | * @throws Exception 99 | * @return void 100 | */ 101 | protected function classExists(string $className): void 102 | { 103 | if (!class_exists($className)) { 104 | throw new Exception($className . ' class does not exists!'); 105 | } 106 | } 107 | 108 | /** 109 | * Create response 110 | * 111 | * @param string $methodName 112 | * @param array $params 113 | * @param bool $methodSuffix 114 | * @param bool $customResponse 115 | * 116 | * @return void 117 | */ 118 | protected function createResponse(string $methodName, array $params, bool $methodSuffix = false, bool $customResponse = false) 119 | { 120 | try { 121 | $this->response = 122 | $customResponse ?: \call_user_func_array( 123 | array( 124 | $this->api, 125 | $this->setMethodName($methodName, $methodSuffix) 126 | ), 127 | $params 128 | ); 129 | } catch (\Throwable $th) { 130 | $message = $this->error($th->getMessage())->response(); 131 | 132 | throw new BillingoApiException($message); 133 | } 134 | 135 | $this->setResponse(); 136 | } 137 | 138 | /** 139 | * Check if data is present 140 | * 141 | * @param array $data 142 | * 143 | * @throws Exception 144 | * @return void 145 | */ 146 | protected function isData(array $data = null): void 147 | { 148 | if (is_null($this->data) && is_null($data)) { 149 | throw new Exception('Data not set!'); 150 | } 151 | } 152 | 153 | /** 154 | * Check if given method exists in given class (api instance) 155 | * 156 | * @param string $methodName 157 | * 158 | * @throws Exception 159 | * @return void 160 | */ 161 | protected function methodExists(string $methodName): void 162 | { 163 | if (!method_exists($this->api, $methodName)) { 164 | throw new Exception($methodName . ' method does not exsits!'); 165 | } 166 | } 167 | 168 | /** 169 | * Set callable method name 170 | * 171 | * @param string $name 172 | * @param boolean $suffix 173 | * 174 | * @return string 175 | */ 176 | protected function setMethodName(string $name, bool $suffix = false): string 177 | { 178 | $methodName = $name; 179 | 180 | if ($suffix) { 181 | $methodName .= $this->apiName; 182 | 183 | if ($this->withHttpInfo) { 184 | $methodName .= 'withHttpInfo'; 185 | } 186 | } 187 | 188 | $this->methodExists($methodName); 189 | 190 | return $methodName; 191 | } 192 | 193 | /** 194 | * Set response 195 | * 196 | * @return void 197 | */ 198 | protected function setResponse(): void 199 | { 200 | if (\is_object($this->response)) { 201 | $this->response = Arr::collapse($this->toArray((array)$this->response)); 202 | } 203 | 204 | if (\is_array($this->response)) { 205 | $this->response = $this->toArray($this->response); 206 | } 207 | 208 | $this->response = (array)$this->response; 209 | } 210 | 211 | /** 212 | * Mapping array and if it's contains object convert it to array because swagger return mixed arrays and objects with protected and private properties 213 | * 214 | * @param array $item 215 | * 216 | * @return array 217 | */ 218 | protected function toArray(array $item): array 219 | { 220 | return \array_map(function ($item) { 221 | if (\is_object($item)) { 222 | if ($item instanceof \DateTime) { 223 | return $item->format('Y-m-d'); 224 | } 225 | return Arr::collapse((array)$item); 226 | } 227 | if (\is_array($item)) { 228 | return $this->toArray($item); 229 | } 230 | return $item; 231 | }, $item); 232 | } 233 | 234 | /** 235 | * Make a new api instance 236 | * 237 | * @param string $name 238 | * 239 | * @throws Exception (classExists) 240 | * @return self 241 | */ 242 | public function api(string $name): self 243 | { 244 | $className = '\\Swagger\\Client\\Api\\' . $name . 'Api'; 245 | 246 | $this->classExists($className); 247 | 248 | $this->apiName = $name; 249 | 250 | $this->api = new $className( 251 | new \GuzzleHttp\Client(), 252 | $this->config 253 | ); 254 | 255 | return $this; 256 | } 257 | 258 | /** 259 | * Get the underlaying Swagger API Object 260 | * 261 | * @return Swagger\Client\Api\$Object 262 | */ 263 | public function getApi() 264 | { 265 | return $this->api; 266 | } 267 | 268 | /** 269 | * Get id from response 270 | * 271 | * @return integer 272 | */ 273 | public function getId(): ?int 274 | { 275 | return $this->response['id']; 276 | } 277 | 278 | /** 279 | * Get response 280 | * 281 | * @return Array 282 | */ 283 | public function getResponse(): array 284 | { 285 | return $this->response; 286 | } 287 | 288 | /** 289 | * Setup data for model 290 | * 291 | * @param array $data 292 | * 293 | * @return self 294 | */ 295 | public function make(array $data): self 296 | { 297 | $this->data = $data; 298 | 299 | return $this; 300 | } 301 | 302 | /** 303 | * Make a new model instance 304 | * 305 | * @param string $name 306 | * @param array $data 307 | * 308 | * @return self 309 | */ 310 | public function model(string $name, array $data = null): self 311 | { 312 | $this->modelClassName = '\\Swagger\\Client\\Model\\' . $name; 313 | 314 | if (!is_null($data)) { 315 | $this->make($data); 316 | } 317 | 318 | $this->classExists($this->modelClassName); 319 | $this->isData(); 320 | 321 | $this->model = new $this->modelClassName($this->data); 322 | 323 | return $this; 324 | } 325 | 326 | /** 327 | * Set withHttpInfo 328 | * 329 | * @return void 330 | */ 331 | public function withHttpInfo() 332 | { 333 | $this->withHttpInfo = true; 334 | 335 | return $this; 336 | } 337 | } 338 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Latest Changelog 2 | 3 | v2.2 -> v2.3.1 4 | Drop support: Laravel 8, 9, 10 and PHP 8.1 5 | Add support: Laravel 12 and PHP 8.2 6 | 7 | # Billingo API V3 Laravel and PHP Wrapper 8 | 9 | This is a simple Laravel (PHP) wrapper for Billingo (billingo.hu) API V3 SwaggerHUB PHP SDK. 10 | 11 | Compatible with: Laravel 11.x and 12.x or PHP 8.2<= 12 | 13 | **You can use the wrapper easily with all type of PHP projects (not just Laravel) from 1.0.0 version without changing except downloadInvoice method.** 14 | 15 | # Installation 16 | 17 | You can install the package via composer or just download it: 18 | 19 | ```bash 20 | composer require deviddev/billingo-api-v3-wrapper 21 | ``` 22 | 23 | # Usage 24 | 25 | ### Laravel 26 | 27 | Publish config file: 28 | 29 | `php artisan vendor:publish --tag="billingo-config"` 30 | 31 | **First set up your Billingo API V3 key in ./config/billingo-api-v3-wrapper.php config file.** 32 | 33 | Import wrapper with facade: 34 | 35 | ```php 36 | use BillingoApiV3Wrapper as BillingoApi; 37 | ``` 38 | 39 | ### PHP 40 | 41 | Import wrapper: 42 | 43 | ```php 44 | use Deviddev\BillingoApiV3Wrapper\BillingoApiV3Wrapper as BillingoApi; 45 | ``` 46 | 47 | You must add your api key to BillingoApi object constructor: 48 | 49 | ```php 50 | $billingoApi = new BillingoApi('YOUR_API_KEY_HERE'); 51 | ``` 52 | 53 | # Available methods 54 | 55 | Make an api instance (eg.: BankAccount, Currency, Document, DocumentBlock, DocumentExport, Organization, Partner, Product, Util): 56 | 57 | ```php 58 | api(string $apiName); 59 | ``` 60 | 61 | Add some data to model: 62 | 63 | ```php 64 | make(array $data); 65 | ``` 66 | 67 | Make a model instance (eg: Address, BankAccount, Currency, Document, etc... - see in ./vendor/deviddev/billingo-api-v3-php-sdk/lib/model): 68 | 69 | ```php 70 | model(string $modelName, array $data = null); 71 | ``` 72 | 73 | (if you don't want use **make()** method simply add necessary data as second parameter) 74 | 75 | With http info (get http info (headers, response code, etc...)): 76 | 77 | ```php 78 | withHttpInfo(); 79 | ``` 80 | 81 | Get invoice, partner, product(call api class method with model instance): 82 | 83 | ```php 84 | get(int $id); 85 | ``` 86 | 87 | Delete partner, product (call api class method with model instance): 88 | 89 | ```php 90 | delete(int $id); 91 | ``` 92 | 93 | Delete payment (call api class method with model instance): 94 | 95 | ```php 96 | deletePayment(int $id); 97 | ``` 98 | 99 | Create model (call api class method with model instance): 100 | 101 | ```php 102 | create(); 103 | ``` 104 | 105 | Create Receipt on Document model: 106 | 107 | ```php 108 | createReceipt(); 109 | ``` 110 | 111 | Update model (call api class method with model instance and model id): 112 | 113 | ```php 114 | update(int $id); 115 | ``` 116 | 117 | Cancel invoice: 118 | 119 | ```php 120 | cancelInvoice(int $invoiceId); 121 | ``` 122 | 123 | Create invoice from proforma invoice: 124 | 125 | ```php 126 | createInvoiceFromProforma(int $invoiceId); 127 | ``` 128 | 129 | Create invoice from draft invoice: 130 | 131 | ```php 132 | createInvoiceFromDraft(int $invoiceId); 133 | ``` 134 | 135 | Create receipt from draft invoice: 136 | 137 | ```php 138 | createReceiptFromDraft(int $invoiceId); 139 | ``` 140 | 141 | Check tax number: 142 | 143 | ```php 144 | checkTaxNumber(string $taxNumber); 145 | ``` 146 | 147 | List model (call api class method with model instance): 148 | 149 | ```php 150 | list(array $conditions); 151 | ``` 152 | 153 | \*\*\* All conditions is optional! 154 | 155 | Download invoice to server: 156 | 157 | ```php 158 | downloadInvoice(int $invoiceId, string $path = null, string $extension = null); 159 | ``` 160 | 161 | Send invoice in email: 162 | 163 | ```php 164 | sendInvoice(int $invoiceId); 165 | ``` 166 | 167 | Get invoice Online Számla status: 168 | 169 | ```php 170 | getOnlineSzamlaStatus(int $invoiceId); 171 | ``` 172 | 173 | Get invoice public url response: 174 | 175 | ```php 176 | getPublicUrl(int $id); 177 | ``` 178 | 179 | Get Billingo API response: 180 | 181 | ```php 182 | getResponse(); 183 | ``` 184 | 185 | Get Billingo API response id (eg.: partner id, invoice id, etc.): 186 | 187 | ```php 188 | getId(); 189 | ``` 190 | 191 | ### Method chaining: 192 | 193 | All pulic methods are chainable, except **getResponse()** and **getId()** methods. 194 | If you don't add some data to `model(string $modelName, array $data = null)` method second `array $data = null` parameter, you **MUST** use `make(array $data)` method **BEFORE** `model()` method, see in examples. 195 | The `withHttpInfo()` method **MUST** be called **IMMEDIATELY AFTER** the `api()`, `make()` or `model()` methods. 196 | 197 | # Examples 198 | 199 | ### Create partner example: 200 | 201 | Partner array: 202 | 203 | ```php 204 | $partner = [ 205 | 'name' => 'Test Company', 206 | 'address' => [ 207 | 'country_code' => 'HU', 208 | 'post_code' => '1010', 209 | 'city' => 'Budapest', 210 | 'address' => 'Nagy Lajos 12.', 211 | ], 212 | 'emails' => ['test@company.hu'], 213 | 'taxcode' => '', 214 | ]; 215 | ``` 216 | 217 | #### Laravel 218 | 219 | Create partner and get response: 220 | 221 | ```php 222 | BillingoApi::api('Partner')->model('PartnerUpsert', $partner)->create()->getResponse(); 223 | ``` 224 | 225 | OR 226 | 227 | Create partner with make and get response: 228 | 229 | ```php 230 | BillingoApi::api('Partner')->make($partner)->model('PartnerUpsert')->create()->getResponse(); 231 | ``` 232 | 233 | OR 234 | 235 | Create partner and get partner id: 236 | 237 | ```php 238 | BillingoApi::api('Partner')->model('PartnerUpsert', $partner)->create()->getId(); 239 | ``` 240 | 241 | OR 242 | 243 | Create partner with make and get partner id: 244 | 245 | ```php 246 | BillingoApi::api('Partner')->make($partner)->model('PartnerUpsert')->create()->getId(); 247 | ``` 248 | 249 | #### PHP 250 | 251 | Create partner and get response: 252 | 253 | ```php 254 | $billingoApi->api('Partner')->model('PartnerUpsert', $partner)->create()->getResponse(); 255 | ``` 256 | 257 | OR 258 | 259 | Create partner with make and get response: 260 | 261 | ```php 262 | $billingoApi->api('Partner')->make($partner)->model('PartnerUpsert')->create()->getResponse(); 263 | ``` 264 | 265 | OR 266 | 267 | Create partner and get partner id: 268 | 269 | ```php 270 | $billingoApi->api('Partner')->model('PartnerUpsert', $partner)->create()->getId(); 271 | ``` 272 | 273 | OR 274 | 275 | Create partner with make and get partner id: 276 | 277 | ```php 278 | $billingoApi->api('Partner')->make($partner)->model('PartnerUpsert')->create()->getId(); 279 | ``` 280 | 281 | ### Update partner example: 282 | 283 | Partner array: 284 | 285 | ```php 286 | $partner = [ 287 | 'name' => 'Test Company updated', 288 | 'address' => [ 289 | 'country_code' => 'HU', 290 | 'post_code' => '1010', 291 | 'city' => 'Budapest', 292 | 'address' => 'Nagy Lajos 12.', 293 | ], 294 | 'emails' => ['test@company.hu'], 295 | 'taxcode' => '', 296 | ]; 297 | ``` 298 | 299 | #### Laravel 300 | 301 | Update partner and get response: 302 | 303 | ```php 304 | BillingoApi::api('Partner')->model('Partner', $partner)->update('BILLINGO_PARTNER_ID')->getResponse(); 305 | ``` 306 | 307 | OR 308 | 309 | Update partner with make and get response: 310 | 311 | ```php 312 | BillingoApi::api('Partner')->make($partner)->model('Partner')->update('BILLINGO_PARTNER_ID')->getResponse(); 313 | ``` 314 | 315 | OR 316 | 317 | Update partner and get partner id: 318 | 319 | ```php 320 | BillingoApi::api('Partner')->model('Partner', $partner)->update('BILLINGO_PARTNER_ID')->getId(); 321 | ``` 322 | 323 | OR 324 | 325 | Update partner with make and get partner id: 326 | 327 | ```php 328 | BillingoApi::api('Partner')->make($partner)->model('Partner')->update('BILLINGO_PARTNER_ID')->getId(); 329 | ``` 330 | 331 | #### PHP 332 | 333 | Update partner and get response: 334 | 335 | ```php 336 | $billingoApi->api('Partner')->model('Partner', $partner)->update('BILLINGO_PARTNER_ID')->getResponse(); 337 | ``` 338 | 339 | OR 340 | 341 | Update partner with make and get response: 342 | 343 | ```php 344 | $billingoApi->api('Partner')->make($partner)->model('Partner')->update('BILLINGO_PARTNER_ID')->getResponse(); 345 | ``` 346 | 347 | OR 348 | 349 | Update partner and get partner id: 350 | 351 | ```php 352 | $billingoApi->api('Partner')->model('Partner', $partner)->update('BILLINGO_PARTNER_ID')->getId(); 353 | ``` 354 | 355 | OR 356 | 357 | Update partner with make and get partner id: 358 | 359 | ```php 360 | $billingoApi->api('Partner')->make($partner)->model('Partner')->update('BILLINGO_PARTNER_ID')->getId(); 361 | ``` 362 | 363 | ### Create invoice example: 364 | 365 | Invoice array: 366 | 367 | ```php 368 | $invoice = [ 369 | 'partner_id' => BILLINGO_PARTNER_ID, // REQUIRED int 370 | 'block_id' => YOUR_BILLINGO_BLOCK_ID, // REQUIRED int 371 | 'bank_account_id' => YOUR_BILLINGO_BANK_ACCOUNT_ID, // int 372 | 'type' => 'invoice', // REQUIRED 373 | 'fulfillment_date' => Carbon::now('Europe/Budapest')->format('Y-m-d'), // REQUIRED, set up other time zone if it's necessaray 374 | 'due_date' => Carbon::now('Europe/Budapest')->format('Y-m-d'), // REQUIRED, set up other time zone if it's necessaray 375 | 'payment_method' => 'online_bankcard', // REQUIRED, see other types in billingo documentation 376 | 'language' => 'hu', // REQUIRED, see others in billingo documentation 377 | 'currency' => 'HUF', // REQUIRED, see others in billingo documentation 378 | 'conversion_rate' => 1, // see others in billingo documentation 379 | 'electronic' => false, // see others in billingo documentation 380 | 'paid' => false, // see others in billingo documentation 381 | 'items' => [ 382 | [ 383 | 'name' => 'Laptop', // REQUIRED 384 | 'unit_price' => '100000', // REQUIRED 385 | 'unit_price_type' => 'gross', // REQUIRED 386 | 'quantity' => 2, // REQUIRED int 387 | 'unit' => 'db', // REQUIRED 388 | 'vat' => '27%', // REQUIRED 389 | 'comment' => 'some comment here...', 390 | ], 391 | ], 392 | 'comment' => 'some comment here...', 393 | 'settings' => [ 394 | 'mediated_servicíe' => false, 395 | 'without_financial_fulfillment' => false, 396 | 'online_payment' => '', 397 | 'round' => 'five', 398 | 'place_id' => 0, 399 | ], 400 | ]; 401 | ``` 402 | 403 | #### Laravel 404 | 405 | Create invoice and get response: 406 | 407 | ```php 408 | BillingoApi::api('Document')->model('DocumentInsert', $invoice)->create()->getResponse(); 409 | ``` 410 | 411 | OR 412 | 413 | Create invoice with make and get response: 414 | 415 | ```php 416 | BillingoApi::api('Document')->make($invoice)->model('DocumentInsert')->create()->getResponse(); 417 | ``` 418 | 419 | OR 420 | 421 | Create invoice and get invoice id: 422 | 423 | ```php 424 | BillingoApi::api('Document')->model('DocumentInsert', $invoice)->create()->getId(); 425 | ``` 426 | 427 | OR 428 | 429 | Create invoice with make and get invoice id: 430 | 431 | ```php 432 | BillingoApi::api('Document')->make($invoice)->model('DocumentInsert')->create()->getId(); 433 | ``` 434 | 435 | #### PHP 436 | 437 | Create invoice and get response: 438 | 439 | ```php 440 | $billingo->api('Document')->model('DocumentInsert', $invoice)->create()->getResponse(); 441 | ``` 442 | 443 | OR 444 | 445 | Create invoice with make and get response: 446 | 447 | ```php 448 | $billingo->api('Document')->make($invoice)->model('DocumentInsert')->create()->getResponse(); 449 | ``` 450 | 451 | OR 452 | 453 | Create invoice and get invoice id: 454 | 455 | ```php 456 | $billingo->api('Document')->model('DocumentInsert', $invoice)->create()->getId(); 457 | ``` 458 | 459 | OR 460 | 461 | Create invoice with make and get invoice id: 462 | 463 | ```php 464 | $billingo->api('Document')->make($invoice)->model('DocumentInsert')->create()->getId(); 465 | ``` 466 | 467 | ### Create receipt example: 468 | 469 | Receipt array: 470 | 471 | ```php 472 | $receipt = [ 473 | 'partner_id' => BILLINGO_PARTNER_ID, // REQUIRED int 474 | 'block_id' => YOUR_BILLINGO_BLOCK_ID, // REQUIRED int 475 | 'type' => 'receipt', // REQUIRED 476 | 'payment_method' => 'online_bankcard', // REQUIRED, see other types in billingo documentation 477 | 'currency' => 'HUF', // REQUIRED, see others in billingo documentation 478 | 'conversion_rate' => 1, // see others in billingo documentation 479 | 'electronic' => false, // see others in billingo documentation 480 | 'items' => [ 481 | [ 482 | 'name' => 'Laptop', // REQUIRED 483 | 'unit_price' => '100000', // REQUIRED 484 | 'vat' => '27%', // REQUIRED 485 | ], 486 | [ 487 | 'product_id' => YOUR_PRODUCT_ID, // REQUIRED 488 | ], 489 | ], 490 | ]; 491 | ``` 492 | 493 | #### Laravel 494 | 495 | Create receipt and get response: 496 | 497 | ```php 498 | BillingoApi::api('Document')->model('ReceiptInsert', $receipt)->create()->getResponse(); 499 | ``` 500 | 501 | OR 502 | 503 | Create receipt with make and get response: 504 | 505 | ```php 506 | BillingoApi::api('Document')->make($receipt)->model('ReceiptInsert')->create()->getResponse(); 507 | ``` 508 | 509 | OR 510 | 511 | Create receipt and get receipt id: 512 | 513 | ```php 514 | BillingoApi::api('Document')->model('ReceiptInsert', $receipt)->create()->getId(); 515 | ``` 516 | 517 | OR 518 | 519 | Create receipt with make and get receipt id: 520 | 521 | ```php 522 | BillingoApi::api('Document')->make($receipt)->model('ReceiptInsert')->create()->getId(); 523 | ``` 524 | 525 | #### PHP 526 | 527 | Create receipt and get response: 528 | 529 | ```php 530 | $billingo->api('Document')->model('ReceiptInsert', $receipt)->create()->getResponse(); 531 | ``` 532 | 533 | OR 534 | 535 | Create receipt with make and get response: 536 | 537 | ```php 538 | $billingo->api('Document')->make($receipt)->model('ReceiptInsert')->create()->getResponse(); 539 | ``` 540 | 541 | OR 542 | 543 | Create receipt and get receipt id: 544 | 545 | ```php 546 | $billingo->api('Document')->model('ReceiptInsert', $receipt)->create()->getId(); 547 | ``` 548 | 549 | OR 550 | 551 | Create receipt with make and get receipt id: 552 | 553 | ```php 554 | $billingo->api('Document')->make($receipt)->model('ReceiptInsert')->create()->getId(); 555 | ``` 556 | 557 | ### List invoices, partners, blocks, etc example: 558 | 559 | #### Laravel 560 | 561 | List invoices: 562 | 563 | ```php 564 | BillingoApi::api('Document')->list([ 565 | 'page' => 1, 566 | 'per_page' => 25, 567 | 'block_id' => 42432, 568 | 'partner_id' => 13123123, 569 | 'payment_method' => 'cash', 570 | 'payment_status' => 'paid', 571 | 'start_date' => '2020-05-10', 572 | 'end_date' => '2020-05-15', 573 | 'start_number' => '1', 574 | 'end_number' => '10', 575 | 'start_year' => 2020, 576 | 'end_year' => 2020, 577 | 'type' => 'invoice' 578 | ])->getResponse(); 579 | ``` 580 | 581 | List partners: 582 | 583 | ```php 584 | BillingoApi::api('Partner')->list([ 585 | 'page' => 1, 586 | 'per_page' => 5 587 | ])->getResponse(); 588 | ``` 589 | 590 | List partners with query string: 591 | 592 | ```php 593 | BillingoApi::api('Partner')->list([ 594 | 'page' => 1, 595 | 'per_page' => 5, 596 | 'query' => 'Teszt partner' 597 | ])->getResponse(); 598 | ``` 599 | 600 | List blocks: 601 | 602 | ```php 603 | BillingoApi::api('DocumentBlock')->list([ 604 | 'page' => 1, 605 | 'per_page' => 5 606 | ])->getResponse(); 607 | ``` 608 | 609 | List banks accounts: 610 | 611 | ```php 612 | BillingoApi::api('BankAccount')->list([ 613 | 'page' => 1, 614 | 'per_page' => 5 615 | ])->getResponse(); 616 | ``` 617 | 618 | List products: 619 | 620 | ```php 621 | BillingoApi::api('Products')->list([ 622 | 'page' => 1, 623 | 'per_page' => 5 624 | ])->getResponse(); 625 | ``` 626 | 627 | #### PHP 628 | 629 | List invoices: 630 | 631 | ```php 632 | $billingoApi->api('Document')->list([ 633 | 'page' => 1, 634 | 'per_page' => 25, 635 | 'block_id' => 42432, 636 | 'partner_id' => 13123123, 637 | 'payment_method' => 'cash', 638 | 'payment_status' => 'paid', 639 | 'start_date' => '2020-05-10', 640 | 'end_date' => '2020-05-15', 641 | 'start_number' => '1', 642 | 'end_number' => '10', 643 | 'start_year' => 2020, 644 | 'end_year' => 2020, 645 | 'type' => 'invoice' 646 | ])->getResponse(); 647 | ``` 648 | 649 | List partners: 650 | 651 | ```php 652 | $billingoApi->api('Partner')->list([ 653 | 'page' => 1, 654 | 'per_page' => 5 655 | ])->getResponse(); 656 | ``` 657 | 658 | List partners with query string: 659 | 660 | ```php 661 | $billingoApi->api('Partner')->list([ 662 | 'page' => 1, 663 | 'per_page' => 5, 664 | 'query' => 'Teszt partner' 665 | ])->getResponse(); 666 | ``` 667 | 668 | List blocks: 669 | 670 | ```php 671 | $billingoApi->api('DocumentBlock')->list([ 672 | 'page' => 1, 673 | 'per_page' => 5 674 | ])->getResponse(); 675 | ``` 676 | 677 | List banks accounts: 678 | 679 | ```php 680 | $billingoApi->api('BankAccount')->list([ 681 | 'page' => 1, 682 | 'per_page' => 5 683 | ])->getResponse(); 684 | ``` 685 | 686 | List products: 687 | 688 | ```php 689 | $billingoApi->api('Products')->list([ 690 | 'page' => 1, 691 | 'per_page' => 5 692 | ])->getResponse(); 693 | ``` 694 | 695 | ### Download invoice example: 696 | 697 | #### Laravel 698 | 699 | Default path is: `./storage/app/invoices` 700 | 701 | Default extension is: `.pdf` 702 | 703 | File name is invoice id. 704 | 705 | Return the path in the response, eg.: 706 | 707 | ```php 708 | path: "invoices/11246867.pdf" 709 | ``` 710 | 711 | Download invoice: 712 | 713 | ```php 714 | BillingoApi::api('Document')->downloadInvoice(INVOICE_ID)->getResponse(); 715 | ``` 716 | 717 | OR 718 | 719 | Download to specified path and extension: 720 | 721 | ```php 722 | BillingoApi::api('Document')->downloadInvoice(INVOICE_ID, 'PATH', 'EXTENSION')->getResponse(); 723 | ``` 724 | 725 | #### PHP 726 | 727 | Come in version 1.1. 728 | 729 | ### Send invoice in e-mail example: 730 | 731 | Return the e-mails array where to send the invoce, eg.: 732 | 733 | ```php 734 | emails: [ 735 | "kiss@kft.hu" 736 | ] 737 | ``` 738 | 739 | #### Laravel 740 | 741 | Send invoice: 742 | 743 | ```php 744 | BillingoApi::api('Document')->sendInvoice(INVOICE_ID)->getResponse(); 745 | ``` 746 | 747 | #### PHP 748 | 749 | Send invoice: 750 | 751 | ```php 752 | $billingoApi->api('Document')->sendInvoice(INVOICE_ID)->getResponse(); 753 | ``` 754 | 755 | ### Get invoice public url example: 756 | 757 | Return the public url array, eg.: 758 | 759 | ```php 760 | [ 761 | public_url: "https://api.billingo.hu/document-access/K3drE0Gvb2eRwQNYlypfasdOlJADB4Y" 762 | ] 763 | ``` 764 | 765 | #### Laravel 766 | 767 | Get invoice public url: 768 | 769 | ```php 770 | BillingoApi::api('Document')->getPublicUrl(INVOICE_ID)->getResponse(); 771 | ``` 772 | 773 | #### PHP 774 | 775 | Get invoice public url: 776 | 777 | ```php 778 | $billingoApi->api('Document')->getPublicUrl(INVOICE_ID)->getResponse(); 779 | ``` 780 | 781 | ### Cancel invoice example: 782 | 783 | #### Laravel 784 | 785 | Cancel invoice: 786 | 787 | ```php 788 | BillingoApi::api('Document')->cancelInvoice(INVOICE_ID)->getResponse(); 789 | ``` 790 | 791 | #### PHP 792 | 793 | Cancel invoice: 794 | 795 | ```php 796 | $billingoApi->api('Document')->cancelInvoice(INVOICE_ID)->getResponse(); 797 | ``` 798 | 799 | ### Create invoice from proforma invoice example: 800 | 801 | #### Laravel 802 | 803 | Create invoice from proforma invoice: 804 | 805 | ```php 806 | BillingoApi::api('Document')->createInvoiceFromProforma(INVOICE_ID)->getResponse(); 807 | ``` 808 | 809 | #### PHP 810 | 811 | Create invoice from proforma invoice: 812 | 813 | ```php 814 | $billingoApi->api('Document')->createInvoiceFromProforma(INVOICE_ID)->getResponse(); 815 | ``` 816 | 817 | #### Laravel 818 | 819 | Create invoice from draft invoice: 820 | 821 | ```php 822 | BillingoApi::api('Document')->createInvoiceFromDraft(INVOICE_ID)->getResponse(); 823 | ``` 824 | 825 | #### PHP 826 | 827 | Create invoice from draft invoice: 828 | 829 | ```php 830 | $billingoApi->api('Document')->createInvoiceFromDraft(INVOICE_ID)->getResponse(); 831 | ``` 832 | 833 | #### Laravel 834 | 835 | Create receipt from draft invoice: 836 | 837 | ```php 838 | BillingoApi::api('Document')->createReceiptFromDraft(INVOICE_ID)->getResponse(); 839 | ``` 840 | 841 | #### PHP 842 | 843 | Create receipt from draft invoice: 844 | 845 | ```php 846 | $billingoApi->api('Document')->createReceiptFromDraft(INVOICE_ID)->getResponse(); 847 | ``` 848 | 849 | ### Check tax number example: 850 | 851 | First set up your NAV connection in your billingo account, because it always return "Invalid tax number!" 852 | 853 | #### Laravel 854 | 855 | Check tax number: 856 | 857 | ```php 858 | BillingoApi::api('Util')->checkTaxNumber('tax_number')->getResponse(); 859 | ``` 860 | 861 | #### PHP 862 | 863 | Check tax number: 864 | 865 | ```php 866 | $billingoApi->api('Util')->checkTaxNumber('tax_number')->getResponse(); 867 | ``` 868 | 869 | ### Get invoice, product, partner example: 870 | 871 | #### Laravel 872 | 873 | Get invoice: 874 | 875 | ```php 876 | BillingoApi::api('Document')->get(INVOICE_ID)->getResponse(); 877 | ``` 878 | 879 | Get partner: 880 | 881 | ```php 882 | BillingoApi::api('Partner')->get(PARTNER_ID)->getResponse(); 883 | ``` 884 | 885 | Get product: 886 | 887 | ```php 888 | BillingoApi::api('Product')->get(PRODUCT_ID)->getResponse(); 889 | ``` 890 | 891 | #### PHP 892 | 893 | Get invoice: 894 | 895 | ```php 896 | $billingoApi->api('Document')->get(INVOICE_ID)->getResponse(); 897 | ``` 898 | 899 | Get partner: 900 | 901 | ```php 902 | $billingoApi->api('Partner')->get(PARTNER_ID)->getResponse(); 903 | ``` 904 | 905 | Get product: 906 | 907 | ```php 908 | $billingoApi->api('Product')->get(PRODUCT_ID)->getResponse(); 909 | ``` 910 | 911 | ### Delete product, partner example: 912 | 913 | #### Laravel 914 | 915 | Delete partner: 916 | 917 | ```php 918 | BillingoApi::api('Partner')->delete(PARTNER_ID)->getResponse(); 919 | ``` 920 | 921 | Delete product: 922 | 923 | ```php 924 | BillingoApi::api('Product')->get(PRODUCT_ID)->getResponse(); 925 | ``` 926 | 927 | #### PHP 928 | 929 | Delete partner: 930 | 931 | ```php 932 | $billingoApi->api('Partner')->delete(PARTNER_ID)->getResponse(); 933 | ``` 934 | 935 | Delete product: 936 | 937 | ```php 938 | $billingoApi->api('Product')->get(PRODUCT_ID)->getResponse(); 939 | ``` 940 | 941 | ### Delete payment example: 942 | 943 | #### Laravel 944 | 945 | Get partner: 946 | 947 | ```php 948 | BillingoApi::api('Partner')->deletePayment(PAYMENT_ID)->getResponse(); 949 | ``` 950 | 951 | #### PHP 952 | 953 | Get partner: 954 | 955 | ```php 956 | $billingoApi->api('Partner')->deletePayment(PAYMENT_ID)->getResponse(); 957 | ``` 958 | 959 | ### With http info example: 960 | 961 | #### Laravel 962 | 963 | With http info: 964 | 965 | ```php 966 | BillingoApi::api('Product')->withHttpInfo()->list(['page' => 1, 'per_page' => 5])->getResponse(); 967 | ``` 968 | 969 | #### PHP 970 | 971 | With http info: 972 | 973 | ```php 974 | $billingoApi->api('Product')->withHttpInfo()->list(['page' => 1, 'per_page' => 5])->getResponse(); 975 | ``` 976 | 977 | ## Testing 978 | 979 | First set up your Billingo API V3 Key in `config/config.php` file. 980 | 981 | Linux, MAC OS 982 | 983 | ``` 984 | $ ./vendor/bin/phpunit 985 | ``` 986 | 987 | OR 988 | 989 | ``` 990 | $ composer test 991 | ``` 992 | 993 | Windows 994 | 995 | ``` 996 | $ vendor\bin\phpunit 997 | ``` 998 | 999 | OR 1000 | 1001 | ``` 1002 | $ composer test-win 1003 | ``` 1004 | 1005 | ## Contributing 1006 | 1007 | Please see [CONTRIBUTING](CONTRIBUTING.md) for details. 1008 | 1009 | ### Security 1010 | 1011 | If you discover any security related issues, please email david.molnar.mega@gmail.com instead of using the issue tracker. 1012 | 1013 | ## Credits 1014 | 1015 | - [David Molnar](https://github.com/deviddev) 1016 | - [All Contributors](../../contributors) 1017 | 1018 | ## License 1019 | 1020 | The MIT License (MIT). Please see [License File](LICENSE.md) for more information. 1021 | 1022 | ## Laravel Package Boilerplate 1023 | 1024 | This package was generated using the [Laravel Package Boilerplate](https://laravelpackageboilerplate.com). 1025 | --------------------------------------------------------------------------------