diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8c8a993 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/dist +/vendor +composer.lock \ No newline at end of file diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..cced727 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,11 @@ +{ + "trailingComma": "es5", + "tabWidth": 4, + "semi": false, + "singleQuote": false, + "endOfLine": "auto", + "bracketSameLine": true, + "html.format.wrapAttributes": "auto", + "html.format.wrapLineLength": 0, + "printWidth": 1000 +} diff --git a/LICENCE b/LICENCE new file mode 100644 index 0000000..609e13d --- /dev/null +++ b/LICENCE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 MOHAMMED BOUBAZINE + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..88db270 --- /dev/null +++ b/README.md @@ -0,0 +1,15 @@ +# Introduction + +Package supports multi payments gateways (All in one Package) for PHP + +# Instalation + +- you can install the package via composer + +```bash +composer require medboubazine/pay +``` + +# Documentation + +[Documentation](./docs/index.md) diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..8b4f07f --- /dev/null +++ b/composer.json @@ -0,0 +1,40 @@ +{ + "name": "medboubazine/pay", + "type": "library", + "description": "All In One . PHP Library for Payment Gateways", + "keywords": [ + "php", + "payment-gateway", + "paypal-checkout", + "paysera-checkout", + "chargily-pay", + "binance-pay" + ], + "license": "MIT", + "authors": [ + { + "name": "Medboubazine", + "email": "mohamedtorino161@gmail.com", + "role": "Developer" + } + ], + "require": { + "php": "^8.1", + "paypal/rest-api-sdk-php": "^1.14", + "illuminate/support": "^10.3", + "rakit/validation": "^1.4", + "webtopay/libwebtopay": "^1.8", + "medboubazine/chargily-checkout": "^1.1", + "medboubazine/binance-pay": "^1.0", + "nesbot/carbon": "^2.66" + }, + "autoload": { + "psr-4": { + "Medboubazine\\Pay\\": "src/" + } + }, + "require-dev": { + "symfony/var-dumper": "^6.2", + "symfony/error-handler": "^6.2" + } +} diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..b23f521 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,15 @@ +# Supported Payment methods + +The package supports the following gateways + +- Paypal +- Paysera +- Chargily Pay (EDAHABIA , CIB) +- Binance Pay (Crypto Currencies) + +# Documentation + +- [Paypal](./payment_methods/paypal.md) +- [Paysera](./payment_methods/paysera.md) +- [Chargily Pay](./payment_methods/chargily_pay.md) +- [Binance Pay](./payment_methods/binance_pay.md) diff --git a/docs/payment_methods/binance_pay.md b/docs/payment_methods/binance_pay.md new file mode 100644 index 0000000..b2f21b4 --- /dev/null +++ b/docs/payment_methods/binance_pay.md @@ -0,0 +1,64 @@ +# Payment Method: Binance Pay + +## Create payment + +```php +$pay = new Pay(); + +$credentials = new Credentials(); + +$credentials->setEnv("");//'sandbox' for testing OR 'live' for production +$credentials->setApiKey("");// Api Key +$credentials->setSecretKey("");//Secret Key +$credentials->setPaymentExpirationTime(60 * 30); //Paymen Expiration in seconds + +$attributes = new Attributes(); + +$attributes->setOrderId("");//Order ID Must Be UNIQUE +$attributes->setAmount("");//Amount +$attributes->setCurrency("");//BUSD or USDT +$attributes->setDescription("");//Order Description +$attributes->setBackUrl("");//Back Url (Must be Active Url) +$attributes->setProcessUrl("");//Payment Processing Url (Must be Active Url) + + +$payment = Pay::createPayment(Pay::PM_BINANCE_PAY, $credentials, $attributes); + + +if ($payment) { + $payment_id = $payment->getId(); + $url = $payment->getId(); + //redirect to url +} else { + // "Payment creation failed +} + +``` + +## Process payment + +```php + +$pay = new Pay(); + +$credentials = new Credentials(); + +$credentials->setApiKey(""); +$credentials->setSecretKey(""); + +$attributes = new Attributes(); + + +$payment = Pay::processPayment(Pay::PM_BINANCE_PAY, $credentials, $attributes); + +if($payment){ + if($payment->getStatus() === "approved"){ + //payment is confirmed + }elseif($payment->getStatus() === "canceled"){ + //payment is canceled + }else($payment->getStatus() === "failed"){ + //payment is failed + } +} + +``` diff --git a/docs/payment_methods/chargily_pay.md b/docs/payment_methods/chargily_pay.md new file mode 100644 index 0000000..024445b --- /dev/null +++ b/docs/payment_methods/chargily_pay.md @@ -0,0 +1,64 @@ +# Payment Method: Chargily Pay + +## Create payment + +```php + +$credentials = new Credentials(); + +$credentials->setApiKey("");// Api Key +$credentials->setSecretKey("");// Secret Key + +$attributes = new Attributes(); + +$attributes->setOrderId("");//Order/Invoice ID +$attributes->setClientFullName("");//Client Fullname/username +$attributes->setClientEmail("");//client email +$attributes->setAmount("");//Amount +$attributes->setDiscount("");//Discount +$attributes->setMethod("");//DAHABIA or CIB +$attributes->setDescription("");//Order Description +$attributes->setBackUrl("");//Back Url (Must be Active Url) +$attributes->setProcessUrl("");//Payment Processing Url (Must be Active Url) + + +$payment = Pay::createPayment(Pay::PM_CHARGILY_PAY, $credentials, $attributes); + + + +if ($payment) { + $payment_id = $payment->getId(); + $url = $payment->getId(); + //redirect to url +} else { + // "Payment creation failed +} + +``` + +## Process payment + +```php + +$pay = new Pay(); + +$credentials = new Credentials(); + +$credentials->setApiKey(""); +$credentials->setSecretKey(""); + +$attributes = new Attributes(); + +$payment = Pay::processPayment(Pay::PM_CHARGILY_PAY, $credentials, $attributes); + +if($payment){ + if($payment->getStatus() === "approved"){ + //payment is confirmed + }elseif($payment->getStatus() === "canceled"){ + //payment is canceled + }else($payment->getStatus() === "failed"){ + //payment is failed + } +} + +``` diff --git a/docs/payment_methods/paypal.md b/docs/payment_methods/paypal.md new file mode 100644 index 0000000..cb0524c --- /dev/null +++ b/docs/payment_methods/paypal.md @@ -0,0 +1,64 @@ +# Payment Method: Paypal + +## Create payment + +```php + +$credentials = new Credentials(); + +$credentials->setEnv("sandbox"); //sandbox OR live +$credentials->setApiKey(""); //Your paypal Api Key +$credentials->setSecretKey(""); //Your paypal Api Key +$credentials->setLogEnabled(false); +//if logEnabled set is true uncoment next line +//$credentials->setLogPath(__DIR__ . "/log/paypal_log.log"); + +$attributes = new Attributes(); + +$attributes->setAmount("10"); +$attributes->setCurrency("USD"); +$attributes->setDescription("Order Amount"); +$attributes->setProcessUrl("/dist/process.php"); // Payment process page +$attributes->setBackUrl("/back.php"); + +$payment = Pay::createPayment(Pay::PM_PAYPAL, $credentials, $attributes); + +if ($payment) { + $payment_id = $payment->getId(); + $url = $payment->getId(); + //redirect to url +} else { + // "Payment creation failed +} + +``` + +## Process payment + +```php +$pay = new Pay(); + +$credentials = new Credentials(); + +$credentials->setEnv(""); +$credentials->setApiKey(""); +$credentials->setSecretKey(""); +$credentials->setLogEnabled(false); +$credentials->setLogPath(__DIR__ . "/log/paypal_log.log"); + +$attributes = new Attributes(); +$attributes->setAcceptOnlyVerifiedAccounts(false); + +$payment = Pay::processPayment(Pay::PM_PAYPAL, $credentials, $attributes); + +if($payment){ + if($payment->getStatus() === "approved"){ + //payment is confirmed + }elseif($payment->getStatus() === "canceled"){ + //payment is canceled + }else($payment->getStatus() === "failed"){ + //payment is failed + } +} + +``` diff --git a/docs/payment_methods/paysera.md b/docs/payment_methods/paysera.md new file mode 100644 index 0000000..3238287 --- /dev/null +++ b/docs/payment_methods/paysera.md @@ -0,0 +1,64 @@ +# Payment Method: Paysera + +## Create payment + +```php +$pay = new Pay(); + +$credentials = new Credentials(); + +$credentials->setEnv("");//'sandbox' for testing Or 'live' for production +$credentials->setProjectId("");//Project Id +$credentials->setSignPassword("");//Sign password + +$attributes = new Attributes(); + +$attributes->setOrderId("");//Order/Invoice Number +$attributes->setAmount("");//Amount +$attributes->setCurrency("");//Currency +$attributes->setCountry("");//Country +$attributes->setBackUrl("");//Back Url +$attributes->setProcessUrl("");//Payment Processing url + + +$payment = Pay::createPayment(Pay::PM_PAYSERA, $credentials, $attributes); + +if ($payment) { + $payment_id = $payment->getId(); + $url = $payment->getId(); + //redirect to url +} else { + // "Payment creation failed +} + +``` + +## Process payment + +```php +$pay = new Pay(); + +$credentials = new Credentials(); + +$credentials->setProjectId(""); +$credentials->setSignPassword(""); + +$attributes = new Attributes(); + +$attributes->setAllowTestPayments(false); +$attributes->setAcceptOnlyMacroPayments(true); + +$payment = Pay::processPayment(Pay::PM_PAYSERA, $credentials, $attributes); + + +if($payment){ + if($payment->getStatus() === "approved"){ + //payment is confirmed + }elseif($payment->getStatus() === "canceled"){ + //payment is canceled + }else($payment->getStatus() === "failed"){ + //payment is failed + } +} + +``` diff --git a/src/Core/Abstracts/PaymentMethod.php b/src/Core/Abstracts/PaymentMethod.php new file mode 100644 index 0000000..d1c35fc --- /dev/null +++ b/src/Core/Abstracts/PaymentMethod.php @@ -0,0 +1,136 @@ +validation()['create']['credentials'] => $credentials, + $this->validation()['create']['attributes'] => $attributes, + ]; + + foreach ($validations as $class => $args) { + $validation = new $class($args->all()); + if (!$validation->passed()) { + throw new ValidationException("(" . substr(get_class($args), strrpos(get_class($args), '\\') + 1) . " is invalid) : " . json_encode($validation->errors()), 1); + } + } + + return null; + } + /** + * Process Payment + * + * @param Credentials $credentials + * @param Attributes $attributes + * @return Payment|null + */ + public function processPayment(Credentials $credentials, Attributes $attributes): ?Payment + { + $validations = [ + $this->validation()['process']['credentials'] => $credentials, + $this->validation()['process']['attributes'] => $attributes, + ]; + + foreach ($validations as $class => $args) { + $validation = new $class($args->all()); + if (!$validation->passed()) { + throw new ValidationException("(" . substr(get_class($args), strrpos(get_class($args), '\\') + 1) . " is invalid) : " . json_encode($validation->errors()), 1); + } + } + return null; + } + /** + * get process messages + * + * @return void + */ + public function getProcessMessages(): array + { + return $this->process_messages; + } + /** + * get process messages + * + * @return void + */ + public function setProcessMessages(string $key, string $value) + { + $this->process_messages[$key] = $value; + return $this; + } + /** + * Set payment + * + * @param Payment $payment + * @return self + */ + public function setPayment(Payment $payment) + { + $this->payment = $payment; + return $this; + } + /** + * Get payment + * + * @return Payment + */ + public function getPayment(): ?Payment + { + return $this->payment ?? null; + } + /** + * Validations + * + * @return array + */ + public function validation(): array + { + return []; + } +} diff --git a/src/Core/Abstracts/Validation.php b/src/Core/Abstracts/Validation.php new file mode 100644 index 0000000..47aced0 --- /dev/null +++ b/src/Core/Abstracts/Validation.php @@ -0,0 +1,54 @@ +make($data, $this->rules()); + + $validation->validate(); + + $this->validation = $validation; + } + /** + * Rules + * + * @return array + */ + public function rules(): array + { + return []; + } + /** + * Errors + * + * @return array + */ + public function errors(): array + { + return ($this->validation) ? $this->validation->errors()->toArray() : []; + } + /** + * Errors + * + * @return array + */ + public function passed(): bool + { + return ($this->validation) ? !$this->validation->fails() : true; + } +} diff --git a/src/Core/Elements/Attributes.php b/src/Core/Elements/Attributes.php new file mode 100644 index 0000000..f7ee405 --- /dev/null +++ b/src/Core/Elements/Attributes.php @@ -0,0 +1,45 @@ +attributes[$attribute_name] = ($arguments[0] ?? null); + return $this; + } + if ($f3_chars == 'get') { + $attribute_name = Str::snake(Str::substr($name, 3, 99)); + return $this->attributes[$attribute_name] ?? null; + } + } + /** + * All + * + * @return array + */ + public function all() + { + return $this->attributes; + } +} diff --git a/src/Core/Elements/Credentials.php b/src/Core/Elements/Credentials.php new file mode 100644 index 0000000..168ba24 --- /dev/null +++ b/src/Core/Elements/Credentials.php @@ -0,0 +1,45 @@ +attributes[$attribute_name] = ($arguments[0] ?? null); + return $this; + } + if ($f3_chars == 'get') { + $attribute_name = Str::snake(Str::substr($name, 3, 99)); + return $this->attributes[$attribute_name] ?? null; + } + } + /** + * All + * + * @return array + */ + public function all() + { + return $this->attributes; + } +} diff --git a/src/Core/Elements/Payment.php b/src/Core/Elements/Payment.php new file mode 100644 index 0000000..a6cfcbc --- /dev/null +++ b/src/Core/Elements/Payment.php @@ -0,0 +1,45 @@ +attributes[$attribute_name] = ($arguments[0] ?? null); + return $this; + } + if ($f3_chars == 'get') { + $attribute_name = Str::snake(Str::substr($name, 3, 99)); + return $this->attributes[$attribute_name] ?? null; + } + } + /** + * All + * + * @return array + */ + public function all() + { + return $this->attributes; + } +} diff --git a/src/Core/Exceptions/InvalidMethodException.php b/src/Core/Exceptions/InvalidMethodException.php new file mode 100644 index 0000000..cc05f6f --- /dev/null +++ b/src/Core/Exceptions/InvalidMethodException.php @@ -0,0 +1,9 @@ + array('name' => 'ALGERIA', 'code' => '213'), + 'PS' => array('name' => 'PALESTINE', 'code' => '970'), + 'AD' => array('name' => 'ANDORRA', 'code' => '376'), + 'AE' => array('name' => 'UNITED ARAB EMIRATES', 'code' => '971'), + 'AF' => array('name' => 'AFGHANISTAN', 'code' => '93'), + 'AG' => array('name' => 'ANTIGUA AND BARBUDA', 'code' => '1268'), + 'AI' => array('name' => 'ANGUILLA', 'code' => '1264'), + 'AL' => array('name' => 'ALBANIA', 'code' => '355'), + 'AM' => array('name' => 'ARMENIA', 'code' => '374'), + 'AN' => array('name' => 'NETHERLANDS ANTILLES', 'code' => '599'), + 'AO' => array('name' => 'ANGOLA', 'code' => '244'), + 'AQ' => array('name' => 'ANTARCTICA', 'code' => '672'), + 'AR' => array('name' => 'ARGENTINA', 'code' => '54'), + 'AS' => array('name' => 'AMERICAN SAMOA', 'code' => '1684'), + 'AT' => array('name' => 'AUSTRIA', 'code' => '43'), + 'AU' => array('name' => 'AUSTRALIA', 'code' => '61'), + 'AW' => array('name' => 'ARUBA', 'code' => '297'), + 'AZ' => array('name' => 'AZERBAIJAN', 'code' => '994'), + 'BA' => array('name' => 'BOSNIA AND HERZEGOVINA', 'code' => '387'), + 'BB' => array('name' => 'BARBADOS', 'code' => '1246'), + 'BD' => array('name' => 'BANGLADESH', 'code' => '880'), + 'BE' => array('name' => 'BELGIUM', 'code' => '32'), + 'BF' => array('name' => 'BURKINA FASO', 'code' => '226'), + 'BG' => array('name' => 'BULGARIA', 'code' => '359'), + 'BH' => array('name' => 'BAHRAIN', 'code' => '973'), + 'BI' => array('name' => 'BURUNDI', 'code' => '257'), + 'BJ' => array('name' => 'BENIN', 'code' => '229'), + 'BL' => array('name' => 'SAINT BARTHELEMY', 'code' => '590'), + 'BM' => array('name' => 'BERMUDA', 'code' => '1441'), + 'BN' => array('name' => 'BRUNEI DARUSSALAM', 'code' => '673'), + 'BO' => array('name' => 'BOLIVIA', 'code' => '591'), + 'BR' => array('name' => 'BRAZIL', 'code' => '55'), + 'BS' => array('name' => 'BAHAMAS', 'code' => '1242'), + 'BT' => array('name' => 'BHUTAN', 'code' => '975'), + 'BW' => array('name' => 'BOTSWANA', 'code' => '267'), + 'BY' => array('name' => 'BELARUS', 'code' => '375'), + 'BZ' => array('name' => 'BELIZE', 'code' => '501'), + 'CA' => array('name' => 'CANADA', 'code' => '1'), + 'CC' => array('name' => 'COCOS (KEELING) ISLANDS', 'code' => '61'), + 'CD' => array('name' => 'CONGO, THE DEMOCRATIC REPUBLIC OF THE', 'code' => '243'), + 'CF' => array('name' => 'CENTRAL AFRICAN REPUBLIC', 'code' => '236'), + 'CG' => array('name' => 'CONGO', 'code' => '242'), + 'CH' => array('name' => 'SWITZERLAND', 'code' => '41'), + 'CI' => array('name' => 'COTE D IVOIRE', 'code' => '225'), + 'CK' => array('name' => 'COOK ISLANDS', 'code' => '682'), + 'CL' => array('name' => 'CHILE', 'code' => '56'), + 'CM' => array('name' => 'CAMEROON', 'code' => '237'), + 'CN' => array('name' => 'CHINA', 'code' => '86'), + 'CO' => array('name' => 'COLOMBIA', 'code' => '57'), + 'CR' => array('name' => 'COSTA RICA', 'code' => '506'), + 'CU' => array('name' => 'CUBA', 'code' => '53'), + 'CV' => array('name' => 'CAPE VERDE', 'code' => '238'), + 'CX' => array('name' => 'CHRISTMAS ISLAND', 'code' => '61'), + 'CY' => array('name' => 'CYPRUS', 'code' => '357'), + 'CZ' => array('name' => 'CZECH REPUBLIC', 'code' => '420'), + 'DE' => array('name' => 'GERMANY', 'code' => '49'), + 'DJ' => array('name' => 'DJIBOUTI', 'code' => '253'), + 'DK' => array('name' => 'DENMARK', 'code' => '45'), + 'DM' => array('name' => 'DOMINICA', 'code' => '1767'), + 'DO' => array('name' => 'DOMINICAN REPUBLIC', 'code' => '1809'), + 'EC' => array('name' => 'ECUADOR', 'code' => '593'), + 'EE' => array('name' => 'ESTONIA', 'code' => '372'), + 'EG' => array('name' => 'EGYPT', 'code' => '20'), + 'ER' => array('name' => 'ERITREA', 'code' => '291'), + 'ES' => array('name' => 'SPAIN', 'code' => '34'), + 'ET' => array('name' => 'ETHIOPIA', 'code' => '251'), + 'FI' => array('name' => 'FINLAND', 'code' => '358'), + 'FJ' => array('name' => 'FIJI', 'code' => '679'), + 'FK' => array('name' => 'FALKLAND ISLANDS (MALVINAS)', 'code' => '500'), + 'FM' => array('name' => 'MICRONESIA, FEDERATED STATES OF', 'code' => '691'), + 'FO' => array('name' => 'FAROE ISLANDS', 'code' => '298'), + 'FR' => array('name' => 'FRANCE', 'code' => '33'), + 'GA' => array('name' => 'GABON', 'code' => '241'), + 'GB' => array('name' => 'UNITED KINGDOM', 'code' => '44'), + 'GD' => array('name' => 'GRENADA', 'code' => '1473'), + 'GE' => array('name' => 'GEORGIA', 'code' => '995'), + 'GH' => array('name' => 'GHANA', 'code' => '233'), + 'GI' => array('name' => 'GIBRALTAR', 'code' => '350'), + 'GL' => array('name' => 'GREENLAND', 'code' => '299'), + 'GM' => array('name' => 'GAMBIA', 'code' => '220'), + 'GN' => array('name' => 'GUINEA', 'code' => '224'), + 'GQ' => array('name' => 'EQUATORIAL GUINEA', 'code' => '240'), + 'GR' => array('name' => 'GREECE', 'code' => '30'), + 'GT' => array('name' => 'GUATEMALA', 'code' => '502'), + 'GU' => array('name' => 'GUAM', 'code' => '1671'), + 'GW' => array('name' => 'GUINEA-BISSAU', 'code' => '245'), + 'GY' => array('name' => 'GUYANA', 'code' => '592'), + 'HK' => array('name' => 'HONG KONG', 'code' => '852'), + 'HN' => array('name' => 'HONDURAS', 'code' => '504'), + 'HR' => array('name' => 'CROATIA', 'code' => '385'), + 'HT' => array('name' => 'HAITI', 'code' => '509'), + 'HU' => array('name' => 'HUNGARY', 'code' => '36'), + 'ID' => array('name' => 'INDONESIA', 'code' => '62'), + 'IE' => array('name' => 'IRELAND', 'code' => '353'), + 'IM' => array('name' => 'ISLE OF MAN', 'code' => '44'), + 'IN' => array('name' => 'INDIA', 'code' => '91'), + 'IQ' => array('name' => 'IRAQ', 'code' => '964'), + 'IR' => array('name' => 'IRAN, ISLAMIC REPUBLIC OF', 'code' => '98'), + 'IS' => array('name' => 'ICELAND', 'code' => '354'), + 'IT' => array('name' => 'ITALY', 'code' => '39'), + 'JM' => array('name' => 'JAMAICA', 'code' => '1876'), + 'JO' => array('name' => 'JORDAN', 'code' => '962'), + 'JP' => array('name' => 'JAPAN', 'code' => '81'), + 'KE' => array('name' => 'KENYA', 'code' => '254'), + 'KG' => array('name' => 'KYRGYZSTAN', 'code' => '996'), + 'KH' => array('name' => 'CAMBODIA', 'code' => '855'), + 'KI' => array('name' => 'KIRIBATI', 'code' => '686'), + 'KM' => array('name' => 'COMOROS', 'code' => '269'), + 'KN' => array('name' => 'SAINT KITTS AND NEVIS', 'code' => '1869'), + 'KP' => array('name' => 'KOREA DEMOCRATIC PEOPLES REPUBLIC OF', 'code' => '850'), + 'KR' => array('name' => 'KOREA REPUBLIC OF', 'code' => '82'), + 'KW' => array('name' => 'KUWAIT', 'code' => '965'), + 'KY' => array('name' => 'CAYMAN ISLANDS', 'code' => '1345'), + 'KZ' => array('name' => 'KAZAKSTAN', 'code' => '7'), + 'LA' => array('name' => 'LAO PEOPLES DEMOCRATIC REPUBLIC', 'code' => '856'), + 'LB' => array('name' => 'LEBANON', 'code' => '961'), + 'LC' => array('name' => 'SAINT LUCIA', 'code' => '1758'), + 'LI' => array('name' => 'LIECHTENSTEIN', 'code' => '423'), + 'LK' => array('name' => 'SRI LANKA', 'code' => '94'), + 'LR' => array('name' => 'LIBERIA', 'code' => '231'), + 'LS' => array('name' => 'LESOTHO', 'code' => '266'), + 'LT' => array('name' => 'LITHUANIA', 'code' => '370'), + 'LU' => array('name' => 'LUXEMBOURG', 'code' => '352'), + 'LV' => array('name' => 'LATVIA', 'code' => '371'), + 'LY' => array('name' => 'LIBYAN ARAB JAMAHIRIYA', 'code' => '218'), + 'MA' => array('name' => 'MOROCCO', 'code' => '212'), + 'MC' => array('name' => 'MONACO', 'code' => '377'), + 'MD' => array('name' => 'MOLDOVA, REPUBLIC OF', 'code' => '373'), + 'ME' => array('name' => 'MONTENEGRO', 'code' => '382'), + 'MF' => array('name' => 'SAINT MARTIN', 'code' => '1599'), + 'MG' => array('name' => 'MADAGASCAR', 'code' => '261'), + 'MH' => array('name' => 'MARSHALL ISLANDS', 'code' => '692'), + 'MK' => array('name' => 'MACEDONIA, THE FORMER YUGOSLAV REPUBLIC OF', 'code' => '389'), + 'ML' => array('name' => 'MALI', 'code' => '223'), + 'MM' => array('name' => 'MYANMAR', 'code' => '95'), + 'MN' => array('name' => 'MONGOLIA', 'code' => '976'), + 'MO' => array('name' => 'MACAU', 'code' => '853'), + 'MP' => array('name' => 'NORTHERN MARIANA ISLANDS', 'code' => '1670'), + 'MR' => array('name' => 'MAURITANIA', 'code' => '222'), + 'MS' => array('name' => 'MONTSERRAT', 'code' => '1664'), + 'MT' => array('name' => 'MALTA', 'code' => '356'), + 'MU' => array('name' => 'MAURITIUS', 'code' => '230'), + 'MV' => array('name' => 'MALDIVES', 'code' => '960'), + 'MW' => array('name' => 'MALAWI', 'code' => '265'), + 'MX' => array('name' => 'MEXICO', 'code' => '52'), + 'MY' => array('name' => 'MALAYSIA', 'code' => '60'), + 'MZ' => array('name' => 'MOZAMBIQUE', 'code' => '258'), + 'NA' => array('name' => 'NAMIBIA', 'code' => '264'), + 'NC' => array('name' => 'NEW CALEDONIA', 'code' => '687'), + 'NE' => array('name' => 'NIGER', 'code' => '227'), + 'NG' => array('name' => 'NIGERIA', 'code' => '234'), + 'NI' => array('name' => 'NICARAGUA', 'code' => '505'), + 'NL' => array('name' => 'NETHERLANDS', 'code' => '31'), + 'NO' => array('name' => 'NORWAY', 'code' => '47'), + 'NP' => array('name' => 'NEPAL', 'code' => '977'), + 'NR' => array('name' => 'NAURU', 'code' => '674'), + 'NU' => array('name' => 'NIUE', 'code' => '683'), + 'NZ' => array('name' => 'NEW ZEALAND', 'code' => '64'), + 'OM' => array('name' => 'OMAN', 'code' => '968'), + 'PA' => array('name' => 'PANAMA', 'code' => '507'), + 'PE' => array('name' => 'PERU', 'code' => '51'), + 'PF' => array('name' => 'FRENCH POLYNESIA', 'code' => '689'), + 'PG' => array('name' => 'PAPUA NEW GUINEA', 'code' => '675'), + 'PH' => array('name' => 'PHILIPPINES', 'code' => '63'), + 'PK' => array('name' => 'PAKISTAN', 'code' => '92'), + 'PL' => array('name' => 'POLAND', 'code' => '48'), + 'PM' => array('name' => 'SAINT PIERRE AND MIQUELON', 'code' => '508'), + 'PN' => array('name' => 'PITCAIRN', 'code' => '870'), + 'PR' => array('name' => 'PUERTO RICO', 'code' => '1'), + 'PT' => array('name' => 'PORTUGAL', 'code' => '351'), + 'PW' => array('name' => 'PALAU', 'code' => '680'), + 'PY' => array('name' => 'PARAGUAY', 'code' => '595'), + 'QA' => array('name' => 'QATAR', 'code' => '974'), + 'RO' => array('name' => 'ROMANIA', 'code' => '40'), + 'RS' => array('name' => 'SERBIA', 'code' => '381'), + 'RU' => array('name' => 'RUSSIAN FEDERATION', 'code' => '7'), + 'RW' => array('name' => 'RWANDA', 'code' => '250'), + 'SA' => array('name' => 'SAUDI ARABIA', 'code' => '966'), + 'SB' => array('name' => 'SOLOMON ISLANDS', 'code' => '677'), + 'SC' => array('name' => 'SEYCHELLES', 'code' => '248'), + 'SD' => array('name' => 'SUDAN', 'code' => '249'), + 'SE' => array('name' => 'SWEDEN', 'code' => '46'), + 'SG' => array('name' => 'SINGAPORE', 'code' => '65'), + 'SH' => array('name' => 'SAINT HELENA', 'code' => '290'), + 'SI' => array('name' => 'SLOVENIA', 'code' => '386'), + 'SK' => array('name' => 'SLOVAKIA', 'code' => '421'), + 'SL' => array('name' => 'SIERRA LEONE', 'code' => '232'), + 'SM' => array('name' => 'SAN MARINO', 'code' => '378'), + 'SN' => array('name' => 'SENEGAL', 'code' => '221'), + 'SO' => array('name' => 'SOMALIA', 'code' => '252'), + 'SR' => array('name' => 'SURINAME', 'code' => '597'), + 'ST' => array('name' => 'SAO TOME AND PRINCIPE', 'code' => '239'), + 'SV' => array('name' => 'EL SALVADOR', 'code' => '503'), + 'SY' => array('name' => 'SYRIAN ARAB REPUBLIC', 'code' => '963'), + 'SZ' => array('name' => 'SWAZILAND', 'code' => '268'), + 'TC' => array('name' => 'TURKS AND CAICOS ISLANDS', 'code' => '1649'), + 'TD' => array('name' => 'CHAD', 'code' => '235'), + 'TG' => array('name' => 'TOGO', 'code' => '228'), + 'TH' => array('name' => 'THAILAND', 'code' => '66'), + 'TJ' => array('name' => 'TAJIKISTAN', 'code' => '992'), + 'TK' => array('name' => 'TOKELAU', 'code' => '690'), + 'TL' => array('name' => 'TIMOR-LESTE', 'code' => '670'), + 'TM' => array('name' => 'TURKMENISTAN', 'code' => '993'), + 'TN' => array('name' => 'TUNISIA', 'code' => '216'), + 'TO' => array('name' => 'TONGA', 'code' => '676'), + 'TR' => array('name' => 'TURKEY', 'code' => '90'), + 'TT' => array('name' => 'TRINIDAD AND TOBAGO', 'code' => '1868'), + 'TV' => array('name' => 'TUVALU', 'code' => '688'), + 'TW' => array('name' => 'TAIWAN, PROVINCE OF CHINA', 'code' => '886'), + 'TZ' => array('name' => 'TANZANIA, UNITED REPUBLIC OF', 'code' => '255'), + 'UA' => array('name' => 'UKRAINE', 'code' => '380'), + 'UG' => array('name' => 'UGANDA', 'code' => '256'), + 'US' => array('name' => 'UNITED STATES', 'code' => '1'), + 'UY' => array('name' => 'URUGUAY', 'code' => '598'), + 'UZ' => array('name' => 'UZBEKISTAN', 'code' => '998'), + 'VA' => array('name' => 'HOLY SEE (VATICAN CITY STATE)', 'code' => '39'), + 'VC' => array('name' => 'SAINT VINCENT AND THE GRENADINES', 'code' => '1784'), + 'VE' => array('name' => 'VENEZUELA', 'code' => '58'), + 'VG' => array('name' => 'VIRGIN ISLANDS, BRITISH', 'code' => '1284'), + 'VI' => array('name' => 'VIRGIN ISLANDS, U.S.', 'code' => '1340'), + 'VN' => array('name' => 'VIET NAM', 'code' => '84'), + 'VU' => array('name' => 'VANUATU', 'code' => '678'), + 'WF' => array('name' => 'WALLIS AND FUTUNA', 'code' => '681'), + 'WS' => array('name' => 'SAMOA', 'code' => '685'), + 'XK' => array('name' => 'KOSOVO', 'code' => '381'), + 'YE' => array('name' => 'YEMEN', 'code' => '967'), + 'YT' => array('name' => 'MAYOTTE', 'code' => '262'), + 'ZA' => array('name' => 'SOUTH AFRICA', 'code' => '27'), + 'ZM' => array('name' => 'ZAMBIA', 'code' => '260'), + 'ZW' => array('name' => 'ZIMBABWE', 'code' => '263') + ]; + } +} diff --git a/src/Core/Helpers/Currencies.php b/src/Core/Helpers/Currencies.php new file mode 100644 index 0000000..b6bd065 --- /dev/null +++ b/src/Core/Helpers/Currencies.php @@ -0,0 +1,194 @@ + "Afghan Afghani", + "ALL" => "Albanian Lek", + "DZD" => "Algerian Dinar", + "AOA" => "Angolan Kwanza", + "ARS" => "Argentine Peso", + "AMD" => "Armenian Dram", + "AWG" => "Aruban Florin", + "AUD" => "Australian Dollar", + "AZN" => "Azerbaijani Manat", + "BSD" => "Bahamian Dollar", + "BHD" => "Bahraini Dinar", + "BDT" => "Bangladeshi Taka", + "BBD" => "Barbadian Dollar", + "BYR" => "Belarusian Ruble", + "BEF" => "Belgian Franc", + "BZD" => "Belize Dollar", + "BMD" => "Bermudan Dollar", + "BTN" => "Bhutanese Ngultrum", + "BTC" => "Bitcoin", + "BOB" => "Bolivian Boliviano", + "BAM" => "Bosnia-Herzegovina Convertible Mark", + "BWP" => "Botswanan Pula", + "BRL" => "Brazilian Real", + "GBP" => "British Pound Sterling", + "BND" => "Brunei Dollar", + "BGN" => "Bulgarian Lev", + "BIF" => "Burundian Franc", + "KHR" => "Cambodian Riel", + "CAD" => "Canadian Dollar", + "CVE" => "Cape Verdean Escudo", + "KYD" => "Cayman Islands Dollar", + "XOF" => "CFA Franc BCEAO", + "XAF" => "CFA Franc BEAC", + "XPF" => "CFP Franc", + "CLP" => "Chilean Peso", + "CLF" => "Chilean Unit of Account", + "CNY" => "Chinese Yuan", + "COP" => "Colombian Peso", + "KMF" => "Comorian Franc", + "CDF" => "Congolese Franc", + "CRC" => "Costa Rican Colón", + "HRK" => "Croatian Kuna", + "CUC" => "Cuban Convertible Peso", + "CZK" => "Czech Republic Koruna", + "DKK" => "Danish Krone", + "DJF" => "Djiboutian Franc", + "DOP" => "Dominican Peso", + "XCD" => "East Caribbean Dollar", + "EGP" => "Egyptian Pound", + "ERN" => "Eritrean Nakfa", + "EEK" => "Estonian Kroon", + "ETB" => "Ethiopian Birr", + "EUR" => "Euro", + "FKP" => "Falkland Islands Pound", + "FJD" => "Fijian Dollar", + "GMD" => "Gambian Dalasi", + "GEL" => "Georgian Lari", + "DEM" => "German Mark", + "GHS" => "Ghanaian Cedi", + "GIP" => "Gibraltar Pound", + "GRD" => "Greek Drachma", + "GTQ" => "Guatemalan Quetzal", + "GNF" => "Guinean Franc", + "GYD" => "Guyanaese Dollar", + "HTG" => "Haitian Gourde", + "HNL" => "Honduran Lempira", + "HKD" => "Hong Kong Dollar", + "HUF" => "Hungarian Forint", + "ISK" => "Icelandic Króna", + "INR" => "Indian Rupee", + "IDR" => "Indonesian Rupiah", + "IRR" => "Iranian Rial", + "IQD" => "Iraqi Dinar", + "ILS" => "Israeli New Sheqel", + "ITL" => "Italian Lira", + "JMD" => "Jamaican Dollar", + "JPY" => "Japanese Yen", + "JOD" => "Jordanian Dinar", + "KZT" => "Kazakhstani Tenge", + "KES" => "Kenyan Shilling", + "KWD" => "Kuwaiti Dinar", + "KGS" => "Kyrgystani Som", + "LAK" => "Laotian Kip", + "LVL" => "Latvian Lats", + "LBP" => "Lebanese Pound", + "LSL" => "Lesotho Loti", + "LRD" => "Liberian Dollar", + "LYD" => "Libyan Dinar", + "LTC" => "Litecoin", + "LTL" => "Lithuanian Litas", + "MOP" => "Macanese Pataca", + "MKD" => "Macedonian Denar", + "MGA" => "Malagasy Ariary", + "MWK" => "Malawian Kwacha", + "MYR" => "Malaysian Ringgit", + "MVR" => "Maldivian Rufiyaa", + "MRO" => "Mauritanian Ouguiya", + "MUR" => "Mauritian Rupee", + "MXN" => "Mexican Peso", + "MDL" => "Moldovan Leu", + "MNT" => "Mongolian Tugrik", + "MAD" => "Moroccan Dirham", + "MZM" => "Mozambican Metical", + "MMK" => "Myanmar Kyat", + "NAD" => "Namibian Dollar", + "NPR" => "Nepalese Rupee", + "ANG" => "Netherlands Antillean Guilder", + "TWD" => "New Taiwan Dollar", + "NZD" => "New Zealand Dollar", + "NIO" => "Nicaraguan Córdoba", + "NGN" => "Nigerian Naira", + "KPW" => "North Korean Won", + "NOK" => "Norwegian Krone", + "OMR" => "Omani Rial", + "PKR" => "Pakistani Rupee", + "PAB" => "Panamanian Balboa", + "PGK" => "Papua New Guinean Kina", + "PYG" => "Paraguayan Guarani", + "PEN" => "Peruvian Nuevo Sol", + "PHP" => "Philippine Peso", + "PLN" => "Polish Zloty", + "QAR" => "Qatari Rial", + "RON" => "Romanian Leu", + "RUB" => "Russian Ruble", + "RWF" => "Rwandan Franc", + "SVC" => "Salvadoran Colón", + "WST" => "Samoan Tala", + "STD" => "São Tomé and Príncipe Dobra", + "SAR" => "Saudi Riyal", + "RSD" => "Serbian Dinar", + "SCR" => "Seychellois Rupee", + "SLL" => "Sierra Leonean Leone", + "SGD" => "Singapore Dollar", + "SKK" => "Slovak Koruna", + "SBD" => "Solomon Islands Dollar", + "SOS" => "Somali Shilling", + "ZAR" => "South African Rand", + "KRW" => "South Korean Won", + "SSP" => "South Sudanese Pound", + "XDR" => "Special Drawing Rights", + "LKR" => "Sri Lankan Rupee", + "SHP" => "St. Helena Pound", + "SDG" => "Sudanese Pound", + "SRD" => "Surinamese Dollar", + "SZL" => "Swazi Lilangeni", + "SEK" => "Swedish Krona", + "CHF" => "Swiss Franc", + "SYP" => "Syrian Pound", + "TJS" => "Tajikistani Somoni", + "TZS" => "Tanzanian Shilling", + "THB" => "Thai Baht", + "TOP" => "Tongan Pa'anga", + "TTD" => "Trinidad & Tobago Dollar", + "TND" => "Tunisian Dinar", + "TRY" => "Turkish Lira", + "TMT" => "Turkmenistani Manat", + "UGX" => "Ugandan Shilling", + "UAH" => "Ukrainian Hryvnia", + "AED" => "United Arab Emirates Dirham", + "UYU" => "Uruguayan Peso", + "USD" => "US Dollar", + "UZS" => "Uzbekistan Som", + "VUV" => "Vanuatu Vatu", + "VEF" => "Venezuelan BolÃvar", + "VND" => "Vietnamese Dong", + "YER" => "Yemeni Rial", + "ZMK" => "Zambian Kwacha", + "ZWL" => "Zimbabwean dollar", + ]; + } +} diff --git a/src/Core/Helpers/PaymentStatus.php b/src/Core/Helpers/PaymentStatus.php new file mode 100644 index 0000000..b14c3d8 --- /dev/null +++ b/src/Core/Helpers/PaymentStatus.php @@ -0,0 +1,113 @@ +createPayment($credentials, $attributes); + } + /** + * process Payment + * + * @param string $method + * @param Credentials $credentials + * @param Attributes $attributes + * @return Payment|null + */ + public static function processPayment(string $method, Credentials $credentials, Attributes $attributes): ?Payment + { + if (!defined(self::class . "::PM_" . Str::upper($method))) { + throw new InvalidMethodException("{$method} is invalid payment method"); + } + + $pm_methods = self::payment_methods(); + + if (!in_array($method, array_keys($pm_methods))) { + throw new InvalidMethodException("'{$method}' is invalid payment method . Allowed methods is : " . implode(",", array_keys($pm_methods))); + } + + $class = $pm_methods[$method]; + $pm = new $class; + + return $pm->processPayment($credentials, $attributes); + } + + /** + * Payment methods + * + * @return array + */ + public static function payment_methods(): array + { + return [ + "binance_pay" => BinancePay::class, + "chargily_pay" => ChargilyPay::class, + "payeer" => Payeer::class, + "paypal" => Paypal::class, + "paysera" => Paysera::class, + ]; + } +} diff --git a/src/PaymentMethods/BinancePay.php b/src/PaymentMethods/BinancePay.php new file mode 100644 index 0000000..81f81a1 --- /dev/null +++ b/src/PaymentMethods/BinancePay.php @@ -0,0 +1,139 @@ +addSeconds($credentials->getPaymentExpirationTime()) + ->valueOf()); + // + $binance_credentials = new ResourcesCredentials(); + $binance_credentials->setApiKey($credentials->getApiKey()) + ->setApiSecret($credentials->getSecretKey()) + ->setEnvTerminalType("WEB"); + // + $order_id = ($credentials->getEnv() === "sandbox") ? "test{$attributes->getOrderId()}" : $attributes->getOrderId(); + + $order = new Order(); + $order->setId($order_id) + ->setAmount($attributes->getAmount()) + ->setCurrency($attributes->getCurrency()) + ->setAllowedCurrencies(["BUSD", "USDT", "BNB"]) + ->setExpireTime($timestamp); + // + $product = new Product; + $product->setId(Str::slug($attributes->getDescription())) + ->setType("02") + ->setCategory("6000") + ->setName($attributes->getDescription()); + // + $urls = new Urls(); + $urls->setReturnUrl($attributes->getBackUrl()) + ->setCancelUrl($attributes->getBackUrl()) + ->setWebhookUrl($attributes->getProcessUrl()); + // + $binance = new Binance(); + //create payment + $binance_payment = $binance->getCheckoutUrl($binance_credentials, $order, $product, $urls); + + if ($binance_payment instanceof \Medboubazine\BinancePay\Core\PayPayment) { + return (new Payment) + ->setId($binance_payment->getPrepayId()) + ->setUrl($binance_payment->getCheckoutUrl()); + } + + // + return null; + } + /** + * Process payment + * + * @return Payment|null + */ + public function processPayment(Credentials $credentials, Attributes $attributes): ?Payment + { + parent::processPayment($credentials, $attributes); + + $binance_credentials = new \Medboubazine\BinancePay\Core\Resources\Credentials(); + $binance_credentials->setApiKey($credentials->getApiKey()) + ->setApiSecret($credentials->getSecretKey()) + ->setEnvTerminalType("WEB"); + // + $binance = new \Medboubazine\BinancePay\Binance(); + // + $webhook_status = $binance->checkWebhook($binance_credentials); + $webhook_status_pay_id = $binance->getWebhookPayId(); + $binance_payment = $binance->getPayment($binance_credentials, $webhook_status_pay_id); //5059 + + if ($webhook_status && $binance_payment) { + $f_name = null; + $l_name = null; + $full_name = null; + $status = PaymentStatus::binancePay($binance_payment->getStatus()); + // + return (new Payment()) + //REQUIRED + ->setId($binance_payment->getPrepayId()) + ->setOrderId($binance_payment->getId()) + ->setStatus($status) + ->setPayerFirstName($f_name) + ->setPayerLastName($l_name) + ->setPayerFullName($full_name) + ->setAmount($binance_payment->getAmount()) + ->setFee("0.00") + ->setTotal($binance_payment->getAmount()) + ->setCurrency($binance_payment->getCurrency()) + //Optional + ->setCreatedAt(Carbon::parse($binance_payment->getCreatedAt(), $binance_payment->getTimeZone())); + } + return null; + } + /** + * Validations + * + * @return array + */ + public function validation(): array + { + return [ + "create" => [ + "credentials" => BinancePayCredentialsForCreateValidation::class, + "attributes" => BinancePayAttributesForCreateValidation::class, + ], + "process" => [ + "credentials" => BinancePayCredentialsForProcessValidation::class, + "attributes" => BinancePayAttributesForProcessValidation::class, + ], + ]; + } +} diff --git a/src/PaymentMethods/ChargilyPay.php b/src/PaymentMethods/ChargilyPay.php new file mode 100644 index 0000000..b8d30a8 --- /dev/null +++ b/src/PaymentMethods/ChargilyPay.php @@ -0,0 +1,130 @@ + $credentials->getApiKey(), + 'api_secret' => $credentials->getSecretKey(), + 'urls' => [ + 'back_url' => $attributes->getBackUrl(), + 'webhook_url' => $attributes->getProcessUrl(), + ], + 'mode' => $attributes->getMethod(), + 'payment' => [ + 'number' => (string) $attributes->getOrderId(), + 'client_name' => $attributes->getClientFullName(), + 'client_email' => $attributes->getClientEmail(), + 'amount' => $attributes->getAmount(), + 'discount' => $attributes->getDiscount() ?? 0, + 'description' => $attributes->getDescription(), + ], + "options" => [ + "headers" => [], + "timeout" => 20, + ], + ]; + $chargily = new Chargily($configurations); + $url = $chargily->getRedirectUrl(); + + if (filter_var($url, FILTER_VALIDATE_URL)) { + return (new Payment) + ->setId($attributes->getOrderId()) + ->setUrl($url); + } + + return null; + } + /** + * Process payment + * + * @return Payment|null + */ + public function processPayment(Credentials $credentials, Attributes $attributes): ?Payment + { + parent::processPayment($credentials, $attributes); + // + try { + $chargily = new Chargily([ + 'api_key' => $credentials->getApiKey(), + 'api_secret' => $credentials->getSecretKey(), + ]); + if ($chargily->checkResponse()) { + $response = $chargily->getResponseDetails(); + $response = $response["invoice"]; + + $f_name = $response['client'] ?? null; + $l_name = null; + $full_name = "{$f_name} {$l_name}"; + $status = PaymentStatus::chargilyPay($response['status']); + + return (new Payment()) + //REQUIRED + ->setId($response['id']) + ->setOrderId($response['invoice_number']) + ->setStatus($status) + ->setPayerFirstName($f_name) + ->setPayerLastName($l_name) + ->setPayerFullName($full_name) + ->setAmount(strval($response['amount'])) + ->setFee(strval($response['fee'])) + ->setTotal(strval($response['due_amount'] / 100)) + ->setCurrency("DZD") + //OPTIONAL + ->setPayerEmail($response['client_email']) + ->setDiscount($response['discount']) + ->setDescription($response['comment']) + ->setMode($response['mode']) + ->setNew($response['new'] == "1") + ->setToken($response['invoice_token']); + } + } catch (Throwable) { + } + + return null; + } + /** + * Validations + * + * @return array + */ + public function validation(): array + { + return [ + "create" => [ + "credentials" => ChargilyPayCredentialsForCreateValidation::class, + "attributes" => ChargilyPayAttributesForCreateValidation::class, + ], + "process" => [ + "credentials" => ChargilyPayCredentialsForProcessValidation::class, + "attributes" => ChargilyPayAttributesForProcessValidation::class, + ], + ]; + } +} diff --git a/src/PaymentMethods/Payeer.php b/src/PaymentMethods/Payeer.php new file mode 100644 index 0000000..0ed35c4 --- /dev/null +++ b/src/PaymentMethods/Payeer.php @@ -0,0 +1,80 @@ +setId() + ->setOrderId() + ->setStatus($status) + ->setPayerFirstName($f_name) + ->setPayerLastName($l_name) + ->setPayerFullName($full_name) + ->setAmount() + ->setFee() + ->setTotal() + ->setCurrency(); + + return null; + } + /** + * Validations + * + * @return array + */ + public function validation(): array + { + return [ + "create" => [ + "credentials" => PayeerCredentialsForCreateValidation::class, + "attributes" => PayeerAttributesForCreateValidation::class, + ], + "process" => [ + "credentials" => PayeerCredentialsForProcessValidation::class, + "attributes" => PayeerAttributesForProcessValidation::class, + ], + ]; + } +} diff --git a/src/PaymentMethods/Paypal.php b/src/PaymentMethods/Paypal.php new file mode 100644 index 0000000..2d9d80d --- /dev/null +++ b/src/PaymentMethods/Paypal.php @@ -0,0 +1,201 @@ +getApiKey(), $credentials->getSecretKey())); + $api_context->setConfig([ + 'mode' => $credentials->getEnv(), + 'log.LogEnabled' => $credentials->getLogEnabled(), + 'log.FileName' => $credentials->getLogPath(), + 'log.LogLevel' => 'DEBUG', + ]); + //Payer + $paypal_payer = new Payer(); + $paypal_payer->setPaymentMethod('paypal'); + //$item + $items = []; + $item = new Item(); + //item info + $currency = $attributes->getCurrency(); + $price = $attributes->getAmount(); + $description = $attributes->getDescription(); + $process_url = $attributes->getProcessUrl(); + $back_url = $attributes->getBackUrl(); + // + $paypal_items[] = $item->setName($description) + ->setCurrency($currency) + ->setQuantity(1) + ->setPrice($price) + ->setDescription($description); + //item list + $paypal_item_list = new ItemList(); + $paypal_item_list->setItems($items); + //details + //amount + $paypal_amount = new Amount(); + $paypal_amount->setCurrency($currency) + ->setTotal($price); + //transaction + $paypal_transaction = new Transaction(); + $paypal_transaction->setAmount($paypal_amount) + ->setItemList($paypal_item_list) + ->setDescription($description); + //redirect urls + $paypal_redirect = new RedirectUrls(); + $paypal_redirect->setReturnUrl($process_url) + ->setCancelUrl($back_url); + //payment + $paypal_payment = new PayPalPayment(); + $paypal_payment->setIntent('sale') + ->setPayer($paypal_payer) + ->setRedirectUrls($paypal_redirect) + ->setTransactions([$paypal_transaction]); + //create payment + $paypal_payment->create($api_context); + if ($paypal_payment) { + + //get DATA + $url = $paypal_payment->getApprovalLink(); + $id = $paypal_payment->getId(); + // + if (filter_var($url, FILTER_VALIDATE_URL)) { + return (new Payment) + ->setId($id) + ->setUrl($url); + } + } + return null; + } + /** + * Process payment + * + * @param Credentials $credentials + * @param Attributes $attributes + * @return Payment + */ + public function processPayment(Credentials $credentials, Attributes $attributes): ?Payment + { + parent::processPayment($credentials, $attributes); + // + $paypal_payment_id = $_GET['paymentId'] ?? null; + $paypal_payer_id = $_GET['PayerID'] ?? null; + // + $api_context = new ApiContext(new OAuthTokenCredential($credentials->getApiKey(), $credentials->getSecretKey())); + $api_context->setConfig([ + 'mode' => $credentials->getEnv(), + 'log.LogEnabled' => $credentials->getLogEnabled(), + 'log.FileName' => $credentials->getLogPath(), + 'log.LogLevel' => 'DEBUG', + ]); + // + $paypal_payment = null; + if ($paypal_payment_id and $paypal_payer_id) { + try { + $paypal_payment = PayPalPayment::get($paypal_payment_id, $api_context) ?? null; + } catch (Exception) { + return null; + } + } + // + if ($paypal_payment) { + if (!$attributes->getAcceptOnlyVerifiedAccounts() or $paypal_payment->getPayer()->getStatus() === 'VERIFIED') { + /** + * END payment execution + */ + if ($paypal_payment->getState() === "created") { + $execution = new PaymentExecution(); + $execution->setPayerId($paypal_payer_id); + $paypal_payment = $paypal_payment->execute($execution, $api_context); + } else { + $paypal_payment = $paypal_payment; + } + /** + * START payment execution + */ + $paypal_payer = $paypal_payment->getPayer(); + $paypal_payer_info = $paypal_payer->getPayerInfo(); + + $f_name = $paypal_payer_info->getFirstName() ?? null; + $l_name = $paypal_payer_info->getLastName() ?? null; + $full_name = "{$f_name} {$l_name}"; + $status = PaymentStatus::paypal($paypal_payment->getState()); + dd($paypal_payment); + + return (new Payment()) + //REQUIRED + ->setId($paypal_payment->getId()) + ->setOrderId($paypal_payment->getId()) + ->setStatus($status) + ->setPayerFirstName($f_name) + ->setPayerLastName($l_name) + ->setPayerFullName($full_name) + ->setAmount("0.00") + ->setFee("0.00") + ->setTotal("0.00") + ->setCurrency("0.00") + //OPTIONAL + ->setPayerStatus($paypal_payer->getStatus()) + ->setPayerPaymentMethod($paypal_payer->getPaymentMethod()) + ->setPayerId($paypal_payer_info->getPayerId()) + ->setPayerEmail($paypal_payer_info->getEmail()) + ->setPayerPhone($paypal_payer_info->getPhone()) + ->setPayerCountryCode($paypal_payer_info->getCountryCode()); + } + } + + return null; + } + /** + * Validations + * + * @return array + */ + public function validation(): array + { + return [ + "create" => [ + "credentials" => PaypalCredentialsForCreateValidation::class, + "attributes" => PaypalAttributesForCreateValidation::class, + ], + "process" => [ + "credentials" => PaypalCredentialsForProcessValidation::class, + "attributes" => PaypalAttributesForProcessValidation::class, + ], + ]; + } +} diff --git a/src/PaymentMethods/Paysera.php b/src/PaymentMethods/Paysera.php new file mode 100644 index 0000000..8d9fc93 --- /dev/null +++ b/src/PaymentMethods/Paysera.php @@ -0,0 +1,127 @@ + $credentials->getProjectId(), + 'sign_password' => $credentials->getSignPassword(), + 'accepturl' => $attributes->getBackUrl(), + 'cancelurl' => $attributes->getBackUrl(), + 'callbackurl' => $attributes->getProcessUrl(), + 'test' => ($credentials->getEnv() === 'sandbox') ? 1 : 0, + 'country' => $attributes->getCountry(), + ]; + // + $configurations['orderid'] = $attributes->getOrderId(); + $configurations['amount'] = ($attributes->getAmount() * 100); + $configurations['currency'] = $attributes->getCurrency(); + // + try { + $url = WebToPay::getPaymentUrl() . "?" . \http_build_query(WebToPay::buildRequest($configurations)); + // + if (filter_var($url, FILTER_VALIDATE_URL)) { + return (new Payment) + ->setUrl($url) + ->setId($attributes->getOrderId()); + } + // + } catch (Throwable) { + } + return null; + } + /** + * Process payment + * + * @return Payment|null + */ + public function processPayment(Credentials $credentials, Attributes $attributes): ?Payment + { + parent::processPayment($credentials, $attributes); + // + try { + $response = WebToPay::validateAndParseData( + $_REQUEST, + $credentials->getProjectId(), + $credentials->getSignPassword(), + ); + // + if ($response['test'] === '1' and !$attributes->getAllowTestPayments()) { + return null; + } + // + if ($response['type'] !== 'macro' and $attributes->getAcceptOnlyMacroPayments()) { + return null; + } + // + $f_name = $response['name'] ?? null; + $l_name = $response['surename'] ?? null; + $full_name = "{$f_name} {$l_name}"; + $status = PaymentStatus::paysera($response['status']); + + return (new Payment) + //REQUIRED + ->setId($response['orderid']) + ->setOrderId($response['orderid']) + ->setStatus($status) + ->setPayerFirstName($f_name) + ->setPayerLastName($l_name) + ->setPayerFullName($full_name) + ->setAmount(strval($response['amount'] / 100)) + ->setFee("0.00") + ->setTotal(strval($response['amount'] / 100)) + ->setCurrency($response['currency']) + //OPTIONAL + ->setCountry($response['country']) + ->setMethod($response['payment']) + ->setPayerEmail($response['p_email']) + ->setPayerCountry($response['payer_ip_country'] ?? null) + ->setPaymentCountry($response['payment_country'] ?? null); + } catch (Throwable) { + } + return null; + } + /** + * Validations + * + * @return array + */ + public function validation(): array + { + return [ + "create" => [ + "credentials" => PayseraCredentialsForCreateValidation::class, + "attributes" => PayseraAttributesForCreateValidation::class, + ], + "process" => [ + "credentials" => PayseraCredentialsForProcessValidation::class, + "attributes" => PayseraAttributesForProcessValidation::class, + ], + ]; + } +} diff --git a/src/Validation/BinancePay/BinancePayAttributesForCreateValidation.php b/src/Validation/BinancePay/BinancePayAttributesForCreateValidation.php new file mode 100644 index 0000000..b1f76d1 --- /dev/null +++ b/src/Validation/BinancePay/BinancePayAttributesForCreateValidation.php @@ -0,0 +1,25 @@ + "required|numeric|min:0.01", + "currency" => "required|min:3|in:BUSD,USDT", + "description" => "required|min:2|max:512", + "process_url" => "required|url", + "back_url" => "required|url", + ]; + } +} diff --git a/src/Validation/BinancePay/BinancePayAttributesForProcessValidation.php b/src/Validation/BinancePay/BinancePayAttributesForProcessValidation.php new file mode 100644 index 0000000..d8e353a --- /dev/null +++ b/src/Validation/BinancePay/BinancePayAttributesForProcessValidation.php @@ -0,0 +1,19 @@ + "required|in:sandbox,live", + "api_key" => "required|min:16", + "secret_key" => "required|min:16", + "payment_expiration_time" => "required|integer", + ]; + } +} diff --git a/src/Validation/BinancePay/BinancePayCredentialsForProcessValidation.php b/src/Validation/BinancePay/BinancePayCredentialsForProcessValidation.php new file mode 100644 index 0000000..31944e8 --- /dev/null +++ b/src/Validation/BinancePay/BinancePayCredentialsForProcessValidation.php @@ -0,0 +1,22 @@ + "required|min:16", + "secret_key" => "required|min:16", + ]; + } +} diff --git a/src/Validation/ChargilyPay/ChargilyPayAttributesForCreateValidation.php b/src/Validation/ChargilyPay/ChargilyPayAttributesForCreateValidation.php new file mode 100644 index 0000000..e29d725 --- /dev/null +++ b/src/Validation/ChargilyPay/ChargilyPayAttributesForCreateValidation.php @@ -0,0 +1,29 @@ + "required|min:1", + "client_full_name" => "required|min:1", + "client_email" => "required|email|min:1", + "amount" => "required|numeric|min:100", + "discount" => "required|numeric|min:0|max:99", + "description" => "required|min:1", + "method" => "required|in:CIB,EDAHABIA", + "back_url" => "required|url", + "process_url" => "required|url", + ]; + } +} diff --git a/src/Validation/ChargilyPay/ChargilyPayAttributesForProcessValidation.php b/src/Validation/ChargilyPay/ChargilyPayAttributesForProcessValidation.php new file mode 100644 index 0000000..846bed3 --- /dev/null +++ b/src/Validation/ChargilyPay/ChargilyPayAttributesForProcessValidation.php @@ -0,0 +1,19 @@ + "required|min:16", + "secret_key" => "required|min:16", + ]; + } +} diff --git a/src/Validation/ChargilyPay/ChargilyPayCredentialsForProcessValidation.php b/src/Validation/ChargilyPay/ChargilyPayCredentialsForProcessValidation.php new file mode 100644 index 0000000..458bcbe --- /dev/null +++ b/src/Validation/ChargilyPay/ChargilyPayCredentialsForProcessValidation.php @@ -0,0 +1,22 @@ + "required|min:16", + "secret_key" => "required|min:16", + ]; + } +} diff --git a/src/Validation/Payeer/PayeerAttributesForCreateValidation.php b/src/Validation/Payeer/PayeerAttributesForCreateValidation.php new file mode 100644 index 0000000..da26b60 --- /dev/null +++ b/src/Validation/Payeer/PayeerAttributesForCreateValidation.php @@ -0,0 +1,19 @@ + "required|numeric|min:0.01", + "currency" => "required|min:3|in:AUD,BRL,CAD,CNY,CZK,DKK,EUR,HKD,HUF,JPY,MYR,MXN,TWD,NZD,NOK,PHP,PLN,RUB,SEK,GBP,THB,SGD,USD,CHF", + "description" => "required|min:2|max:512", + "process_url" => "required|url", + "cancel_url" => "required|url", + ]; + } +} diff --git a/src/Validation/Paypal/PaypalAttributesForProcessValidation.php b/src/Validation/Paypal/PaypalAttributesForProcessValidation.php new file mode 100644 index 0000000..a9011a6 --- /dev/null +++ b/src/Validation/Paypal/PaypalAttributesForProcessValidation.php @@ -0,0 +1,21 @@ + "required|boolean", + ]; + } +} diff --git a/src/Validation/Paypal/PaypalCredentialsForCreateValidation.php b/src/Validation/Paypal/PaypalCredentialsForCreateValidation.php new file mode 100644 index 0000000..2419d28 --- /dev/null +++ b/src/Validation/Paypal/PaypalCredentialsForCreateValidation.php @@ -0,0 +1,25 @@ + "required|min:32", + "secret_key" => "required|min:32", + "env" => "required|in:sandbox,live", + "log_enabled" => "required|boolean", + "log_path" => "required_if:log_enabled,true", + ]; + } +} diff --git a/src/Validation/Paypal/PaypalCredentialsForProcessValidation.php b/src/Validation/Paypal/PaypalCredentialsForProcessValidation.php new file mode 100644 index 0000000..bf61fb0 --- /dev/null +++ b/src/Validation/Paypal/PaypalCredentialsForProcessValidation.php @@ -0,0 +1,25 @@ + "required|min:32", + "secret_key" => "required|min:32", + "env" => "required|in:sandbox,live", + "log_enabled" => "required|boolean", + "log_path" => "required_if:log_enabled,true", + ]; + } +} diff --git a/src/Validation/Paysera/PayseraAttributesForCreateValidation.php b/src/Validation/Paysera/PayseraAttributesForCreateValidation.php new file mode 100644 index 0000000..0683155 --- /dev/null +++ b/src/Validation/Paysera/PayseraAttributesForCreateValidation.php @@ -0,0 +1,28 @@ + "required|url", + "process_url" => "required|url", + "country" => "required|in:" . implode(",", Countries::getCodes()), + "order_id" => "required|numeric|min:1", + "currency" => "required|in:" . implode(",", Currencies::getCodes()), + "amount" => "required|numeric|min:1", + ]; + } +} diff --git a/src/Validation/Paysera/PayseraAttributesForProcessValidation.php b/src/Validation/Paysera/PayseraAttributesForProcessValidation.php new file mode 100644 index 0000000..cb6245f --- /dev/null +++ b/src/Validation/Paysera/PayseraAttributesForProcessValidation.php @@ -0,0 +1,22 @@ + "required|boolean", + "accept_only_macro_payments" => "required|boolean", + ]; + } +} diff --git a/src/Validation/Paysera/PayseraCredentialsForCreateValidation.php b/src/Validation/Paysera/PayseraCredentialsForCreateValidation.php new file mode 100644 index 0000000..6d05314 --- /dev/null +++ b/src/Validation/Paysera/PayseraCredentialsForCreateValidation.php @@ -0,0 +1,23 @@ + "required|numeric|min:1", + "sign_password" => "required|min:16", + "env" => "required|in:sandbox,live" + ]; + } +} diff --git a/src/Validation/Paysera/PayseraCredentialsForProcessValidation.php b/src/Validation/Paysera/PayseraCredentialsForProcessValidation.php new file mode 100644 index 0000000..7e7601a --- /dev/null +++ b/src/Validation/Paysera/PayseraCredentialsForProcessValidation.php @@ -0,0 +1,22 @@ + "required|numeric|min:1", + "sign_password" => "required|min:16", + ]; + } +}