mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-06-23 20:00:33 -04:00
commit
ff82d7df06
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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)) {
|
||||||
|
@ -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'])) {
|
||||||
|
@ -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 = [
|
||||||
|
@ -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();
|
||||||
|
|
||||||
}
|
}
|
53
app/PaymentDrivers/Authorize/AuthorizeCreditCard.php
Normal file
53
app/PaymentDrivers/Authorize/AuthorizeCreditCard.php
Normal 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)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
66
app/PaymentDrivers/Authorize/AuthorizeTransactions.php
Normal file
66
app/PaymentDrivers/Authorize/AuthorizeTransactions.php
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
@ -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)
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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') }}
|
||||||
|
@ -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>
|
@ -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
|
Loading…
x
Reference in New Issue
Block a user