diff --git a/app/Models/SystemLog.php b/app/Models/SystemLog.php index ab3d8cac8b68..1340bb4cebbe 100644 --- a/app/Models/SystemLog.php +++ b/app/Models/SystemLog.php @@ -70,7 +70,8 @@ class SystemLog extends Model const TYPE_PAYFAST = 310; const TYPE_PAYTRACE = 311; const TYPE_MOLLIE = 312; - + const TYPE_SQUARE = 320; + const TYPE_QUOTA_EXCEEDED = 400; const TYPE_UPSTREAM_FAILURE = 401; diff --git a/app/PaymentDrivers/Square/CreditCard.php b/app/PaymentDrivers/Square/CreditCard.php new file mode 100644 index 000000000000..f83da6137fa6 --- /dev/null +++ b/app/PaymentDrivers/Square/CreditCard.php @@ -0,0 +1,153 @@ +square_class = $square_class; + } + + public function authorizeView($data) + { + + $data['gateway'] = $this->square_class; + + return render('gateways.square.credit_card.authorize', $data); + + } + + public function authorizeRequest($request) + { + + $billing_address = new \Square\Models\Address(); + $billing_address->setAddressLine1($this->square_class->client->address1); + $billing_address->setAddressLine2($this->square_class->client->address2); + $billing_address->setLocality($this->square_class->client->city); + $billing_address->setAdministrativeDistrictLevel1($this->square_class->client->state); + $billing_address->setPostalCode($this->square_class->client->postal_code); + $billing_address->setCountry($this->square_class->client->country->iso_3166_2); + + $card = new \Square\Models\Card(); + $card->setCardholderName('Amelia Earhart'); + $card->setBillingAddress($billing_address); + $card->setCustomerId('VDKXEEKPJN48QDG3BGGFAK05P8'); + $card->setReferenceId('user-id-1'); + + $body = new \Square\Models\CreateCardRequest( + '4935a656-a929-4792-b97c-8848be85c27c', + 'cnon:uIbfJXhXETSP197M3GB', + $card + ); + + $api_response = $client->getCardsApi()->createCard($body); + + if ($api_response->isSuccess()) { + $result = $api_response->getResult(); + } else { + $errors = $api_response->getErrors(); + } + + + return back(); + } + + public function paymentView($data) + { + + $data['gateway'] = $this->square_class; + $data['client_token'] = $this->braintree->gateway->clientToken()->generate(); + + return render('gateways.braintree.credit_card.pay', $data); + + } + + public function processPaymentResponse($request) + { + + } + + /* This method is stubbed ready to go - you just need to harvest the equivalent 'transaction_reference' */ + private function processSuccessfulPayment($response) + { + $amount = array_sum(array_column($this->square_class->payment_hash->invoices(), 'amount')) + $this->square_class->payment_hash->fee_total; + + $payment_record = []; + $payment_record['amount'] = $amount; + $payment_record['payment_type'] = PaymentType::CREDIT_CARD_OTHER; + $payment_record['gateway_type_id'] = GatewayType::CREDIT_CARD; + // $payment_record['transaction_reference'] = $response->transaction_id; + + $payment = $this->square_class->createPayment($payment_record, Payment::STATUS_COMPLETED); + + return redirect()->route('client.payments.show', ['payment' => $this->encodePrimaryKey($payment->id)]); + + } + + private function processUnsuccessfulPayment($response) + { + /*Harvest your own errors here*/ + // $error = $response->status_message; + + // if(property_exists($response, 'approval_message') && $response->approval_message) + // $error .= " - {$response->approval_message}"; + + // $error_code = property_exists($response, 'approval_message') ? $response->approval_message : 'Undefined code'; + + $data = [ + 'response' => $response, + 'error' => $error, + 'error_code' => $error_code, + ]; + + return $this->square_class->processUnsuccessfulTransaction($data); + + } + + + /* Helpers */ + + /* + You will need some helpers to handle successful and unsuccessful responses + + Some considerations after a succesful transaction include: + + Logging of events: success +/- failure + Recording a payment + Notifications + */ + + + + +} \ No newline at end of file diff --git a/app/PaymentDrivers/SquarePaymentDriver.php b/app/PaymentDrivers/SquarePaymentDriver.php new file mode 100644 index 000000000000..10647bf54992 --- /dev/null +++ b/app/PaymentDrivers/SquarePaymentDriver.php @@ -0,0 +1,105 @@ + CreditCard::class, //maps GatewayType => Implementation class + ]; + + const SYSTEM_LOG_TYPE = SystemLog::TYPE_SQUARE; //define a constant for your gateway ie TYPE_YOUR_CUSTOM_GATEWAY - set the const in the SystemLog model + + public function init() + { + + $this->square = new Square\SquareClient([ + 'accessToken' => 'EAAAEHeoSxEUZWXCd0makP0-HA0V4OLZ-S-T2Gmc91llp08ColiOX9NpP-LQZIId', + 'environment' => Square\Environment::SANDBOX, + ]); + + return $this; /* This is where you boot the gateway with your auth credentials*/ + } + + /* Returns an array of gateway types for the payment gateway */ + public function gatewayTypes(): array + { + $types = []; + + $types[] = GatewayType::CREDIT_CARD; + + return $types; + } + + /* Sets the payment method initialized */ + public function setPaymentMethod($payment_method_id) + { + $class = self::$methods[$payment_method_id]; + $this->payment_method = new $class($this); + return $this; + } + + public function authorizeView(array $data) + { + return $this->payment_method->authorizeView($data); //this is your custom implementation from here + } + + public function authorizeResponse($request) + { + return $this->payment_method->authorizeResponse($request); //this is your custom implementation from here + } + + public function processPaymentView(array $data) + { + return $this->payment_method->paymentView($data); //this is your custom implementation from here + } + + public function processPaymentResponse($request) + { + return $this->payment_method->paymentResponse($request); //this is your custom implementation from here + } + + public function refund(Payment $payment, $amount, $return_client_response = false) + { + //this is your custom implementation from here + } + + public function tokenBilling(ClientGatewayToken $cgt, PaymentHash $payment_hash) + { + //this is your custom implementation from here + } + + public function processWebhookRequest(PaymentWebhookRequest $request, Payment $payment = null) + { + } +} \ No newline at end of file diff --git a/composer.json b/composer.json index 8595adacbbc3..41d1d8b1692c 100644 --- a/composer.json +++ b/composer.json @@ -69,6 +69,7 @@ "pragmarx/google2fa": "^8.0", "predis/predis": "^1.1", "sentry/sentry-laravel": "^2", + "square/square": "13.0.0.20210721", "stripe/stripe-php": "^7.50", "symfony/http-client": "^5.2", "tijsverkoyen/css-to-inline-styles": "^2.2", diff --git a/composer.lock b/composer.lock index 89eea29d9e7b..4a0615b198f0 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,122 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "275a9dd3910b6ec79607b098406dc6c7", + "content-hash": "93253273cd8399a0e083a064160b70bf", "packages": [ + { + "name": "apimatic/jsonmapper", + "version": "v2.0.3", + "source": { + "type": "git", + "url": "https://github.com/apimatic/jsonmapper.git", + "reference": "f7588f1ab692c402a9118e65cb9fd42b74e5e0db" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/apimatic/jsonmapper/zipball/f7588f1ab692c402a9118e65cb9fd42b74e5e0db", + "reference": "f7588f1ab692c402a9118e65cb9fd42b74e5e0db", + "shasum": "" + }, + "require-dev": { + "phpunit/phpunit": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0", + "squizlabs/php_codesniffer": "^3.0.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "apimatic\\jsonmapper\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "OSL-3.0" + ], + "authors": [ + { + "name": "Christian Weiske", + "email": "christian.weiske@netresearch.de", + "homepage": "http://www.netresearch.de/", + "role": "Developer" + }, + { + "name": "Mehdi Jaffery", + "email": "mehdi.jaffery@apimatic.io", + "homepage": "http://apimatic.io/", + "role": "Developer" + } + ], + "description": "Map nested JSON structures onto PHP classes", + "support": { + "email": "mehdi.jaffery@apimatic.io", + "issues": "https://github.com/apimatic/jsonmapper/issues", + "source": "https://github.com/apimatic/jsonmapper/tree/v2.0.3" + }, + "time": "2021-07-16T09:02:23+00:00" + }, + { + "name": "apimatic/unirest-php", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/apimatic/unirest-php.git", + "reference": "b4e399a8970c3a5c611f734282f306381f9d1eee" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/apimatic/unirest-php/zipball/b4e399a8970c3a5c611f734282f306381f9d1eee", + "reference": "b4e399a8970c3a5c611f734282f306381f9d1eee", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "php": ">=5.6.0" + }, + "require-dev": { + "phpunit/phpunit": "^5 || ^6 || ^7" + }, + "suggest": { + "ext-json": "Allows using JSON Bodies for sending and parsing requests" + }, + "type": "library", + "autoload": { + "psr-0": { + "Unirest\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mashape", + "email": "opensource@mashape.com", + "homepage": "https://www.mashape.com", + "role": "Developer" + }, + { + "name": "APIMATIC", + "email": "opensource@apimatic.io", + "homepage": "https://www.apimatic.io", + "role": "Developer" + } + ], + "description": "Unirest PHP", + "homepage": "https://github.com/apimatic/unirest-php", + "keywords": [ + "client", + "curl", + "http", + "https", + "rest" + ], + "support": { + "email": "opensource@apimatic.io", + "issues": "https://github.com/apimatic/unirest-php/issues", + "source": "https://github.com/apimatic/unirest-php/tree/2.0.0" + }, + "time": "2020-04-07T17:16:29+00:00" + }, { "name": "asm/php-ansible", "version": "dev-main", @@ -7459,6 +7573,63 @@ ], "time": "2021-06-16T09:26:40+00:00" }, + { + "name": "square/square", + "version": "13.0.0.20210721", + "source": { + "type": "git", + "url": "https://github.com/square/square-php-sdk.git", + "reference": "03d90445854cd3b500f75061a9c63956799b8ecf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/square/square-php-sdk/zipball/03d90445854cd3b500f75061a9c63956799b8ecf", + "reference": "03d90445854cd3b500f75061a9c63956799b8ecf", + "shasum": "" + }, + "require": { + "apimatic/jsonmapper": "^2.0.2", + "apimatic/unirest-php": "^2.0", + "ext-curl": "*", + "ext-json": "*", + "ext-mbstring": "*", + "php": ">=7.2" + }, + "require-dev": { + "phan/phan": "^3.0", + "phpunit/phpunit": "^7.5 || ^8.5", + "squizlabs/php_codesniffer": "^3.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Square\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Square Developer Platform", + "email": "developers@squareup.com", + "homepage": "https://squareup.com/developers" + } + ], + "description": "Use Square APIs to manage and run business including payment, customer, product, inventory, and employee management.", + "homepage": "https://squareup.com/developers", + "keywords": [ + "api", + "sdk", + "square" + ], + "support": { + "issues": "https://github.com/square/square-php-sdk/issues", + "source": "https://github.com/square/square-php-sdk/tree/13.0.0.20210721" + }, + "time": "2021-07-21T06:43:15+00:00" + }, { "name": "stripe/stripe-php", "version": "v7.88.0", @@ -14972,5 +15143,5 @@ "platform-dev": { "php": "^7.3|^7.4|^8.0" }, - "plugin-api-version": "2.1.0" + "plugin-api-version": "2.0.0" } diff --git a/database/migrations/2021_08_14_054458_square_payment_driver.php b/database/migrations/2021_08_14_054458_square_payment_driver.php new file mode 100644 index 000000000000..7da0bb5949fa --- /dev/null +++ b/database/migrations/2021_08_14_054458_square_payment_driver.php @@ -0,0 +1,49 @@ +accessToken = ""; + $fields->applicationId = ""; + $fields->locationId = ""; + $fields->testMode = false; + + $square = new Gateway(); + $square->id = 57; + $square->name = "Square"; + $square->provider = "Square"; + $square->key = '65faab2ab6e3223dbe848b1686490baz'; + $square->sort_order = 4343; + $square->is_offsite = false; + $square->visible = true; + $square->fields = json_encode($fields); + $square->save(); + + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + // + } +}