1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-11-10 05:02:36 +01:00

Made changes to include PHP-Payments. Added Recommended Gateways to the Company/Payments UI.

This commit is contained in:
blkmutt 2014-03-29 20:21:57 -04:00
commit 227282a8cf
18 changed files with 410 additions and 62 deletions

3
.gitignore vendored
View File

@ -18,4 +18,5 @@
/ninja.sublime-project
/ninja.sublime-workspace
/tests/_log
.idea
.idea
.project

View File

@ -102,19 +102,43 @@ class AccountController extends \BaseController {
{
$accountGateway = $account->account_gateways[0];
$config = $accountGateway->config;
}
}
$recommendedGateways = Gateway::remember(DEFAULT_QUERY_CACHE)
->where('recommended', '=', '1')
->orderBy('sort_order')
->get();
$recommendedGatewayArray = array();
foreach($recommendedGateways as $recommendedGateway)
{
$newRow = count($recommendedGatewayArray) + 1 == round(count($recommendedGateways) / 2);
$arrayItem = array(
'value' => $recommendedGateway->id,
'data-imageUrl' => $recommendedGateway->getLogoUrl(),
'data-siteUrl' => $recommendedGateway->site_url,
'data-newRow' => $newRow
);
$recommendedGatewayArray[$recommendedGateway->name] = $arrayItem;
}
$data = [
'account' => $account,
'accountGateway' => $accountGateway,
'config' => json_decode($config),
'gateways' => Gateway::remember(DEFAULT_QUERY_CACHE)->get(),
'gateways' => Gateway::remember(DEFAULT_QUERY_CACHE)
->orderBy('name')
->get(),
'recommendedGateways' => $recommendedGatewayArray,
];
foreach ($data['gateways'] as $gateway)
{
$gateway->fields = Omnipay::create($gateway->provider)->getDefaultParameters();
$paymentLibrary = $gateway->paymentlibrary;
$gateway->fields = $gateway->getFields();
if ($accountGateway && $accountGateway->gateway_id == $gateway->id)
{
$accountGateway->fields = $gateway->fields;
@ -439,7 +463,10 @@ class AccountController extends \BaseController {
if ($gatewayId = Input::get('gateway_id'))
{
$gateway = Gateway::findOrFail($gatewayId);
$fields = Omnipay::create($gateway->provider)->getDefaultParameters();
$paymentLibrary = $gateway->paymentlibrary;
$fields = $gateway->getFields();
foreach ($fields as $field => $details)
{

View File

@ -129,8 +129,9 @@ class PaymentController extends \BaseController
private function getPaymentDetails($invoice, $input = null)
{
$key = $invoice->invoice_number . '_details';
$paymentLibrary = $invoice->client->account->account_gateways[0]->gateway->paymentlibrary;
if ($input)
if ($input && $paymentLibrary->name == "Omnipay")
{
$data = [
'firstName' => $input['first_name'],
@ -152,6 +153,33 @@ class PaymentController extends \BaseController
];
Session::put($key, $data);
}
else if ($input && $paymentLibrary->name == "PHP-Payments")
{
$input = Input::all();
$data = [
'first_name' => $input['first_name'],
'last_name' => $input['last_name'],
'cc_number' => $input['card_number'],
'cc_exp' => $input['expiration_month'].$input['expiration_year'],
'cc_code' => $input['cvv'],
'street' => $input['address1'],
'street2' => $input['address2'],
'city' => $input['city'],
'state' => $input['state'],
'postal_code' => $input['postal_code'],
'amt' => $invoice->amount,
'ship_to_street' => $input['address1'],
'ship_to_city' => $input['city'],
'ship_to_state' => $input['state'],
'ship_to_postal_code' => $input['postal_code'],
'currency_code' => $invoice->client->currency->code,
'returnUrl' => URL::to('complete'),
'cancelUrl' => URL::to('/')
];
Session::put($key, $data);
return $data;
}
else if (Session::get($key))
{
@ -162,15 +190,22 @@ class PaymentController extends \BaseController
$data = [];
}
$card = new CreditCard($data);
return [
'amount' => $invoice->amount,
'card' => $card,
'currency' => $invoice->client->currency->code,
'returnUrl' => URL::to('complete'),
'cancelUrl' => URL::to('/')
];
if($paymentLibrary->name == "Omnipay")
{
$card = new CreditCard($data);
return [
'amount' => $invoice->amount,
'card' => $card,
'currency' => $invoice->client->currency->code,
'returnUrl' => URL::to('complete'),
'cancelUrl' => URL::to('/')
];
}
else
{
return $data;
}
}
public function show_payment($invitationKey)
@ -235,7 +270,7 @@ class PaymentController extends \BaseController
$invitation = Invitation::with('invoice.invoice_items', 'invoice.client.currency', 'invoice.client.account.account_gateways.gateway')->where('invitation_key', '=', $invitationKey)->firstOrFail();
$invoice = $invitation->invoice;
$accountGateway = $invoice->client->account->account_gateways[0];
$gateway = self::createGateway($accountGateway);
$paymentLibrary = $accountGateway->gateway->paymentlibrary;
if ($onSite)
{
@ -247,44 +282,77 @@ class PaymentController extends \BaseController
$client->postal_code = trim(Input::get('postal_code'));
$client->save();
}
try
{
$details = self::getPaymentDetails($invoice, Input::all());
$response = $gateway->purchase($details)->send();
$ref = $response->getTransactionReference();
if (!$ref)
{
Session::flash('error', $response->getMessage());
return Redirect::to('payment/' . $invitationKey)
->withInput();
if($paymentLibrary->name == "Omnipay")
{
$gateway = self::createGateway($accountGateway);
$details = self::getPaymentDetails($invoice, Input::all());
$response = $gateway->purchase($details)->send();
$ref = $response->getTransactionReference();
if (!$ref)
{
Session::flash('error', $response->getMessage());
return Redirect::to('payment/' . $invitationKey)
->withInput();
}
if ($response->isSuccessful())
{
$payment = self::createPayment($invitation, $ref);
$invoice->invoice_status_id = INVOICE_STATUS_PAID;
$invoice->save();
Event::fire('invoice.paid', $payment);
Session::flash('message', 'Successfully applied payment');
return Redirect::to('view/' . $payment->invitation->invitation_key);
}
else if ($response->isRedirect())
{
$invitation->transaction_reference = $ref;
$invitation->save();
$response->redirect();
}
else
{
Session::flash('error', $response->getMessage());
return Utils::fatalError('Sorry, there was an error processing your payment. Please try again later.<p>', $response->getMessage());
}
}
else if ($input && $paymentLibrary->name == "PHP-Payments")
{
$provider = $accountGateway->gateway->provider;
$p = new PHP_Payments;
$config = Payment_Utility::load('config', 'drivers/'.$provider);
$details = self::getPaymentDetails($invoice, Input::all());
$response = $p->oneoff_payment($provider, $details, $config);
if ($response->isSuccessful())
{
$payment = self::createPayment($invitation, $ref);
$invoice->invoice_status_id = INVOICE_STATUS_PAID;
$invoice->save();
Event::fire('invoice.paid', $payment);
Session::flash('message', 'Successfully applied payment');
return Redirect::to('view/' . $payment->invitation->invitation_key);
}
else if ($response->isRedirect())
{
$invitation->transaction_reference = $ref;
$invitation->save();
$response->redirect();
}
else
{
Session::flash('error', $response->getMessage());
return Utils::fatalError('Sorry, there was an error processing your payment. Please try again later.<p>', $response->getMessage());
}
if ($response->status == 'Success')
{
$payment = self::createPayment($invitation, $ref);
$invoice->invoice_status_id = INVOICE_STATUS_PAID;
$invoice->save();
Event::fire('invoice.paid', $payment);
Session::flash('message', 'Successfully applied payment');
return Redirect::to('view/' . $payment->invitation->invitation_key);
}
else
{
Session::flash('error', $response->details);
return Utils::fatalError('Sorry, there was an error processing your payment. Please try again later.<p>', $response->reason);
}
}
}
catch (\Exception $e)
{

View File

@ -0,0 +1,61 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreatePaymentLibraries extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::dropIfExists('payment_libraries');
Schema::create('payment_libraries', function($t)
{
$t->increments('id');
$t->timestamps();
$t->string('name');
$t->boolean('visible')->default(true);
});
DB::table('payment_libraries')->insert(['name' => 'Omnipay']);
DB::table('payment_libraries')->insert(['name' => 'PHP-Payments']);
Schema::table('gateways', function($table)
{
$table->unsignedInteger('payment_library_id')->default(1);
});
DB::table('gateways')->update(['payment_library_id' => 1]);
Schema::table('gateways', function($table)
{
$table->foreign('payment_library_id')->references('id')->on('payment_libraries')->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
if (Schema::hasColumn('gateways', 'payment_library_id'))
{
Schema::table('gateways', function($table)
{
$table->dropForeign('gateways_payment_library_id_foreign');
$table->dropColumn('payment_library_id');
});
}
Schema::dropIfExists('payment_libraries');
}
}

View File

@ -0,0 +1,49 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddSortAndRecommendedToGateways extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('gateways', function($table)
{
$table->unsignedInteger('sort_order')->default(10000);
$table->boolean('recommended');
$table->string('site_url', 200);
});
}
public function down()
{
if (Schema::hasColumn('gateways', 'sort_order'))
{
Schema::table('gateways', function($table)
{
$table->dropColumn('sort_order');
});
}
if (Schema::hasColumn('gateways', 'recommended'))
{
Schema::table('gateways', function($table)
{
$table->dropColumn('recommended');
});
}
if (Schema::hasColumn('gateways', 'site_url'))
{
Schema::table('gateways', function($table)
{
$table->dropColumn('site_url');
});
}
}
}

View File

@ -18,6 +18,9 @@ class DatabaseSeeder extends Seeder {
$this->call('CountriesSeeder');
$this->command->info('Seeded the countries!');
$this->call('PaymentLibrariesSeeder');
$this->command->info('Seeded the Payment Libraries!');
}
}

View File

@ -0,0 +1,40 @@
<?php
class PaymentLibrariesSeeder extends Seeder
{
public function run()
{
$gateways = [
array('name'=>'BeanStream', 'provider'=>'BeanStream', 'payment_library_id' => 2),
array('name'=>'Amazon Simplepay', 'provider'=>'Amazon_Simplepay', 'payment_library_id' => 2),
array('name'=>'Bluepay', 'provider'=>'Bluepay', 'payment_library_id' => 2),
array('name'=>'Braintree', 'provider'=>'Braintree', 'payment_library_id' => 2),
array('name'=>'Google Checkout', 'provider'=>'Google_Checkout', 'payment_library_id' => 2),
array('name'=>'Psigate', 'provider'=>'Psigate', 'payment_library_id' => 2),
array('name'=>'Quickbooksms', 'provider'=>'Quickbooksms', 'payment_library_id' => 2)
];
$updateProviders = array(
0 => 'AuthorizeNet_AIM',
1 => 'BeanStream',
2 => 'iTransact',
3 => 'FirstData_Connect',
4 => 'PayPal_Pro',
5 => 'TwoCheckout'
);
foreach ($gateways as $gateway)
{
Gateway::create($gateway);
}
Gateway::whereIn('provider', $updateProviders)->update(array('recommended' => 1));
Gateway::where('provider', '=', 'AuthorizeNet_AIM')->update(array('sort_order' => 5, 'site_url' => 'http://www.authorize.net/'));
Gateway::where('provider', '=', 'BeanStream')->update(array('sort_order' => 10, 'site_url' => 'http://www.beanstream.com/'));
Gateway::where('provider', '=', 'FirstData_Connect')->update(array('sort_order' => 20, 'site_url' => 'https://www.firstdata.com/'));
Gateway::where('provider', '=', 'PayPal_Pro')->update(array('sort_order' => 25, 'site_url' => 'https://www.paypal.com/'));
Gateway::where('provider', '=', 'TwoCheckout')->update(array('sort_order' => 30, 'site_url' => 'https://www.2checkout.com/'));
}
}

View File

@ -4,4 +4,35 @@ class Gateway extends Eloquent
{
public $timestamps = false;
protected $softDelete = false;
public function paymentlibrary()
{
return $this->belongsTo('PaymentLibrary', 'payment_library_id');
}
public function getLogoUrl()
{
return '/images/gateways/logo_'.$this->provider.'.png';
}
public function getFields()
{
$paymentLibrary = $this->paymentlibrary;
if($paymentLibrary->name == 'Omnipay')
{
$fields = Omnipay::create($this->provider)->getDefaultParameters();
}
else
{
$fields = Payment_Utility::load('config', 'drivers/'.$this->provider);
}
if($fields == null)
{
$fields = array();
}
return $fields;
}
}

View File

@ -0,0 +1,11 @@
<?php
class PaymentLibrary extends Eloquent
{
protected $table = 'payment_libraries';
public function gateways()
{
return $this->hasMany('Gateway', 'payment_library_id');
}
}

View File

@ -10,6 +10,15 @@
{{ Former::populateField('notify_paid', intval(Auth::user()->notify_paid)) }}
{{ Former::legend('Payment Gateway') }}
{{Former::label('Lorem Ipsum goes here.')}}
<div class="two-column">
{{ Former::radios('recommendedGateway_id')
->label('Recommended Gateways')
->radios($recommendedGateways)
->class('recommended-gateway')}}
</div>
@if ($accountGateway)
{{ Former::populateField('gateway_id', $accountGateway->gateway_id) }}
@ -22,12 +31,14 @@
@endforeach
@endif
{{ Former::select('gateway_id')->label('Provider')->addOption('', '')
->fromQuery($gateways, 'name', 'id')->onchange('setFieldsShown()'); }}
{{ Former::select('gateway_id')->label('PayPal & Other Gateways')->addOption('', '')
->dataClass('gateway-dropdown')
->fromQuery($gateways, 'name', 'id')
->onchange('setFieldsShown()'); }}
@foreach ($gateways as $gateway)
<div id="gateway_{{ $gateway->id }}_div" style="display: none">
<div id="gateway_{{ $gateway->id }}_div" class='gateway-fields' style="display: none">
@foreach ($gateway->fields as $field => $details)
@if (in_array($field, ['solutionType', 'landingPage', 'headerImageUrl', 'brandName']))
@ -51,21 +62,54 @@
<script type="text/javascript">
var gateways = {{ $gateways }};
function setFieldsShown() {
var val = $('#gateway_id').val();
for (var i=0; i<gateways.length; i++) {
var gateway = gateways[i];
if (val == gateway.id) {
$('#gateway_' + gateway.id + '_div').show();
} else {
$('#gateway_' + gateway.id + '_div').hide();
}
var activeElement = $('.recommended-gateway[value=' + val + ']');
var recommendedRadios = $('#recommendedGateway_id');
$('.gateway-fields').hide();
$('#gateway_' + val + '_div').show();
if(activeElement && !activeElement.attr('checked'))
{
activeElement.attr('checked', true);
}
}
$(function() {
$(document).ready(function() {
$('.recommended-gateway').change(
function(){
var recVal = $(this).val();
$('#gateway_id').val(recVal);
setFieldsShown();
}
);
$('select[data-class=gateway-dropdown]').change(function(){
$('.recommended-gateway').attr('checked', false);
var activeElement = $('.recommended-gateway[value=' + $(this).val() + ']');
if(activeElement)
{
activeElement.attr('checked', true);
}
});
$('.recommended-gateway').each(function(){
var contents = $(this).parent().contents();
contents[contents.length - 1].nodeValue = '';
$(this).after('<img src="' +$(this).attr('data-imageUrl') + '" /><br />');
$(this).parent().children().last().after('<a href="' + $(this).attr('data-siteUrl') + '">Create an account</a>');
if($(this).attr('data-newRow') && true)
{
}
});
setFieldsShown();
$('.two-column .form-group .col-lg-8').removeClass('col-lg-8');
$('.two-column .form-group .col-sm-8').removeClass('col-sm-8');
});
</script>

View File

@ -26,7 +26,8 @@
"app/database/migrations",
"app/database/seeds",
"app/tests/TestCase.php",
"app/libraries"
"app/libraries",
"vendor/php-payments/lib"
],
"psr-0" : {
"ninja" : "app/"

View File

@ -538,7 +538,19 @@ body {
transition: all 0.5s ease;
}
/***********************************************
New/edit invoice page
************************************************/
.two-column .form-group div {
-webkit-column-count:2; /* Chrome, Safari, Opera */
-moz-column-count:2; /* Firefox */
column-count:2;
}
.two-column .form-group div .radio {
margin-left:10px;
}
/***********************************************
Add mouse over drop down to header menu

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB