mirror of
				https://github.com/invoiceninja/invoiceninja.git
				synced 2025-10-31 01:17:33 -04:00 
			
		
		
		
	
						commit
						398382fb69
					
				| @ -787,6 +787,27 @@ class CreateSingleAccount extends Command | |||||||
|             $cg->fees_and_limits = $fees_and_limits; |             $cg->fees_and_limits = $fees_and_limits; | ||||||
|             $cg->save(); |             $cg->save(); | ||||||
|         } |         } | ||||||
|  | 
 | ||||||
|  |         if (config('ninja.testvars.square') && ($this->gateway == 'all' || $this->gateway == 'square')) { | ||||||
|  |             $cg = new CompanyGateway; | ||||||
|  |             $cg->company_id = $company->id; | ||||||
|  |             $cg->user_id = $user->id; | ||||||
|  |             $cg->gateway_key = '65faab2ab6e3223dbe848b1686490baz'; | ||||||
|  |             $cg->require_cvv = true; | ||||||
|  |             $cg->require_billing_address = true; | ||||||
|  |             $cg->require_shipping_address = true; | ||||||
|  |             $cg->update_details = true; | ||||||
|  |             $cg->config = encrypt(config('ninja.testvars.square')); | ||||||
|  |             $cg->save(); | ||||||
|  | 
 | ||||||
|  |             $gateway_types = $cg->driver(new Client)->gatewayTypes(); | ||||||
|  | 
 | ||||||
|  |             $fees_and_limits = new stdClass; | ||||||
|  |             $fees_and_limits->{$gateway_types[0]} = new FeesAndLimits; | ||||||
|  | 
 | ||||||
|  |             $cg->fees_and_limits = $fees_and_limits; | ||||||
|  |             $cg->save(); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private function createRecurringInvoice($client) |     private function createRecurringInvoice($client) | ||||||
|  | |||||||
| @ -81,9 +81,13 @@ class Gateway extends StaticModel | |||||||
|             case 1: |             case 1: | ||||||
|                 return [GatewayType::CREDIT_CARD => ['refund' => true, 'token_billing' => true]];//Authorize.net
 |                 return [GatewayType::CREDIT_CARD => ['refund' => true, 'token_billing' => true]];//Authorize.net
 | ||||||
|                 break; |                 break; | ||||||
|             case 1: |             case 11: | ||||||
|                 return [GatewayType::CREDIT_CARD => ['refund' => false, 'token_billing' => false]];//Payfast
 |                 return [GatewayType::CREDIT_CARD => ['refund' => false, 'token_billing' => false]];//Payfast
 | ||||||
|                 break; |                 break; | ||||||
|  |             case 7: | ||||||
|  |                 return [ | ||||||
|  |                     GatewayType::CREDIT_CARD => ['refund' => false, 'token_billing' => true], // Mollie
 | ||||||
|  |                 ]; | ||||||
|             case 15: |             case 15: | ||||||
|                 return [GatewayType::PAYPAL => ['refund' => true, 'token_billing' => false]]; //Paypal
 |                 return [GatewayType::PAYPAL => ['refund' => true, 'token_billing' => false]]; //Paypal
 | ||||||
|                 break; |                 break; | ||||||
| @ -110,11 +114,12 @@ class Gateway extends StaticModel | |||||||
|                     GatewayType::PAYPAL => ['refund' => true, 'token_billing' => true] |                     GatewayType::PAYPAL => ['refund' => true, 'token_billing' => true] | ||||||
|                 ]; |                 ]; | ||||||
|                 break; |                 break; | ||||||
|             case 7: |             case 57: | ||||||
|                 return [ |                 return [ | ||||||
|                     GatewayType::CREDIT_CARD => ['refund' => false, 'token_billing' => true], // Mollie
 |                     GatewayType::CREDIT_CARD => ['refund' => true, 'token_billing' => true], //Square
 | ||||||
|                 ]; |                 ]; | ||||||
|                 break; |                 break; | ||||||
|  |                 break; | ||||||
|             default: |             default: | ||||||
|                 return []; |                 return []; | ||||||
|                 break; |                 break; | ||||||
|  | |||||||
| @ -70,6 +70,7 @@ class SystemLog extends Model | |||||||
|     const TYPE_PAYFAST = 310; |     const TYPE_PAYFAST = 310; | ||||||
|     const TYPE_PAYTRACE = 311; |     const TYPE_PAYTRACE = 311; | ||||||
|     const TYPE_MOLLIE = 312; |     const TYPE_MOLLIE = 312; | ||||||
|  |     const TYPE_SQUARE = 320; | ||||||
| 
 | 
 | ||||||
