2015-03-17 02:30:56 +01:00
|
|
|
<?php namespace App\Http\Controllers;
|
2015-03-16 22:45:25 +01:00
|
|
|
|
2015-03-26 07:24:02 +01:00
|
|
|
use Datatable;
|
|
|
|
use Input;
|
|
|
|
use Redirect;
|
2015-04-15 18:35:41 +02:00
|
|
|
use Request;
|
2015-03-26 07:24:02 +01:00
|
|
|
use Session;
|
|
|
|
use Utils;
|
|
|
|
use View;
|
2015-04-02 15:06:16 +02:00
|
|
|
use Validator;
|
|
|
|
use Omnipay;
|
|
|
|
use CreditCard;
|
|
|
|
use URL;
|
2015-04-08 15:19:17 +02:00
|
|
|
use Cache;
|
2015-03-31 19:42:37 +02:00
|
|
|
use App\Models\Invoice;
|
2015-04-02 15:06:16 +02:00
|
|
|
use App\Models\Invitation;
|
2015-03-31 19:42:37 +02:00
|
|
|
use App\Models\Client;
|
2016-04-30 23:54:56 +02:00
|
|
|
use App\Models\Account;
|
2015-03-31 19:42:37 +02:00
|
|
|
use App\Models\PaymentType;
|
2015-04-14 20:58:07 +02:00
|
|
|
use App\Models\License;
|
2015-04-15 18:35:41 +02:00
|
|
|
use App\Models\Payment;
|
2015-05-08 10:21:29 +02:00
|
|
|
use App\Models\Affiliate;
|
2015-03-26 07:24:02 +01:00
|
|
|
use App\Ninja\Repositories\PaymentRepository;
|
|
|
|
use App\Ninja\Repositories\InvoiceRepository;
|
|
|
|
use App\Ninja\Repositories\AccountRepository;
|
|
|
|
use App\Ninja\Mailers\ContactMailer;
|
2016-04-30 23:54:56 +02:00
|
|
|
use App\Ninja\Mailers\UserMailer;
|
2015-09-10 19:50:09 +02:00
|
|
|
use App\Services\PaymentService;
|
2015-03-26 07:24:02 +01:00
|
|
|
|
2015-10-28 20:22:07 +01:00
|
|
|
use App\Http\Requests\CreatePaymentRequest;
|
|
|
|
use App\Http\Requests\UpdatePaymentRequest;
|
|
|
|
|
2015-03-26 07:24:02 +01:00
|
|
|
class PaymentController extends BaseController
|
2015-03-16 22:45:25 +01:00
|
|
|
{
|
2016-04-26 03:53:39 +02:00
|
|
|
protected $entity = ENTITY_PAYMENT;
|
2016-03-16 00:08:00 +01:00
|
|
|
|
2016-04-30 23:54:56 +02:00
|
|
|
public function __construct(PaymentRepository $paymentRepo, InvoiceRepository $invoiceRepo, AccountRepository $accountRepo, ContactMailer $contactMailer, PaymentService $paymentService, UserMailer $userMailer)
|
2015-03-16 22:45:25 +01:00
|
|
|
{
|
2016-03-16 00:08:00 +01:00
|
|
|
// parent::__construct();
|
2015-03-16 22:45:25 +01:00
|
|
|
|
|
|
|
$this->paymentRepo = $paymentRepo;
|
|
|
|
$this->invoiceRepo = $invoiceRepo;
|
|
|
|
$this->accountRepo = $accountRepo;
|
|
|
|
$this->contactMailer = $contactMailer;
|
2015-09-10 19:50:09 +02:00
|
|
|
$this->paymentService = $paymentService;
|
2016-04-30 23:54:56 +02:00
|
|
|
$this->userMailer = $userMailer;
|
2015-03-16 22:45:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function index()
|
|
|
|
{
|
|
|
|
return View::make('list', array(
|
|
|
|
'entityType' => ENTITY_PAYMENT,
|
|
|
|
'title' => trans('texts.payments'),
|
2016-03-17 23:04:03 +01:00
|
|
|
'sortCol' => '6',
|
2015-11-24 12:59:30 +01:00
|
|
|
'columns' => Utils::trans([
|
|
|
|
'checkbox',
|
|
|
|
'invoice',
|
|
|
|
'client',
|
|
|
|
'transaction_reference',
|
|
|
|
'method',
|
2016-04-24 04:10:51 +02:00
|
|
|
'source',
|
2015-11-24 12:59:30 +01:00
|
|
|
'payment_amount',
|
|
|
|
'payment_date',
|
2016-04-23 22:40:19 +02:00
|
|
|
'status',
|
2015-11-30 12:29:43 +01:00
|
|
|
''
|
2015-11-24 12:59:30 +01:00
|
|
|
]),
|
2015-03-16 22:45:25 +01:00
|
|
|
));
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getDatatable($clientPublicId = null)
|
|
|
|
{
|
2015-11-05 23:37:04 +01:00
|
|
|
return $this->paymentService->getDatatable($clientPublicId, Input::get('sSearch'));
|
2015-03-16 22:45:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function create($clientPublicId = 0, $invoicePublicId = 0)
|
|
|
|
{
|
2016-04-26 03:53:39 +02:00
|
|
|
$this->authorizeCreate();
|
2016-03-16 00:08:00 +01:00
|
|
|
|
2015-04-22 21:21:04 +02:00
|
|
|
$invoices = Invoice::scope()
|
|
|
|
->where('is_recurring', '=', false)
|
|
|
|
->where('is_quote', '=', false)
|
|
|
|
->where('invoices.balance', '>', 0)
|
|
|
|
->with('client', 'invoice_status')
|
|
|
|
->orderBy('invoice_number')->get();
|
|
|
|
|
2015-03-16 22:45:25 +01:00
|
|
|
$data = array(
|
|
|
|
'clientPublicId' => Input::old('client') ? Input::old('client') : $clientPublicId,
|
|
|
|
'invoicePublicId' => Input::old('invoice') ? Input::old('invoice') : $invoicePublicId,
|
|
|
|
'invoice' => null,
|
2015-04-22 21:21:04 +02:00
|
|
|
'invoices' => $invoices,
|
2015-03-16 22:45:25 +01:00
|
|
|
'payment' => null,
|
|
|
|
'method' => 'POST',
|
|
|
|
'url' => "payments",
|
|
|
|
'title' => trans('texts.new_payment'),
|
2015-04-08 15:19:17 +02:00
|
|
|
'paymentTypes' => Cache::get('paymentTypes'),
|
2015-11-04 08:48:47 +01:00
|
|
|
'paymentTypeId' => Input::get('paymentTypeId'),
|
2015-03-16 22:45:25 +01:00
|
|
|
'clients' => Client::scope()->with('contacts')->orderBy('name')->get(), );
|
|
|
|
|
|
|
|
return View::make('payments.edit', $data);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function edit($publicId)
|
|
|
|
{
|
|
|
|
$payment = Payment::scope($publicId)->firstOrFail();
|
2016-03-16 00:08:00 +01:00
|
|
|
|
2016-04-26 03:53:39 +02:00
|
|
|
$this->authorize('edit', $payment);
|
2016-03-16 00:08:00 +01:00
|
|
|
|
2015-03-16 22:45:25 +01:00
|
|
|
$payment->payment_date = Utils::fromSqlDate($payment->payment_date);
|
|
|
|
|
|
|
|
$data = array(
|
|
|
|
'client' => null,
|
|
|
|
'invoice' => null,
|
|
|
|
'invoices' => Invoice::scope()->where('is_recurring', '=', false)->where('is_quote', '=', false)
|
|
|
|
->with('client', 'invoice_status')->orderBy('invoice_number')->get(),
|
|
|
|
'payment' => $payment,
|
|
|
|
'method' => 'PUT',
|
|
|
|
'url' => 'payments/'.$publicId,
|
|
|
|
'title' => trans('texts.edit_payment'),
|
2015-04-08 15:19:17 +02:00
|
|
|
'paymentTypes' => Cache::get('paymentTypes'),
|
2015-03-16 22:45:25 +01:00
|
|
|
'clients' => Client::scope()->with('contacts')->orderBy('name')->get(), );
|
|
|
|
|
|
|
|
return View::make('payments.edit', $data);
|
|
|
|
}
|
|
|
|
|
|
|
|
private function getLicensePaymentDetails($input, $affiliate)
|
|
|
|
{
|
2015-09-10 19:50:09 +02:00
|
|
|
$data = $this->paymentService->convertInputForOmnipay($input);
|
2015-03-16 22:45:25 +01:00
|
|
|
$card = new CreditCard($data);
|
|
|
|
|
|
|
|
return [
|
|
|
|
'amount' => $affiliate->price,
|
|
|
|
'card' => $card,
|
|
|
|
'currency' => 'USD',
|
|
|
|
'returnUrl' => URL::to('license_complete'),
|
|
|
|
'cancelUrl' => URL::to('/')
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
2016-04-29 23:50:21 +02:00
|
|
|
public function show_payment($invitationKey, $paymentType = false, $sourceId = false)
|
2015-06-10 10:34:20 +02:00
|
|
|
{
|
2016-01-18 10:13:39 +01:00
|
|
|
|
2015-04-15 18:35:41 +02:00
|
|
|
$invitation = Invitation::with('invoice.invoice_items', 'invoice.client.currency', 'invoice.client.account.account_gateways.gateway')->where('invitation_key', '=', $invitationKey)->firstOrFail();
|
|
|
|
$invoice = $invitation->invoice;
|
|
|
|
$client = $invoice->client;
|
|
|
|
$account = $client->account;
|
|
|
|
$useToken = false;
|
2015-03-16 22:45:25 +01:00
|
|
|
|
2015-06-10 22:55:23 +02:00
|
|
|
if ($paymentType) {
|
|
|
|
$paymentType = 'PAYMENT_TYPE_' . strtoupper($paymentType);
|
|
|
|
} else {
|
2015-12-23 12:49:49 +01:00
|
|
|
$paymentType = Session::get($invitation->id . 'payment_type') ?:
|
|
|
|
$account->account_gateways[0]->getPaymentType();
|
2015-06-10 10:34:20 +02:00
|
|
|
}
|
2016-01-18 10:13:39 +01:00
|
|
|
|
2016-05-07 04:33:03 +02:00
|
|
|
$data = array();
|
2016-04-29 23:50:21 +02:00
|
|
|
|
2016-05-07 04:33:03 +02:00
|
|
|
if ($paymentType != PAYMENT_TYPE_BRAINTREE_PAYPAL) {
|
|
|
|
if ($paymentType == PAYMENT_TYPE_TOKEN) {
|
|
|
|
$useToken = true;
|
|
|
|
$accountGateway = $invoice->client->account->getTokenGateway();
|
|
|
|
$paymentType = $accountGateway->getPaymentType();
|
|
|
|
} else {
|
|
|
|
$accountGateway = $invoice->client->account->getGatewayByType($paymentType);
|
|
|
|
}
|
2015-03-16 22:45:25 +01:00
|
|
|
|
2016-05-07 04:33:03 +02:00
|
|
|
Session::put($invitation->id . 'payment_type', $paymentType);
|
2016-01-18 10:13:39 +01:00
|
|
|
|
2016-05-07 04:33:03 +02:00
|
|
|
$gateway = $accountGateway->gateway;
|
2015-09-20 23:05:02 +02:00
|
|
|
|
2016-05-07 04:33:03 +02:00
|
|
|
$acceptedCreditCardTypes = $accountGateway->getCreditcardTypes();
|
|
|
|
|
|
|
|
$isOffsite = ($paymentType != PAYMENT_TYPE_CREDIT_CARD && $accountGateway->getPaymentType() != PAYMENT_TYPE_STRIPE)
|
|
|
|
|| $gateway->id == GATEWAY_EWAY
|
|
|
|
|| $gateway->id == GATEWAY_TWO_CHECKOUT
|
|
|
|
|| $gateway->id == GATEWAY_PAYFAST
|
|
|
|
|| $gateway->id == GATEWAY_MOLLIE;
|
|
|
|
|
|
|
|
// Handle offsite payments
|
|
|
|
if ($useToken || $isOffsite) {
|
|
|
|
if (Session::has('error')) {
|
|
|
|
Session::reflash();
|
|
|
|
return Redirect::to('view/' . $invitationKey);
|
|
|
|
} else {
|
|
|
|
return self::do_payment($invitationKey, false, $useToken, $sourceId);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$data += [
|
|
|
|
'accountGateway' => $accountGateway,
|
|
|
|
'acceptedCreditCardTypes' => $acceptedCreditCardTypes,
|
|
|
|
'gateway' => $gateway,
|
|
|
|
'showAddress' => $accountGateway->show_address,
|
|
|
|
];
|
|
|
|
|
|
|
|
if ($paymentType == PAYMENT_TYPE_STRIPE_ACH) {
|
|
|
|
$data['currencies'] = Cache::get('currencies');
|
2015-03-16 22:45:25 +01:00
|
|
|
}
|
2016-05-07 04:33:03 +02:00
|
|
|
|
|
|
|
if ($gateway->id == GATEWAY_BRAINTREE) {
|
|
|
|
$data['braintreeClientToken'] = $this->paymentService->getBraintreeClientToken($account);
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
if ($deviceData = Input::get('details')) {
|
|
|
|
Session::put($invitation->id . 'device_data', $deviceData);
|
|
|
|
}
|
|
|
|
|
|
|
|
Session::put($invitation->id . 'payment_type', PAYMENT_TYPE_BRAINTREE_PAYPAL);
|
|
|
|
$paypalDetails = json_decode(Input::get('details'));
|
|
|
|
if (!$sourceId || !$paypalDetails) {
|
|
|
|
return Redirect::to('view/'.$invitationKey);
|
|
|
|
}
|
|
|
|
$data['paypalDetails'] = $paypalDetails;
|
2015-04-15 18:35:41 +02:00
|
|
|
}
|
2015-03-16 22:45:25 +01:00
|
|
|
|
2016-05-07 04:33:03 +02:00
|
|
|
$data += [
|
2015-03-16 22:45:25 +01:00
|
|
|
'showBreadcrumbs' => false,
|
|
|
|
'url' => 'payment/'.$invitationKey,
|
2015-04-16 21:57:12 +02:00
|
|
|
'amount' => $invoice->getRequestedAmount(),
|
2015-03-16 22:45:25 +01:00
|
|
|
'invoiceNumber' => $invoice->invoice_number,
|
|
|
|
'client' => $client,
|
|
|
|
'contact' => $invitation->contact,
|
2016-04-29 23:50:21 +02:00
|
|
|
'paymentType' => $paymentType,
|
2015-04-08 15:19:17 +02:00
|
|
|
'countries' => Cache::get('countries'),
|
2015-06-10 10:34:20 +02:00
|
|
|
'currencyId' => $client->getCurrencyId(),
|
2015-07-30 16:44:47 +02:00
|
|
|
'currencyCode' => $client->currency ? $client->currency->code : ($account->currency ? $account->currency->code : 'USD'),
|
2015-04-28 22:13:52 +02:00
|
|
|
'account' => $client->account,
|
2016-05-07 04:33:03 +02:00
|
|
|
'sourceId' => $sourceId,
|
2016-04-29 23:50:21 +02:00
|
|
|
'clientFontUrl' => $client->account->getFontsUrl(),
|
2015-03-16 22:45:25 +01:00
|
|
|
];
|
|
|
|
|
2016-04-29 23:50:21 +02:00
|
|
|
return View::make('payments.add_paymentmethod', $data);
|
2015-03-16 22:45:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function show_license_payment()
|
|
|
|
{
|
|
|
|
if (Input::has('return_url')) {
|
|
|
|
Session::set('return_url', Input::get('return_url'));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Input::has('affiliate_key')) {
|
|
|
|
if ($affiliate = Affiliate::where('affiliate_key', '=', Input::get('affiliate_key'))->first()) {
|
|
|
|
Session::set('affiliate_id', $affiliate->id);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-09-02 12:59:03 +02:00
|
|
|
if (Input::has('product_id')) {
|
|
|
|
Session::set('product_id', Input::get('product_id'));
|
|
|
|
} else if (!Session::has('product_id')) {
|
|
|
|
Session::set('product_id', PRODUCT_ONE_CLICK_INSTALL);
|
|
|
|
}
|
2015-03-16 22:45:25 +01:00
|
|
|
|
|
|
|
if (!Session::get('affiliate_id')) {
|
|
|
|
return Utils::fatalError();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Utils::isNinjaDev() && Input::has('test_mode')) {
|
|
|
|
Session::set('test_mode', Input::get('test_mode'));
|
|
|
|
}
|
|
|
|
|
|
|
|
$account = $this->accountRepo->getNinjaAccount();
|
|
|
|
$account->load('account_gateways.gateway');
|
2016-04-29 23:50:21 +02:00
|
|
|
$accountGateway = $account->getGatewayByType(PAYMENT_TYPE_STRIPE_CREDIT_CARD);
|
2015-03-16 22:45:25 +01:00
|
|
|
$gateway = $accountGateway->gateway;
|
|
|
|
$acceptedCreditCardTypes = $accountGateway->getCreditcardTypes();
|
|
|
|
|
|
|
|
$affiliate = Affiliate::find(Session::get('affiliate_id'));
|
|
|
|
|
|
|
|
$data = [
|
|
|
|
'showBreadcrumbs' => false,
|
|
|
|
'hideHeader' => true,
|
|
|
|
'url' => 'license',
|
|
|
|
'amount' => $affiliate->price,
|
|
|
|
'client' => false,
|
|
|
|
'contact' => false,
|
|
|
|
'gateway' => $gateway,
|
2015-12-27 12:37:54 +01:00
|
|
|
'account' => $account,
|
|
|
|
'accountGateway' => $accountGateway,
|
2015-03-16 22:45:25 +01:00
|
|
|
'acceptedCreditCardTypes' => $acceptedCreditCardTypes,
|
2015-04-08 15:19:17 +02:00
|
|
|
'countries' => Cache::get('countries'),
|
2015-03-16 22:45:25 +01:00
|
|
|
'currencyId' => 1,
|
2015-12-27 12:37:54 +01:00
|
|
|
'currencyCode' => 'USD',
|
2015-03-16 22:45:25 +01:00
|
|
|
'paymentTitle' => $affiliate->payment_title,
|
|
|
|
'paymentSubtitle' => $affiliate->payment_subtitle,
|
2015-08-03 10:52:47 +02:00
|
|
|
'showAddress' => true,
|
2015-03-16 22:45:25 +01:00
|
|
|
];
|
|
|
|
|
2016-04-29 23:50:21 +02:00
|
|
|
return View::make('payments.add_paymentmethod', $data);
|
2015-03-16 22:45:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function do_license_payment()
|
|
|
|
{
|
|
|
|
$testMode = Session::get('test_mode') === 'true';
|
|
|
|
|
|
|
|
$rules = array(
|
|
|
|
'first_name' => 'required',
|
|
|
|
'last_name' => 'required',
|
|
|
|
'card_number' => 'required',
|
|
|
|
'expiration_month' => 'required',
|
|
|
|
'expiration_year' => 'required',
|
|
|
|
'cvv' => 'required',
|
|
|
|
'address1' => 'required',
|
|
|
|
'city' => 'required',
|
|
|
|
'state' => 'required',
|
|
|
|
'postal_code' => 'required',
|
2015-04-28 22:13:52 +02:00
|
|
|
'country_id' => 'required',
|
2015-03-16 22:45:25 +01:00
|
|
|
);
|
|
|
|
|
|
|
|
$validator = Validator::make(Input::all(), $rules);
|
|
|
|
|
|
|
|
if ($validator->fails()) {
|
|
|
|
return Redirect::to('license')
|
2015-09-20 23:05:02 +02:00
|
|
|
->withErrors($validator)
|
|
|
|
->withInput();
|
2015-03-16 22:45:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
$account = $this->accountRepo->getNinjaAccount();
|
|
|
|
$account->load('account_gateways.gateway');
|
2016-04-29 23:50:21 +02:00
|
|
|
$accountGateway = $account->getGatewayByType(PAYMENT_TYPE_STRIPE_CREDIT_CARD);
|
2015-03-16 22:45:25 +01:00
|
|
|
|
|
|
|
try {
|
|
|
|
$affiliate = Affiliate::find(Session::get('affiliate_id'));
|
|
|
|
|
|
|
|
if ($testMode) {
|
|
|
|
$ref = 'TEST_MODE';
|
|
|
|
} else {
|
2015-09-10 19:50:09 +02:00
|
|
|
$gateway = $this->paymentService->createGateway($accountGateway);
|
2015-03-16 22:45:25 +01:00
|
|
|
$details = self::getLicensePaymentDetails(Input::all(), $affiliate);
|
|
|
|
$response = $gateway->purchase($details)->send();
|
|
|
|
$ref = $response->getTransactionReference();
|
|
|
|
|
2015-09-10 19:50:09 +02:00
|
|
|
if (!$response->isSuccessful() || !$ref) {
|
|
|
|
$this->error('License', $response->getMessage(), $accountGateway);
|
2015-03-16 22:45:25 +01:00
|
|
|
return Redirect::to('license')->withInput();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$licenseKey = Utils::generateLicense();
|
|
|
|
|
|
|
|
$license = new License();
|
|
|
|
$license->first_name = Input::get('first_name');
|
|
|
|
$license->last_name = Input::get('last_name');
|
|
|
|
$license->email = Input::get('email');
|
|
|
|
$license->transaction_reference = $ref;
|
|
|
|
$license->license_key = $licenseKey;
|
|
|
|
$license->affiliate_id = Session::get('affiliate_id');
|
|
|
|
$license->product_id = Session::get('product_id');
|
|
|
|
$license->save();
|
|
|
|
|
|
|
|
$data = [
|
|
|
|
'message' => $affiliate->payment_subtitle,
|
|
|
|
'license' => $licenseKey,
|
|
|
|
'hideHeader' => true,
|
2015-10-02 10:32:13 +02:00
|
|
|
'productId' => $license->product_id,
|
|
|
|
'price' => $affiliate->price,
|
2015-03-16 22:45:25 +01:00
|
|
|
];
|
|
|
|
|
|
|
|
$name = "{$license->first_name} {$license->last_name}";
|
|
|
|
$this->contactMailer->sendLicensePaymentConfirmation($name, $license->email, $affiliate->price, $license->license_key, $license->product_id);
|
|
|
|
|
|
|
|
if (Session::has('return_url')) {
|
2015-07-07 22:08:16 +02:00
|
|
|
$data['redirectTo'] = Session::get('return_url')."?license_key={$license->license_key}&product_id=".Session::get('product_id');
|
|
|
|
$data['message'] = "Redirecting to " . Session::get('return_url');
|
2015-03-16 22:45:25 +01:00
|
|
|
}
|
2015-07-07 22:08:16 +02:00
|
|
|
|
|
|
|
return View::make('public.license', $data);
|
2015-03-16 22:45:25 +01:00
|
|
|
} catch (\Exception $e) {
|
2015-09-10 19:50:09 +02:00
|
|
|
$this->error('License-Uncaught', false, $accountGateway, $e);
|
2015-03-16 22:45:25 +01:00
|
|
|
return Redirect::to('license')->withInput();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public function claim_license()
|
|
|
|
{
|
|
|
|
$licenseKey = Input::get('license_key');
|
|
|
|
$productId = Input::get('product_id', PRODUCT_ONE_CLICK_INSTALL);
|
|
|
|
|
|
|
|
$license = License::where('license_key', '=', $licenseKey)
|
2015-06-03 19:55:48 +02:00
|
|
|
->where('is_claimed', '<', 5)
|
2015-03-16 22:45:25 +01:00
|
|
|
->where('product_id', '=', $productId)
|
|
|
|
->first();
|
|
|
|
|
|
|
|
if ($license) {
|
|
|
|
if ($license->transaction_reference != 'TEST_MODE') {
|
2015-04-14 20:58:07 +02:00
|
|
|
$license->is_claimed = $license->is_claimed + 1;
|
2015-03-16 22:45:25 +01:00
|
|
|
$license->save();
|
|
|
|
}
|
|
|
|
|
2015-05-19 21:14:00 +02:00
|
|
|
return $productId == PRODUCT_INVOICE_DESIGNS ? file_get_contents(storage_path() . '/invoice_designs.txt') : 'valid';
|
2015-03-16 22:45:25 +01:00
|
|
|
} else {
|
|
|
|
return 'invalid';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-29 23:50:21 +02:00
|
|
|
public function do_payment($invitationKey, $onSite = true, $useToken = false, $sourceId = false)
|
2015-03-16 22:45:25 +01:00
|
|
|
{
|
2015-07-12 21:43:45 +02:00
|
|
|
$invitation = Invitation::with('invoice.invoice_items', 'invoice.client.currency', 'invoice.client.account.currency', 'invoice.client.account.account_gateways.gateway')->where('invitation_key', '=', $invitationKey)->firstOrFail();
|
|
|
|
$invoice = $invitation->invoice;
|
|
|
|
$client = $invoice->client;
|
|
|
|
$account = $client->account;
|
2016-04-29 23:50:21 +02:00
|
|
|
$paymentType = Session::get($invitation->id . 'payment_type');
|
|
|
|
$accountGateway = $account->getGatewayByType($paymentType);
|
2015-07-12 21:43:45 +02:00
|
|
|
|
|
|
|
$rules = [
|
2015-03-16 22:45:25 +01:00
|
|
|
'first_name' => 'required',
|
|
|
|
'last_name' => 'required',
|
2015-07-12 21:43:45 +02:00
|
|
|
];
|
|
|
|
|
2016-05-01 04:45:51 +02:00
|
|
|
if ( ! Input::get('stripeToken') && ! Input::get('payment_method_nonce') && !(Input::get('plaidPublicToken') && Input::get('plaidAccountId'))) {
|
2015-11-29 21:13:50 +01:00
|
|
|
$rules = array_merge(
|
|
|
|
$rules,
|
|
|
|
[
|
|
|
|
'card_number' => 'required',
|
|
|
|
'expiration_month' => 'required',
|
|
|
|
'expiration_year' => 'required',
|
|
|
|
'cvv' => 'required',
|
|
|
|
]
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2016-05-07 04:33:03 +02:00
|
|
|
$requireAddress = $accountGateway->show_address && $paymentType != PAYMENT_TYPE_STRIPE_ACH && $paymentType != PAYMENT_TYPE_BRAINTREE_PAYPAL;
|
|
|
|
|
|
|
|
if ($requireAddress) {
|
2015-07-12 21:43:45 +02:00
|
|
|
$rules = array_merge($rules, [
|
|
|
|
'address1' => 'required',
|
|
|
|
'city' => 'required',
|
|
|
|
'state' => 'required',
|
|
|
|
'postal_code' => 'required',
|
|
|
|
'country_id' => 'required',
|
|
|
|
]);
|
|
|
|
}
|
2015-03-16 22:45:25 +01:00
|
|
|
|
|
|
|
if ($onSite) {
|
|
|
|
$validator = Validator::make(Input::all(), $rules);
|
|
|
|
|
|
|
|
if ($validator->fails()) {
|
|
|
|
return Redirect::to('payment/'.$invitationKey)
|
2015-06-10 10:34:20 +02:00
|
|
|
->withErrors($validator)
|
2015-12-23 15:21:48 +01:00
|
|
|
->withInput(Request::except('cvv'));
|
2015-03-16 22:45:25 +01:00
|
|
|
}
|
2015-08-03 09:15:58 +02:00
|
|
|
|
2016-05-07 04:33:03 +02:00
|
|
|
if ($requireAddress && $accountGateway->update_address) {
|
2015-08-03 09:15:58 +02:00
|
|
|
$client->address1 = trim(Input::get('address1'));
|
|
|
|
$client->address2 = trim(Input::get('address2'));
|
|
|
|
$client->city = trim(Input::get('city'));
|
|
|
|
$client->state = trim(Input::get('state'));
|
|
|
|
$client->postal_code = trim(Input::get('postal_code'));
|
|
|
|
$client->country_id = Input::get('country_id');
|
|
|
|
$client->save();
|
|
|
|
}
|
2015-03-16 22:45:25 +01:00
|
|
|
}
|
2015-09-10 19:50:09 +02:00
|
|
|
|
2015-03-16 22:45:25 +01:00
|
|
|
try {
|
2015-09-20 23:05:02 +02:00
|
|
|
// For offsite payments send the client's details on file
|
|
|
|
// If we're using a token then we don't need to send any other data
|
|
|
|
if (!$onSite || $useToken) {
|
|
|
|
$data = false;
|
|
|
|
} else {
|
|
|
|
$data = Input::all();
|
|
|
|
}
|
|
|
|
|
2015-09-10 19:50:09 +02:00
|
|
|
$gateway = $this->paymentService->createGateway($accountGateway);
|
2015-10-21 06:30:23 +02:00
|
|
|
$details = $this->paymentService->getPaymentDetails($invitation, $accountGateway, $data);
|
2015-09-10 19:50:09 +02:00
|
|
|
|
|
|
|
// check if we're creating/using a billing token
|
2015-04-15 18:35:41 +02:00
|
|
|
if ($accountGateway->gateway_id == GATEWAY_STRIPE) {
|
2016-05-06 17:21:06 +02:00
|
|
|
if ($paymentType == PAYMENT_TYPE_STRIPE_ACH && !Input::get('authorize_ach')) {
|
|
|
|
Session::flash('error', trans('texts.ach_authorization_required'));
|
|
|
|
return Redirect::to('payment/'.$invitationKey)->withInput(Request::except('cvv'));
|
|
|
|
}
|
|
|
|
|
2015-04-15 18:35:41 +02:00
|
|
|
if ($useToken) {
|
2015-11-27 13:55:28 +01:00
|
|
|
$details['customerReference'] = $client->getGatewayToken();
|
2016-04-24 04:10:51 +02:00
|
|
|
unset($details['token']);
|
2016-04-29 23:50:21 +02:00
|
|
|
if ($sourceId) {
|
|
|
|
$details['cardReference'] = $sourceId;
|
|
|
|
}
|
|
|
|
} elseif ($account->token_billing_type_id == TOKEN_BILLING_ALWAYS || Input::get('token_billing') || $paymentType == PAYMENT_TYPE_STRIPE_ACH) {
|
|
|
|
$token = $this->paymentService->createToken($gateway, $details, $accountGateway, $client, $invitation->contact_id, $customerReference/* return parameter */);
|
2015-09-10 19:50:09 +02:00
|
|
|
if ($token) {
|
2016-04-24 04:10:51 +02:00
|
|
|
$details['token'] = $token;
|
|
|
|
$details['customerReference'] = $customerReference;
|
2016-04-29 23:50:21 +02:00
|
|
|
|
2016-05-01 04:45:51 +02:00
|
|
|
if ($paymentType == PAYMENT_TYPE_STRIPE_ACH && empty(Input::get('plaidPublicToken')) ) {
|
2016-04-29 23:50:21 +02:00
|
|
|
// The user needs to complete verification
|
|
|
|
Session::flash('message', trans('texts.bank_account_verification_next_steps'));
|
|
|
|
return Redirect::to('/client/paymentmethods');
|
|
|
|
}
|
2015-06-03 19:55:48 +02:00
|
|
|
} else {
|
2015-09-10 19:50:09 +02:00
|
|
|
$this->error('Token-No-Ref', $this->paymentService->lastError, $accountGateway);
|
2015-12-29 18:49:40 +01:00
|
|
|
return Redirect::to('payment/'.$invitationKey)->withInput(Request::except('cvv'));
|
2015-03-16 22:45:25 +01:00
|
|
|
}
|
|
|
|
}
|
2016-04-27 01:59:52 +02:00
|
|
|
} elseif ($accountGateway->gateway_id == GATEWAY_BRAINTREE) {
|
2016-05-07 04:33:03 +02:00
|
|
|
$deviceData = Input::get('device_data');
|
|
|
|
if (!$deviceData) {
|
|
|
|
$deviceData = Session::get($invitation->id . 'device_data');
|
|
|
|
}
|
|
|
|
|
2016-04-27 01:59:52 +02:00
|
|
|
if ($token = Input::get('payment_method_nonce')) {
|
|
|
|
$details['token'] = $token;
|
|
|
|
unset($details['card']);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($useToken) {
|
|
|
|
$details['customerId'] = $customerId = $client->getGatewayToken();
|
2016-04-29 23:50:21 +02:00
|
|
|
if (!$sourceId) {
|
|
|
|
$customer = $gateway->findCustomer($customerId)->send();
|
|
|
|
$details['paymentMethodToken'] = $customer->getData()->paymentMethods[0]->token;
|
|
|
|
} else {
|
|
|
|
$details['paymentMethodToken'] = $sourceId;
|
|
|
|
}
|
2016-04-27 01:59:52 +02:00
|
|
|
unset($details['token']);
|
|
|
|
} elseif ($account->token_billing_type_id == TOKEN_BILLING_ALWAYS || Input::get('token_billing')) {
|
2016-04-29 23:50:21 +02:00
|
|
|
$token = $this->paymentService->createToken($gateway, $details, $accountGateway, $client, $invitation->contact_id, $customerReference/* return parameter */);
|
2016-04-27 01:59:52 +02:00
|
|
|
if ($token) {
|
|
|
|
$details['paymentMethodToken'] = $token;
|
|
|
|
$details['customerId'] = $customerReference;
|
|
|
|
unset($details['token']);
|
|
|
|
} else {
|
|
|
|
$this->error('Token-No-Ref', $this->paymentService->lastError, $accountGateway);
|
|
|
|
return Redirect::to('payment/'.$invitationKey)->withInput(Request::except('cvv'));
|
|
|
|
}
|
|
|
|
}
|
2016-05-07 04:33:03 +02:00
|
|
|
|
|
|
|
if($deviceData) {
|
|
|
|
$details['deviceData'] = $deviceData;
|
|
|
|
}
|
2015-04-15 18:35:41 +02:00
|
|
|
}
|
2015-09-10 19:50:09 +02:00
|
|
|
|
2015-04-15 18:35:41 +02:00
|
|
|
$response = $gateway->purchase($details)->send();
|
2015-10-21 06:30:23 +02:00
|
|
|
|
2016-01-18 10:13:39 +01:00
|
|
|
|
2015-09-20 23:05:02 +02:00
|
|
|
if ($accountGateway->gateway_id == GATEWAY_EWAY) {
|
|
|
|
$ref = $response->getData()['AccessCode'];
|
2015-10-20 21:04:49 +02:00
|
|
|
} elseif ($accountGateway->gateway_id == GATEWAY_TWO_CHECKOUT) {
|
|
|
|
$ref = $response->getData()['cart_order_id'];
|
2015-11-02 10:47:47 +01:00
|
|
|
} elseif ($accountGateway->gateway_id == GATEWAY_PAYFAST) {
|
|
|
|
$ref = $response->getData()['m_payment_id'];
|
2016-01-18 10:13:39 +01:00
|
|
|
} elseif ($accountGateway->gateway_id == GATEWAY_GOCARDLESS) {
|
|
|
|
$ref = $response->getData()['signature'];
|
2016-04-11 21:09:05 +02:00
|
|
|
} elseif ($accountGateway->gateway_id == GATEWAY_CYBERSOURCE) {
|
|
|
|
$ref = $response->getData()['transaction_uuid'];
|
2015-09-20 23:05:02 +02:00
|
|
|
} else {
|
|
|
|
$ref = $response->getTransactionReference();
|
|
|
|
}
|
2016-01-18 10:13:39 +01:00
|
|
|
|
2015-04-15 18:35:41 +02:00
|
|
|
if (!$ref) {
|
2015-09-10 19:50:09 +02:00
|
|
|
$this->error('No-Ref', $response->getMessage(), $accountGateway);
|
2015-03-16 22:45:25 +01:00
|
|
|
|
2015-04-15 18:35:41 +02:00
|
|
|
if ($onSite) {
|
2015-12-23 15:21:48 +01:00
|
|
|
return Redirect::to('payment/'.$invitationKey)
|
|
|
|
->withInput(Request::except('cvv'));
|
2015-04-15 18:35:41 +02:00
|
|
|
} else {
|
|
|
|
return Redirect::to('view/'.$invitationKey);
|
2015-03-16 22:45:25 +01:00
|
|
|
}
|
2015-04-15 18:35:41 +02:00
|
|
|
}
|
2015-03-16 22:45:25 +01:00
|
|
|
|
2015-06-07 10:05:30 +02:00
|
|
|
if ($response->isSuccessful()) {
|
2016-04-25 16:06:27 +02:00
|
|
|
$payment = $this->paymentService->createPayment($invitation, $accountGateway, $ref, null, $details, $response);
|
2015-04-15 18:35:41 +02:00
|
|
|
Session::flash('message', trans('texts.applied_payment'));
|
2015-03-16 22:45:25 +01:00
|
|
|
|
2015-06-03 19:55:48 +02:00
|
|
|
if ($account->account_key == NINJA_ACCOUNT_KEY) {
|
|
|
|
Session::flash('trackEventCategory', '/account');
|
|
|
|
Session::flash('trackEventAction', '/buy_pro_plan');
|
|
|
|
}
|
|
|
|
|
2015-04-15 18:35:41 +02:00
|
|
|
return Redirect::to('view/'.$payment->invitation->invitation_key);
|
|
|
|
} elseif ($response->isRedirect()) {
|
2016-01-18 10:13:39 +01:00
|
|
|
|
2015-04-15 18:35:41 +02:00
|
|
|
$invitation->transaction_reference = $ref;
|
|
|
|
$invitation->save();
|
2015-04-17 13:57:17 +02:00
|
|
|
Session::put('transaction_reference', $ref);
|
2015-04-15 18:35:41 +02:00
|
|
|
Session::save();
|
|
|
|
$response->redirect();
|
|
|
|
} else {
|
2015-12-29 18:49:40 +01:00
|
|
|
$this->error('Unknown', $response->getMessage(), $accountGateway);
|
|
|
|
if ($onSite) {
|
|
|
|
return Redirect::to('payment/'.$invitationKey)->withInput(Request::except('cvv'));
|
|
|
|
} else {
|
|
|
|
return Redirect::to('view/'.$invitationKey);
|
|
|
|
}
|
2015-03-16 22:45:25 +01:00
|
|
|
}
|
|
|
|
} catch (\Exception $e) {
|
2015-09-10 19:50:09 +02:00
|
|
|
$this->error('Uncaught', false, $accountGateway, $e);
|
2015-03-16 22:45:25 +01:00
|
|
|
if ($onSite) {
|
2015-12-23 15:21:48 +01:00
|
|
|
return Redirect::to('payment/'.$invitationKey)->withInput(Request::except('cvv'));
|
2015-03-16 22:45:25 +01:00
|
|
|
} else {
|
|
|
|
return Redirect::to('view/'.$invitationKey);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public function offsite_payment()
|
|
|
|
{
|
|
|
|
$payerId = Request::query('PayerID');
|
|
|
|
$token = Request::query('token');
|
|
|
|
|
2015-04-17 13:57:17 +02:00
|
|
|
if (!$token) {
|
|
|
|
$token = Session::pull('transaction_reference');
|
|
|
|
}
|
|
|
|
if (!$token) {
|
|
|
|
return redirect(NINJA_WEB_URL);
|
|
|
|
}
|
|
|
|
|
2015-03-16 22:45:25 +01:00
|
|
|
$invitation = Invitation::with('invoice.client.currency', 'invoice.client.account.account_gateways.gateway')->where('transaction_reference', '=', $token)->firstOrFail();
|
|
|
|
$invoice = $invitation->invoice;
|
2015-10-13 09:11:44 +02:00
|
|
|
$client = $invoice->client;
|
|
|
|
$account = $client->account;
|
2015-03-16 22:45:25 +01:00
|
|
|
|
2015-12-30 19:45:52 +01:00
|
|
|
if ($payerId) {
|
|
|
|
$paymentType = PAYMENT_TYPE_PAYPAL;
|
|
|
|
} else {
|
|
|
|
$paymentType = Session::get($invitation->id . 'payment_type');
|
|
|
|
}
|
|
|
|
if (!$paymentType) {
|
|
|
|
$this->error('No-Payment-Type', false, false);
|
|
|
|
return Redirect::to($invitation->getLink());
|
|
|
|
}
|
|
|
|
$accountGateway = $account->getGatewayByType($paymentType);
|
2015-09-10 19:50:09 +02:00
|
|
|
$gateway = $this->paymentService->createGateway($accountGateway);
|
2015-03-16 22:45:25 +01:00
|
|
|
|
2015-07-01 21:01:12 +02:00
|
|
|
// Check for Dwolla payment error
|
|
|
|
if ($accountGateway->isGateway(GATEWAY_DWOLLA) && Input::get('error')) {
|
2015-09-10 19:50:09 +02:00
|
|
|
$this->error('Dwolla', Input::get('error_description'), $accountGateway);
|
2015-10-13 09:11:44 +02:00
|
|
|
return Redirect::to($invitation->getLink());
|
2015-07-01 21:01:12 +02:00
|
|
|
}
|
|
|
|
|
2015-11-02 23:05:28 +01:00
|
|
|
// PayFast transaction referencce
|
|
|
|
if ($accountGateway->isGateway(GATEWAY_PAYFAST) && Request::has('pt')) {
|
|
|
|
$token = Request::query('pt');
|
|
|
|
}
|
|
|
|
|
2015-03-16 22:45:25 +01:00
|
|
|
try {
|
2016-04-11 21:09:05 +02:00
|
|
|
if ($accountGateway->isGateway(GATEWAY_CYBERSOURCE)) {
|
|
|
|
if (Input::get('decision') == 'ACCEPT') {
|
|
|
|
$payment = $this->paymentService->createPayment($invitation, $accountGateway, $token, $payerId);
|
|
|
|
Session::flash('message', trans('texts.applied_payment'));
|
|
|
|
} else {
|
|
|
|
Session::flash('error', Input::get('message'));
|
|
|
|
}
|
|
|
|
return Redirect::to($invitation->getLink());
|
|
|
|
} elseif (method_exists($gateway, 'completePurchase')
|
2016-01-18 09:30:42 +01:00
|
|
|
&& !$accountGateway->isGateway(GATEWAY_TWO_CHECKOUT)
|
|
|
|
&& !$accountGateway->isGateway(GATEWAY_CHECKOUT_COM)) {
|
2015-10-21 06:30:23 +02:00
|
|
|
$details = $this->paymentService->getPaymentDetails($invitation, $accountGateway);
|
2016-01-18 10:13:39 +01:00
|
|
|
|
2015-12-21 20:57:55 +01:00
|
|
|
$response = $this->paymentService->completePurchase($gateway, $accountGateway, $details, $token);
|
2016-01-18 10:13:39 +01:00
|
|
|
|
2015-11-02 19:43:22 +01:00
|
|
|
$ref = $response->getTransactionReference() ?: $token;
|
2015-03-16 22:45:25 +01:00
|
|
|
|
2015-12-21 20:57:55 +01:00
|
|
|
if ($response->isCancelled()) {
|
|
|
|
// do nothing
|
|
|
|
} elseif ($response->isSuccessful()) {
|
2016-04-25 16:06:27 +02:00
|
|
|
$payment = $this->paymentService->createPayment($invitation, $accountGateway, $ref, $payerId, $details, $purchaseResponse);
|
2015-04-17 13:57:17 +02:00
|
|
|
Session::flash('message', trans('texts.applied_payment'));
|
|
|
|
} else {
|
2015-09-10 19:50:09 +02:00
|
|
|
$this->error('offsite', $response->getMessage(), $accountGateway);
|
2015-04-17 13:57:17 +02:00
|
|
|
}
|
2015-12-21 20:57:55 +01:00
|
|
|
return Redirect::to($invitation->getLink());
|
2015-03-16 22:45:25 +01:00
|
|
|
} else {
|
2015-12-23 12:49:49 +01:00
|
|
|
$payment = $this->paymentService->createPayment($invitation, $accountGateway, $token, $payerId);
|
2015-04-17 13:57:17 +02:00
|
|
|
Session::flash('message', trans('texts.applied_payment'));
|
2015-10-13 09:11:44 +02:00
|
|
|
return Redirect::to($invitation->getLink());
|
2015-03-16 22:45:25 +01:00
|
|
|
}
|
|
|
|
} catch (\Exception $e) {
|
2015-09-10 19:50:09 +02:00
|
|
|
$this->error('Offsite-uncaught', false, $accountGateway, $e);
|
2015-10-13 09:11:44 +02:00
|
|
|
return Redirect::to($invitation->getLink());
|
2015-03-16 22:45:25 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-10-28 20:22:07 +01:00
|
|
|
public function store(CreatePaymentRequest $request)
|
2015-03-16 22:45:25 +01:00
|
|
|
{
|
2015-10-28 20:22:07 +01:00
|
|
|
$input = $request->input();
|
2016-03-16 03:07:11 +01:00
|
|
|
|
2016-04-26 03:53:39 +02:00
|
|
|
$this->authorizeUpdate($data);
|
2016-03-16 03:07:11 +01:00
|
|
|
|
2015-12-07 22:41:48 +01:00
|
|
|
$input['invoice_id'] = Invoice::getPrivateId($input['invoice']);
|
|
|
|
$input['client_id'] = Client::getPrivateId($input['client']);
|
2015-10-28 20:22:07 +01:00
|
|
|
$payment = $this->paymentRepo->save($input);
|
2015-03-16 22:45:25 +01:00
|
|
|
|
2015-10-28 20:22:07 +01:00
|
|
|
if (Input::get('email_receipt')) {
|
|
|
|
$this->contactMailer->sendPaymentConfirmation($payment);
|
|
|
|
Session::flash('message', trans('texts.created_payment_emailed_client'));
|
|
|
|
} else {
|
|
|
|
Session::flash('message', trans('texts.created_payment'));
|
|
|
|
}
|
|
|
|
|
|
|
|
return redirect()->to($payment->client->getRoute());
|
2015-03-16 22:45:25 +01:00
|
|
|
}
|
|
|
|
|
2015-10-28 20:22:07 +01:00
|
|
|
public function update(UpdatePaymentRequest $request)
|
2015-03-16 22:45:25 +01:00
|
|
|
{
|
2015-10-28 20:22:07 +01:00
|
|
|
$input = $request->input();
|
2016-03-16 03:07:11 +01:00
|
|
|
|
2016-04-26 03:53:39 +02:00
|
|
|
$this->authorizeUpdate($data);
|
2016-03-16 03:07:11 +01:00
|
|
|
|
2015-10-28 20:22:07 +01:00
|
|
|
$payment = $this->paymentRepo->save($input);
|
2015-03-16 22:45:25 +01:00
|
|
|
|
2015-10-28 20:22:07 +01:00
|
|
|
Session::flash('message', trans('texts.updated_payment'));
|
2015-03-16 22:45:25 +01:00
|
|
|
|
2015-10-28 20:22:07 +01:00
|
|
|
return redirect()->to($payment->getRoute());
|
2015-03-16 22:45:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function bulk()
|
|
|
|
{
|
|
|
|
$action = Input::get('action');
|
2016-04-23 22:40:19 +02:00
|
|
|
$amount = Input::get('amount');
|
2015-10-28 20:22:07 +01:00
|
|
|
$ids = Input::get('public_id') ? Input::get('public_id') : Input::get('ids');
|
2016-04-23 22:40:19 +02:00
|
|
|
$count = $this->paymentService->bulk($ids, $action, array('amount'=>$amount));
|
2015-03-16 22:45:25 +01:00
|
|
|
|
|
|
|
if ($count > 0) {
|
2016-04-23 22:40:19 +02:00
|
|
|
$message = Utils::pluralize($action=='refund'?'refunded_payment':$action.'d_payment', $count);
|
2015-03-16 22:45:25 +01:00
|
|
|
Session::flash('message', $message);
|
|
|
|
}
|
|
|
|
|
|
|
|
return Redirect::to('payments');
|
|
|
|
}
|
2015-09-10 19:50:09 +02:00
|
|
|
|
2015-12-30 19:45:52 +01:00
|
|
|
private function error($type, $error, $accountGateway = false, $exception = false)
|
2015-09-10 19:50:09 +02:00
|
|
|
{
|
|
|
|
$message = '';
|
|
|
|
if ($accountGateway && $accountGateway->gateway) {
|
|
|
|
$message = $accountGateway->gateway->name . ': ';
|
|
|
|
}
|
2015-11-02 23:05:28 +01:00
|
|
|
$message .= $error ?: trans('texts.payment_error');
|
2015-09-10 19:50:09 +02:00
|
|
|
|
|
|
|
Session::flash('error', $message);
|
2016-03-22 16:14:40 +01:00
|
|
|
Utils::logError("Payment Error [{$type}]: " . ($exception ? Utils::getErrorString($exception) : $message), 'PHP', true);
|
2015-09-10 19:50:09 +02:00
|
|
|
}
|
2016-04-29 23:50:21 +02:00
|
|
|
|
|
|
|
public function getBankInfo($routingNumber) {
|
|
|
|
if (strlen($routingNumber) != 9 || !preg_match('/\d{9}/', $routingNumber)) {
|
|
|
|
return response()->json([
|
|
|
|
'message' => 'Invalid routing number',
|
|
|
|
], 400);
|
|
|
|
}
|
|
|
|
|
|
|
|
$data = static::getBankData($routingNumber);
|
|
|
|
|
|
|
|
if (is_string($data)) {
|
|
|
|
return response()->json([
|
|
|
|
'message' => $data,
|
|
|
|
], 500);
|
|
|
|
} elseif (!empty($data)) {
|
|
|
|
return $data;
|
|
|
|
}
|
|
|
|
|
|
|
|
return response()->json([
|
|
|
|
'message' => 'Bank not found',
|
|
|
|
], 404);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static function getBankData($routingNumber) {
|
|
|
|
$cached = Cache::get('bankData:'.$routingNumber);
|
|
|
|
|
|
|
|
if ($cached != null) {
|
|
|
|
return $cached == false ? null : $cached;
|
|
|
|
}
|
|
|
|
|
|
|
|
$dataPath = base_path('vendor/gatepay/FedACHdir/FedACHdir.txt');
|
|
|
|
|
|
|
|
if (!file_exists($dataPath) || !$size = filesize($dataPath)) {
|
|
|
|
return 'Invalid data file';
|
|
|
|
}
|
|
|
|
|
|
|
|
$lineSize = 157;
|
|
|
|
$numLines = $size/$lineSize;
|
|
|
|
|
|
|
|
if ($numLines % 1 != 0) {
|
|
|
|
// The number of lines should be an integer
|
|
|
|
return 'Invalid data file';
|
|
|
|
}
|
|
|
|
|
|
|
|
// Format: http://www.sco.ca.gov/Files-21C/Bank_Master_Interface_Information_Package.pdf
|
|
|
|
$file = fopen($dataPath, 'r');
|
|
|
|
|
|
|
|
// Binary search
|
|
|
|
$low = 0;
|
|
|
|
$high = $numLines - 1;
|
|
|
|
while ($low <= $high) {
|
|
|
|
$mid = floor(($low + $high) / 2);
|
|
|
|
|
|
|
|
fseek($file, $mid * $lineSize);
|
|
|
|
$thisNumber = fread($file, 9);
|
|
|
|
|
|
|
|
if ($thisNumber > $routingNumber) {
|
|
|
|
$high = $mid - 1;
|
|
|
|
} else if ($thisNumber < $routingNumber) {
|
|
|
|
$low = $mid + 1;
|
|
|
|
} else {
|
|
|
|
$data = array('routing_number' => $thisNumber);
|
|
|
|
fseek($file, 26, SEEK_CUR);
|
|
|
|
$data['name'] = trim(fread($file, 36));
|
|
|
|
$data['address'] = trim(fread($file, 36));
|
|
|
|
$data['city'] = trim(fread($file, 20));
|
|
|
|
$data['state'] = fread($file, 2);
|
|
|
|
$data['zip'] = fread($file, 5).'-'.fread($file, 4);
|
|
|
|
$data['phone'] = fread($file, 10);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!empty($data)) {
|
|
|
|
Cache::put('bankData:'.$routingNumber, $data, 5);
|
|
|
|
return $data;
|
|
|
|
} else {
|
|
|
|
Cache::put('bankData:'.$routingNumber, false, 5);
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
2016-04-30 23:54:56 +02:00
|
|
|
|
|
|
|
public function handlePaymentWebhook($accountKey, $gatewayId)
|
|
|
|
{
|
|
|
|
$gatewayId = intval($gatewayId);
|
|
|
|
|
|
|
|
if ($gatewayId != GATEWAY_STRIPE) {
|
|
|
|
return response()->json([
|
|
|
|
'message' => 'Unsupported gateway',
|
|
|
|
], 404);
|
|
|
|
}
|
|
|
|
|
|
|
|
$account = Account::where('accounts.account_key', '=', $accountKey)->first();
|
|
|
|
|
|
|
|
if (!$account) {
|
|
|
|
return response()->json([
|
|
|
|
'message' => 'Unknown account',
|
|
|
|
], 404);
|
|
|
|
}
|
|
|
|
|
|
|
|
$eventId = Input::get('id');
|
|
|
|
$eventType= Input::get('type');
|
|
|
|
|
|
|
|
if (!$eventId) {
|
|
|
|
return response()->json([
|
|
|
|
'message' => 'Missing event id',
|
|
|
|
], 400);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!$eventType) {
|
|
|
|
return response()->json([
|
|
|
|
'message' => 'Missing event type',
|
|
|
|
], 400);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!in_array($eventType, array('charge.failed', 'charge.succeeded'))) {
|
|
|
|
return array('message' => 'Ignoring event');
|
|
|
|
}
|
|
|
|
|
|
|
|
$accountGateway = $account->getGatewayConfig(intval($gatewayId));
|
|
|
|
|
|
|
|
// Fetch the event directly from Stripe for security
|
|
|
|
$eventDetails = $this->paymentService->makeStripeCall($accountGateway, 'GET', 'events/'.$eventId);
|
|
|
|
|
|
|
|
if (is_string($eventDetails) || !$eventDetails) {
|
|
|
|
return response()->json([
|
|
|
|
'message' => $eventDetails ? $eventDetails : 'Could not get event details.',
|
|
|
|
], 500);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($eventType != $eventDetails['type']) {
|
|
|
|
return response()->json([
|
|
|
|
'message' => 'Event type mismatch',
|
|
|
|
], 400);
|
|
|
|
}
|
|
|
|
|
2016-05-01 06:37:14 +02:00
|
|
|
if (!$eventDetails['pending_webhooks']) {
|
2016-04-30 23:54:56 +02:00
|
|
|
return response()->json([
|
|
|
|
'message' => 'This is not a pending event',
|
|
|
|
], 400);
|
|
|
|
}
|
|
|
|
|
|
|
|
$charge = $eventDetails['data']['object'];
|
|
|
|
$transactionRef = $charge['id'];
|
|
|
|
|
|
|
|
$payment = Payment::where('transaction_reference', '=', $transactionRef)->first();
|
|
|
|
|
|
|
|
if (!$payment) {
|
|
|
|
return array('message' => 'Unknown payment');
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($eventType == 'charge.failed') {
|
2016-05-01 06:38:48 +02:00
|
|
|
if (!$payment->isFailed()) {
|
2016-04-30 23:54:56 +02:00
|
|
|
$payment->markFailed($charge['failure_message']);
|
|
|
|
$this->userMailer->sendNotification($payment->user, $payment->invoice, 'payment_failed', $payment);
|
|
|
|
}
|
|
|
|
} elseif ($eventType == 'charge.succeeded') {
|
|
|
|
$payment->markComplete();
|
|
|
|
}
|
|
|
|
|
|
|
|
return array('message' => 'Processed successfully');
|
|
|
|
}
|
2015-03-16 22:45:25 +01:00
|
|
|
}
|