├── src ├── Dto │ ├── Discount.php │ └── Price.php └── SpatiePriceApi.php ├── LICENSE.md ├── .php-cs.dist.php ├── CHANGELOG.md ├── composer.json └── README.md /src/Dto/Discount.php: -------------------------------------------------------------------------------- 1 | active = $active; 30 | 31 | $this->percentage = $percentage; 32 | 33 | $this->name = $name; 34 | 35 | $this->expiresAtTimestamp = $expiresAtTimestamp; 36 | } 37 | 38 | public function expiresAt(): Carbon 39 | { 40 | return Carbon::createFromTimestamp($this->expiresAtTimestamp); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) Spatie bvba 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 13 | all 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 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/Dto/Price.php: -------------------------------------------------------------------------------- 1 | priceInCents = $priceInCents; 32 | $this->currencyCode = $currencyCode; 33 | $this->currencySymbol = $currencySymbol; 34 | $this->formattedPrice = $formattedPrice; 35 | } 36 | 37 | public function formattedPrice(): HtmlString 38 | { 39 | $amount = number_format($this->priceInCents / 100, 2, '.', ' '); 40 | 41 | $amount = Str::replaceLast('.00', '', $amount); 42 | 43 | $string = "{$amount} {$this->currencyCode}"; 44 | 45 | return new HtmlString($string); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /.php-cs.dist.php: -------------------------------------------------------------------------------- 1 | in([ 5 | __DIR__ . '/src', 6 | __DIR__ . '/tests', 7 | ]) 8 | ->name('*.php') 9 | ->notName('*.blade.php') 10 | ->ignoreDotFiles(true) 11 | ->ignoreVCS(true); 12 | 13 | return (new PhpCsFixer\Config()) 14 | ->setRules([ 15 | '@PSR12' => true, 16 | 'array_syntax' => ['syntax' => 'short'], 17 | 'ordered_imports' => ['sort_algorithm' => 'alpha'], 18 | 'no_unused_imports' => true, 19 | 'not_operator_with_successor_space' => true, 20 | 'trailing_comma_in_multiline' => true, 21 | 'phpdoc_scalar' => true, 22 | 'unary_operator_spaces' => true, 23 | 'binary_operator_spaces' => true, 24 | 'blank_line_before_statement' => [ 25 | 'statements' => ['break', 'continue', 'declare', 'return', 'throw', 'try'], 26 | ], 27 | 'phpdoc_single_line_var_spacing' => true, 28 | 'phpdoc_var_without_name' => true, 29 | 'class_attributes_separation' => [ 30 | 'elements' => [ 31 | 'method' => 'one', 32 | ], 33 | ], 34 | 'method_argument_space' => [ 35 | 'on_multiline' => 'ensure_fully_multiline', 36 | 'keep_multiple_spaces_after_comma' => true, 37 | ], 38 | 'single_trait_insert_per_statement' => true, 39 | ]) 40 | ->setFinder($finder); 41 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to `spatie-price-api` will be documented in this file 4 | 5 | ## 1.5.0 - 2025-02-27 6 | 7 | * Laravel 12 8 | 9 | **Full Changelog**: https://github.com/spatie/spatie-price-api/compare/1.4.0...1.5.0 10 | 11 | ## 1.4.0 - 2024-05-10 12 | 13 | * Add support for L11 14 | 15 | **Full Changelog**: https://github.com/spatie/spatie-price-api/compare/1.3.0...1.4.0 16 | 17 | ## 1.3.0 - 2023-03-13 18 | 19 | - Add support for Laravel 10 20 | 21 | **Full Changelog**: https://github.com/spatie/spatie-price-api/compare/1.2.0...1.3.0 22 | 23 | ## 1.2.0 - 2022-04-27 24 | 25 | ## What's Changed 26 | 27 | - Remove FreeGeoIP from package by @AlexVanderbist in https://github.com/spatie/spatie-price-api/pull/1 28 | 29 | ## New Contributors 30 | 31 | - @AlexVanderbist made their first contribution in https://github.com/spatie/spatie-price-api/pull/1 32 | 33 | **Full Changelog**: https://github.com/spatie/spatie-price-api/compare/1.1.3...1.2.0 34 | 35 | ## 1.1.3 - 2022-04-25 36 | 37 | - Re-add PHP 7.4 support (required for front-line-php.com) 38 | 39 | **Full Changelog**: https://github.com/spatie/spatie-price-api/compare/1.1.2...1.1.3 40 | 41 | ## 1.1.2 - 2022-04-25 42 | 43 | - Handle FreeGeoIP timeouts 44 | 45 | **Full Changelog**: https://github.com/spatie/spatie-price-api/compare/1.1.1...1.1.2 46 | 47 | ## 1.1.0 - 2021-08-30 48 | 49 | - add price for bundle 50 | 51 | ## 1.0.4 - 2021-05-06 52 | 53 | - improve formatting 54 | 55 | ## 1.0.3 - 2020-11-26 56 | 57 | - improve formatting 58 | 59 | ## 1.0.2 - 2020-11-26 60 | 61 | - fix composer.json 62 | 63 | ## 1.0.1 - 2020-11-26 64 | 65 | - fix deps 66 | 67 | ## 1.0.0 - 2020-11-26 68 | 69 | - initial release 70 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "spatie/spatie-price-api", 3 | "description": "The Price API used at promotional sites for our own products", 4 | "keywords": [ 5 | "spatie", 6 | "spatie-price-api" 7 | ], 8 | "homepage": "https://github.com/spatie/spatie-price-api", 9 | "license": "MIT", 10 | "authors": [ 11 | { 12 | "name": "Freek Van der Herten", 13 | "email": "freek@spatie.be", 14 | "homepage": "https://spatie.be", 15 | "role": "Developer" 16 | } 17 | ], 18 | "require": { 19 | "php": "^8.2", 20 | "guzzlehttp/guzzle": "^7.2", 21 | "illuminate/contracts": "^10.0|^11.0|^12.0", 22 | "illuminate/http": "^10.0|^11.0|^12.0" 23 | }, 24 | "require-dev": { 25 | "orchestra/testbench": "^8.0|^9.0|^10.0", 26 | "phpunit/phpunit": "^10.5|^11.0", 27 | "spatie/phpunit-snapshot-assertions": "^5.1" 28 | }, 29 | "autoload": { 30 | "psr-4": { 31 | "Spatie\\PriceApi\\": "src" 32 | } 33 | }, 34 | "autoload-dev": { 35 | "psr-4": { 36 | "Spatie\\PriceApi\\Tests\\": "tests" 37 | } 38 | }, 39 | "scripts": { 40 | "test": "vendor/bin/phpunit --colors=always", 41 | "test-coverage": "vendor/bin/phpunit --coverage-html coverage" 42 | }, 43 | "config": { 44 | "sort-packages": true 45 | }, 46 | "minimum-stability": "dev", 47 | "prefer-stable": true, 48 | "funding": [ 49 | { 50 | "type": "github", 51 | "url": "https://github.com/sponsors/spatie" 52 | }, 53 | { 54 | "type": "other", 55 | "url": "https://spatie.be/open-source/support-us" 56 | } 57 | ] 58 | } 59 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | [](https://supportukrainenow.org) 3 | 4 | # The price API used at promotional sites for our own products 5 | 6 | [![Latest Version on Packagist](https://img.shields.io/packagist/v/spatie/spatie-price-api.svg?style=flat-square)](https://packagist.org/packages/spatie/spatie-price-api) 7 | ![Tests](https://github.com/spatie/spatie-price-api/workflows/Tests/badge.svg) 8 | [![Total Downloads](https://img.shields.io/packagist/dt/spatie/spatie-price-api.svg?style=flat-square)](https://packagist.org/packages/spatie/spatie-price-api) 9 | 10 | This package can retrieve prices from the API at spatie.be. It is used at the promotional sites for [our own products](https://spatie.be/products). Though it is open source, the package is not intended to be used by third parties. 11 | 12 | ## Support us 13 | 14 | [](https://spatie.be/github-ad-click/spatie-price-api) 15 | 16 | We invest a lot of resources into creating [best in class open source packages](https://spatie.be/open-source). You can support us by [buying one of our paid products](https://spatie.be/open-source/support-us). 17 | 18 | We highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using. You'll find our address on [our contact page](https://spatie.be/about-us). We publish all received postcards on [our virtual postcard wall](https://spatie.be/open-source/postcards). 19 | 20 | ## Installation 21 | 22 | You can install the package via composer: 23 | 24 | ```bash 25 | composer require spatie/spatie-price-api 26 | ``` 27 | 28 | ## Usage 29 | 30 | You can get a pricing information using the `App\Support\SpatiePrices\SpatiePriceApi::getPriceForPurchasable()` method. 31 | 32 | ## Testing 33 | 34 | ``` bash 35 | composer test 36 | ``` 37 | 38 | ## Changelog 39 | 40 | Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently. 41 | 42 | ## Contributing 43 | 44 | Please see [CONTRIBUTING](https://github.com/spatie/.github/blob/main/CONTRIBUTING.md) for details. 45 | 46 | ## Security Vulnerabilities 47 | 48 | Please review [our security policy](../../security/policy) on how to report security vulnerabilities. 49 | 50 | ## Credits 51 | 52 | - [Freek Van der Herten](https://github.com/freekmurze) 53 | - [All Contributors](../../contributors) 54 | 55 | ## License 56 | 57 | The MIT License (MIT). Please see [License File](LICENSE.md) for more information. 58 | -------------------------------------------------------------------------------- /src/SpatiePriceApi.php: -------------------------------------------------------------------------------- 1 | ip(); 15 | 16 | $response = Cache::remember("price-{$purchasableId}-{$ip}", 60, function () use ($ip, $purchasableId) { 17 | $response = Http::get("https://spatie.be/api/price/{$purchasableId}/{$ip}"); 18 | 19 | if (! $response->successful()) { 20 | return null; 21 | } 22 | 23 | return $response->json(); 24 | }); 25 | 26 | if (is_null($response) || ! array_key_exists('actual', $response)) { 27 | return [ 28 | 'couldFetchPrice' => false, 29 | 'actual' => null, 30 | 'withoutDiscount' => null, 31 | 'discount' => null, 32 | ]; 33 | } 34 | 35 | return [ 36 | 'couldFetchPrice' => true, 37 | 'actual' => Price::createFromResponse($response['actual']), 38 | 'withoutDiscount' => Price::createFromResponse($response['without_discount']), 39 | 'discount' => Discount::createFromResponse($response['discount']), 40 | ]; 41 | } 42 | 43 | public static function getPriceForBundle(int $bundleId): ?array 44 | { 45 | $ip = request()->ip(); 46 | 47 | $response = Cache::remember("bundle-price-{$bundleId}-{$ip}", 60, function () use ($bundleId, $ip) { 48 | $response = Http::get("https://spatie.be/api/bundle-price/{$bundleId}/{$ip}"); 49 | 50 | if (! $response->successful()) { 51 | return null; 52 | } 53 | 54 | return $response->json(); 55 | }); 56 | 57 | if (is_null($response) || ! array_key_exists('actual', $response)) { 58 | return [ 59 | 'couldFetchPrice' => false, 60 | 'actual' => null, 61 | 'withoutDiscount' => null, 62 | 'discount' => null, 63 | ]; 64 | } 65 | 66 | return [ 67 | 'couldFetchPrice' => true, 68 | 'actual' => Price::createFromResponse($response['actual']), 69 | 'withoutDiscount' => Price::createFromResponse($response['without_discount']), 70 | 'discount' => Discount::createFromResponse($response['discount']), 71 | ]; 72 | } 73 | } 74 | --------------------------------------------------------------------------------