Merge pull request #3804 from turbo124/v2

Working on Authorize.net
This commit is contained in:
David Bomba 2020-06-16 14:02:02 +10:00 committed by GitHub
commit ff82d7df06
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 278 additions and 43 deletions

View File

@ -130,7 +130,7 @@ class PaymentController extends Controller
return $gateway return $gateway
->driver(auth()->user()->client) ->driver(auth()->user()->client)
->setPaymentMethod() ->setPaymentMethod($request->input('payment_method_id'))
->processPaymentResponse($request); ->processPaymentResponse($request);
} }
} }

View File

@ -67,6 +67,10 @@ class StoreInvoiceRequest extends Request
$input['client_id'] = $this->decodePrimaryKey($input['client_id']); $input['client_id'] = $this->decodePrimaryKey($input['client_id']);
} }
if (array_key_exists('assigned_user_id', $input) && is_string($input['assigned_user_id'])) {
$input['assigned_user_id'] = $this->decodePrimaryKey($input['assigned_user_id']);
}
if (isset($input['client_contacts'])) { if (isset($input['client_contacts'])) {
foreach ($input['client_contacts'] as $key => $contact) { foreach ($input['client_contacts'] as $key => $contact) {
if (!array_key_exists('send_email', $contact) || !array_key_exists('id', $contact)) { if (!array_key_exists('send_email', $contact) || !array_key_exists('id', $contact)) {

View File

@ -65,6 +65,10 @@ class UpdateInvoiceRequest extends Request
$input['client_id'] = $this->decodePrimaryKey($input['client_id']); $input['client_id'] = $this->decodePrimaryKey($input['client_id']);
} }
if (array_key_exists('assigned_user_id', $input) && is_string($input['assigned_user_id'])) {
$input['assigned_user_id'] = $this->decodePrimaryKey($input['assigned_user_id']);
}
if (isset($input['invitations'])) { if (isset($input['invitations'])) {
foreach ($input['invitations'] as $key => $value) { foreach ($input['invitations'] as $key => $value) {
if (is_numeric($input['invitations'][$key]['id'])) { if (is_numeric($input['invitations'][$key]['id'])) {

View File

@ -99,6 +99,7 @@ class Invoice extends BaseModel
'custom_surcharge_tax3', 'custom_surcharge_tax3',
'custom_surcharge_tax4', 'custom_surcharge_tax4',
'design_id', 'design_id',
'assigned_user_id',
]; ];
protected $casts = [ protected $casts = [

View File

@ -20,4 +20,6 @@ abstract class AbstractPaymentDriver
abstract public function refund($amount, $transaction_reference, $return_client_response = false); abstract public function refund($amount, $transaction_reference, $return_client_response = false);
abstract public function bootPaymentMethod();
} }

View File

@ -0,0 +1,53 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com)
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\PaymentDrivers\Authorize;
use App\Models\ClientGatewayToken;
use App\PaymentDrivers\AuthorizePaymentDriver;
/**
* Class AuthorizeCreditCard
* @package App\PaymentDrivers\Authorize
*
*/
class AuthorizeCreditCard
{
public $authorize;
public function __construct(AuthorizePaymentDriver $authorize)
{
$this->authorize = $authorize;
}
public function processPaymentView($data)
{
$tokens = ClientGatewayToken::where('client_id', $this->authorize->client->id)
->where('company_gateway_id', $this->authorize->company_gateway->id)
->where('gateway_type_id', $this->authorize->payment_method_id)
->get();
$data['tokens'] = $tokens;
$data['gateway'] = $this->authorize->company_gateway;
$data['public_client_id'] = $this->authorize->init()->getPublicClientKey();
$data['api_login_id'] = $this->authorize->company_gateway->getConfigField('apiLoginId');
return render('gateways.authorize.credit_card_payment', $data);
}
public function processPaymentResponse($response)
{
}
}

View File

@ -0,0 +1,66 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com)
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\PaymentDrivers\Authorize;
use net\authorize\api\contract\v1\GetTransactionDetailsRequest;
use net\authorize\api\controller\GetTransactionDetailsController;
/**
* Class AuthorizeTransactions
* @package App\PaymentDrivers\Authorize
*
*/
class AuthorizeTransactions
{
public $authorize;
public function __construct(AuthorizePaymentDriver $authorize)
{
$this->authorize = $authorize;
}
function getTransactionDetails($transactionId)
{
/* Create a merchantAuthenticationType object with authentication details
retrieved from the constants file */
$this->authorize->init();
// Set the transaction's refId
$refId = 'ref' . time();
$request = new GetTransactionDetailsRequest();
$request->setMerchantAuthentication($this->authorize->merchant_authentication);
$request->setTransId($transactionId);
$controller = new GetTransactionDetailsController($request);
$response = $controller->executeWithApiResponse($this->authorize->mode());
if (($response != null) && ($response->getMessages()->getResultCode() == "Ok"))
{
echo "SUCCESS: Transaction Status:" . $response->getTransaction()->getTransactionStatus() . "\n";
echo " Auth Amount:" . $response->getTransaction()->getAuthAmount() . "\n";
echo " Trans ID:" . $response->getTransaction()->getTransId() . "\n";
}
else
{
echo "ERROR : Invalid response\n";
$errorMessages = $response->getMessages()->getMessage();
echo "Response : " . $errorMessages[0]->getCode() . " " .$errorMessages[0]->getText() . "\n";
}
return $response;
}
}

View File

@ -33,6 +33,19 @@ class AuthorizePaymentDriver extends BaseDriver
public $merchant_authentication; public $merchant_authentication;
public static $methods = [
GatewayType::CREDIT_CARD => AuthorizeCreditCard::class,
];
public function bootPaymentMethod()
{info(print_r($this->getPaymentMethod(),1));
$class = self::$methods[$this->getPaymentMethod()];
$this->payment_method = new $class($this);
return $this;
}
/** /**
* Returns the gateway types * Returns the gateway types
*/ */
@ -97,6 +110,8 @@ class AuthorizePaymentDriver extends BaseDriver
public function processPaymentView($data) public function processPaymentView($data)
{ {
return $this->bootPaymentMethod()->payment_method->processPaymentView($data);
} }
public function processPaymentResponse($request) public function processPaymentResponse($request)

View File

@ -46,8 +46,13 @@ class BaseDriver extends AbstractPaymentDriver
/* The client */ /* The client */
public $client; public $client;
/* The payment method id*/
public $payment_method_id;
public $payment_method; public $payment_method;
public static $methods = [];
public function __construct(CompanyGateway $company_gateway, Client $client = null, $invitation = false) public function __construct(CompanyGateway $company_gateway, Client $client = null, $invitation = false)
{ {
$this->company_gateway = $company_gateway; $this->company_gateway = $company_gateway;
@ -85,6 +90,12 @@ class BaseDriver extends AbstractPaymentDriver
*/ */
public function refund($amount, $transaction_reference, $return_client_response = false) {} public function refund($amount, $transaction_reference, $return_client_response = false) {}
/**
* Initializes an instance of the payment method
* @return object The payment method instance
*/
public function bootPaymentMethod() {}
/** /**
* Set the inbound request payment method type for access. * Set the inbound request payment method type for access.
* *
@ -92,7 +103,10 @@ class BaseDriver extends AbstractPaymentDriver
*/ */
public function setPaymentMethod($payment_method_id) public function setPaymentMethod($payment_method_id)
{ {
$this->payment_method = $payment_method_id; info("setting payment method {$payment_method_id}");
$this->payment_method_id = $payment_method_id;
return $this; return $this;
} }
@ -103,6 +117,6 @@ class BaseDriver extends AbstractPaymentDriver
*/ */
public function getPaymentMethod() public function getPaymentMethod()
{ {
return $this->payment_method; return $this->payment_method_id;
} }
} }

View File

@ -31,46 +31,9 @@
</div> </div>
<div> <div>
<dl> <dl>
<div class="bg-gray-50 px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6 flex items-center">
<dt class="text-sm leading-5 font-medium text-gray-500 mr-4"> @include('portal.ninja2020.gateways.authorize.credit_card')
{{ ctrans('texts.name') }}
</dt>
<dd class="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2">
<input class="input w-full" id="cardholder_name" type="text" placeholder="{{ ctrans('texts.name') }}">
</dd>
</div>
<div class="bg-white px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt class="text-sm leading-5 font-medium text-gray-500">
{{ ctrans('texts.credit_card') }}
</dt>
<dd class="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2">
<input class="input w-full" id="card_number" type="text" placeholder="{{ ctrans('texts.card_number') }}">
</dd>
</div>
<div class="bg-white px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt class="text-sm leading-5 font-medium text-gray-500">
{{ ctrans('texts.expiration_month') }}
</dt>
<dd class="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2">
<input class="input w-full" id="expiration_month" type="text" placeholder="{{ ctrans('texts.expiration_month') }}">
</dd>
</div>
<div class="bg-white px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt class="text-sm leading-5 font-medium text-gray-500">
{{ ctrans('texts.expiration_year') }}
</dt>
<dd class="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2">
<input class="input w-full" id="expiration_year" type="text" placeholder="{{ ctrans('texts.expiration_year') }}">
</dd>
</div>
<div class="bg-white px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt class="text-sm leading-5 font-medium text-gray-500">
{{ ctrans('texts.cvv') }}
</dt>
<dd class="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2">
<input class="input w-full" id="cvv" type="text" placeholder="{{ ctrans('texts.cvv') }}">
</dd>
</div>
<div class="bg-gray-50 px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6"> <div class="bg-gray-50 px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt class="text-sm leading-5 font-medium text-gray-500"> <dt class="text-sm leading-5 font-medium text-gray-500">
{{ ctrans('texts.save_as_default') }} {{ ctrans('texts.save_as_default') }}

View File

@ -0,0 +1,40 @@
<div class="bg-gray-50 px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6 flex items-center">
<dt class="text-sm leading-5 font-medium text-gray-500 mr-4">
{{ ctrans('texts.name') }}
</dt>
<dd class="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2">
<input class="input w-full" id="cardholder_name" type="text" placeholder="{{ ctrans('texts.name') }}">
</dd>
</div>
<div class="bg-white px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt class="text-sm leading-5 font-medium text-gray-500">
{{ ctrans('texts.credit_card') }}
</dt>
<dd class="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2">
<input class="input w-full" id="card_number" type="text" placeholder="{{ ctrans('texts.card_number') }}">
</dd>
</div>
<div class="bg-white px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt class="text-sm leading-5 font-medium text-gray-500">
{{ ctrans('texts.expiration_month') }}
</dt>
<dd class="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2">
<input class="input w-full" id="expiration_month" type="text" placeholder="{{ ctrans('texts.expiration_month') }}">
</dd>
</div>
<div class="bg-white px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt class="text-sm leading-5 font-medium text-gray-500">
{{ ctrans('texts.expiration_year') }}
</dt>
<dd class="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2">
<input class="input w-full" id="expiration_year" type="text" placeholder="{{ ctrans('texts.expiration_year') }}">
</dd>
</div>
<div class="bg-white px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt class="text-sm leading-5 font-medium text-gray-500">
{{ ctrans('texts.cvv') }}
</dt>
<dd class="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2">
<input class="input w-full" id="cvv" type="text" placeholder="{{ ctrans('texts.cvv') }}">
</dd>
</div>

View File

@ -0,0 +1,73 @@
@extends('portal.ninja2020.layout.app')
@section('meta_title', ctrans('texts.add_credit_card'))
@push('head')
<meta name="authorize-public-key" content="{{ $public_client_id }}">
<meta name="authorize-login-id" content="{{ $api_login_id }}">
@endpush
@section('body')
<form action="{{ route('client.payment_methods.store') }}" method="post" id="server_response">
@csrf
<input type="hidden" name="company_gateway_id" value="{{ $gateway->id }}">
<input type="hidden" name="gateway_type_id" value="1">
<input type="hidden" name="gateway_response" id="gateway_response">
<input type="hidden" name="is_default" id="is_default">
<input type="hidden" name="dataValue" id="dataValue" />
<input type="hidden" name="dataDescriptor" id="dataDescriptor" />
<input type="hidden" name="token" id="token" />
<input type="hidden" name="save_method" id="save_method" />
</form>
<div class="container mx-auto">
<div class="grid grid-cols-6 gap-4">
<div class="col-span-6 md:col-start-2 md:col-span-4">
<div class="alert alert-failure mb-4" hidden id="errors"></div>
<div class="bg-white shadow overflow-hidden sm:rounded-lg">
<div class="px-4 py-5 border-b border-gray-200 sm:px-6">
</div>
<div>
@if($tokens->count() == 0)
<dl>
@include('portal.ninja2020.gateways.authorize.credit_card')
<div class="bg-gray-50 px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt class="text-sm leading-5 font-medium text-gray-500">
{{ ctrans('texts.save_as_default') }}
</dt>
<dd class="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2">
<input type="checkbox" class="form-checkbox" name="proxy_is_default"
id="proxy_is_default"/>
</dd>
</div>
<div class="bg-white px-4 py-5 flex justify-end">
<button type="primary" id="card_button">{{ ctrans('texts.pay_now') }}</button>
</div>
</dl>
@else
<!-- TODO Iterate through the tokens and display the card type and last4 and present
a button for payment -->
<ul>
@foreach($tokens as $token)
<li>
$token->meta->brand : $token->meta->last4 : <button class="primary" id="{{ $token->token }}">{{ ctrans('texts.pay_now') }}</button>
</li>
@endforeach
</ul>
@endif
</div>
</div>
</div>
</div>
</div>
@endsection
@push('footer')
@if($gateway->getConfigField('testMode'))
<script src="https://jstest.authorize.net/v1/Accept.js" charset="utf-8"></script>
@else
<script src="https://js.authorize.net/v1/Accept.js" charset="utf-8"></script>
@endif
<script src="{{ asset('js/clients/payment_methods/authorize-authorize-card.js') }}"></script>
@endpush