├── .gitignore ├── img.png ├── src ├── Responses │ ├── FloosakErrorResponse.php │ ├── FloosakRequestKeyResponse.php │ ├── FloosakResponse.php │ ├── FloosakBalanceEnquiryResponse.php │ ├── FloosakPurchaseStatusResponse.php │ ├── FloosakRefundResponse.php │ ├── FloosakPurchaseRequestResponse.php │ ├── FloosakPurchaseConfirmResponse.php │ └── FloosakVerifyKeyResponse.php ├── Facade │ └── FloosakPaymentGateway.php ├── FloosakServiceProvider.php ├── Guzzle.php ├── Floosak.php ├── FloosakAttributes.php └── Actions │ └── RequestKey.php ├── config └── floosak.php ├── composer.json ├── README.md └── composer.lock /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | vendor 3 | .idea -------------------------------------------------------------------------------- /img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Alsharie/floosak-payment/HEAD/img.png -------------------------------------------------------------------------------- /src/Responses/FloosakErrorResponse.php: -------------------------------------------------------------------------------- 1 | data = (array) json_decode((string)$response); 13 | $this->data['status_code'] = $status; 14 | } 15 | 16 | } -------------------------------------------------------------------------------- /config/floosak.php: -------------------------------------------------------------------------------- 1 | [ 5 | 'phone' => env('FLOOSAK_MERCHANT_PHONE'), 6 | 'short_code' => env('FLOOSAK_MERCHANT_SHORT_CODE'), 7 | 'wallet_id' => env('FLOOSAK_MERCHANT_WALLET_ID'), 8 | 'key' => env('FLOOSAK_MERCHANT_KEY'), 9 | ], 10 | 'url' => [ 11 | 'base' => env('FLOOSAK_BASE_URL', 'https://staging.fintech-expert.net'), 12 | ] 13 | ]; 14 | -------------------------------------------------------------------------------- /src/Facade/FloosakPaymentGateway.php: -------------------------------------------------------------------------------- 1 | data['request_id'])) { 15 | return $this->data['request_id']; 16 | } 17 | 18 | return false; 19 | } 20 | 21 | 22 | 23 | 24 | } -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "alsharie/floosak-payment", 3 | "description": "Floosak payment gateway", 4 | "type": "library", 5 | "require": { 6 | "php": ">=7.4", 7 | "guzzlehttp/guzzle": "^7.5.1", 8 | "illuminate/support": ">=9.33" 9 | }, 10 | "license": "MIT", 11 | "autoload": { 12 | "psr-4": { 13 | "Alsharie\\FloosakPayment\\": "src/" 14 | } 15 | }, 16 | "authors": [ 17 | { 18 | "name": "Alsharie", 19 | "email": "abdulrahman.alsharie@gmail.com" 20 | } 21 | ], 22 | "extra": { 23 | "laravel": { 24 | "providers": [ 25 | "Alsharie\\FloosakPayment\\FloosakServiceProvider" 26 | ], 27 | "aliases": { 28 | "FloosakPayment": "FloosakPaymentGateway" 29 | } 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/FloosakServiceProvider.php: -------------------------------------------------------------------------------- 1 | publishes([ 25 | __DIR__ . '/../config/floosak.php' => config_path('floosak.php'), 26 | ]); 27 | 28 | // Merge config 29 | $this->mergeConfigFrom(__DIR__ . '/../config/floosak.php', 'Floosak'); 30 | } 31 | 32 | /** 33 | * Register the application services. 34 | * 35 | * @return void 36 | */ 37 | public function register() 38 | { 39 | $this->app->singleton(Floosak::class, function () { 40 | return new Floosak(); 41 | }); 42 | 43 | } 44 | } -------------------------------------------------------------------------------- /src/Responses/FloosakResponse.php: -------------------------------------------------------------------------------- 1 | data = (array)json_decode($response, true); 22 | } 23 | 24 | 25 | /** 26 | * @return mixed 27 | */ 28 | public function __get($name) 29 | { 30 | return $this->data[$name]; 31 | } 32 | 33 | /** 34 | * @return array 35 | */ 36 | public function body() 37 | { 38 | return $this->data; 39 | } 40 | 41 | /** 42 | * @return string 43 | */ 44 | public function message() 45 | { 46 | return $this->data['message'] ?? ''; 47 | } 48 | 49 | public function isSuccess() 50 | { 51 | if (isset($this->data['is_success'])) 52 | return $this->data['is_success']; 53 | 54 | return $this->success; 55 | } 56 | 57 | 58 | } -------------------------------------------------------------------------------- /src/Responses/FloosakBalanceEnquiryResponse.php: -------------------------------------------------------------------------------- 1 | data['balnce'])) { 15 | return $this->data['balnce']; 16 | } 17 | 18 | return false; 19 | } 20 | 21 | 22 | /** 23 | * @return string 24 | */ 25 | public function getDate() 26 | { 27 | if (!empty($this->data['t_date'])) { 28 | return $this->data['t_date']; 29 | } 30 | 31 | return false; 32 | } 33 | 34 | /** 35 | * @return string 36 | */ 37 | public function getResult() 38 | { 39 | if (!empty($this->data['result'])) { 40 | return $this->data['result']; 41 | } 42 | 43 | return false; 44 | } 45 | 46 | 47 | /** 48 | * @return string 49 | */ 50 | public function getReqId() 51 | { 52 | if (!empty($this->data['req_id'])) { 53 | return $this->data['req_id']; 54 | } 55 | 56 | return false; 57 | } 58 | 59 | 60 | } -------------------------------------------------------------------------------- /src/Responses/FloosakPurchaseStatusResponse.php: -------------------------------------------------------------------------------- 1 | data['purchase_id'])) { 15 | return $this->data['purchase_id']; 16 | } 17 | 18 | return false; 19 | } 20 | 21 | 22 | /** 23 | * @return string 24 | */ 25 | public function getAmount() 26 | { 27 | if (!empty($this->data['amount'])) { 28 | return $this->data['amount']; 29 | } 30 | 31 | return false; 32 | } 33 | 34 | /** 35 | * @return string 36 | */ 37 | public function getStatus() 38 | { 39 | if (!empty($this->data['status'])) { 40 | return $this->data['status']; 41 | } 42 | 43 | return false; 44 | } 45 | 46 | 47 | /** 48 | * @return string 49 | */ 50 | public function getRefId() 51 | { 52 | if (!empty($this->data['ref_id'])) { 53 | return $this->data['ref_id']; 54 | } 55 | 56 | return false; 57 | } 58 | 59 | 60 | } -------------------------------------------------------------------------------- /src/Responses/FloosakRefundResponse.php: -------------------------------------------------------------------------------- 1 | data['data']['balance'])) { 15 | return $this->data['data']['balance']; 16 | } 17 | 18 | return false; 19 | } 20 | 21 | 22 | /** 23 | * @return string 24 | */ 25 | public function getAmount() 26 | { 27 | if (!empty($this->data['data']['net'])) { 28 | return $this->data['data']['net']; 29 | } 30 | 31 | return false; 32 | } 33 | 34 | /** 35 | * @return string 36 | */ 37 | public function getStatus() 38 | { 39 | if (!empty($this->data['data']['status'])) { 40 | return $this->data['data']['status']; 41 | } 42 | 43 | return false; 44 | } 45 | 46 | 47 | /** 48 | * @return string 49 | */ 50 | public function getRefundId() 51 | { 52 | if (!empty($this->data['data']['id'])) { 53 | return $this->data['data']['id']; 54 | } 55 | 56 | return false; 57 | } 58 | 59 | 60 | } -------------------------------------------------------------------------------- /src/Responses/FloosakPurchaseRequestResponse.php: -------------------------------------------------------------------------------- 1 | data['data']['status'])) { 15 | return $this->data['data']['status']; 16 | } 17 | 18 | return false; 19 | } 20 | 21 | /** 22 | * @return string 23 | */ 24 | public function getAmount() 25 | { 26 | if (!empty($this->data['data']['net'])) { 27 | return $this->data['data']['net']; 28 | } 29 | 30 | return false; 31 | } 32 | 33 | 34 | /** 35 | * @return string 36 | */ 37 | public function getPurchaseId() 38 | { 39 | if (!empty($this->data['data']['id'])) { 40 | return $this->data['data']['id']; 41 | } 42 | 43 | return false; 44 | } 45 | 46 | /** 47 | * @return string 48 | */ 49 | public function getRefId() 50 | { 51 | if (!empty($this->data['data']['reference_id'])) { 52 | return $this->data['data']['reference_id']; 53 | } 54 | 55 | return false; 56 | } 57 | 58 | 59 | } -------------------------------------------------------------------------------- /src/Responses/FloosakPurchaseConfirmResponse.php: -------------------------------------------------------------------------------- 1 | data['data']['status'])) { 15 | return $this->data['data']['status']; 16 | } 17 | 18 | return false; 19 | } 20 | 21 | /** 22 | * @return string 23 | */ 24 | public function getAmount() 25 | { 26 | if (!empty($this->data['data']['net'])) { 27 | return $this->data['data']['net']; 28 | } 29 | 30 | return false; 31 | } 32 | 33 | 34 | /** 35 | * @return string 36 | */ 37 | public function getTransactionId() 38 | { 39 | if (!empty($this->data['data']['id'])) { 40 | return $this->data['data']['id']; 41 | } 42 | 43 | return false; 44 | } 45 | 46 | /** 47 | * @return string 48 | */ 49 | public function getRefId() 50 | { 51 | if (!empty($this->data['data']['reference_id'])) { 52 | return $this->data['data']['reference_id']; 53 | } 54 | 55 | return false; 56 | } 57 | 58 | 59 | } -------------------------------------------------------------------------------- /src/Responses/FloosakVerifyKeyResponse.php: -------------------------------------------------------------------------------- 1 | data['key'])) { 16 | return $this->data['key']; 17 | } 18 | 19 | return false; 20 | } 21 | 22 | 23 | /** 24 | * @return string 25 | */ 26 | public function getAccount() 27 | { 28 | if (!empty($this->data['account_detail'])) { 29 | if ($this->data['account_detail']['account']) 30 | return $this->data['account_detail']['account']; 31 | } 32 | 33 | return false; 34 | } 35 | 36 | 37 | 38 | /** 39 | * @return string 40 | */ 41 | public function getWallets() 42 | { 43 | if ($this->getAccount()) { 44 | return $this->getAccount()['wallets']; 45 | } 46 | 47 | return false; 48 | } 49 | /** 50 | * @return string 51 | */ 52 | public function getWalletId() 53 | { 54 | if ($this->getWallets()) { 55 | return $this->getWallets()[0]['id']; 56 | } 57 | 58 | return false; 59 | } 60 | 61 | 62 | } -------------------------------------------------------------------------------- /src/Guzzle.php: -------------------------------------------------------------------------------- 1 | guzzleClient = new Client(); 32 | $this->basePath = config('floosak.url.base'); 33 | } 34 | 35 | /** 36 | * @param $path 37 | * @param $attributes 38 | * @param $method 39 | * @return ResponseInterface 40 | * @throws GuzzleException 41 | */ 42 | protected function sendRequest($path, $attributes, $headers=[], $method = 'POST'): ResponseInterface 43 | { 44 | return $this->guzzleClient->request( 45 | $method, 46 | $path, 47 | [ 48 | 'headers' => [ 49 | ...$headers, 50 | 'Content-Type' => 'application/json', 51 | 'Accept' => 'application/json', 52 | 'x-channel' => 'merchant' 53 | ], 54 | 'json' => $attributes, 55 | ] 56 | ); 57 | } 58 | 59 | 60 | protected function getRequestKeyPath(): string 61 | { 62 | return $this->basePath . '/' . "api/v1/request/key"; 63 | } 64 | 65 | 66 | protected function getVerifyKeyPath(): string 67 | { 68 | return $this->basePath . '/' . "api/v1/verify/key"; 69 | } 70 | 71 | protected function getPurchaseRequestPath(): string 72 | { 73 | return $this->basePath . '/' . "api/v1/merchant/p2mcl"; 74 | } 75 | 76 | protected function getPurchaseConfirmPath(): string 77 | { 78 | return $this->basePath . '/' . "api/v1/merchant/p2mcl/confirm"; 79 | } 80 | 81 | 82 | protected function getRefundPath(): string 83 | { 84 | return $this->basePath . '/' . "api/v1/merchant/p2mcl/refund"; 85 | } 86 | 87 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # floosak-payment 2 | ![img.png](img.png) 3 | 4 | laravel package for floosak payment getway 5 | 6 | Floosak payment api after update to (p2mcl) 7 | 8 | install the package 9 | `composer require alsharie/floosak-payment` 10 | 11 | You can publish using the following command 12 | 13 | `php artisan vendor:publish --provider="Alsharie\FloosakPayment\FloosakServiceProvider"` 14 | 15 | When published, the `config/floosak.php` config file contains: 16 | 17 | ```php 18 | return [ 19 | 'auth' => [ 20 | 'phone' => env('FLOOSAK_MERCHANT_PHONE'), 21 | 'short_code' => env('FLOOSAK_MERCHANT_SHORT_CODE'), 22 | 'wallet_id' => env('FLOOSAK_MERCHANT_WALLET_ID'), 23 | 'key' => env('FLOOSAK_MERCHANT_KEY'), 24 | ], 25 | 'url' => [ 26 | 'base' => env('FLOOSAK_BASE_URL', 'https://staging.fintech-expert.net'), 27 | ] 28 | ]; 29 | ``` 30 | 31 | ***If you don't have the request_id and key you must do the following:*** 32 | 33 | ### 1. get request Id 34 | 35 | ```php 36 | $floosak = new Floosak(); 37 | $response = $floosak->requestKey(); 38 | 39 | if ($response->isSuccess()) { 40 | $request_id = $response->getRequestId(); 41 | .... 42 | .... 43 | } 44 | 45 | ``` 46 | 47 | ### 2. verify request Id 48 | 49 | after getting the response ***YOU MUST*** store `key`,`request_id` in `config/floosak.php` or in your `.env` 50 | 51 | ```php 52 | $floosak = new Floosak(); 53 | $response = $floosak 54 | ->setOtp(/*otp*/) 55 | ->setRequestId(/*requestId*/) 56 | ->verifyKey(); 57 | 58 | if ($response->isSuccess()) { 59 | $key= $response->getKey(); 60 | $wallet_id= $response->getWalletId(); 61 | //todo:: store $key and $wallet_id 62 | 63 | } else { 64 | 65 | return $response->body(); 66 | } 67 | ``` 68 | 69 | ------------------------ 70 | To purchase using Floosak payment 71 | 72 | ### 1. Purchase 73 | 74 | ```php 75 | $floosak = new Floosak(); 76 | $response = $floosak 77 | ->setRequestId(/*ref_id*/) // random number you generate most 78 | ->setAmount(/*amount*/) 79 | ->setCustomerPhone(/*phone*/) 80 | ->setPurpose(/*purpose*/) 81 | ->purchase(); 82 | 83 | if ($response->isSuccess()) { 84 | $purchase_id = $response->getPurchaseId(); 85 | .... 86 | .... 87 | } 88 | 89 | ``` 90 | 91 | ### 2. Confirm purchase 92 | 93 | ```php 94 | $floosak = new Floosak(); 95 | $response = $floosak 96 | ->setPurchaseId(/*purchase_id*/) // you get it from the response of the above request `purchase()` 97 | ->setOtp(/*user_otp*/) 98 | ->confirmPurchase(); 99 | if ($response->isSuccess()) { 100 | $tran_id = $response->getTransactionId(); 101 | .... 102 | .... 103 | } 104 | 105 | ``` 106 | 107 | 108 | -------------- 109 | ### Refund 110 | 111 | ```php 112 | $floosak = new Floosak(); 113 | $response = $floosak 114 | ->setRequestId(/*ref_id*/) // the random number you generated 115 | ->setTransactionId(/*tran_id*/) 116 | ->setAmount(/*amount*/) // amount to refund 117 | ->refund(); 118 | 119 | if ($response->isSuccess()) { 120 | return $response->getBalance(); 121 | } 122 | 123 | ``` 124 | 125 | you can get the full **response body** using `$response->body()` for all requests -------------------------------------------------------------------------------- /src/Floosak.php: -------------------------------------------------------------------------------- 1 | setAuthAttributes(); 27 | 28 | try { 29 | $response = $this->sendRequest( 30 | $this->getRequestKeyPath(), 31 | $this->attributes 32 | ); 33 | 34 | return new FloosakRequestKeyResponse((string)$response->getBody()); 35 | } catch (\GuzzleHttp\Exception\RequestException $e) { 36 | return new FloosakErrorResponse($e->getResponse()->getBody(),$e->getResponse()->getStatusCode()); 37 | } 38 | } 39 | 40 | /** 41 | * set request_id and otp before call this method 42 | * 43 | * ---------------------------- 44 | * _important note :_ 45 | * After getting the 'key' and 'request_id' successfull add them to floosk config 46 | * 47 | * ------------------------------------ 48 | * 49 | * @return FloosakVerifyKeyResponse|FloosakErrorResponse 50 | */ 51 | public function verifyKey() 52 | { 53 | 54 | try { 55 | $response = $this->sendRequest( 56 | $this->getVerifyKeyPath(), 57 | $this->attributes 58 | ); 59 | 60 | return new FloosakVerifyKeyResponse((string)$response->getBody()); 61 | } catch (\GuzzleHttp\Exception\RequestException $e) { 62 | return new FloosakErrorResponse($e->getResponse()->getBody(),$e->getResponse()->getStatusCode()); 63 | } 64 | } 65 | 66 | /** 67 | * @return FloosakPurchaseRequestResponse|FloosakErrorResponse 68 | */ 69 | public function purchase() 70 | { 71 | // set `source_wallet_id`, and `key` . 72 | $this->setMerchantWalletId(); 73 | $this->setAuthorization(); 74 | 75 | try { 76 | $response = $this->sendRequest( 77 | $this->getPurchaseRequestPath(), 78 | $this->attributes, 79 | $this->headers, 80 | ); 81 | 82 | 83 | return new FloosakPurchaseRequestResponse((string)$response->getBody()); 84 | } catch (\GuzzleHttp\Exception\RequestException $e) { 85 | return new FloosakErrorResponse($e->getResponse()->getBody(),$e->getResponse()->getStatusCode()); 86 | } 87 | } 88 | 89 | /** 90 | * @return FloosakPurchaseConfirmResponse|FloosakErrorResponse 91 | */ 92 | public function confirmPurchase() 93 | { 94 | // set `key` . 95 | $this->setAuthorization(); 96 | 97 | try { 98 | $response = $this->sendRequest( 99 | $this->getPurchaseConfirmPath(), 100 | $this->attributes, 101 | $this->headers, 102 | ); 103 | 104 | return new FloosakPurchaseConfirmResponse((string)$response->getBody()); 105 | } catch (\GuzzleHttp\Exception\RequestException $e) { 106 | return new FloosakErrorResponse($e->getResponse()->getBody(),$e->getResponse()->getStatusCode()); 107 | } 108 | } 109 | 110 | 111 | /** 112 | * @return FloosakRefundResponse|FloosakErrorResponse 113 | */ 114 | public function refund() 115 | { 116 | // set `key` . 117 | $this->setAuthorization(); 118 | 119 | try { 120 | $response = $this->sendRequest( 121 | $this->getRefundPath(), 122 | $this->attributes 123 | ); 124 | 125 | return new FloosakRefundResponse((string)$response->getBody()); 126 | } catch (\GuzzleHttp\Exception\RequestException $e) { 127 | return new FloosakErrorResponse($e->getResponse()->getBody(),$e->getResponse()->getStatusCode()); 128 | } 129 | } 130 | 131 | 132 | } -------------------------------------------------------------------------------- /src/FloosakAttributes.php: -------------------------------------------------------------------------------- 1 | attributes['request_id'] = $requestId; 24 | return $this; 25 | } 26 | 27 | /** 28 | * This field contains any random number you generate 29 | * @param $refId 30 | * @return FloosakAttributes 31 | */ 32 | public function setRefId($refId): FloosakAttributes 33 | { 34 | $this->attributes['ref_id'] = $refId; 35 | return $this; 36 | } 37 | 38 | 39 | /** 40 | * This field contains any random number you generate 41 | * used in [Balance Enquiry] request 42 | * @param $reqId 43 | * @return FloosakAttributes 44 | */ 45 | public function setReqId($reqId): FloosakAttributes 46 | { 47 | $this->attributes['req_id'] = $reqId; 48 | return $this; 49 | } 50 | 51 | /** 52 | * This field contains id of product purchase which customer 53 | * want to pay for it. 54 | * You got from [purchase request] API 55 | * @param $purchaseId 56 | * @return FloosakAttributes 57 | */ 58 | public function setPurchaseId($purchaseId): FloosakAttributes 59 | { 60 | $this->attributes['purchase_id'] = $purchaseId; 61 | return $this; 62 | } 63 | 64 | /** 65 | * This field contains id of transaction you will use to refund 66 | * amount to customer or check status payment process. 67 | * @param $transactionId 68 | * @return FloosakAttributes 69 | */ 70 | public function setTransactionId($transactionId): FloosakAttributes 71 | { 72 | $this->attributes['transaction_id'] = $transactionId; 73 | return $this; 74 | } 75 | 76 | /** 77 | * it’s 6 digit and unique we sent it to customer phone via SMS 78 | * when you use purchase request API. 79 | * @param $otp 80 | * @return FloosakAttributes 81 | */ 82 | public function setOtp($otp): FloosakAttributes 83 | { 84 | $this->attributes['otp'] = $otp; 85 | return $this; 86 | } 87 | 88 | /** 89 | * @param $phone 90 | * @return FloosakAttributes 91 | */ 92 | public function setCustomerPhone($phone): FloosakAttributes 93 | { 94 | $this->attributes['target_phone'] = $phone; 95 | return $this; 96 | } 97 | 98 | 99 | /** 100 | * @param $phone 101 | * @return FloosakAttributes 102 | */ 103 | public function setTargetPhone($phone): FloosakAttributes 104 | { 105 | $this->attributes['target_phone'] = $phone; 106 | return $this; 107 | } 108 | 109 | 110 | /** 111 | * @param $purpose 112 | * @return FloosakAttributes 113 | */ 114 | public function setPurpose($purpose): FloosakAttributes 115 | { 116 | $this->attributes['purpose'] = $purpose; 117 | return $this; 118 | } 119 | 120 | 121 | /** 122 | * @param $amount 123 | * @return FloosakAttributes 124 | */ 125 | public function setAmount($amount): FloosakAttributes 126 | { 127 | $this->attributes['amount'] = $amount; 128 | return $this; 129 | } 130 | 131 | 132 | /** 133 | * @param array $attributes 134 | * @return FloosakAttributes 135 | */ 136 | public function setAttributes(array $attributes): FloosakAttributes 137 | { 138 | $this->attributes = $attributes; 139 | return $this; 140 | } 141 | 142 | /** 143 | * @param array $attributes 144 | * 145 | * @return FloosakAttributes 146 | */ 147 | public function mergeAttributes(array $attributes): FloosakAttributes 148 | { 149 | $this->attributes = array_merge($this->attributes, $attributes); 150 | return $this; 151 | } 152 | 153 | /** 154 | * @param mixed $key 155 | * @param mixed $value 156 | * 157 | * @return FloosakAttributes 158 | */ 159 | public function setAttribute($key, $value): FloosakAttributes 160 | { 161 | $this->attributes[$key] = $value; 162 | return $this; 163 | } 164 | 165 | /** 166 | * @param mixed $key 167 | * 168 | * @return boolean 169 | */ 170 | public function hasAttribute($key): bool 171 | { 172 | return isset($this->attributes[$key]); 173 | } 174 | 175 | /** 176 | * @param mixed $key 177 | * 178 | * @return FloosakAttributes 179 | */ 180 | public function removeAttribute($key): FloosakAttributes 181 | { 182 | $this->attributes = array_filter($this->attributes, function ($name) use ($key) { 183 | return $name !== $key; 184 | }, ARRAY_FILTER_USE_KEY); 185 | 186 | return $this; 187 | } 188 | 189 | 190 | /** 191 | * @return void 192 | */ 193 | protected function setAuthAttributes() 194 | { 195 | $this->attributes['phone'] = config('floosak.auth.phone'); 196 | $this->attributes['short_code'] = config('floosak.auth.short_code'); 197 | } 198 | 199 | 200 | /** 201 | * @return void 202 | */ 203 | protected function setMerchantWalletId() 204 | { 205 | $this->attributes['source_wallet_id'] = config('floosak.auth.wallet_id'); 206 | } 207 | 208 | /** 209 | * @return void 210 | */ 211 | protected function setAuthorization() 212 | { 213 | $this->headers['Authorization'] = 'Bearer ' . config('floosak.auth.key'); 214 | } 215 | } -------------------------------------------------------------------------------- /src/Actions/RequestKey.php: -------------------------------------------------------------------------------- 1 | attributes['ref_id'] = $refId; 36 | return $this; 37 | } 38 | 39 | /** 40 | * This field contains id of product purchase which customer 41 | * want to pay for it. 42 | * You got from purchase request AP 43 | * @return $this 44 | */ 45 | public function setPurchaseId($purchaseId): Floosak 46 | { 47 | $this->attributes['purchase_id'] = $purchaseId; 48 | return $this; 49 | } 50 | 51 | /** 52 | * This field contains id of transaction you will use to refund 53 | * amount to customer or check status payment process. 54 | * @return $this 55 | */ 56 | public function setTransactionId($transactionId): Floosak 57 | { 58 | $this->attributes['transaction_id'] = $transactionId; 59 | return $this; 60 | } 61 | 62 | /** 63 | * t’s 6 digit and unique we sent it to customer phone via SMS 64 | * when you use purchase request API. 65 | * @return $this 66 | */ 67 | public function setOtp($otp): Floosak 68 | { 69 | $this->attributes['otp'] = $otp; 70 | return $this; 71 | } 72 | 73 | /** 74 | * @return $this 75 | */ 76 | public function setCustomerPhone($phone) 77 | { 78 | $this->attributes['customer_phone'] = $phone; 79 | return $this; 80 | } 81 | 82 | 83 | /** 84 | * @return $this 85 | */ 86 | public function setAmount($amount) 87 | { 88 | $this->attributes['amount'] = $amount; 89 | return $this; 90 | } 91 | 92 | 93 | 94 | /** 95 | * @return $this 96 | */ 97 | public function setAttributes(array $attributes) 98 | { 99 | $this->attributes = $attributes; 100 | return $this; 101 | } 102 | 103 | /** 104 | * @param array $attributes 105 | * 106 | * @return $this 107 | */ 108 | public function mergeAttributes(array $attributes) 109 | { 110 | $this->attributes = array_merge($this->attributes, $attributes); 111 | return $this; 112 | } 113 | 114 | /** 115 | * @param mixed $key 116 | * @param mixed $value 117 | * 118 | * @return $this 119 | */ 120 | public function setAttribute($key, $value) 121 | { 122 | $this->attributes[$key] = $value; 123 | return $this; 124 | } 125 | 126 | /** 127 | * @param mixed $key 128 | * 129 | * @return boolean 130 | */ 131 | public function hasAttribute($key) 132 | { 133 | return isset($this->attributes[$key]); 134 | } 135 | 136 | /** 137 | * @param mixed $key 138 | * 139 | * @return Floosak 140 | */ 141 | public function removeAttribute($key) 142 | { 143 | $this->attributes = array_filter($this->attributes, function ($name) use ($key) { 144 | return $name !== $key; 145 | }, ARRAY_FILTER_USE_KEY); 146 | 147 | return $this; 148 | } 149 | 150 | /** 151 | * @return FloosakResponse 152 | * @throws Exception 153 | */ 154 | public function pay() 155 | { 156 | // set `terminal_id`, and `password` . 157 | $this->setAuthAttributes(); 158 | 159 | // generate request 160 | $this->generateRequestHash(); 161 | 162 | // set setMerchantIp if not set 163 | $this->_setMerchantIp(); 164 | 165 | try { 166 | $response = $this->guzzleClient->request( 167 | $this->method, 168 | $this->getEndPointPath(), 169 | [ 170 | 'json' => $this->attributes, 171 | ] 172 | ); 173 | 174 | return new FloosakResponse((string)$response->getBody()); 175 | } catch (\Throwable $e) { 176 | throw new Exception($e->getMessage()); 177 | } 178 | } 179 | 180 | /** 181 | * @param string $transaction_id 182 | * @return mixed 183 | * @throws Exception 184 | */ 185 | public function verify(string $transaction_id) 186 | { 187 | // set `terminal_id`, and `password` now. 188 | $this->setAuthAttributes(); 189 | 190 | // As requestHas for paying request is different from requestHash for find request. 191 | $this->generateFindRequestHash(); 192 | 193 | // set setMerchantIp if not set 194 | $this->_setMerchantIp(); 195 | 196 | $this->attributes['transid'] = $transaction_id; 197 | 198 | try { 199 | $response = $this->guzzleClient->request( 200 | $this->method, 201 | $this->getEndPointPath(), 202 | [ 203 | 'json' => $this->attributes, 204 | ] 205 | ); 206 | 207 | return new FloosakResponse((string)$response->getBody()); 208 | } catch (\Throwable $e) { 209 | throw new Exception($e->getMessage()); 210 | } 211 | } 212 | 213 | /** 214 | * @return void 215 | */ 216 | protected function generateRequestHash() 217 | { 218 | $this->generateHash(); 219 | $this->attributes['action'] = '1'; // action is always 1 220 | } 221 | 222 | /** 223 | * Security Check API For transaction performed authorization 224 | * @return void 225 | */ 226 | protected function generateFindRequestHash() 227 | { 228 | $this->generateHash(); 229 | $this->attributes['action'] = '10'; // action is always 1 230 | } 231 | 232 | /** 233 | * @return void 234 | */ 235 | protected function setAuthAttributes() 236 | { 237 | $this->attributes['phone'] = config('floosak.auth.phone'); 238 | $this->attributes['short_code'] = config('floosak.auth.short_code'); 239 | $this->attributes['required_id'] = config('floosak.auth.required_id'); 240 | $this->attributes['key'] = config('floosak.auth.key'); 241 | } 242 | 243 | /** 244 | * 245 | * Create SHA256 Hash with below mention Parameters.Merchant needs to form the below hash sequence before posting the transaction to floosak. 246 | * Below is the SHA 256 Hash creation format : 247 | * Hash Sequence :- trackid|Terminalid|password|secret_key|amount|currency_code 248 | * Note : Terminalid, password, secret_key will be provided by Floosak 249 | * 250 | * @return void 251 | */ 252 | protected function generateHash(): void 253 | { 254 | 255 | $requestHash = $this->attributes['trackid'] . '|' . config('floosak.auth.terminal_id') . '|' . config('floosak.auth.password') . '|' . config('floosak.auth.merchant_key') . '|' . $this->attributes['amount'] . '|' . $this->attributes['currency']; 256 | $this->attributes['requestHash'] = hash('sha256', $requestHash); 257 | } 258 | 259 | /** 260 | * return the server ip address 261 | * @return mixed|string 262 | * @throws Exception 263 | */ 264 | protected function _getServerIP() 265 | { 266 | $ip_address = ''; 267 | if (isset($_SERVER['HTTP_CLIENT_IP'])) { 268 | $ip_address = $_SERVER['HTTP_CLIENT_IP']; 269 | } else if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { 270 | $ip_address = $_SERVER['HTTP_X_FORWARDED_FOR']; 271 | } else if (isset($_SERVER['HTTP_X_FORWARDED'])) { 272 | $ip_address = $_SERVER['HTTP_X_FORWARDED']; 273 | } else if (isset($_SERVER['HTTP_FORWARDED_FOR'])) { 274 | $ip_address = $_SERVER['HTTP_FORWARDED_FOR']; 275 | } else if (isset($_SERVER['HTTP_FORWARDED'])) { 276 | $ip_address = $_SERVER['HTTP_FORWARDED']; 277 | } else if (isset($_SERVER['REMOTE_ADDR'])) { 278 | $ip_address = $_SERVER['REMOTE_ADDR']; 279 | } else if (isset($_SERVER['SERVER_ADDR'])) { 280 | $ip_address = $_SERVER['SERVER_ADDR']; 281 | } else { 282 | throw new Exception('Unable to get server ip address'); 283 | } 284 | 285 | return $ip_address; 286 | } 287 | 288 | 289 | /** 290 | * set setMerchantIp attribute if not set 291 | * @return void 292 | */ 293 | protected function _setMerchantIp() 294 | { 295 | if (!$this->hasAttribute('merchantIp')) { 296 | $this->attributes['merchantIp'] = $this->_getServerIP(); 297 | } 298 | } 299 | } -------------------------------------------------------------------------------- /composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", 5 | "This file is @generated automatically" 6 | ], 7 | "content-hash": "56787395cfb4b86598f358872e7b3e76", 8 | "packages": [ 9 | { 10 | "name": "carbonphp/carbon-doctrine-types", 11 | "version": "3.1.0", 12 | "source": { 13 | "type": "git", 14 | "url": "https://github.com/CarbonPHP/carbon-doctrine-types.git", 15 | "reference": "a31d3358a2a5d6ae947df1691d1f321418a5f3d5" 16 | }, 17 | "dist": { 18 | "type": "zip", 19 | "url": "https://api.github.com/repos/CarbonPHP/carbon-doctrine-types/zipball/a31d3358a2a5d6ae947df1691d1f321418a5f3d5", 20 | "reference": "a31d3358a2a5d6ae947df1691d1f321418a5f3d5", 21 | "shasum": "" 22 | }, 23 | "require": { 24 | "php": "^8.1" 25 | }, 26 | "conflict": { 27 | "doctrine/dbal": "<4.0.0 || >=5.0.0" 28 | }, 29 | "require-dev": { 30 | "doctrine/dbal": "^4.0.0", 31 | "nesbot/carbon": "^2.71.0 || ^3.0.0", 32 | "phpunit/phpunit": "^10.3" 33 | }, 34 | "type": "library", 35 | "autoload": { 36 | "psr-4": { 37 | "Carbon\\Doctrine\\": "src/Carbon/Doctrine/" 38 | } 39 | }, 40 | "notification-url": "https://packagist.org/downloads/", 41 | "license": [ 42 | "MIT" 43 | ], 44 | "authors": [ 45 | { 46 | "name": "KyleKatarn", 47 | "email": "kylekatarnls@gmail.com" 48 | } 49 | ], 50 | "description": "Types to use Carbon in Doctrine", 51 | "keywords": [ 52 | "carbon", 53 | "date", 54 | "datetime", 55 | "doctrine", 56 | "time" 57 | ], 58 | "support": { 59 | "issues": "https://github.com/CarbonPHP/carbon-doctrine-types/issues", 60 | "source": "https://github.com/CarbonPHP/carbon-doctrine-types/tree/3.1.0" 61 | }, 62 | "funding": [ 63 | { 64 | "url": "https://github.com/kylekatarnls", 65 | "type": "github" 66 | }, 67 | { 68 | "url": "https://opencollective.com/Carbon", 69 | "type": "open_collective" 70 | }, 71 | { 72 | "url": "https://tidelift.com/funding/github/packagist/nesbot/carbon", 73 | "type": "tidelift" 74 | } 75 | ], 76 | "time": "2023-12-10T15:33:53+00:00" 77 | }, 78 | { 79 | "name": "doctrine/inflector", 80 | "version": "2.0.8", 81 | "source": { 82 | "type": "git", 83 | "url": "https://github.com/doctrine/inflector.git", 84 | "reference": "f9301a5b2fb1216b2b08f02ba04dc45423db6bff" 85 | }, 86 | "dist": { 87 | "type": "zip", 88 | "url": "https://api.github.com/repos/doctrine/inflector/zipball/f9301a5b2fb1216b2b08f02ba04dc45423db6bff", 89 | "reference": "f9301a5b2fb1216b2b08f02ba04dc45423db6bff", 90 | "shasum": "" 91 | }, 92 | "require": { 93 | "php": "^7.2 || ^8.0" 94 | }, 95 | "require-dev": { 96 | "doctrine/coding-standard": "^11.0", 97 | "phpstan/phpstan": "^1.8", 98 | "phpstan/phpstan-phpunit": "^1.1", 99 | "phpstan/phpstan-strict-rules": "^1.3", 100 | "phpunit/phpunit": "^8.5 || ^9.5", 101 | "vimeo/psalm": "^4.25 || ^5.4" 102 | }, 103 | "type": "library", 104 | "autoload": { 105 | "psr-4": { 106 | "Doctrine\\Inflector\\": "lib/Doctrine/Inflector" 107 | } 108 | }, 109 | "notification-url": "https://packagist.org/downloads/", 110 | "license": [ 111 | "MIT" 112 | ], 113 | "authors": [ 114 | { 115 | "name": "Guilherme Blanco", 116 | "email": "guilhermeblanco@gmail.com" 117 | }, 118 | { 119 | "name": "Roman Borschel", 120 | "email": "roman@code-factory.org" 121 | }, 122 | { 123 | "name": "Benjamin Eberlei", 124 | "email": "kontakt@beberlei.de" 125 | }, 126 | { 127 | "name": "Jonathan Wage", 128 | "email": "jonwage@gmail.com" 129 | }, 130 | { 131 | "name": "Johannes Schmitt", 132 | "email": "schmittjoh@gmail.com" 133 | } 134 | ], 135 | "description": "PHP Doctrine Inflector is a small library that can perform string manipulations with regard to upper/lowercase and singular/plural forms of words.", 136 | "homepage": "https://www.doctrine-project.org/projects/inflector.html", 137 | "keywords": [ 138 | "inflection", 139 | "inflector", 140 | "lowercase", 141 | "manipulation", 142 | "php", 143 | "plural", 144 | "singular", 145 | "strings", 146 | "uppercase", 147 | "words" 148 | ], 149 | "support": { 150 | "issues": "https://github.com/doctrine/inflector/issues", 151 | "source": "https://github.com/doctrine/inflector/tree/2.0.8" 152 | }, 153 | "funding": [ 154 | { 155 | "url": "https://www.doctrine-project.org/sponsorship.html", 156 | "type": "custom" 157 | }, 158 | { 159 | "url": "https://www.patreon.com/phpdoctrine", 160 | "type": "patreon" 161 | }, 162 | { 163 | "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finflector", 164 | "type": "tidelift" 165 | } 166 | ], 167 | "time": "2023-06-16T13:40:37+00:00" 168 | }, 169 | { 170 | "name": "guzzlehttp/guzzle", 171 | "version": "7.8.1", 172 | "source": { 173 | "type": "git", 174 | "url": "https://github.com/guzzle/guzzle.git", 175 | "reference": "41042bc7ab002487b876a0683fc8dce04ddce104" 176 | }, 177 | "dist": { 178 | "type": "zip", 179 | "url": "https://api.github.com/repos/guzzle/guzzle/zipball/41042bc7ab002487b876a0683fc8dce04ddce104", 180 | "reference": "41042bc7ab002487b876a0683fc8dce04ddce104", 181 | "shasum": "" 182 | }, 183 | "require": { 184 | "ext-json": "*", 185 | "guzzlehttp/promises": "^1.5.3 || ^2.0.1", 186 | "guzzlehttp/psr7": "^1.9.1 || ^2.5.1", 187 | "php": "^7.2.5 || ^8.0", 188 | "psr/http-client": "^1.0", 189 | "symfony/deprecation-contracts": "^2.2 || ^3.0" 190 | }, 191 | "provide": { 192 | "psr/http-client-implementation": "1.0" 193 | }, 194 | "require-dev": { 195 | "bamarni/composer-bin-plugin": "^1.8.2", 196 | "ext-curl": "*", 197 | "php-http/client-integration-tests": "dev-master#2c025848417c1135031fdf9c728ee53d0a7ceaee as 3.0.999", 198 | "php-http/message-factory": "^1.1", 199 | "phpunit/phpunit": "^8.5.36 || ^9.6.15", 200 | "psr/log": "^1.1 || ^2.0 || ^3.0" 201 | }, 202 | "suggest": { 203 | "ext-curl": "Required for CURL handler support", 204 | "ext-intl": "Required for Internationalized Domain Name (IDN) support", 205 | "psr/log": "Required for using the Log middleware" 206 | }, 207 | "type": "library", 208 | "extra": { 209 | "bamarni-bin": { 210 | "bin-links": true, 211 | "forward-command": false 212 | } 213 | }, 214 | "autoload": { 215 | "files": [ 216 | "src/functions_include.php" 217 | ], 218 | "psr-4": { 219 | "GuzzleHttp\\": "src/" 220 | } 221 | }, 222 | "notification-url": "https://packagist.org/downloads/", 223 | "license": [ 224 | "MIT" 225 | ], 226 | "authors": [ 227 | { 228 | "name": "Graham Campbell", 229 | "email": "hello@gjcampbell.co.uk", 230 | "homepage": "https://github.com/GrahamCampbell" 231 | }, 232 | { 233 | "name": "Michael Dowling", 234 | "email": "mtdowling@gmail.com", 235 | "homepage": "https://github.com/mtdowling" 236 | }, 237 | { 238 | "name": "Jeremy Lindblom", 239 | "email": "jeremeamia@gmail.com", 240 | "homepage": "https://github.com/jeremeamia" 241 | }, 242 | { 243 | "name": "George Mponos", 244 | "email": "gmponos@gmail.com", 245 | "homepage": "https://github.com/gmponos" 246 | }, 247 | { 248 | "name": "Tobias Nyholm", 249 | "email": "tobias.nyholm@gmail.com", 250 | "homepage": "https://github.com/Nyholm" 251 | }, 252 | { 253 | "name": "Márk Sági-Kazár", 254 | "email": "mark.sagikazar@gmail.com", 255 | "homepage": "https://github.com/sagikazarmark" 256 | }, 257 | { 258 | "name": "Tobias Schultze", 259 | "email": "webmaster@tubo-world.de", 260 | "homepage": "https://github.com/Tobion" 261 | } 262 | ], 263 | "description": "Guzzle is a PHP HTTP client library", 264 | "keywords": [ 265 | "client", 266 | "curl", 267 | "framework", 268 | "http", 269 | "http client", 270 | "psr-18", 271 | "psr-7", 272 | "rest", 273 | "web service" 274 | ], 275 | "support": { 276 | "issues": "https://github.com/guzzle/guzzle/issues", 277 | "source": "https://github.com/guzzle/guzzle/tree/7.8.1" 278 | }, 279 | "funding": [ 280 | { 281 | "url": "https://github.com/GrahamCampbell", 282 | "type": "github" 283 | }, 284 | { 285 | "url": "https://github.com/Nyholm", 286 | "type": "github" 287 | }, 288 | { 289 | "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/guzzle", 290 | "type": "tidelift" 291 | } 292 | ], 293 | "time": "2023-12-03T20:35:24+00:00" 294 | }, 295 | { 296 | "name": "guzzlehttp/promises", 297 | "version": "2.0.2", 298 | "source": { 299 | "type": "git", 300 | "url": "https://github.com/guzzle/promises.git", 301 | "reference": "bbff78d96034045e58e13dedd6ad91b5d1253223" 302 | }, 303 | "dist": { 304 | "type": "zip", 305 | "url": "https://api.github.com/repos/guzzle/promises/zipball/bbff78d96034045e58e13dedd6ad91b5d1253223", 306 | "reference": "bbff78d96034045e58e13dedd6ad91b5d1253223", 307 | "shasum": "" 308 | }, 309 | "require": { 310 | "php": "^7.2.5 || ^8.0" 311 | }, 312 | "require-dev": { 313 | "bamarni/composer-bin-plugin": "^1.8.2", 314 | "phpunit/phpunit": "^8.5.36 || ^9.6.15" 315 | }, 316 | "type": "library", 317 | "extra": { 318 | "bamarni-bin": { 319 | "bin-links": true, 320 | "forward-command": false 321 | } 322 | }, 323 | "autoload": { 324 | "psr-4": { 325 | "GuzzleHttp\\Promise\\": "src/" 326 | } 327 | }, 328 | "notification-url": "https://packagist.org/downloads/", 329 | "license": [ 330 | "MIT" 331 | ], 332 | "authors": [ 333 | { 334 | "name": "Graham Campbell", 335 | "email": "hello@gjcampbell.co.uk", 336 | "homepage": "https://github.com/GrahamCampbell" 337 | }, 338 | { 339 | "name": "Michael Dowling", 340 | "email": "mtdowling@gmail.com", 341 | "homepage": "https://github.com/mtdowling" 342 | }, 343 | { 344 | "name": "Tobias Nyholm", 345 | "email": "tobias.nyholm@gmail.com", 346 | "homepage": "https://github.com/Nyholm" 347 | }, 348 | { 349 | "name": "Tobias Schultze", 350 | "email": "webmaster@tubo-world.de", 351 | "homepage": "https://github.com/Tobion" 352 | } 353 | ], 354 | "description": "Guzzle promises library", 355 | "keywords": [ 356 | "promise" 357 | ], 358 | "support": { 359 | "issues": "https://github.com/guzzle/promises/issues", 360 | "source": "https://github.com/guzzle/promises/tree/2.0.2" 361 | }, 362 | "funding": [ 363 | { 364 | "url": "https://github.com/GrahamCampbell", 365 | "type": "github" 366 | }, 367 | { 368 | "url": "https://github.com/Nyholm", 369 | "type": "github" 370 | }, 371 | { 372 | "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises", 373 | "type": "tidelift" 374 | } 375 | ], 376 | "time": "2023-12-03T20:19:20+00:00" 377 | }, 378 | { 379 | "name": "guzzlehttp/psr7", 380 | "version": "2.6.2", 381 | "source": { 382 | "type": "git", 383 | "url": "https://github.com/guzzle/psr7.git", 384 | "reference": "45b30f99ac27b5ca93cb4831afe16285f57b8221" 385 | }, 386 | "dist": { 387 | "type": "zip", 388 | "url": "https://api.github.com/repos/guzzle/psr7/zipball/45b30f99ac27b5ca93cb4831afe16285f57b8221", 389 | "reference": "45b30f99ac27b5ca93cb4831afe16285f57b8221", 390 | "shasum": "" 391 | }, 392 | "require": { 393 | "php": "^7.2.5 || ^8.0", 394 | "psr/http-factory": "^1.0", 395 | "psr/http-message": "^1.1 || ^2.0", 396 | "ralouphie/getallheaders": "^3.0" 397 | }, 398 | "provide": { 399 | "psr/http-factory-implementation": "1.0", 400 | "psr/http-message-implementation": "1.0" 401 | }, 402 | "require-dev": { 403 | "bamarni/composer-bin-plugin": "^1.8.2", 404 | "http-interop/http-factory-tests": "^0.9", 405 | "phpunit/phpunit": "^8.5.36 || ^9.6.15" 406 | }, 407 | "suggest": { 408 | "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" 409 | }, 410 | "type": "library", 411 | "extra": { 412 | "bamarni-bin": { 413 | "bin-links": true, 414 | "forward-command": false 415 | } 416 | }, 417 | "autoload": { 418 | "psr-4": { 419 | "GuzzleHttp\\Psr7\\": "src/" 420 | } 421 | }, 422 | "notification-url": "https://packagist.org/downloads/", 423 | "license": [ 424 | "MIT" 425 | ], 426 | "authors": [ 427 | { 428 | "name": "Graham Campbell", 429 | "email": "hello@gjcampbell.co.uk", 430 | "homepage": "https://github.com/GrahamCampbell" 431 | }, 432 | { 433 | "name": "Michael Dowling", 434 | "email": "mtdowling@gmail.com", 435 | "homepage": "https://github.com/mtdowling" 436 | }, 437 | { 438 | "name": "George Mponos", 439 | "email": "gmponos@gmail.com", 440 | "homepage": "https://github.com/gmponos" 441 | }, 442 | { 443 | "name": "Tobias Nyholm", 444 | "email": "tobias.nyholm@gmail.com", 445 | "homepage": "https://github.com/Nyholm" 446 | }, 447 | { 448 | "name": "Márk Sági-Kazár", 449 | "email": "mark.sagikazar@gmail.com", 450 | "homepage": "https://github.com/sagikazarmark" 451 | }, 452 | { 453 | "name": "Tobias Schultze", 454 | "email": "webmaster@tubo-world.de", 455 | "homepage": "https://github.com/Tobion" 456 | }, 457 | { 458 | "name": "Márk Sági-Kazár", 459 | "email": "mark.sagikazar@gmail.com", 460 | "homepage": "https://sagikazarmark.hu" 461 | } 462 | ], 463 | "description": "PSR-7 message implementation that also provides common utility methods", 464 | "keywords": [ 465 | "http", 466 | "message", 467 | "psr-7", 468 | "request", 469 | "response", 470 | "stream", 471 | "uri", 472 | "url" 473 | ], 474 | "support": { 475 | "issues": "https://github.com/guzzle/psr7/issues", 476 | "source": "https://github.com/guzzle/psr7/tree/2.6.2" 477 | }, 478 | "funding": [ 479 | { 480 | "url": "https://github.com/GrahamCampbell", 481 | "type": "github" 482 | }, 483 | { 484 | "url": "https://github.com/Nyholm", 485 | "type": "github" 486 | }, 487 | { 488 | "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/psr7", 489 | "type": "tidelift" 490 | } 491 | ], 492 | "time": "2023-12-03T20:05:35+00:00" 493 | }, 494 | { 495 | "name": "illuminate/collections", 496 | "version": "v10.37.3", 497 | "source": { 498 | "type": "git", 499 | "url": "https://github.com/illuminate/collections.git", 500 | "reference": "8e4c4f97ea066cd6aec962ef8a6abc09dfd5e754" 501 | }, 502 | "dist": { 503 | "type": "zip", 504 | "url": "https://api.github.com/repos/illuminate/collections/zipball/8e4c4f97ea066cd6aec962ef8a6abc09dfd5e754", 505 | "reference": "8e4c4f97ea066cd6aec962ef8a6abc09dfd5e754", 506 | "shasum": "" 507 | }, 508 | "require": { 509 | "illuminate/conditionable": "^10.0", 510 | "illuminate/contracts": "^10.0", 511 | "illuminate/macroable": "^10.0", 512 | "php": "^8.1" 513 | }, 514 | "suggest": { 515 | "symfony/var-dumper": "Required to use the dump method (^6.2)." 516 | }, 517 | "type": "library", 518 | "extra": { 519 | "branch-alias": { 520 | "dev-master": "10.x-dev" 521 | } 522 | }, 523 | "autoload": { 524 | "files": [ 525 | "helpers.php" 526 | ], 527 | "psr-4": { 528 | "Illuminate\\Support\\": "" 529 | } 530 | }, 531 | "notification-url": "https://packagist.org/downloads/", 532 | "license": [ 533 | "MIT" 534 | ], 535 | "authors": [ 536 | { 537 | "name": "Taylor Otwell", 538 | "email": "taylor@laravel.com" 539 | } 540 | ], 541 | "description": "The Illuminate Collections package.", 542 | "homepage": "https://laravel.com", 543 | "support": { 544 | "issues": "https://github.com/laravel/framework/issues", 545 | "source": "https://github.com/laravel/framework" 546 | }, 547 | "time": "2023-11-27T14:46:52+00:00" 548 | }, 549 | { 550 | "name": "illuminate/conditionable", 551 | "version": "v10.37.3", 552 | "source": { 553 | "type": "git", 554 | "url": "https://github.com/illuminate/conditionable.git", 555 | "reference": "d0958e4741fc9d6f516a552060fd1b829a85e009" 556 | }, 557 | "dist": { 558 | "type": "zip", 559 | "url": "https://api.github.com/repos/illuminate/conditionable/zipball/d0958e4741fc9d6f516a552060fd1b829a85e009", 560 | "reference": "d0958e4741fc9d6f516a552060fd1b829a85e009", 561 | "shasum": "" 562 | }, 563 | "require": { 564 | "php": "^8.0.2" 565 | }, 566 | "type": "library", 567 | "extra": { 568 | "branch-alias": { 569 | "dev-master": "10.x-dev" 570 | } 571 | }, 572 | "autoload": { 573 | "psr-4": { 574 | "Illuminate\\Support\\": "" 575 | } 576 | }, 577 | "notification-url": "https://packagist.org/downloads/", 578 | "license": [ 579 | "MIT" 580 | ], 581 | "authors": [ 582 | { 583 | "name": "Taylor Otwell", 584 | "email": "taylor@laravel.com" 585 | } 586 | ], 587 | "description": "The Illuminate Conditionable package.", 588 | "homepage": "https://laravel.com", 589 | "support": { 590 | "issues": "https://github.com/laravel/framework/issues", 591 | "source": "https://github.com/laravel/framework" 592 | }, 593 | "time": "2023-02-03T08:06:17+00:00" 594 | }, 595 | { 596 | "name": "illuminate/contracts", 597 | "version": "v10.37.3", 598 | "source": { 599 | "type": "git", 600 | "url": "https://github.com/illuminate/contracts.git", 601 | "reference": "f6bf37a272fda164f6c451407c99f820eb1eb95b" 602 | }, 603 | "dist": { 604 | "type": "zip", 605 | "url": "https://api.github.com/repos/illuminate/contracts/zipball/f6bf37a272fda164f6c451407c99f820eb1eb95b", 606 | "reference": "f6bf37a272fda164f6c451407c99f820eb1eb95b", 607 | "shasum": "" 608 | }, 609 | "require": { 610 | "php": "^8.1", 611 | "psr/container": "^1.1.1|^2.0.1", 612 | "psr/simple-cache": "^1.0|^2.0|^3.0" 613 | }, 614 | "type": "library", 615 | "extra": { 616 | "branch-alias": { 617 | "dev-master": "10.x-dev" 618 | } 619 | }, 620 | "autoload": { 621 | "psr-4": { 622 | "Illuminate\\Contracts\\": "" 623 | } 624 | }, 625 | "notification-url": "https://packagist.org/downloads/", 626 | "license": [ 627 | "MIT" 628 | ], 629 | "authors": [ 630 | { 631 | "name": "Taylor Otwell", 632 | "email": "taylor@laravel.com" 633 | } 634 | ], 635 | "description": "The Illuminate Contracts package.", 636 | "homepage": "https://laravel.com", 637 | "support": { 638 | "issues": "https://github.com/laravel/framework/issues", 639 | "source": "https://github.com/laravel/framework" 640 | }, 641 | "time": "2023-10-30T00:59:22+00:00" 642 | }, 643 | { 644 | "name": "illuminate/macroable", 645 | "version": "v10.37.3", 646 | "source": { 647 | "type": "git", 648 | "url": "https://github.com/illuminate/macroable.git", 649 | "reference": "dff667a46ac37b634dcf68909d9d41e94dc97c27" 650 | }, 651 | "dist": { 652 | "type": "zip", 653 | "url": "https://api.github.com/repos/illuminate/macroable/zipball/dff667a46ac37b634dcf68909d9d41e94dc97c27", 654 | "reference": "dff667a46ac37b634dcf68909d9d41e94dc97c27", 655 | "shasum": "" 656 | }, 657 | "require": { 658 | "php": "^8.1" 659 | }, 660 | "type": "library", 661 | "extra": { 662 | "branch-alias": { 663 | "dev-master": "10.x-dev" 664 | } 665 | }, 666 | "autoload": { 667 | "psr-4": { 668 | "Illuminate\\Support\\": "" 669 | } 670 | }, 671 | "notification-url": "https://packagist.org/downloads/", 672 | "license": [ 673 | "MIT" 674 | ], 675 | "authors": [ 676 | { 677 | "name": "Taylor Otwell", 678 | "email": "taylor@laravel.com" 679 | } 680 | ], 681 | "description": "The Illuminate Macroable package.", 682 | "homepage": "https://laravel.com", 683 | "support": { 684 | "issues": "https://github.com/laravel/framework/issues", 685 | "source": "https://github.com/laravel/framework" 686 | }, 687 | "time": "2023-06-05T12:46:42+00:00" 688 | }, 689 | { 690 | "name": "illuminate/support", 691 | "version": "v10.37.3", 692 | "source": { 693 | "type": "git", 694 | "url": "https://github.com/illuminate/support.git", 695 | "reference": "c28657bdda8014017197e2a40edd7d162ce03e8a" 696 | }, 697 | "dist": { 698 | "type": "zip", 699 | "url": "https://api.github.com/repos/illuminate/support/zipball/c28657bdda8014017197e2a40edd7d162ce03e8a", 700 | "reference": "c28657bdda8014017197e2a40edd7d162ce03e8a", 701 | "shasum": "" 702 | }, 703 | "require": { 704 | "doctrine/inflector": "^2.0", 705 | "ext-ctype": "*", 706 | "ext-filter": "*", 707 | "ext-mbstring": "*", 708 | "illuminate/collections": "^10.0", 709 | "illuminate/conditionable": "^10.0", 710 | "illuminate/contracts": "^10.0", 711 | "illuminate/macroable": "^10.0", 712 | "nesbot/carbon": "^2.67", 713 | "php": "^8.1", 714 | "voku/portable-ascii": "^2.0" 715 | }, 716 | "conflict": { 717 | "tightenco/collect": "<5.5.33" 718 | }, 719 | "suggest": { 720 | "illuminate/filesystem": "Required to use the composer class (^10.0).", 721 | "league/commonmark": "Required to use Str::markdown() and Stringable::markdown() (^2.0.2).", 722 | "ramsey/uuid": "Required to use Str::uuid() (^4.7).", 723 | "symfony/process": "Required to use the composer class (^6.2).", 724 | "symfony/uid": "Required to use Str::ulid() (^6.2).", 725 | "symfony/var-dumper": "Required to use the dd function (^6.2).", 726 | "vlucas/phpdotenv": "Required to use the Env class and env helper (^5.4.1)." 727 | }, 728 | "type": "library", 729 | "extra": { 730 | "branch-alias": { 731 | "dev-master": "10.x-dev" 732 | } 733 | }, 734 | "autoload": { 735 | "files": [ 736 | "helpers.php" 737 | ], 738 | "psr-4": { 739 | "Illuminate\\Support\\": "" 740 | } 741 | }, 742 | "notification-url": "https://packagist.org/downloads/", 743 | "license": [ 744 | "MIT" 745 | ], 746 | "authors": [ 747 | { 748 | "name": "Taylor Otwell", 749 | "email": "taylor@laravel.com" 750 | } 751 | ], 752 | "description": "The Illuminate Support package.", 753 | "homepage": "https://laravel.com", 754 | "support": { 755 | "issues": "https://github.com/laravel/framework/issues", 756 | "source": "https://github.com/laravel/framework" 757 | }, 758 | "time": "2023-12-12T19:36:09+00:00" 759 | }, 760 | { 761 | "name": "nesbot/carbon", 762 | "version": "2.72.1", 763 | "source": { 764 | "type": "git", 765 | "url": "https://github.com/briannesbitt/Carbon.git", 766 | "reference": "2b3b3db0a2d0556a177392ff1a3bf5608fa09f78" 767 | }, 768 | "dist": { 769 | "type": "zip", 770 | "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/2b3b3db0a2d0556a177392ff1a3bf5608fa09f78", 771 | "reference": "2b3b3db0a2d0556a177392ff1a3bf5608fa09f78", 772 | "shasum": "" 773 | }, 774 | "require": { 775 | "carbonphp/carbon-doctrine-types": "*", 776 | "ext-json": "*", 777 | "php": "^7.1.8 || ^8.0", 778 | "psr/clock": "^1.0", 779 | "symfony/polyfill-mbstring": "^1.0", 780 | "symfony/polyfill-php80": "^1.16", 781 | "symfony/translation": "^3.4 || ^4.0 || ^5.0 || ^6.0" 782 | }, 783 | "provide": { 784 | "psr/clock-implementation": "1.0" 785 | }, 786 | "require-dev": { 787 | "doctrine/dbal": "^2.0 || ^3.1.4 || ^4.0", 788 | "doctrine/orm": "^2.7 || ^3.0", 789 | "friendsofphp/php-cs-fixer": "^3.0", 790 | "kylekatarnls/multi-tester": "^2.0", 791 | "ondrejmirtes/better-reflection": "*", 792 | "phpmd/phpmd": "^2.9", 793 | "phpstan/extension-installer": "^1.0", 794 | "phpstan/phpstan": "^0.12.99 || ^1.7.14", 795 | "phpunit/php-file-iterator": "^2.0.5 || ^3.0.6", 796 | "phpunit/phpunit": "^7.5.20 || ^8.5.26 || ^9.5.20", 797 | "squizlabs/php_codesniffer": "^3.4" 798 | }, 799 | "bin": [ 800 | "bin/carbon" 801 | ], 802 | "type": "library", 803 | "extra": { 804 | "branch-alias": { 805 | "dev-3.x": "3.x-dev", 806 | "dev-master": "2.x-dev" 807 | }, 808 | "laravel": { 809 | "providers": [ 810 | "Carbon\\Laravel\\ServiceProvider" 811 | ] 812 | }, 813 | "phpstan": { 814 | "includes": [ 815 | "extension.neon" 816 | ] 817 | } 818 | }, 819 | "autoload": { 820 | "psr-4": { 821 | "Carbon\\": "src/Carbon/" 822 | } 823 | }, 824 | "notification-url": "https://packagist.org/downloads/", 825 | "license": [ 826 | "MIT" 827 | ], 828 | "authors": [ 829 | { 830 | "name": "Brian Nesbitt", 831 | "email": "brian@nesbot.com", 832 | "homepage": "https://markido.com" 833 | }, 834 | { 835 | "name": "kylekatarnls", 836 | "homepage": "https://github.com/kylekatarnls" 837 | } 838 | ], 839 | "description": "An API extension for DateTime that supports 281 different languages.", 840 | "homepage": "https://carbon.nesbot.com", 841 | "keywords": [ 842 | "date", 843 | "datetime", 844 | "time" 845 | ], 846 | "support": { 847 | "docs": "https://carbon.nesbot.com/docs", 848 | "issues": "https://github.com/briannesbitt/Carbon/issues", 849 | "source": "https://github.com/briannesbitt/Carbon" 850 | }, 851 | "funding": [ 852 | { 853 | "url": "https://github.com/sponsors/kylekatarnls", 854 | "type": "github" 855 | }, 856 | { 857 | "url": "https://opencollective.com/Carbon#sponsor", 858 | "type": "opencollective" 859 | }, 860 | { 861 | "url": "https://tidelift.com/subscription/pkg/packagist-nesbot-carbon?utm_source=packagist-nesbot-carbon&utm_medium=referral&utm_campaign=readme", 862 | "type": "tidelift" 863 | } 864 | ], 865 | "time": "2023-12-08T23:47:49+00:00" 866 | }, 867 | { 868 | "name": "psr/clock", 869 | "version": "1.0.0", 870 | "source": { 871 | "type": "git", 872 | "url": "https://github.com/php-fig/clock.git", 873 | "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d" 874 | }, 875 | "dist": { 876 | "type": "zip", 877 | "url": "https://api.github.com/repos/php-fig/clock/zipball/e41a24703d4560fd0acb709162f73b8adfc3aa0d", 878 | "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d", 879 | "shasum": "" 880 | }, 881 | "require": { 882 | "php": "^7.0 || ^8.0" 883 | }, 884 | "type": "library", 885 | "autoload": { 886 | "psr-4": { 887 | "Psr\\Clock\\": "src/" 888 | } 889 | }, 890 | "notification-url": "https://packagist.org/downloads/", 891 | "license": [ 892 | "MIT" 893 | ], 894 | "authors": [ 895 | { 896 | "name": "PHP-FIG", 897 | "homepage": "https://www.php-fig.org/" 898 | } 899 | ], 900 | "description": "Common interface for reading the clock.", 901 | "homepage": "https://github.com/php-fig/clock", 902 | "keywords": [ 903 | "clock", 904 | "now", 905 | "psr", 906 | "psr-20", 907 | "time" 908 | ], 909 | "support": { 910 | "issues": "https://github.com/php-fig/clock/issues", 911 | "source": "https://github.com/php-fig/clock/tree/1.0.0" 912 | }, 913 | "time": "2022-11-25T14:36:26+00:00" 914 | }, 915 | { 916 | "name": "psr/container", 917 | "version": "2.0.2", 918 | "source": { 919 | "type": "git", 920 | "url": "https://github.com/php-fig/container.git", 921 | "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" 922 | }, 923 | "dist": { 924 | "type": "zip", 925 | "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", 926 | "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", 927 | "shasum": "" 928 | }, 929 | "require": { 930 | "php": ">=7.4.0" 931 | }, 932 | "type": "library", 933 | "extra": { 934 | "branch-alias": { 935 | "dev-master": "2.0.x-dev" 936 | } 937 | }, 938 | "autoload": { 939 | "psr-4": { 940 | "Psr\\Container\\": "src/" 941 | } 942 | }, 943 | "notification-url": "https://packagist.org/downloads/", 944 | "license": [ 945 | "MIT" 946 | ], 947 | "authors": [ 948 | { 949 | "name": "PHP-FIG", 950 | "homepage": "https://www.php-fig.org/" 951 | } 952 | ], 953 | "description": "Common Container Interface (PHP FIG PSR-11)", 954 | "homepage": "https://github.com/php-fig/container", 955 | "keywords": [ 956 | "PSR-11", 957 | "container", 958 | "container-interface", 959 | "container-interop", 960 | "psr" 961 | ], 962 | "support": { 963 | "issues": "https://github.com/php-fig/container/issues", 964 | "source": "https://github.com/php-fig/container/tree/2.0.2" 965 | }, 966 | "time": "2021-11-05T16:47:00+00:00" 967 | }, 968 | { 969 | "name": "psr/http-client", 970 | "version": "1.0.3", 971 | "source": { 972 | "type": "git", 973 | "url": "https://github.com/php-fig/http-client.git", 974 | "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90" 975 | }, 976 | "dist": { 977 | "type": "zip", 978 | "url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90", 979 | "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90", 980 | "shasum": "" 981 | }, 982 | "require": { 983 | "php": "^7.0 || ^8.0", 984 | "psr/http-message": "^1.0 || ^2.0" 985 | }, 986 | "type": "library", 987 | "extra": { 988 | "branch-alias": { 989 | "dev-master": "1.0.x-dev" 990 | } 991 | }, 992 | "autoload": { 993 | "psr-4": { 994 | "Psr\\Http\\Client\\": "src/" 995 | } 996 | }, 997 | "notification-url": "https://packagist.org/downloads/", 998 | "license": [ 999 | "MIT" 1000 | ], 1001 | "authors": [ 1002 | { 1003 | "name": "PHP-FIG", 1004 | "homepage": "https://www.php-fig.org/" 1005 | } 1006 | ], 1007 | "description": "Common interface for HTTP clients", 1008 | "homepage": "https://github.com/php-fig/http-client", 1009 | "keywords": [ 1010 | "http", 1011 | "http-client", 1012 | "psr", 1013 | "psr-18" 1014 | ], 1015 | "support": { 1016 | "source": "https://github.com/php-fig/http-client" 1017 | }, 1018 | "time": "2023-09-23T14:17:50+00:00" 1019 | }, 1020 | { 1021 | "name": "psr/http-factory", 1022 | "version": "1.0.2", 1023 | "source": { 1024 | "type": "git", 1025 | "url": "https://github.com/php-fig/http-factory.git", 1026 | "reference": "e616d01114759c4c489f93b099585439f795fe35" 1027 | }, 1028 | "dist": { 1029 | "type": "zip", 1030 | "url": "https://api.github.com/repos/php-fig/http-factory/zipball/e616d01114759c4c489f93b099585439f795fe35", 1031 | "reference": "e616d01114759c4c489f93b099585439f795fe35", 1032 | "shasum": "" 1033 | }, 1034 | "require": { 1035 | "php": ">=7.0.0", 1036 | "psr/http-message": "^1.0 || ^2.0" 1037 | }, 1038 | "type": "library", 1039 | "extra": { 1040 | "branch-alias": { 1041 | "dev-master": "1.0.x-dev" 1042 | } 1043 | }, 1044 | "autoload": { 1045 | "psr-4": { 1046 | "Psr\\Http\\Message\\": "src/" 1047 | } 1048 | }, 1049 | "notification-url": "https://packagist.org/downloads/", 1050 | "license": [ 1051 | "MIT" 1052 | ], 1053 | "authors": [ 1054 | { 1055 | "name": "PHP-FIG", 1056 | "homepage": "https://www.php-fig.org/" 1057 | } 1058 | ], 1059 | "description": "Common interfaces for PSR-7 HTTP message factories", 1060 | "keywords": [ 1061 | "factory", 1062 | "http", 1063 | "message", 1064 | "psr", 1065 | "psr-17", 1066 | "psr-7", 1067 | "request", 1068 | "response" 1069 | ], 1070 | "support": { 1071 | "source": "https://github.com/php-fig/http-factory/tree/1.0.2" 1072 | }, 1073 | "time": "2023-04-10T20:10:41+00:00" 1074 | }, 1075 | { 1076 | "name": "psr/http-message", 1077 | "version": "2.0", 1078 | "source": { 1079 | "type": "git", 1080 | "url": "https://github.com/php-fig/http-message.git", 1081 | "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71" 1082 | }, 1083 | "dist": { 1084 | "type": "zip", 1085 | "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71", 1086 | "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71", 1087 | "shasum": "" 1088 | }, 1089 | "require": { 1090 | "php": "^7.2 || ^8.0" 1091 | }, 1092 | "type": "library", 1093 | "extra": { 1094 | "branch-alias": { 1095 | "dev-master": "2.0.x-dev" 1096 | } 1097 | }, 1098 | "autoload": { 1099 | "psr-4": { 1100 | "Psr\\Http\\Message\\": "src/" 1101 | } 1102 | }, 1103 | "notification-url": "https://packagist.org/downloads/", 1104 | "license": [ 1105 | "MIT" 1106 | ], 1107 | "authors": [ 1108 | { 1109 | "name": "PHP-FIG", 1110 | "homepage": "https://www.php-fig.org/" 1111 | } 1112 | ], 1113 | "description": "Common interface for HTTP messages", 1114 | "homepage": "https://github.com/php-fig/http-message", 1115 | "keywords": [ 1116 | "http", 1117 | "http-message", 1118 | "psr", 1119 | "psr-7", 1120 | "request", 1121 | "response" 1122 | ], 1123 | "support": { 1124 | "source": "https://github.com/php-fig/http-message/tree/2.0" 1125 | }, 1126 | "time": "2023-04-04T09:54:51+00:00" 1127 | }, 1128 | { 1129 | "name": "psr/simple-cache", 1130 | "version": "3.0.0", 1131 | "source": { 1132 | "type": "git", 1133 | "url": "https://github.com/php-fig/simple-cache.git", 1134 | "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865" 1135 | }, 1136 | "dist": { 1137 | "type": "zip", 1138 | "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/764e0b3939f5ca87cb904f570ef9be2d78a07865", 1139 | "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865", 1140 | "shasum": "" 1141 | }, 1142 | "require": { 1143 | "php": ">=8.0.0" 1144 | }, 1145 | "type": "library", 1146 | "extra": { 1147 | "branch-alias": { 1148 | "dev-master": "3.0.x-dev" 1149 | } 1150 | }, 1151 | "autoload": { 1152 | "psr-4": { 1153 | "Psr\\SimpleCache\\": "src/" 1154 | } 1155 | }, 1156 | "notification-url": "https://packagist.org/downloads/", 1157 | "license": [ 1158 | "MIT" 1159 | ], 1160 | "authors": [ 1161 | { 1162 | "name": "PHP-FIG", 1163 | "homepage": "https://www.php-fig.org/" 1164 | } 1165 | ], 1166 | "description": "Common interfaces for simple caching", 1167 | "keywords": [ 1168 | "cache", 1169 | "caching", 1170 | "psr", 1171 | "psr-16", 1172 | "simple-cache" 1173 | ], 1174 | "support": { 1175 | "source": "https://github.com/php-fig/simple-cache/tree/3.0.0" 1176 | }, 1177 | "time": "2021-10-29T13:26:27+00:00" 1178 | }, 1179 | { 1180 | "name": "ralouphie/getallheaders", 1181 | "version": "3.0.3", 1182 | "source": { 1183 | "type": "git", 1184 | "url": "https://github.com/ralouphie/getallheaders.git", 1185 | "reference": "120b605dfeb996808c31b6477290a714d356e822" 1186 | }, 1187 | "dist": { 1188 | "type": "zip", 1189 | "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", 1190 | "reference": "120b605dfeb996808c31b6477290a714d356e822", 1191 | "shasum": "" 1192 | }, 1193 | "require": { 1194 | "php": ">=5.6" 1195 | }, 1196 | "require-dev": { 1197 | "php-coveralls/php-coveralls": "^2.1", 1198 | "phpunit/phpunit": "^5 || ^6.5" 1199 | }, 1200 | "type": "library", 1201 | "autoload": { 1202 | "files": [ 1203 | "src/getallheaders.php" 1204 | ] 1205 | }, 1206 | "notification-url": "https://packagist.org/downloads/", 1207 | "license": [ 1208 | "MIT" 1209 | ], 1210 | "authors": [ 1211 | { 1212 | "name": "Ralph Khattar", 1213 | "email": "ralph.khattar@gmail.com" 1214 | } 1215 | ], 1216 | "description": "A polyfill for getallheaders.", 1217 | "support": { 1218 | "issues": "https://github.com/ralouphie/getallheaders/issues", 1219 | "source": "https://github.com/ralouphie/getallheaders/tree/develop" 1220 | }, 1221 | "time": "2019-03-08T08:55:37+00:00" 1222 | }, 1223 | { 1224 | "name": "symfony/deprecation-contracts", 1225 | "version": "v3.4.0", 1226 | "source": { 1227 | "type": "git", 1228 | "url": "https://github.com/symfony/deprecation-contracts.git", 1229 | "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf" 1230 | }, 1231 | "dist": { 1232 | "type": "zip", 1233 | "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/7c3aff79d10325257a001fcf92d991f24fc967cf", 1234 | "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf", 1235 | "shasum": "" 1236 | }, 1237 | "require": { 1238 | "php": ">=8.1" 1239 | }, 1240 | "type": "library", 1241 | "extra": { 1242 | "branch-alias": { 1243 | "dev-main": "3.4-dev" 1244 | }, 1245 | "thanks": { 1246 | "name": "symfony/contracts", 1247 | "url": "https://github.com/symfony/contracts" 1248 | } 1249 | }, 1250 | "autoload": { 1251 | "files": [ 1252 | "function.php" 1253 | ] 1254 | }, 1255 | "notification-url": "https://packagist.org/downloads/", 1256 | "license": [ 1257 | "MIT" 1258 | ], 1259 | "authors": [ 1260 | { 1261 | "name": "Nicolas Grekas", 1262 | "email": "p@tchwork.com" 1263 | }, 1264 | { 1265 | "name": "Symfony Community", 1266 | "homepage": "https://symfony.com/contributors" 1267 | } 1268 | ], 1269 | "description": "A generic function and convention to trigger deprecation notices", 1270 | "homepage": "https://symfony.com", 1271 | "support": { 1272 | "source": "https://github.com/symfony/deprecation-contracts/tree/v3.4.0" 1273 | }, 1274 | "funding": [ 1275 | { 1276 | "url": "https://symfony.com/sponsor", 1277 | "type": "custom" 1278 | }, 1279 | { 1280 | "url": "https://github.com/fabpot", 1281 | "type": "github" 1282 | }, 1283 | { 1284 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 1285 | "type": "tidelift" 1286 | } 1287 | ], 1288 | "time": "2023-05-23T14:45:45+00:00" 1289 | }, 1290 | { 1291 | "name": "symfony/polyfill-mbstring", 1292 | "version": "v1.28.0", 1293 | "source": { 1294 | "type": "git", 1295 | "url": "https://github.com/symfony/polyfill-mbstring.git", 1296 | "reference": "42292d99c55abe617799667f454222c54c60e229" 1297 | }, 1298 | "dist": { 1299 | "type": "zip", 1300 | "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/42292d99c55abe617799667f454222c54c60e229", 1301 | "reference": "42292d99c55abe617799667f454222c54c60e229", 1302 | "shasum": "" 1303 | }, 1304 | "require": { 1305 | "php": ">=7.1" 1306 | }, 1307 | "provide": { 1308 | "ext-mbstring": "*" 1309 | }, 1310 | "suggest": { 1311 | "ext-mbstring": "For best performance" 1312 | }, 1313 | "type": "library", 1314 | "extra": { 1315 | "branch-alias": { 1316 | "dev-main": "1.28-dev" 1317 | }, 1318 | "thanks": { 1319 | "name": "symfony/polyfill", 1320 | "url": "https://github.com/symfony/polyfill" 1321 | } 1322 | }, 1323 | "autoload": { 1324 | "files": [ 1325 | "bootstrap.php" 1326 | ], 1327 | "psr-4": { 1328 | "Symfony\\Polyfill\\Mbstring\\": "" 1329 | } 1330 | }, 1331 | "notification-url": "https://packagist.org/downloads/", 1332 | "license": [ 1333 | "MIT" 1334 | ], 1335 | "authors": [ 1336 | { 1337 | "name": "Nicolas Grekas", 1338 | "email": "p@tchwork.com" 1339 | }, 1340 | { 1341 | "name": "Symfony Community", 1342 | "homepage": "https://symfony.com/contributors" 1343 | } 1344 | ], 1345 | "description": "Symfony polyfill for the Mbstring extension", 1346 | "homepage": "https://symfony.com", 1347 | "keywords": [ 1348 | "compatibility", 1349 | "mbstring", 1350 | "polyfill", 1351 | "portable", 1352 | "shim" 1353 | ], 1354 | "support": { 1355 | "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.28.0" 1356 | }, 1357 | "funding": [ 1358 | { 1359 | "url": "https://symfony.com/sponsor", 1360 | "type": "custom" 1361 | }, 1362 | { 1363 | "url": "https://github.com/fabpot", 1364 | "type": "github" 1365 | }, 1366 | { 1367 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 1368 | "type": "tidelift" 1369 | } 1370 | ], 1371 | "time": "2023-07-28T09:04:16+00:00" 1372 | }, 1373 | { 1374 | "name": "symfony/polyfill-php80", 1375 | "version": "v1.28.0", 1376 | "source": { 1377 | "type": "git", 1378 | "url": "https://github.com/symfony/polyfill-php80.git", 1379 | "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5" 1380 | }, 1381 | "dist": { 1382 | "type": "zip", 1383 | "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/6caa57379c4aec19c0a12a38b59b26487dcfe4b5", 1384 | "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5", 1385 | "shasum": "" 1386 | }, 1387 | "require": { 1388 | "php": ">=7.1" 1389 | }, 1390 | "type": "library", 1391 | "extra": { 1392 | "branch-alias": { 1393 | "dev-main": "1.28-dev" 1394 | }, 1395 | "thanks": { 1396 | "name": "symfony/polyfill", 1397 | "url": "https://github.com/symfony/polyfill" 1398 | } 1399 | }, 1400 | "autoload": { 1401 | "files": [ 1402 | "bootstrap.php" 1403 | ], 1404 | "psr-4": { 1405 | "Symfony\\Polyfill\\Php80\\": "" 1406 | }, 1407 | "classmap": [ 1408 | "Resources/stubs" 1409 | ] 1410 | }, 1411 | "notification-url": "https://packagist.org/downloads/", 1412 | "license": [ 1413 | "MIT" 1414 | ], 1415 | "authors": [ 1416 | { 1417 | "name": "Ion Bazan", 1418 | "email": "ion.bazan@gmail.com" 1419 | }, 1420 | { 1421 | "name": "Nicolas Grekas", 1422 | "email": "p@tchwork.com" 1423 | }, 1424 | { 1425 | "name": "Symfony Community", 1426 | "homepage": "https://symfony.com/contributors" 1427 | } 1428 | ], 1429 | "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", 1430 | "homepage": "https://symfony.com", 1431 | "keywords": [ 1432 | "compatibility", 1433 | "polyfill", 1434 | "portable", 1435 | "shim" 1436 | ], 1437 | "support": { 1438 | "source": "https://github.com/symfony/polyfill-php80/tree/v1.28.0" 1439 | }, 1440 | "funding": [ 1441 | { 1442 | "url": "https://symfony.com/sponsor", 1443 | "type": "custom" 1444 | }, 1445 | { 1446 | "url": "https://github.com/fabpot", 1447 | "type": "github" 1448 | }, 1449 | { 1450 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 1451 | "type": "tidelift" 1452 | } 1453 | ], 1454 | "time": "2023-01-26T09:26:14+00:00" 1455 | }, 1456 | { 1457 | "name": "symfony/translation", 1458 | "version": "v6.4.0", 1459 | "source": { 1460 | "type": "git", 1461 | "url": "https://github.com/symfony/translation.git", 1462 | "reference": "b1035dbc2a344b21f8fa8ac451c7ecec4ea45f37" 1463 | }, 1464 | "dist": { 1465 | "type": "zip", 1466 | "url": "https://api.github.com/repos/symfony/translation/zipball/b1035dbc2a344b21f8fa8ac451c7ecec4ea45f37", 1467 | "reference": "b1035dbc2a344b21f8fa8ac451c7ecec4ea45f37", 1468 | "shasum": "" 1469 | }, 1470 | "require": { 1471 | "php": ">=8.1", 1472 | "symfony/deprecation-contracts": "^2.5|^3", 1473 | "symfony/polyfill-mbstring": "~1.0", 1474 | "symfony/translation-contracts": "^2.5|^3.0" 1475 | }, 1476 | "conflict": { 1477 | "symfony/config": "<5.4", 1478 | "symfony/console": "<5.4", 1479 | "symfony/dependency-injection": "<5.4", 1480 | "symfony/http-client-contracts": "<2.5", 1481 | "symfony/http-kernel": "<5.4", 1482 | "symfony/service-contracts": "<2.5", 1483 | "symfony/twig-bundle": "<5.4", 1484 | "symfony/yaml": "<5.4" 1485 | }, 1486 | "provide": { 1487 | "symfony/translation-implementation": "2.3|3.0" 1488 | }, 1489 | "require-dev": { 1490 | "nikic/php-parser": "^4.13", 1491 | "psr/log": "^1|^2|^3", 1492 | "symfony/config": "^5.4|^6.0|^7.0", 1493 | "symfony/console": "^5.4|^6.0|^7.0", 1494 | "symfony/dependency-injection": "^5.4|^6.0|^7.0", 1495 | "symfony/finder": "^5.4|^6.0|^7.0", 1496 | "symfony/http-client-contracts": "^2.5|^3.0", 1497 | "symfony/http-kernel": "^5.4|^6.0|^7.0", 1498 | "symfony/intl": "^5.4|^6.0|^7.0", 1499 | "symfony/polyfill-intl-icu": "^1.21", 1500 | "symfony/routing": "^5.4|^6.0|^7.0", 1501 | "symfony/service-contracts": "^2.5|^3", 1502 | "symfony/yaml": "^5.4|^6.0|^7.0" 1503 | }, 1504 | "type": "library", 1505 | "autoload": { 1506 | "files": [ 1507 | "Resources/functions.php" 1508 | ], 1509 | "psr-4": { 1510 | "Symfony\\Component\\Translation\\": "" 1511 | }, 1512 | "exclude-from-classmap": [ 1513 | "/Tests/" 1514 | ] 1515 | }, 1516 | "notification-url": "https://packagist.org/downloads/", 1517 | "license": [ 1518 | "MIT" 1519 | ], 1520 | "authors": [ 1521 | { 1522 | "name": "Fabien Potencier", 1523 | "email": "fabien@symfony.com" 1524 | }, 1525 | { 1526 | "name": "Symfony Community", 1527 | "homepage": "https://symfony.com/contributors" 1528 | } 1529 | ], 1530 | "description": "Provides tools to internationalize your application", 1531 | "homepage": "https://symfony.com", 1532 | "support": { 1533 | "source": "https://github.com/symfony/translation/tree/v6.4.0" 1534 | }, 1535 | "funding": [ 1536 | { 1537 | "url": "https://symfony.com/sponsor", 1538 | "type": "custom" 1539 | }, 1540 | { 1541 | "url": "https://github.com/fabpot", 1542 | "type": "github" 1543 | }, 1544 | { 1545 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 1546 | "type": "tidelift" 1547 | } 1548 | ], 1549 | "time": "2023-11-29T08:14:36+00:00" 1550 | }, 1551 | { 1552 | "name": "symfony/translation-contracts", 1553 | "version": "v3.4.0", 1554 | "source": { 1555 | "type": "git", 1556 | "url": "https://github.com/symfony/translation-contracts.git", 1557 | "reference": "dee0c6e5b4c07ce851b462530088e64b255ac9c5" 1558 | }, 1559 | "dist": { 1560 | "type": "zip", 1561 | "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/dee0c6e5b4c07ce851b462530088e64b255ac9c5", 1562 | "reference": "dee0c6e5b4c07ce851b462530088e64b255ac9c5", 1563 | "shasum": "" 1564 | }, 1565 | "require": { 1566 | "php": ">=8.1" 1567 | }, 1568 | "type": "library", 1569 | "extra": { 1570 | "branch-alias": { 1571 | "dev-main": "3.4-dev" 1572 | }, 1573 | "thanks": { 1574 | "name": "symfony/contracts", 1575 | "url": "https://github.com/symfony/contracts" 1576 | } 1577 | }, 1578 | "autoload": { 1579 | "psr-4": { 1580 | "Symfony\\Contracts\\Translation\\": "" 1581 | }, 1582 | "exclude-from-classmap": [ 1583 | "/Test/" 1584 | ] 1585 | }, 1586 | "notification-url": "https://packagist.org/downloads/", 1587 | "license": [ 1588 | "MIT" 1589 | ], 1590 | "authors": [ 1591 | { 1592 | "name": "Nicolas Grekas", 1593 | "email": "p@tchwork.com" 1594 | }, 1595 | { 1596 | "name": "Symfony Community", 1597 | "homepage": "https://symfony.com/contributors" 1598 | } 1599 | ], 1600 | "description": "Generic abstractions related to translation", 1601 | "homepage": "https://symfony.com", 1602 | "keywords": [ 1603 | "abstractions", 1604 | "contracts", 1605 | "decoupling", 1606 | "interfaces", 1607 | "interoperability", 1608 | "standards" 1609 | ], 1610 | "support": { 1611 | "source": "https://github.com/symfony/translation-contracts/tree/v3.4.0" 1612 | }, 1613 | "funding": [ 1614 | { 1615 | "url": "https://symfony.com/sponsor", 1616 | "type": "custom" 1617 | }, 1618 | { 1619 | "url": "https://github.com/fabpot", 1620 | "type": "github" 1621 | }, 1622 | { 1623 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 1624 | "type": "tidelift" 1625 | } 1626 | ], 1627 | "time": "2023-07-25T15:08:44+00:00" 1628 | }, 1629 | { 1630 | "name": "voku/portable-ascii", 1631 | "version": "2.0.1", 1632 | "source": { 1633 | "type": "git", 1634 | "url": "https://github.com/voku/portable-ascii.git", 1635 | "reference": "b56450eed252f6801410d810c8e1727224ae0743" 1636 | }, 1637 | "dist": { 1638 | "type": "zip", 1639 | "url": "https://api.github.com/repos/voku/portable-ascii/zipball/b56450eed252f6801410d810c8e1727224ae0743", 1640 | "reference": "b56450eed252f6801410d810c8e1727224ae0743", 1641 | "shasum": "" 1642 | }, 1643 | "require": { 1644 | "php": ">=7.0.0" 1645 | }, 1646 | "require-dev": { 1647 | "phpunit/phpunit": "~6.0 || ~7.0 || ~9.0" 1648 | }, 1649 | "suggest": { 1650 | "ext-intl": "Use Intl for transliterator_transliterate() support" 1651 | }, 1652 | "type": "library", 1653 | "autoload": { 1654 | "psr-4": { 1655 | "voku\\": "src/voku/" 1656 | } 1657 | }, 1658 | "notification-url": "https://packagist.org/downloads/", 1659 | "license": [ 1660 | "MIT" 1661 | ], 1662 | "authors": [ 1663 | { 1664 | "name": "Lars Moelleken", 1665 | "homepage": "http://www.moelleken.org/" 1666 | } 1667 | ], 1668 | "description": "Portable ASCII library - performance optimized (ascii) string functions for php.", 1669 | "homepage": "https://github.com/voku/portable-ascii", 1670 | "keywords": [ 1671 | "ascii", 1672 | "clean", 1673 | "php" 1674 | ], 1675 | "support": { 1676 | "issues": "https://github.com/voku/portable-ascii/issues", 1677 | "source": "https://github.com/voku/portable-ascii/tree/2.0.1" 1678 | }, 1679 | "funding": [ 1680 | { 1681 | "url": "https://www.paypal.me/moelleken", 1682 | "type": "custom" 1683 | }, 1684 | { 1685 | "url": "https://github.com/voku", 1686 | "type": "github" 1687 | }, 1688 | { 1689 | "url": "https://opencollective.com/portable-ascii", 1690 | "type": "open_collective" 1691 | }, 1692 | { 1693 | "url": "https://www.patreon.com/voku", 1694 | "type": "patreon" 1695 | }, 1696 | { 1697 | "url": "https://tidelift.com/funding/github/packagist/voku/portable-ascii", 1698 | "type": "tidelift" 1699 | } 1700 | ], 1701 | "time": "2022-03-08T17:03:00+00:00" 1702 | } 1703 | ], 1704 | "packages-dev": [], 1705 | "aliases": [], 1706 | "minimum-stability": "stable", 1707 | "stability-flags": [], 1708 | "prefer-stable": false, 1709 | "prefer-lowest": false, 1710 | "platform": { 1711 | "php": ">=7.4" 1712 | }, 1713 | "platform-dev": [], 1714 | "plugin-api-version": "2.3.0" 1715 | } 1716 | --------------------------------------------------------------------------------