|     const TYPE_QUOTA_EXCEEDED = 400; |     const TYPE_QUOTA_EXCEEDED = 400; | ||||||
|     const TYPE_UPSTREAM_FAILURE = 401; |     const TYPE_UPSTREAM_FAILURE = 401; | ||||||
|  | |||||||
							
								
								
									
										328
									
								
								app/PaymentDrivers/Square/CreditCard.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										328
									
								
								app/PaymentDrivers/Square/CreditCard.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,328 @@ | |||||||
|  | <?php | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Invoice Ninja (https://invoiceninja.com). | ||||||
|  |  * | ||||||
|  |  * @link https://github.com/invoiceninja/invoiceninja source repository | ||||||
|  |  * | ||||||
|  |  * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com) | ||||||
|  |  * | ||||||
|  |  * @license https://www.elastic.co/licensing/elastic-license | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | namespace App\PaymentDrivers\Square; | ||||||
|  | 
 | ||||||
|  | use App\Exceptions\PaymentFailed; | ||||||
|  | use App\Jobs\Mail\PaymentFailureMailer; | ||||||
|  | use App\Jobs\Util\SystemLogger; | ||||||
|  | use App\Models\ClientGatewayToken; | ||||||
|  | use App\Models\GatewayType; | ||||||
|  | use App\Models\Payment; | ||||||
|  | use App\Models\PaymentHash; | ||||||
|  | use App\Models\PaymentType; | ||||||
|  | use App\Models\SystemLog; | ||||||
|  | use App\PaymentDrivers\SquarePaymentDriver; | ||||||
|  | use App\Utils\Traits\MakesHash; | ||||||
|  | use Illuminate\Http\Request; | ||||||
|  | use Illuminate\Support\Facades\Cache; | ||||||
|  | use Illuminate\Support\Str; | ||||||
|  | 
 | ||||||
