mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
Enabled off-site payment with PayPal Express
This commit is contained in:
parent
e80422d030
commit
b523d6f44d
@ -115,12 +115,21 @@ class PaymentController extends \BaseController
|
|||||||
$function = "set" . ucfirst($key);
|
$function = "set" . ucfirst($key);
|
||||||
$gateway->$function($val);
|
$gateway->$function($val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
if (!Utils::isProd())
|
||||||
|
{
|
||||||
|
$gateway->setTestMode(true);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
return $gateway;
|
return $gateway;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getPaymentDetails($invoice, $input = null)
|
private function getPaymentDetails($invoice, $input = null)
|
||||||
{
|
{
|
||||||
|
$key = $invoice->invoice_number . '_details';
|
||||||
|
|
||||||
if ($input)
|
if ($input)
|
||||||
{
|
{
|
||||||
$data = [
|
$data = [
|
||||||
@ -142,11 +151,15 @@ class PaymentController extends \BaseController
|
|||||||
'shippingPostcode' => $input['postal_code'],
|
'shippingPostcode' => $input['postal_code'],
|
||||||
];
|
];
|
||||||
|
|
||||||
Session::put($invoice->invoice_number . '_details', $data);
|
Session::put($key, $data);
|
||||||
|
}
|
||||||
|
else if (Session::get($key))
|
||||||
|
{
|
||||||
|
$data = Session::get($key);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$data = Session::get($invoice->invoice_number . '_details');
|
$data = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
$card = new CreditCard($data);
|
$card = new CreditCard($data);
|
||||||
@ -162,6 +175,12 @@ class PaymentController extends \BaseController
|
|||||||
|
|
||||||
public function show_payment($invitationKey)
|
public function show_payment($invitationKey)
|
||||||
{
|
{
|
||||||
|
// For PayPal Express we redirect straight to their site
|
||||||
|
if (Auth::user()->account->isGatewayConfigured(GATEWAY_PAYPAL_EXPRESS))
|
||||||
|
{
|
||||||
|
return self::do_payment($invitationKey, false);
|
||||||
|
}
|
||||||
|
|
||||||
$invitation = Invitation::with('contact', 'invoice.client')->where('invitation_key', '=', $invitationKey)->firstOrFail();
|
$invitation = Invitation::with('contact', 'invoice.client')->where('invitation_key', '=', $invitationKey)->firstOrFail();
|
||||||
$invoice = $invitation->invoice;
|
$invoice = $invitation->invoice;
|
||||||
$client = $invoice->client;
|
$client = $invoice->client;
|
||||||
@ -177,7 +196,7 @@ class PaymentController extends \BaseController
|
|||||||
return View::make('payments.payment', $data);
|
return View::make('payments.payment', $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function do_payment($invitationKey)
|
public function do_payment($invitationKey, $onSite = true)
|
||||||
{
|
{
|
||||||
$rules = array(
|
$rules = array(
|
||||||
'first_name' => 'required',
|
'first_name' => 'required',
|
||||||
@ -192,20 +211,24 @@ class PaymentController extends \BaseController
|
|||||||
'postal_code' => 'required',
|
'postal_code' => 'required',
|
||||||
);
|
);
|
||||||
|
|
||||||
$validator = Validator::make(Input::all(), $rules);
|
if ($onSite)
|
||||||
|
|
||||||
if ($validator->fails())
|
|
||||||
{
|
{
|
||||||
return Redirect::to('payment/' . $invitationKey)
|
$validator = Validator::make(Input::all(), $rules);
|
||||||
->withErrors($validator);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$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);
|
|
||||||
|
|
||||||
|
if ($validator->fails())
|
||||||
|
{
|
||||||
|
return Redirect::to('payment/' . $invitationKey)
|
||||||
|
->withErrors($validator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$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);
|
||||||
|
|
||||||
|
if ($onSite)
|
||||||
|
{
|
||||||
$client = $invoice->client;
|
$client = $invoice->client;
|
||||||
$client->address1 = trim(Input::get('address1'));
|
$client->address1 = trim(Input::get('address1'));
|
||||||
$client->address2 = trim(Input::get('address2'));
|
$client->address2 = trim(Input::get('address2'));
|
||||||
@ -213,51 +236,51 @@ class PaymentController extends \BaseController
|
|||||||
$client->state = trim(Input::get('state'));
|
$client->state = trim(Input::get('state'));
|
||||||
$client->postal_code = trim(Input::get('postal_code'));
|
$client->postal_code = trim(Input::get('postal_code'));
|
||||||
$client->save();
|
$client->save();
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
|
{
|
||||||
|
$details = self::getPaymentDetails($invoice, Input::all());
|
||||||
|
$response = $gateway->purchase($details)->send();
|
||||||
|
$ref = $response->getTransactionReference();
|
||||||
|
|
||||||
|
if (!$ref)
|
||||||
{
|
{
|
||||||
$details = self::getPaymentDetails($invoice, Input::all());
|
Session::flash('error', $response->getMessage());
|
||||||
$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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (\Exception $e)
|
|
||||||
{
|
|
||||||
Session::flash('error', $e->getMessage());
|
|
||||||
return Redirect::to('payment/' . $invitationKey)
|
return Redirect::to('payment/' . $invitationKey)
|
||||||
->withInput();
|
->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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (\Exception $e)
|
||||||
|
{
|
||||||
|
Session::flash('error', $e->getMessage());
|
||||||
|
return Redirect::to('payment/' . $invitationKey)
|
||||||
|
->withInput();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,13 @@
|
|||||||
|
|
||||||
class Utils
|
class Utils
|
||||||
{
|
{
|
||||||
public static function basePath() {
|
public static function isProd()
|
||||||
|
{
|
||||||
|
return App::environment() == ENV_PRODUCTION;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function basePath()
|
||||||
|
{
|
||||||
return substr($_SERVER['SCRIPT_NAME'], 0, strrpos($_SERVER['SCRIPT_NAME'], '/') + 1);
|
return substr($_SERVER['SCRIPT_NAME'], 0, strrpos($_SERVER['SCRIPT_NAME'], '/') + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,14 +118,22 @@ class Account extends Eloquent
|
|||||||
|
|
||||||
public function getLogoWidth()
|
public function getLogoWidth()
|
||||||
{
|
{
|
||||||
list($width, $height) = getimagesize($this->getLogoPath());
|
$path = $this->getLogoPath();
|
||||||
|
if (!file_exists($path)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
list($width, $height) = getimagesize($path);
|
||||||
return $width;
|
return $width;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getLogoHeight()
|
public function getLogoHeight()
|
||||||
{
|
{
|
||||||
list($width, $height) = getimagesize($this->getLogoPath());
|
$path = $this->getLogoPath();
|
||||||
return $height;
|
if (!file_exists($path)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
list($width, $height) = getimagesize($path);
|
||||||
|
return $height;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getNextInvoiceNumber()
|
public function getNextInvoiceNumber()
|
||||||
|
@ -235,9 +235,7 @@ class Activity extends Eloquent
|
|||||||
$client->last_login = $now;
|
$client->last_login = $now;
|
||||||
$client->save();
|
$client->save();
|
||||||
|
|
||||||
$activity = new Activity;
|
$activity = Activity::getBlank($invitation);
|
||||||
$activity->user_id = $invitation->user_id;
|
|
||||||
$activity->account_id = $invitation->user->account_id;
|
|
||||||
$activity->client_id = $invitation->invoice->client_id;
|
$activity->client_id = $invitation->invoice->client_id;
|
||||||
$activity->invitation_id = $invitation->id;
|
$activity->invitation_id = $invitation->id;
|
||||||
$activity->contact_id = $invitation->contact_id;
|
$activity->contact_id = $invitation->contact_id;
|
||||||
@ -259,7 +257,7 @@ class Activity extends Eloquent
|
|||||||
|
|
||||||
if ($payment->contact_id)
|
if ($payment->contact_id)
|
||||||
{
|
{
|
||||||
$activity = new Activity;
|
$activity = Activity::getBlank($client);
|
||||||
$activity->contact_id = $payment->contact_id;
|
$activity->contact_id = $payment->contact_id;
|
||||||
$activity->message = Utils::encodeActivity($payment->invitation->contact, 'entered payment');
|
$activity->message = Utils::encodeActivity($payment->invitation->contact, 'entered payment');
|
||||||
}
|
}
|
||||||
|
@ -258,6 +258,8 @@ define('DEFAULT_DATE_PICKER_FORMAT', 'M d, yyyy');
|
|||||||
define('DEFAULT_DATETIME_FORMAT', 'F j, Y, g:i a');
|
define('DEFAULT_DATETIME_FORMAT', 'F j, Y, g:i a');
|
||||||
define('DEFAULT_QUERY_CACHE', 120);
|
define('DEFAULT_QUERY_CACHE', 120);
|
||||||
|
|
||||||
|
define('GATEWAY_PAYPAL_EXPRESS', 17);
|
||||||
|
|
||||||
|
|
||||||
if (Auth::check() && !Session::has(SESSION_TIMEZONE))
|
if (Auth::check() && !Session::has(SESSION_TIMEZONE))
|
||||||
{
|
{
|
||||||
|
@ -980,7 +980,7 @@
|
|||||||
self.discount = ko.observable('');
|
self.discount = ko.observable('');
|
||||||
self.frequency_id = ko.observable('');
|
self.frequency_id = ko.observable('');
|
||||||
//self.currency_id = ko.observable({{ $client && $client->currency_id ? $client->currency_id : Session::get(SESSION_CURRENCY) }});
|
//self.currency_id = ko.observable({{ $client && $client->currency_id ? $client->currency_id : Session::get(SESSION_CURRENCY) }});
|
||||||
self.terms = ko.observable(wordWrapText('{{ str_replace(["\r\n","\r","\n"], '\n', stripslashes($account->invoice_terms)) }}', 300));
|
self.terms = ko.observable(wordWrapText('{{ str_replace(["\r\n","\r","\n"], '\n', addslashes($account->invoice_terms)) }}', 300));
|
||||||
self.set_default_terms = ko.observable(false);
|
self.set_default_terms = ko.observable(false);
|
||||||
self.public_notes = ko.observable('');
|
self.public_notes = ko.observable('');
|
||||||
self.po_number = ko.observable('');
|
self.po_number = ko.observable('');
|
||||||
|
@ -15,7 +15,7 @@ function GetReportTemplate4(doc, invoice, layout, checkMath) {
|
|||||||
if (invoice.image)
|
if (invoice.image)
|
||||||
{
|
{
|
||||||
var left = layout.headerRight - invoice.imageWidth;
|
var left = layout.headerRight - invoice.imageWidth;
|
||||||
doc.addImage(invoice.image, 'JPEG', left, 20);
|
doc.addImage(invoice.image, 'JPEG', left, 30);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* table header */
|
/* table header */
|
||||||
@ -91,8 +91,8 @@ function GetReportTemplate4(doc, invoice, layout, checkMath) {
|
|||||||
|
|
||||||
doc.setFontType("bold");
|
doc.setFontType("bold");
|
||||||
doc.text(layout.footerLeft, y, 'Balance Due');
|
doc.text(layout.footerLeft, y, 'Balance Due');
|
||||||
|
|
||||||
total = formatMoney(total - (invoice.amount - invoice.balance), currencyId);
|
total = formatMoney(invoice.balance_amount, currencyId)
|
||||||
var totalX = layout.headerRight - (doc.getStringUnitWidth(total) * doc.internal.getFontSize());
|
var totalX = layout.headerRight - (doc.getStringUnitWidth(total) * doc.internal.getFontSize());
|
||||||
doc.text(totalX, y, total);
|
doc.text(totalX, y, total);
|
||||||
|
|
||||||
@ -626,17 +626,17 @@ $.fn.datepicker.defaults.todayHighlight = true;
|
|||||||
|
|
||||||
function GetPdf(invoice,checkMath,report_id){
|
function GetPdf(invoice,checkMath,report_id){
|
||||||
var layout = {
|
var layout = {
|
||||||
accountTop: 30,
|
accountTop: 40,
|
||||||
marginLeft: 50,
|
marginLeft: 50,
|
||||||
marginRight: 550,
|
marginRight: 550,
|
||||||
headerTop: 140,
|
headerTop: 150,
|
||||||
headerLeft: 360,
|
headerLeft: 360,
|
||||||
headerRight: 550,
|
headerRight: 550,
|
||||||
rowHeight: 15,
|
rowHeight: 15,
|
||||||
tableRowHeight: 10,
|
tableRowHeight: 10,
|
||||||
footerLeft: 420,
|
footerLeft: 420,
|
||||||
tablePadding: 12,
|
tablePadding: 12,
|
||||||
tableTop: 250,
|
tableTop: 260,
|
||||||
descriptionLeft: 162,
|
descriptionLeft: 162,
|
||||||
unitCostRight: 410,
|
unitCostRight: 410,
|
||||||
qtyRight: 480,
|
qtyRight: 480,
|
||||||
@ -691,7 +691,6 @@ function GetReportTemplate1(doc, invoice, layout, checkMath)
|
|||||||
var account = invoice.account;
|
var account = invoice.account;
|
||||||
var currencyId = client.currency_id;
|
var currencyId = client.currency_id;
|
||||||
|
|
||||||
layout.headerTop = 140;
|
|
||||||
layout.headerRight = 550;
|
layout.headerRight = 550;
|
||||||
layout.rowHeight = 15;
|
layout.rowHeight = 15;
|
||||||
|
|
||||||
@ -700,7 +699,7 @@ function GetReportTemplate1(doc, invoice, layout, checkMath)
|
|||||||
if (invoice.image)
|
if (invoice.image)
|
||||||
{
|
{
|
||||||
var left = layout.headerRight - invoice.imageWidth;
|
var left = layout.headerRight - invoice.imageWidth;
|
||||||
doc.addImage(invoice.image, 'JPEG', layout.marginLeft, 20);
|
doc.addImage(invoice.image, 'JPEG', layout.marginLeft, 30);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (invoice.imageLogo1)
|
if (invoice.imageLogo1)
|
||||||
@ -726,8 +725,8 @@ function GetReportTemplate1(doc, invoice, layout, checkMath)
|
|||||||
SetPdfColor('Black',doc); //set black color
|
SetPdfColor('Black',doc); //set black color
|
||||||
doc.setFontSize(9);
|
doc.setFontSize(9);
|
||||||
|
|
||||||
displayInvoice(doc, invoice, 50, 160, layout);
|
displayInvoice(doc, invoice, 50, 170, layout);
|
||||||
displayClient(doc, invoice, 220, 160, layout);
|
displayClient(doc, invoice, 220, 170, layout);
|
||||||
|
|
||||||
doc.setLineWidth(0.3);
|
doc.setLineWidth(0.3);
|
||||||
doc.setDrawColor(200,200,200);
|
doc.setDrawColor(200,200,200);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user