From 60dd8d3b6cfe179a90f232b90f4ed5f663c6c1ee Mon Sep 17 00:00:00 2001 From: = Date: Sun, 15 Aug 2021 20:27:52 +1000 Subject: [PATCH 1/3] Add Payment Method --- app/PaymentDrivers/Square/CreditCard.php | 25 ++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/app/PaymentDrivers/Square/CreditCard.php b/app/PaymentDrivers/Square/CreditCard.php index 76b3ca63ad..495317a84f 100644 --- a/app/PaymentDrivers/Square/CreditCard.php +++ b/app/PaymentDrivers/Square/CreditCard.php @@ -73,6 +73,7 @@ class CreditCard $result = $api_response->getBody(); $payment = json_decode($result); + nlog($payment); } else { $errors = $api_response->getErrors(); @@ -178,7 +179,8 @@ Success response looks like this: } */ - + nlog("customer id = ".$result->getCustomer()->getId()); + nlog("source_id = ".$payment->payment->id); $card = new \Square\Models\Card(); $card->setCardholderName($this->square_driver->client->present()->name()); @@ -197,9 +199,13 @@ Success response looks like this: ->getCardsApi() ->createCard($body); + $card = false; + if ($api_response->isSuccess()) { - $result = $api_response->getResult(); - nlog($result->getBody()); + $card = $api_response->getBody(); + nlog($card); + $card = json_decode($card); + nlog("ressy"); nlog($result); } else { @@ -239,22 +245,21 @@ Success response looks like this: */ $cgt = []; - $cgt['token'] = $result->getId(); + $cgt['token'] = $card->card->id; $cgt['payment_method_id'] = GatewayType::CREDIT_CARD; $payment_meta = new \stdClass; - $payment_meta->exp_month = $result->getExpMonth(); - $payment_meta->exp_year = $result->getExpYear(); - $payment_meta->brand = $result->getCardBrand(); - $payment_meta->last4 = $result->getLast4(); + $payment_meta->exp_month = $card->card->exp_month; + $payment_meta->exp_year = $card->card->exp_year; + $payment_meta->brand = $card->card->card_brand; + $payment_meta->last4 = $card->card->last_4; $payment_meta->type = GatewayType::CREDIT_CARD; $cgt['payment_meta'] = $payment_meta; $token = $this->square_driver->storeGatewayToken($cgt, []); - - return back(); + return redirect()->route('client.payment_methods.index'); } public function paymentView($data) From 5c72aa3052555f095e2326a1e42d9c115f0e753b Mon Sep 17 00:00:00 2001 From: = Date: Sun, 15 Aug 2021 20:39:05 +1000 Subject: [PATCH 2/3] Clean up Square --- app/PaymentDrivers/Square/CreditCard.php | 144 ++++------------------- 1 file changed, 20 insertions(+), 124 deletions(-) diff --git a/app/PaymentDrivers/Square/CreditCard.php b/app/PaymentDrivers/Square/CreditCard.php index 495317a84f..65a790df05 100644 --- a/app/PaymentDrivers/Square/CreditCard.php +++ b/app/PaymentDrivers/Square/CreditCard.php @@ -50,6 +50,7 @@ class CreditCard public function authorizeResponse($request) { + /* Step one - process a $1 payment - but don't complete it*/ $payment = false; $amount_money = new \Square\Models\Money(); @@ -69,69 +70,14 @@ class CreditCard $api_response = $this->square_driver->square->getPaymentsApi()->createPayment($body); if ($api_response->isSuccess()) { - // $result = $api_response->getResult(); - $result = $api_response->getBody(); $payment = json_decode($result); - nlog($payment); - } else { $errors = $api_response->getErrors(); - nlog($errors); + return $this->processUnsuccessfulPayment($errors); } - - -/* -Success response looks like this: - - -{ - "payment": { - "id": "Dv9xlBgSgVB8i6eT0imRYFjcrOaZY", - "created_at": "2021-03-31T20:56:13.220Z", - "updated_at": "2021-03-31T20:56:13.411Z", - "amount_money": { - "amount": 100, - "currency": "USD" - }, - "status": "COMPLETED", - "delay_duration": "PT168H", - "source_type": "CARD", - "card_details": { - "status": "CAPTURED", - "card": { - "card_brand": "AMERICAN_EXPRESS", - "last_4": "6550", - "exp_month": 3, - "exp_year": 2023, - "fingerprint": "sq-1-hPdOWUYtEMft3yQ", - "card_type": "CREDIT", - "prepaid_type": "NOT_PREPAID", - "bin": "371263" - }, - "entry_method": "KEYED", - "cvv_status": "CVV_ACCEPTED", - "avs_status": "AVS_ACCEPTED", - "statement_description": "SQ *DEFAULT TEST ACCOUNT", - "card_payment_timeline": { - "authorized_at": "2021-03-31T20:56:13.334Z", - "captured_at": "2021-03-31T20:56:13.411Z" - } - }, - "location_id": "VJN4XSBFTVPK9", - "total_money": { - "amount": 100, - "currency": "USD" - }, - "approved_money": { - "amount": 100, - "currency": "USD" - } - } -} -*/ - + /* Step two - create the customer */ $billing_address = new \Square\Models\Address(); $billing_address->setAddressLine1($this->square_driver->client->address1); $billing_address->setAddressLine2($this->square_driver->client->address2); @@ -156,32 +102,13 @@ Success response looks like this: if ($api_response->isSuccess()) { $result = $api_response->getResult(); - nlog($result); + } else { $errors = $api_response->getErrors(); - nlog($errors); + return $this->processUnsuccessfulPayment($errors); } -/*Customer now created response - -{ - "customer": { - "id": "Q6VKKKGW8GWQNEYMDRMV01QMK8", - "created_at": "2021-03-31T18:27:07.803Z", - "updated_at": "2021-03-31T18:27:07Z", - "given_name": "Amelia", - "family_name": "Earhart", - "email_address": "Amelia.Earhart@example.com", - "preferences": { - "email_unsubscribed": false - } - } -} - -*/ - nlog("customer id = ".$result->getCustomer()->getId()); - nlog("source_id = ".$payment->payment->id); - + /* Step 3 create the card */ $card = new \Square\Models\Card(); $card->setCardholderName($this->square_driver->client->present()->name()); $card->setBillingAddress($billing_address); @@ -203,47 +130,14 @@ Success response looks like this: if ($api_response->isSuccess()) { $card = $api_response->getBody(); - nlog($card); $card = json_decode($card); - - nlog("ressy"); - nlog($result); } else { $errors = $api_response->getErrors(); - nlog("i got errors"); - nlog($errors); + + return $this->processUnsuccessfulPayment($errors); } -/** - * -{ - "card": { - "id": "ccof:uIbfJXhXETSP197M3GB", //this is the token - "billing_address": { - "address_line_1": "500 Electric Ave", - "address_line_2": "Suite 600", - "locality": "New York", - "administrative_district_level_1": "NY", - "postal_code": "10003", - "country": "US" - }, - "bin": "411111", - "card_brand": "VISA", - "card_type": "CREDIT", - "cardholder_name": "Amelia Earhart", - "customer_id": "Q6VKKKGW8GWQNEYMDRMV01QMK8", - "enabled": true, - "exp_month": 11, - "exp_year": 2018, - "last_4": "1111", - "prepaid_type": "NOT_PREPAID", - "reference_id": "user-id-1", - "version": 1 - } -} - -*/ - + /* Create the token in Invoice Ninja*/ $cgt = []; $cgt['token'] = $card->card->id; $cgt['payment_method_id'] = GatewayType::CREDIT_CARD; @@ -296,18 +190,20 @@ Success response looks like this: 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'; + // array ( + // 0 => + // Square\Models\Error::__set_state(array( + // 'category' => 'INVALID_REQUEST_ERROR', + // 'code' => 'INVALID_CARD_DATA', + // 'detail' => 'Invalid card data.', + // 'field' => 'source_id', + // )), + // ) $data = [ 'response' => $response, - 'error' => $error, - 'error_code' => $error_code, + 'error' => $response[0]['detail'], + 'error_code' => '', ]; return $this->square_driver->processUnsuccessfulTransaction($data); From e76fc995ed646135ff5d4c592f5f934baee1208e Mon Sep 17 00:00:00 2001 From: = Date: Sun, 15 Aug 2021 21:14:18 +1000 Subject: [PATCH 3/3] Refactor for Square --- app/PaymentDrivers/Square/CreditCard.php | 119 ++++++++++++++--------- 1 file changed, 75 insertions(+), 44 deletions(-) diff --git a/app/PaymentDrivers/Square/CreditCard.php b/app/PaymentDrivers/Square/CreditCard.php index 65a790df05..b2f2a72391 100644 --- a/app/PaymentDrivers/Square/CreditCard.php +++ b/app/PaymentDrivers/Square/CreditCard.php @@ -77,42 +77,12 @@ class CreditCard return $this->processUnsuccessfulPayment($errors); } - /* Step two - create the customer */ - $billing_address = new \Square\Models\Address(); - $billing_address->setAddressLine1($this->square_driver->client->address1); - $billing_address->setAddressLine2($this->square_driver->client->address2); - $billing_address->setLocality($this->square_driver->client->city); - $billing_address->setAdministrativeDistrictLevel1($this->square_driver->client->state); - $billing_address->setPostalCode($this->square_driver->client->postal_code); - $billing_address->setCountry($this->square_driver->client->country->iso_3166_2); - - $body = new \Square\Models\CreateCustomerRequest(); - $body->setGivenName($this->square_driver->client->present()->name()); - $body->setFamilyName(''); - $body->setEmailAddress($this->square_driver->client->present()->email()); - $body->setAddress($billing_address); - $body->setPhoneNumber($this->square_driver->client->phone); - $body->setReferenceId($this->square_driver->client->number); - $body->setNote('Created by Invoice Ninja.'); - - $api_response = $this->square_driver - ->square - ->getCustomersApi() - ->createCustomer($body); - - if ($api_response->isSuccess()) { - $result = $api_response->getResult(); - - } else { - $errors = $api_response->getErrors(); - return $this->processUnsuccessfulPayment($errors); - } - + /* Step 3 create the card */ $card = new \Square\Models\Card(); $card->setCardholderName($this->square_driver->client->present()->name()); - $card->setBillingAddress($billing_address); - $card->setCustomerId($result->getCustomer()->getId()); + // $card->setBillingAddress($billing_address); + $card->setCustomerId($this->findOrCreateClient()); $card->setReferenceId(Str::random(8)); $body = new \Square\Models\CreateCardRequest( @@ -211,19 +181,80 @@ class CreditCard } - /* 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 - */ + private function findOrCreateClient() + { + $email_address = new \Square\Models\CustomerTextFilter(); + $email_address->setExact($this->square_driver->client->present()->email()); + + $filter = new \Square\Models\CustomerFilter(); + $filter->setEmailAddress($email_address); + + $query = new \Square\Models\CustomerQuery(); + $query->setFilter($filter); + + $body = new \Square\Models\SearchCustomersRequest(); + $body->setQuery($query); + + $api_response = $this->square_driver + ->init() + ->square + ->getCustomersApi() + ->searchCustomers($body); + + $customers = false; + + if ($api_response->isSuccess()) { + $customers = $api_response->getBody(); + $customers = json_decode($customers); + } else { + $errors = $api_response->getErrors(); + } + + if($customers) + return $customers->customers[0]->id; + + return $this->createClient(); + } + + private function createClient() + { + + /* Step two - create the customer */ + $billing_address = new \Square\Models\Address(); + $billing_address->setAddressLine1($this->square_driver->client->address1); + $billing_address->setAddressLine2($this->square_driver->client->address2); + $billing_address->setLocality($this->square_driver->client->city); + $billing_address->setAdministrativeDistrictLevel1($this->square_driver->client->state); + $billing_address->setPostalCode($this->square_driver->client->postal_code); + $billing_address->setCountry($this->square_driver->client->country->iso_3166_2); + + $body = new \Square\Models\CreateCustomerRequest(); + $body->setGivenName($this->square_driver->client->present()->name()); + $body->setFamilyName(''); + $body->setEmailAddress($this->square_driver->client->present()->email()); + $body->setAddress($billing_address); + $body->setPhoneNumber($this->square_driver->client->phone); + $body->setReferenceId($this->square_driver->client->number); + $body->setNote('Created by Invoice Ninja.'); + + $api_response = $this->square_driver + ->init() + ->square + ->getCustomersApi() + ->createCustomer($body); + + if ($api_response->isSuccess()) { + $result = $api_response->getResult(); + return $result->getCustomer()->getId(); + + } else { + $errors = $api_response->getErrors(); + return $this->processUnsuccessfulPayment($errors); + } + + } } \ No newline at end of file