diff --git a/app/Http/Requests/Payments/PaymentWebhookRequest.php b/app/Http/Requests/Payments/PaymentWebhookRequest.php index ea11d0af2056..50bc276c14ae 100644 --- a/app/Http/Requests/Payments/PaymentWebhookRequest.php +++ b/app/Http/Requests/Payments/PaymentWebhookRequest.php @@ -74,9 +74,9 @@ class PaymentWebhookRequest extends Request { // For testing purposes we'll slow down the webhook processing by 2 seconds // to make sure webhook request doesn't came before our processing. - if (app()->environment() !== 'production') { + //if (app()->environment() !== 'production') { sleep(2); - } + //} // Some gateways, like Checkout, we can dynamically pass payment hash, // which we will resolve here and get payment information from it. diff --git a/app/Mail/Engine/PaymentEmailEngine.php b/app/Mail/Engine/PaymentEmailEngine.php index d008f38f0bd1..137be2392677 100644 --- a/app/Mail/Engine/PaymentEmailEngine.php +++ b/app/Mail/Engine/PaymentEmailEngine.php @@ -133,6 +133,7 @@ class PaymentEmailEngine extends BaseEmailEngine $data['$email'] = ['value' => isset($this->contact) ? $this->contact->email : 'no contact email on record', 'label' => ctrans('texts.email')]; $data['$client_name'] = ['value' => $this->client->present()->name() ?: ' ', 'label' => ctrans('texts.client_name')]; $data['$client.name'] = &$data['$client_name']; + $data['$client'] = &$data['$client_name']; $data['$client.address1'] = &$data['$address1']; $data['$client.address2'] = &$data['$address2']; $data['$client_address'] = ['value' => $this->client->present()->address() ?: ' ', 'label' => ctrans('texts.address')]; diff --git a/app/Mail/SupportMessageSent.php b/app/Mail/SupportMessageSent.php index 429202661a17..5e513c9eb015 100644 --- a/app/Mail/SupportMessageSent.php +++ b/app/Mail/SupportMessageSent.php @@ -60,11 +60,12 @@ class SupportMessageSent extends Mailable $company = auth()->user()->company(); $user = auth()->user(); + $db = str_replace("db-ninja-", "", $company->db); if(Ninja::isHosted()) - $subject = "{$priority}Hosted-{$company->db} :: Customer Support - {$plan} ".date('M jS, g:ia'); + $subject = "{$priority}Hosted-{$company->db} :: {$plan} :: ".date('M jS, g:ia'); else - $subject = "{$priority}Self Hosted :: Customer Support - [{$plan}] ".date('M jS, g:ia'); + $subject = "{$priority}Self Hosted :: {$plan} :: ".date('M jS, g:ia'); return $this->from(config('mail.from.address'), $user->present()->name()) ->replyTo($user->email, $user->present()->name()) diff --git a/app/Models/CompanyGateway.php b/app/Models/CompanyGateway.php index b9105b566e9e..1204b8e0ea1a 100644 --- a/app/Models/CompanyGateway.php +++ b/app/Models/CompanyGateway.php @@ -69,16 +69,20 @@ class CompanyGateway extends BaseModel // const TYPE_CUSTOM = 306; // const TYPE_BRAINTREE = 307; // const TYPE_WEPAY = 309; + // const TYPE_PAYFAST = 310; + // const TYPE_PAYTRACE = 311; public $gateway_consts = [ '38f2c48af60c7dd69e04248cbb24c36e' => 300, 'd14dd26a37cecc30fdd65700bfb55b23' => 301, + 'd14dd26a47cecc30fdd65700bfb67b34' => 301, '3758e7f7c6f4cecf0f4f348b9a00f456' => 304, '3b6621f970ab18887c4f6dca78d3f8bb' => 305, '54faab2ab6e3223dbe848b1686490baa' => 306, - 'd14dd26a47cecc30fdd65700bfb67b34' => 301, - '8fdeed552015b3c7b44ed6c8ebd9e992' => 309, 'f7ec488676d310683fb51802d076d713' => 307, + '8fdeed552015b3c7b44ed6c8ebd9e992' => 309, + 'd6814fc83f45d2935e7777071e629ef9' => 310, + 'bbd736b3254b0aabed6ad7fda1298c88' => 311, ]; protected $touches = []; diff --git a/app/Models/Gateway.php b/app/Models/Gateway.php index 32fc20999409..7d22a21aa9f7 100644 --- a/app/Models/Gateway.php +++ b/app/Models/Gateway.php @@ -81,6 +81,9 @@ class Gateway extends StaticModel case 1: return [GatewayType::CREDIT_CARD => ['refund' => true, 'token_billing' => true]];//Authorize.net break; + case 1: + return [GatewayType::CREDIT_CARD => ['refund' => false, 'token_billing' => false]];//Payfast + break; case 15: return [GatewayType::PAYPAL => ['refund' => true, 'token_billing' => false]]; //Paypal break; @@ -95,6 +98,8 @@ class Gateway extends StaticModel case 39: return [GatewayType::CREDIT_CARD => ['refund' => true, 'token_billing' => true]]; //Checkout break; + case 46: + return [GatewayType::CREDIT_CARD => ['refund' => true, 'token_billing' => true]]; //Paytrace case 49: return [GatewayType::CREDIT_CARD => ['refund' => true, 'token_billing' => true], GatewayType::BANK_TRANSFER => ['refund' => true, 'token_billing' => true]]; //WePay diff --git a/app/Models/SystemLog.php b/app/Models/SystemLog.php index 7614c01ecccc..5e933edfe8a1 100644 --- a/app/Models/SystemLog.php +++ b/app/Models/SystemLog.php @@ -68,7 +68,7 @@ class SystemLog extends Model const TYPE_BRAINTREE = 307; const TYPE_WEPAY = 309; const TYPE_PAYFAST = 310; - + const TYPE_PAYTRACE = 311; const TYPE_QUOTA_EXCEEDED = 400; const TYPE_UPSTREAM_FAILURE = 401; diff --git a/app/PaymentDrivers/BaseDriver.php b/app/PaymentDrivers/BaseDriver.php index ef59a3d0d82c..2ad64c1ae8c3 100644 --- a/app/PaymentDrivers/BaseDriver.php +++ b/app/PaymentDrivers/BaseDriver.php @@ -431,6 +431,61 @@ class BaseDriver extends AbstractPaymentDriver return false; } + /*Generic Global unsuccessful transaction method when the client is present*/ + public function processUnsuccessfulTransaction($response, $client_present = true) + { + $error = $response['error']; + $error_code = $response['error_code']; + + $this->unWindGatewayFees($this->payment_hash); + + PaymentFailureMailer::dispatch($this->client, $error, $this->client->company, $this->payment_hash->data->amount_with_fee); + + $nmo = new NinjaMailerObject; + $nmo->mailable = new NinjaMailer( (new ClientPaymentFailureObject($this->client, $error, $this->client->company, $this->payment_hash))->build() ); + $nmo->company = $this->client->company; + $nmo->settings = $this->client->company->settings; + + $invoices = Invoice::whereIn('id', $this->transformKeys(array_column($this->payment_hash->invoices(), 'invoice_id')))->withTrashed()->get(); + + $invoices->each(function ($invoice){ + + $invoice->service()->deletePdf(); + + }); + + $invoices->first()->invitations->each(function ($invitation) use ($nmo){ + + if ($invitation->contact->send_email && $invitation->contact->email) { + + $nmo->to_user = $invitation->contact; + NinjaMailerJob::dispatch($nmo); + + } + + }); + + $message = [ + 'server_response' => $response, + 'data' => $this->payment_hash->data, + ]; + + SystemLogger::dispatch( + $message, + SystemLog::CATEGORY_GATEWAY_RESPONSE, + SystemLog::EVENT_GATEWAY_FAILURE, + $this::SYSTEM_LOG_TYPE, + $this->client, + $this->client->company, + ); + + if($client_present) + throw new PaymentFailed($error, 500); + + } + + + public function checkRequirements() { if ($this->company_gateway->require_billing_address) { diff --git a/app/PaymentDrivers/PayTrace/CreditCard.php b/app/PaymentDrivers/PayTrace/CreditCard.php new file mode 100644 index 000000000000..692469c86d48 --- /dev/null +++ b/app/PaymentDrivers/PayTrace/CreditCard.php @@ -0,0 +1,256 @@ +paytrace_driver = $paytrace_driver; + } + + public function authorizeView($data) + { + + $data['client_key'] = $this->paytrace_driver->getAuthToken(); + $data['gateway'] = $this->paytrace_driver; + + return render('gateways.paytrace.authorize', $data); + } + + // +"success": true + // +"response_code": 160 + // +"status_message": "The customer profile for PLS5U60OoLUfQXzcmtJYNefPA0gTthzT/11 was successfully created." + // +"customer_id": "PLS5U60OoLUfQXzcmtJYNefPA0gTthzT" + + //if(!$response->success) + //handle failure + + public function authorizeResponse($request) + { + $data = $request->all(); + + $response = $this->createCustomer($data); + + return redirect()->route('client.payment_methods.index'); + + } + + // "_token" => "Vl1xHflBYQt9YFSaNCPTJKlY5x3rwcFE9kvkw71I" + // "company_gateway_id" => "1" + // "HPF_Token" => "e484a92c-90ed-4468-ac4d-da66824c75de" + // "enc_key" => "zqz6HMHCXALWdX5hyBqrIbSwU7TBZ0FTjjLB3Cp0FQY=" + // "amount" => "Amount" + // "q" => "/client/payment_methods" + // "method" => "1" + // ] + + // "customer_id":"customer789", + // "hpf_token":"e369847e-3027-4174-9161-fa0d4e98d318", + // "enc_key":"lI785yOBMet4Rt9o4NLXEyV84WBU3tdStExcsfoaOoo=", + // "integrator_id":"xxxxxxxxxx", + // "billing_address":{ + // "name":"Mark Smith", + // "street_address":"8320 E. West St.", + // "city":"Spokane", + // "state":"WA", + // "zip":"85284" + // } + + private function createCustomer($data) + { + $post_data = [ + 'customer_id' => Str::random(32), + 'hpf_token' => $data['HPF_Token'], + 'enc_key' => $data['enc_key'], + 'integrator_id' => $this->company_gateway->getConfigField('integratorId'), + 'billing_address' => $this->buildBillingAddress(), + ]; + + $response = $this->paytrace_driver->gatewayRequest('/v1/customer/pt_protect_create', $post_data); + + $cgt = []; + $cgt['token'] = $response->customer_id; + $cgt['payment_method_id'] = GatewayType::CREDIT_CARD; + + $profile = $this->getCustomerProfile($response->customer_id); + + $payment_meta = new \stdClass; + $payment_meta->exp_month = $profile->credit_card->expiration_month; + $payment_meta->exp_year = $profile->credit_card->expiration_year; + $payment_meta->brand = 'CC'; + $payment_meta->last4 = $profile->credit_card->masked_number; + $payment_meta->type = GatewayType::CREDIT_CARD; + + $cgt['payment_meta'] = $payment_meta; + + $token = $this->paytrace_driver->storeGatewayToken($cgt, []); + + return $response; + } + + private function getCustomerProfile($customer_id) + { + $profile = $this->paytrace_driver->gatewayRequest('/v1/customer/export', [ + 'integrator_id' => $this->company_gateway->getConfigField('integratorId'), + 'customer_id' => $customer_id, + // 'include_bin' => true, + ]); + + return $profile->customers[0]; + + } + + private function buildBillingAddress() + { + return [ + 'name' => $this->paytrace_driver->client->present()->name(), + 'street_address' => $this->paytrace_driver->client->address1, + 'city' => $this->paytrace_driver->client->city, + 'state' => $this->paytrace_driver->client->state, + 'zip' => $this->paytrace_driver->client->postal_code + ]; + } + + public function paymentView($data) + { + + $data['client_key'] = $this->paytrace_driver->getAuthToken(); + $data['gateway'] = $this->paytrace_driver; + + return render('gateways.paytrace.pay', $data); + + } + + public function paymentResponse(Request $request) + { + $response_array = $request->all(); + + if($request->token) + $this->processTokenPayment($request->token, $request); + + if ($request->has('store_card') && $request->input('store_card') === true) { + + $response = $this->createCustomer($request->all()); + + $this->processTokenPayment($response->customer_id, $request); + } + + //process a regular charge here: + $data = [ + 'hpf_token' => $response_array['HPF_Token'], + 'enc_key' => $response_array['enc_key'], + 'integrator_id' => $this->company_gateway->getConfigField('integratorId'), + 'billing_address' => $this->buildBillingAddress(), + 'amount' => $request->input('amount_with_fee'), + 'invoice_id' => $this->harvestInvoiceId(), + ]; + + $response = $this->paytrace_driver->gatewayRequest('/v1/transactions/sale/pt_protect', $data); + + if($response->success) + return $this->processSuccessfulPayment($response); + + return $this->processUnsuccessfulPayment($response); + + } + + public function processTokenPayment($token, $request) + { + + $data = [ + 'customer_id' => $request->token, + 'integrator_id' => $this->company_gateway->getConfigField('integratorId'), + 'amount' => $request->input('amount_with_fee'), + ]; + + $response = $this->paytrace_driver->gatewayRequest('/v1/transactions/sale/by_customer', $data); + + if($response->success){ + $this->paytrace_driver->logSuccessfulGatewayResponse(['response' => $response, 'data' => $this->paytrace_driver->payment_hash], SystemLog::TYPE_PAYTRACE); + + return $this->processSuccessfulPayment($response); + } + + return $this->processUnsuccessfulPayment($response); + } + + private function harvestInvoiceId() + { + $_invoice = collect($this->paytrace_driver->payment_hash->data->invoices)->first(); + $invoice = Invoice::withTrashed()->find($this->decodePrimaryKey($_invoice->invoice_id)); + + if($invoice) + return ctrans('texts.invoice_number') . "# " . $invoice->number; + + return ctrans('texts.invoice_number') . "####"; + } + + private function processSuccessfulPayment($response) + { + $amount = array_sum(array_column($this->paytrace_driver->payment_hash->invoices(), 'amount')) + $this->paytrace_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->paytrace_driver->createPayment($payment_record, Payment::STATUS_COMPLETED); + + return redirect()->route('client.payments.show', ['payment' => $this->encodePrimaryKey($payment->id)]); + + } + + private function processUnsuccessfulPayment($response) + { + + $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->paytrace_driver->processUnsuccessfulTransaction($data); + + } + +} \ No newline at end of file diff --git a/app/PaymentDrivers/PaytracePaymentDriver.php b/app/PaymentDrivers/PaytracePaymentDriver.php new file mode 100644 index 000000000000..9b103ca28eb9 --- /dev/null +++ b/app/PaymentDrivers/PaytracePaymentDriver.php @@ -0,0 +1,234 @@ + CreditCard::class, //maps GatewayType => Implementation class + ]; + + const SYSTEM_LOG_TYPE = SystemLog::TYPE_PAYTRACE; //define a constant for your gateway ie TYPE_YOUR_CUSTOM_GATEWAY - set the const in the SystemLog model + + public function init() + { + 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) + { + // $cgt = ClientGatewayToken::where('company_gateway_id', $payment->company_gateway_id) + // ->where('gateway_type_id', $payment->gateway_type_id) + // ->first(); + + $data = [ + 'amount' => $amount, + //'customer_id' => $cgt->token, + 'transaction_id' => $payment->transaction_reference, + 'integrator_id' => '959195xd1CuC' + ]; + + $response = $this->gatewayRequest('/v1/transactions/refund/for_transaction', $data); + + if($response && $response->success) + { + + SystemLogger::dispatch(['server_response' => $response, 'data' => $data], SystemLog::CATEGORY_GATEWAY_RESPONSE, SystemLog::EVENT_GATEWAY_SUCCESS, SystemLog::TYPE_PAYTRACE, $this->client, $this->client->company); + + return [ + 'transaction_reference' => $response->transaction_id, + 'transaction_response' => json_encode($response), + 'success' => true, + 'description' => $response->status_message, + 'code' => $response->response_code, + ]; + + } + + SystemLogger::dispatch(['server_response' => $response, 'data' => $data], SystemLog::CATEGORY_GATEWAY_RESPONSE, SystemLog::EVENT_GATEWAY_FAILURE, SystemLog::TYPE_PAYTRACE, $this->client, $this->client->company); + + return [ + 'transaction_reference' => null, + 'transaction_response' => json_encode($response), + 'success' => false, + 'description' => $response->status_message, + 'code' => 422, + ]; + + } + + public function tokenBilling(ClientGatewayToken $cgt, PaymentHash $payment_hash) + { + $amount = array_sum(array_column($payment_hash->invoices(), 'amount')) + $payment_hash->fee_total; + + $data = [ + 'customer_id' => $cgt->token, + 'integrator_id' => $this->company_gateway->getConfigField('integratorId'), + 'amount' => $amount, + ]; + + $response = $this->gatewayRequest('/v1/transactions/sale/by_customer', $data); + + if($response && $response->success) + { + $data = [ + 'gateway_type_id' => $cgt->gateway_type_id, + 'payment_type' => PaymentType::CREDIT_CARD_OTHER, + 'transaction_reference' => $response->transaction_id, + 'amount' => $amount, + ]; + + $payment = $this->createPayment($data); + $payment->meta = $cgt->meta; + $payment->save(); + + $payment_hash->payment_id = $payment->id; + $payment_hash->save(); + + return $payment; + } + + $error = $response->status_message; + + if(property_exists($response, 'approval_message') && $response->approval_message) + $error .= " - {$response->approval_message}"; + + $data = [ + 'response' => $response, + 'error' => $error, + 'error_code' => 500, + ]; + + $this->processUnsuccessfulTransaction($data, false); + } + + public function processWebhookRequest(PaymentWebhookRequest $request, Payment $payment = null) + { + } + + /*Helpers*/ + private function generateAuthHeaders() + { + + $url = 'https://api.paytrace.com/oauth/token'; + $data = [ + 'grant_type' => 'password', + 'username' => $this->company_gateway->getConfigField('username'), + 'password' => $this->company_gateway->getConfigField('password') + ]; + + $response = CurlUtils::post($url, $data, $headers = false); + + $auth_data = json_decode($response); + + $headers = []; + $headers[] = 'Content-type: application/json'; + $headers[] = 'Authorization: Bearer '.$auth_data->access_token; + + return $headers; + + } + + public function getAuthToken() + { + + $headers = $this->generateAuthHeaders(); + + $response = CurlUtils::post('https://api.paytrace.com/v1/payment_fields/token/create', [], $headers); + + $response = json_decode($response); + + if($response) + return $response->clientKey; + + return false; + } + + public function gatewayRequest($uri, $data, $headers = false) + { + + $base_url = "https://api.paytrace.com{$uri}"; + + $headers = $this->generateAuthHeaders(); + + $response = CurlUtils::post($base_url, json_encode($data), $headers); + + $response = json_decode($response); + + if($response) + return $response; + + return false; + + } +} diff --git a/app/PaymentDrivers/Stripe/Charge.php b/app/PaymentDrivers/Stripe/Charge.php index 2e8c06d7d1bc..2ae298a335e2 100644 --- a/app/PaymentDrivers/Stripe/Charge.php +++ b/app/PaymentDrivers/Stripe/Charge.php @@ -74,7 +74,7 @@ class Charge 'confirm' => true, 'description' => $description, ]; -nlog($data); + $response = $this->stripe->createPaymentIntent($data, $this->stripe->stripe_connect_auth); // $response = $local_stripe->paymentIntents->create($data); diff --git a/config/ninja.php b/config/ninja.php index 878174e2f07a..ac835e3624f5 100644 --- a/config/ninja.php +++ b/config/ninja.php @@ -84,6 +84,10 @@ return [ 'test_email' => env('TEST_EMAIL', 'test@example.com'), 'wepay' => env('WEPAY_KEYS', ''), 'braintree' => env('BRAINTREE_KEYS', ''), + 'paytrace' => [ + 'username' => env('PAYTRACE_U', ''), + 'password' => env('PAYTRACE_P','') + ], ], 'contact' => [ 'email' => env('MAIL_FROM_ADDRESS'), diff --git a/database/migrations/2021_07_20_095537_activate_paytrace_payment_driver.php b/database/migrations/2021_07_20_095537_activate_paytrace_payment_driver.php new file mode 100644 index 000000000000..e690af365e3c --- /dev/null +++ b/database/migrations/2021_07_20_095537_activate_paytrace_payment_driver.php @@ -0,0 +1,39 @@ +fields); + $fields->integratorId = ""; + + $paytrace->fields = json_encode($fields); + $paytrace->provider = 'Paytrace'; + $paytrace->visible = true; + $paytrace->save(); + } + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + // + } +} diff --git a/database/seeders/PaymentLibrariesSeeder.php b/database/seeders/PaymentLibrariesSeeder.php index b9ff0f84146f..328282dee23c 100644 --- a/database/seeders/PaymentLibrariesSeeder.php +++ b/database/seeders/PaymentLibrariesSeeder.php @@ -70,7 +70,7 @@ class PaymentLibrariesSeeder extends Seeder ['id' => 43, 'name' => 'Fasapay', 'provider' => 'Fasapay', 'key' => '1b2cef0e8c800204a29f33953aaf3360', 'fields' => ''], ['id' => 44, 'name' => 'Komoju', 'provider' => 'Komoju', 'key' => '7ea2d40ecb1eb69ef8c3d03e5019028a', 'fields' => '{"apiKey":"","accountId":"","paymentMethod":"credit_card","testMode":false,"locale":"en"}'], ['id' => 45, 'name' => 'Paysafecard', 'provider' => 'Paysafecard', 'key' => '70ab90cd6c5c1ab13208b3cef51c0894', 'fields' => '{"username":"","password":"","testMode":false}'], - ['id' => 46, 'name' => 'Paytrace', 'provider' => 'Paytrace_CreditCard', 'key' => 'bbd736b3254b0aabed6ad7fda1298c88', 'fields' => '{"username":"","password":"","testMode":false,"endpoint":"https:\/\/paytrace.com\/api\/default.pay"}'], + ['id' => 46, 'name' => 'Paytrace', 'provider' => 'Paytrace', 'key' => 'bbd736b3254b0aabed6ad7fda1298c88', 'fields' => '{"username":"","password":"","integratorId":"","testMode":false,"endpoint":"https:\/\/paytrace.com\/api\/default.pay"}'], ['id' => 47, 'name' => 'Secure Trading', 'provider' => 'SecureTrading', 'key' => '231cb401487b9f15babe04b1ac4f7a27', 'fields' => '{"siteReference":"","username":"","password":"","applyThreeDSecure":false,"accountType":"ECOM"}'], ['id' => 48, 'name' => 'SecPay', 'provider' => 'SecPay', 'key' => 'bad8699d581d9fa040e59c0bb721a76c', 'fields' => '{"mid":"","vpnPswd":"","remotePswd":"","usageType":"","confirmEmail":"","testStatus":"true","mailCustomer":"true","additionalOptions":""}'], ['id' => 49, 'name' => 'WePay', 'provider' => 'WePay', 'is_offsite' => false, 'sort_order' => 3, 'key' => '8fdeed552015b3c7b44ed6c8ebd9e992', 'fields' => '{"accountId":"","accessToken":"","type":"goods","testMode":false,"feePayer":"payee"}'], @@ -96,7 +96,7 @@ class PaymentLibrariesSeeder extends Seeder Gateway::query()->update(['visible' => 0]); - Gateway::whereIn('id', [1,15,20,39,55,50])->update(['visible' => 1]); + Gateway::whereIn('id', [1,15,20,39,46,55,50])->update(['visible' => 1]); if (Ninja::isHosted()) { Gateway::whereIn('id', [20])->update(['visible' => 0]); diff --git a/resources/views/portal/ninja2020/gateways/paytrace/authorize.blade.php b/resources/views/portal/ninja2020/gateways/paytrace/authorize.blade.php new file mode 100644 index 000000000000..2d8ce5482e6b --- /dev/null +++ b/resources/views/portal/ninja2020/gateways/paytrace/authorize.blade.php @@ -0,0 +1,145 @@ +@extends('portal.ninja2020.layout.payments', ['gateway_title' => ctrans('texts.credit_card'), 'card_title' => ctrans('texts.credit_card')]) + +@section('gateway_head') +@endsection + +@section('gateway_content') + + @if(!Request::isSecure()) +

{{ ctrans('texts.https_required') }}

+ @endif + + +
+ @csrf + +
+ +
+ +
+ + + + + +
+ +
+ +
+@endsection + +@section('gateway_footer') + + + + + +@endsection diff --git a/resources/views/portal/ninja2020/gateways/paytrace/pay.blade.php b/resources/views/portal/ninja2020/gateways/paytrace/pay.blade.php new file mode 100644 index 000000000000..4535639e43d4 --- /dev/null +++ b/resources/views/portal/ninja2020/gateways/paytrace/pay.blade.php @@ -0,0 +1,207 @@ +@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') +
+ @csrf + + + + + + + + + + + + + @component('portal.ninja2020.components.general.card-element', ['title' => ctrans('texts.payment_type')]) + {{ ctrans('texts.credit_card') }} + @endcomponent + + @include('portal.ninja2020.gateways.includes.payment_details') + + @component('portal.ninja2020.components.general.card-element', ['title' => ctrans('texts.pay_with')]) + @if(count($tokens) > 0) + @foreach($tokens as $token) + + @endforeach + @endisset + + + @endcomponent + + @include('portal.ninja2020.gateways.includes.save_card') + +
+ +
+ +
+ @include('portal.ninja2020.gateways.includes.pay_now', ['type' => 'submit']) +
+@endsection + +@section('gateway_footer') + + + + +@endsection diff --git a/resources/views/vendor/livewire/simple-bootstrap.blade.php b/resources/views/vendor/livewire/simple-bootstrap.blade.php new file mode 100644 index 000000000000..dbc374434911 --- /dev/null +++ b/resources/views/vendor/livewire/simple-bootstrap.blade.php @@ -0,0 +1,29 @@ +
+ @if ($paginator->hasPages()) + + @endif +