|  | class CreditCard | ||||||
|  | { | ||||||
|  |     use MakesHash; | ||||||
|  | 
 | ||||||
|  |     public $square_driver; | ||||||
|  | 
 | ||||||
|  |     public function __construct(SquarePaymentDriver $square_driver) | ||||||
|  |     { | ||||||
|  |         $this->square_driver = $square_driver; | ||||||
|  |         $this->square_driver->init(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public function authorizeView($data) | ||||||
|  |     { | ||||||
|  | 
 | ||||||
|  |         $data['gateway'] = $this->square_driver; | ||||||
|  | 
 | ||||||
|  |         return render('gateways.square.credit_card.authorize', $data); | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public function authorizeResponse($request) | ||||||
|  |     { | ||||||
|  |         $payment = false; | ||||||
|  | 
 | ||||||
|  |         $amount_money = new \Square\Models\Money(); | ||||||
|  |         $amount_money->setAmount(100); //amount in cents
 | ||||||
|  |         $amount_money->setCurrency($this->square_driver->client->currency()->code); | ||||||
|  | 
 | ||||||
|  |         $body = new \Square\Models\CreatePaymentRequest( | ||||||
|  |             $request->sourceId, | ||||||
|  |             Str::random(32), | ||||||
|  |             $amount_money | ||||||
|  |         ); | ||||||
|  | 
 | ||||||
|  |         $body->setAutocomplete(false); | ||||||
|  |         $body->setLocationId($this->square_driver->company_gateway->getConfigField('locationId')); | ||||||
|  |         $body->setReferenceId(Str::random(16)); | ||||||
|  | 
 | ||||||
|  |         $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); | ||||||
|  | 
 | ||||||
|  |         } else { | ||||||
|  |             $errors = $api_response->getErrors(); | ||||||
|  |             nlog($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" | ||||||
|  |     } | ||||||
|  |    } | ||||||
|  | } | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  |         $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(); | ||||||
|  |             nlog($result); | ||||||
|  |         } else { | ||||||
|  |             $errors = $api_response->getErrors(); | ||||||
|  |             nlog($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 | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         $card = new \Square\Models\Card(); | ||||||
|  |         $card->setCardholderName($this->square_driver->client->present()->name()); | ||||||
|  |         $card->setBillingAddress($billing_address); | ||||||
|  |         $card->setCustomerId($result->getCustomer()->getId()); | ||||||
|  |         $card->setReferenceId(Str::random(8)); | ||||||
|  | 
 | ||||||
|  |         $body = new \Square\Models\CreateCardRequest( | ||||||
|  |             Str::random(32), | ||||||
|  |             $payment->payment->id, | ||||||
|  |             $card | ||||||
|  |         ); | ||||||
|  | 
 | ||||||
|  |         $api_response = $this->square_driver | ||||||
|  |                              ->square | ||||||
|  |                              ->getCardsApi() | ||||||
|  |                              ->createCard($body); | ||||||
|  | 
 | ||||||
|  |         if ($api_response->isSuccess()) { | ||||||
|  |             $result = $api_response->getResult(); | ||||||
|  |             nlog($result->getBody()); | ||||||
|  |             nlog("ressy"); | ||||||
|  |             nlog($result); | ||||||
|  |         } else { | ||||||
|  |             $errors = $api_response->getErrors(); | ||||||
|  |             nlog("i got errors"); | ||||||
|  |             nlog($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 | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  |         $cgt = []; | ||||||
|  |         $cgt['token'] = $result->getId(); | ||||||
|  |         $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->type = GatewayType::CREDIT_CARD; | ||||||
|  | 
 | ||||||
|  |         $cgt['payment_meta'] = $payment_meta; | ||||||
|  | 
 | ||||||
|  |         $token = $this->square_driver->storeGatewayToken($cgt, []); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         return back(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public function paymentView($data) | ||||||
|  |     { | ||||||
|  | 
 | ||||||
|  |         $data['gateway'] = $this->square_driver; | ||||||
|  |         $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_driver->payment_hash->invoices(), 'amount')) + $this->square_driver->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_driver->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_driver->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 | ||||||
|  |      */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | } | ||||||
							
								
								
									
										105
									
								
								app/PaymentDrivers/SquarePaymentDriver.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								app/PaymentDrivers/SquarePaymentDriver.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,105 @@ | |||||||
|  | <?php | ||||||
|  | /** | ||||||
|  |  * Invoice Ninja (https://invoiceninja.com). | ||||||
|  |  * | ||||||
|  |  * @link https://github.com/invoiceninja/invoiceninja source repository | ||||||
|  |  * | ||||||
|  |  * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com) | ||||||
|  |  * | ||||||
|  |  * @license https://www.elastic.co/licensing/elastic-license | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | namespace App\PaymentDrivers; | ||||||
|  | 
 | ||||||
|  | use App\Http\Requests\Payments\PaymentWebhookRequest; | ||||||
|  | use App\Models\ClientGatewayToken; | ||||||
|  | use App\Models\GatewayType; | ||||||
|  | use App\Models\Payment; | ||||||
|  | use App\Models\PaymentHash; | ||||||
|  | use App\Models\SystemLog; | ||||||
|  | use App\PaymentDrivers\Square\CreditCard; | ||||||
|  | use App\Utils\Traits\MakesHash; | ||||||
|  | 
 | ||||||
|  | class SquarePaymentDriver extends BaseDriver | ||||||
|  | { | ||||||
|  |     use MakesHash; | ||||||
|  | 
 | ||||||
|  |     public $refundable = true; //does this gateway support refunds?
 | ||||||
|  | 
 | ||||||
|  |     public $token_billing = true; //does this gateway support token billing?
 | ||||||
|  | 
 | ||||||
|  |     public $can_authorise_credit_card = true; //does this gateway support authorizations?
 | ||||||
|  | 
 | ||||||
|  |     public $square;  | ||||||
|  | 
 | ||||||
|  |     public $payment_method; | ||||||
|  | 
 | ||||||
|  |     public static $methods = [ | ||||||
|  |         GatewayType::CREDIT_CARD => CreditCard::class, //maps GatewayType => Implementation class
 | ||||||
|  |     ]; | ||||||
|  | 
 | ||||||
|  |     const SYSTEM_LOG_TYPE = SystemLog::TYPE_SQUARE;  | ||||||
|  | 
 | ||||||
|  |     public function init() | ||||||
|  |     { | ||||||
|  | 
 | ||||||
|  |         $this->square = new \Square\SquareClient([ | ||||||
|  |             'accessToken' => $this->company_gateway->getConfigField('accessToken'), | ||||||
|  |             'environment' => $this->company_gateway->getConfigField('testMode') ? \Square\Environment::SANDBOX : \Square\Environment::PRODUCTION, | ||||||
|  |         ]); | ||||||
|  | 
 | ||||||
|  |         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) | ||||||
|  |     { | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -69,6 +69,7 @@ | |||||||
|         "pragmarx/google2fa": "^8.0", |         "pragmarx/google2fa": "^8.0", | ||||||
|         "predis/predis": "^1.1", |         "predis/predis": "^1.1", | ||||||
|         "sentry/sentry-laravel": "^2", |         "sentry/sentry-laravel": "^2", | ||||||
|  |         "square/square": "13.0.0.20210721", | ||||||
|         "stripe/stripe-php": "^7.50", |         "stripe/stripe-php": "^7.50", | ||||||
|         "symfony/http-client": "^5.2", |         "symfony/http-client": "^5.2", | ||||||
|         "tijsverkoyen/css-to-inline-styles": "^2.2", |         "tijsverkoyen/css-to-inline-styles": "^2.2", | ||||||
|  | |||||||
							
								
								
									
										175
									
								
								composer.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										175
									
								
								composer.lock
									
									
									
										generated
									
									
									
								
							| @ -4,8 +4,122 @@ | |||||||
|         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", |         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", | ||||||
|         "This file is @generated automatically" |         "This file is @generated automatically" | ||||||
|     ], |     ], | ||||||
|     "content-hash": "275a9dd3910b6ec79607b098406dc6c7", |     "content-hash": "93253273cd8399a0e083a064160b70bf", | ||||||
|     "packages": [ |     "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", |             "name": "asm/php-ansible", | ||||||
|             "version": "dev-main", |             "version": "dev-main", | ||||||
| @ -7459,6 +7573,63 @@ | |||||||
|             ], |             ], | ||||||
|             "time": "2021-06-16T09:26:40+00:00" |             "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", |             "name": "stripe/stripe-php", | ||||||
|             "version": "v7.88.0", |             "version": "v7.88.0", | ||||||
| @ -14972,5 +15143,5 @@ | |||||||
|     "platform-dev": { |     "platform-dev": { | ||||||
|         "php": "^7.3|^7.4|^8.0" |         "php": "^7.3|^7.4|^8.0" | ||||||
|     }, |     }, | ||||||
|     "plugin-api-version": "2.1.0" |     "plugin-api-version": "2.0.0" | ||||||
| } | } | ||||||
|  | |||||||
| @ -90,6 +90,7 @@ return [ | |||||||
|             'decrypted' => env('PAYTRACE_KEYS', ''), |             'decrypted' => env('PAYTRACE_KEYS', ''), | ||||||
|         ], |         ], | ||||||
|         'mollie' => env('MOLLIE_KEYS', ''), |         'mollie' => env('MOLLIE_KEYS', ''), | ||||||
|  |         'square' => env('SQUARE_KEYS',''), | ||||||
|     ], |     ], | ||||||
|     'contact' => [ |     'contact' => [ | ||||||
|         'email' => env('MAIL_FROM_ADDRESS'), |         'email' => env('MAIL_FROM_ADDRESS'), | ||||||
|  | |||||||
| @ -0,0 +1,49 @@ | |||||||
|  | <?php | ||||||
|  | 
 | ||||||
|  | use App\Models\Gateway; | ||||||
|  | use Illuminate\Database\Migrations\Migration; | ||||||
|  | use Illuminate\Database\Schema\Blueprint; | ||||||
|  | use Illuminate\Support\Facades\Schema; | ||||||
|  | use Illuminate\Database\Eloquent\Model; | ||||||
|  | 
 | ||||||
|  | class SquarePaymentDriver extends Migration | ||||||
|  | { | ||||||
|  |     /** | ||||||
|  |      * Run the migrations. | ||||||
|  |      * | ||||||
|  |      * @return void | ||||||
|  |      */ | ||||||
|  |     public function up() | ||||||
|  |     { | ||||||
|  |          | ||||||
|  |         Model::unguard(); | ||||||
|  | 
 | ||||||
|  |         $fields = new \stdClass; | ||||||
|  |         $fields->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() | ||||||
|  |     { | ||||||
|  |         //
 | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -80,6 +80,7 @@ class PaymentLibrariesSeeder extends Seeder | |||||||
|             ['id' => 53, 'name' => 'PagSeguro', 'provider' => 'PagSeguro', 'key' => 'ef498756b54db63c143af0ec433da803', 'fields' => '{"email":"","token":"","sandbox":false}'], |             ['id' => 53, 'name' => 'PagSeguro', 'provider' => 'PagSeguro', 'key' => 'ef498756b54db63c143af0ec433da803', 'fields' => '{"email":"","token":"","sandbox":false}'], | ||||||
|             ['id' => 54, 'name' => 'PAYMILL', 'provider' => 'Paymill', 'key' => 'ca52f618a39367a4c944098ebf977e1c', 'fields' => '{"apiKey":""}'], |             ['id' => 54, 'name' => 'PAYMILL', 'provider' => 'Paymill', 'key' => 'ca52f618a39367a4c944098ebf977e1c', 'fields' => '{"apiKey":""}'], | ||||||
|             ['id' => 55, 'name' => 'Custom', 'provider' => 'Custom', 'is_offsite' => true, 'sort_order' => 21, 'key' => '54faab2ab6e3223dbe848b1686490baa', 'fields' => '{"name":"","text":""}'], |             ['id' => 55, 'name' => 'Custom', 'provider' => 'Custom', 'is_offsite' => true, 'sort_order' => 21, 'key' => '54faab2ab6e3223dbe848b1686490baa', 'fields' => '{"name":"","text":""}'], | ||||||
|  |             ['id' => 57, 'name' => 'Square', 'provider' => 'Square', 'is_offsite' => false, 'sort_order' => 21, 'key' => '65faab2ab6e3223dbe848b1686490baz', 'fields' => '{"accessToken":"","applicationId":"","locationId":"","testMode":"false"}'], | ||||||
|         ]; |         ]; | ||||||
| 
 | 
 | ||||||
|         foreach ($gateways as $gateway) { |         foreach ($gateways as $gateway) { | ||||||
| @ -96,7 +97,7 @@ class PaymentLibrariesSeeder extends Seeder | |||||||
| 
 | 
 | ||||||
|         Gateway::query()->update(['visible' => 0]); |         Gateway::query()->update(['visible' => 0]); | ||||||
| 
 | 
 | ||||||
|         Gateway::whereIn('id', [1,7,15,20,39,46,55,50])->update(['visible' => 1]); |         Gateway::whereIn('id', [1,7,15,20,39,46,55,50,57])->update(['visible' => 1]); | ||||||
| 
 | 
 | ||||||
|         if (Ninja::isHosted()) { |         if (Ninja::isHosted()) { | ||||||
|             Gateway::whereIn('id', [20])->update(['visible' => 0]); |             Gateway::whereIn('id', [20])->update(['visible' => 0]); | ||||||
|  | |||||||
| @ -0,0 +1,167 @@ | |||||||
|  | @extends('portal.ninja2020.layout.payments', ['gateway_title' => ctrans('texts.payment_type_credit_card'), 'card_title' | ||||||
|  | => ctrans('texts.payment_type_credit_card')]) | ||||||
|  | 
 | ||||||
|  | @section('gateway_head') | ||||||
|  | @endsection | ||||||
|  | 
 | ||||||
|  | @section('gateway_content') | ||||||
|  |     <form action="{{ route('client.payment_methods.store', ['method' => App\Models\GatewayType::CREDIT_CARD]) }}" | ||||||
|  |         method="post" id="server_response"> | ||||||
|  |         @csrf | ||||||
|  |         <input type="text" name="sourceId" id="sourceId" hidden> | ||||||
|  |     | ||||||
|  |     <div class="alert alert-failure mb-4" hidden id="errors"></div> | ||||||
|  | 
 | ||||||
|  |     @component('portal.ninja2020.components.general.card-element-single') | ||||||
|  |             <div id="card-container"></div> | ||||||
|  | 
 | ||||||
|  |             <div id="payment-status-container"></div> | ||||||
|  | 
 | ||||||
|  |          </form> | ||||||
|  |     @endcomponent | ||||||
|  | 
 | ||||||
|  |     @component('portal.ninja2020.gateways.includes.pay_now') | ||||||
|  |         {{ ctrans('texts.add_payment_method') }} | ||||||
|  |     @endcomponent | ||||||
|  | @endsection | ||||||
|  | 
 | ||||||
|  | @section('gateway_footer') | ||||||
|  | 
 | ||||||
|  |  <script | ||||||
|  |       type="text/javascript" | ||||||
|  |       src="https://sandbox.web.squarecdn.com/v1/square.js" | ||||||
|  |     ></script> | ||||||
|  |     <script> | ||||||
|  |       const appId = "{{ $gateway->company_gateway->getConfigField('applicationId') }}"; | ||||||
|  |       const locationId = "{{ $gateway->company_gateway->getConfigField('locationId') }}"; | ||||||
|  | 
 | ||||||
|  |       const darkModeCardStyle = { | ||||||
|  |         '.input-container': { | ||||||
|  |           borderColor: '#2D2D2D', | ||||||
|  |           borderRadius: '6px', | ||||||
|  |         }, | ||||||
|  |         '.input-container.is-focus': { | ||||||
|  |           borderColor: '#006AFF', | ||||||
|  |         }, | ||||||
|  |         '.input-container.is-error': { | ||||||
|  |           borderColor: '#ff1600', | ||||||
|  |         }, | ||||||
|  |         '.message-text': { | ||||||
|  |           color: '#999999', | ||||||
|  |         }, | ||||||
|  |         '.message-icon': { | ||||||
|  |           color: '#999999', | ||||||
|  |         }, | ||||||
|  |         '.message-text.is-error': { | ||||||
|  |           color: '#ff1600', | ||||||
|  |         }, | ||||||
|  |         '.message-icon.is-error': { | ||||||
|  |           color: '#ff1600', | ||||||
|  |         }, | ||||||
|  |         input: { | ||||||
|  |           backgroundColor: '#2D2D2D', | ||||||
|  |           color: '#FFFFFF', | ||||||
|  |           fontFamily: 'helvetica neue, sans-serif', | ||||||
|  |         }, | ||||||
|  |         'input::placeholder': { | ||||||
|  |           color: '#999999', | ||||||
|  |         }, | ||||||
|  |         'input.is-error': { | ||||||
|  |           color: '#ff1600', | ||||||
|  |         }, | ||||||
|  |       }; | ||||||
|  | 
 | ||||||
|  |       async function initializeCard(payments) { | ||||||
|  |         const card = await payments.card({ | ||||||
|  |           style: darkModeCardStyle, | ||||||
|  |         }); | ||||||
|  |         await card.attach('#card-container'); | ||||||
|  | 
 | ||||||
|  |         return card; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       async function tokenize(paymentMethod) { | ||||||
|  |         const tokenResult = await paymentMethod.tokenize(); | ||||||
|  |         if (tokenResult.status === 'OK') { | ||||||
|  |           return tokenResult.token; | ||||||
|  |         } else { | ||||||
|  |           let errorMessage = `Tokenization failed with status: ${tokenResult.status}`; | ||||||
|  |           if (tokenResult.errors) { | ||||||
|  |             errorMessage += ` and errors: ${JSON.stringify( | ||||||
|  |               tokenResult.errors | ||||||
|  |             )}`; | ||||||
|  |           } | ||||||
|  | 
 | ||||||
|  |           throw new Error(errorMessage); | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       // status is either SUCCESS or FAILURE;
 | ||||||
|  |       function displayPaymentResults(status) { | ||||||
|  |         const statusContainer = document.getElementById( | ||||||
|  |           'payment-status-container' | ||||||
|  |         ); | ||||||
|  |         if (status === 'SUCCESS') { | ||||||
|  |           statusContainer.classList.remove('is-failure'); | ||||||
|  |           statusContainer.classList.add('is-success'); | ||||||
|  |         } else { | ||||||
|  |           statusContainer.classList.remove('is-success'); | ||||||
|  |           statusContainer.classList.add('is-failure'); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         statusContainer.style.visibility = 'visible'; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       document.addEventListener('DOMContentLoaded', async function () { | ||||||
|  |         if (!window.Square) { | ||||||
|  |           throw new Error('Square.js failed to load properly'); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         let payments; | ||||||
|  |         try { | ||||||
|  |           payments = window.Square.payments(appId, locationId); | ||||||
|  |         } catch { | ||||||
|  |           const statusContainer = document.getElementById( | ||||||
|  |             'payment-status-container' | ||||||
|  |           ); | ||||||
|  |           statusContainer.className = 'missing-credentials'; | ||||||
|  |           statusContainer.style.visibility = 'visible'; | ||||||
|  |           return; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         let card; | ||||||
|  |         try { | ||||||
|  |           card = await initializeCard(payments); | ||||||
|  |         } catch (e) { | ||||||
|  |           console.error('Initializing Card failed', e); | ||||||
|  |           return; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         async function handlePaymentMethodSubmission(event, paymentMethod) { | ||||||
|  |           event.preventDefault(); | ||||||
|  | 
 | ||||||
|  |           try { | ||||||
|  |             // disable the submit button as we await tokenization and make a payment request.
 | ||||||
|  |             cardButton.disabled = true; | ||||||
|  |             const token = await tokenize(paymentMethod); | ||||||
|  | 
 | ||||||
|  |             document.getElementById('sourceId').value = token; | ||||||
|  |             document.getElementById('server_response').submit(); | ||||||
|  |      | ||||||
|  |             displayPaymentResults('SUCCESS'); | ||||||
|  | 
 | ||||||
|  |           } catch (e) { | ||||||
|  |             cardButton.disabled = false; | ||||||
|  |             displayPaymentResults('FAILURE'); | ||||||
|  |             console.error(e.message); | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         const cardButton = document.getElementById('pay-now'); | ||||||
|  |         cardButton.addEventListener('click', async function (event) { | ||||||
|  |           await handlePaymentMethodSubmission(event, card); | ||||||
|  |         }); | ||||||
|  |       }); | ||||||
|  |     </script> | ||||||
|  | 
 | ||||||
|  |   @endsection | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user