v2 first commit

This commit is contained in:
denisdulici
2019-11-16 10:21:14 +03:00
parent 5b23e9c2c4
commit 6d50fa8442
3075 changed files with 3451681 additions and 65594 deletions

View File

@ -0,0 +1,144 @@
<?php
namespace Modules\PaypalStandard\Http\Controllers;
use App\Abstracts\Http\PaymentController;
use App\Http\Requests\Portal\InvoicePayment as PaymentRequest;
use App\Models\Income\Invoice;
use GuzzleHttp\Client;
use Illuminate\Http\Request;
use Monolog\Handler\StreamHandler;
use Monolog\Logger;
class Payment extends PaymentController
{
public $alias = 'paypal-standard';
public $type = 'redirect';
public function show(Invoice $invoice, PaymentRequest $request)
{
$setting = $this->setting;
$this->setContactFirstLastName($invoice);
$setting['action'] = ($setting['mode'] == 'live') ? 'https://www.paypal.com/cgi-bin/webscr' : 'https://www.sandbox.paypal.com/cgi-bin/webscr';
$invoice_url = $this->getInvoiceUrl($invoice);
$html = view('paypal-standard::show', compact('setting', 'invoice', 'invoice_url'))->render();
return response()->json([
'code' => $setting['code'],
'name' => $setting['name'],
'description' => trans('paypal-standard::general.description'),
'redirect' => false,
'html' => $html,
]);
}
public function return(Invoice $invoice, Request $request)
{
$success = true;
switch ($request['payment_status']) {
case 'Completed':
$message = trans('messages.success.added', ['type' => trans_choice('general.payments', 1)]);
break;
case 'Canceled_Reversal':
case 'Denied':
case 'Expired':
case 'Failed':
case 'Pending':
case 'Processed':
case 'Refunded':
case 'Reversed':
case 'Voided':
$message = trans('messages.error.added', ['type' => trans_choice('general.payments', 1)]);
$success = false;
break;
}
if ($success) {
flash($message)->success();
} else {
flash($message)->warning();
}
$invoice_url = $this->getInvoiceUrl($invoice);
return redirect($invoice_url);
}
public function complete(Invoice $invoice, Request $request)
{
$setting = $this->setting;
$paypal_log = new Logger('Paypal');
$paypal_log->pushHandler(new StreamHandler(storage_path('logs/paypal.log')), Logger::INFO);
if (!$invoice) {
return;
}
$url = ($setting['mode'] == 'live') ? 'https://ipnpb.paypal.com/cgi-bin/webscr' : 'https://www.sandbox.paypal.com/cgi-bin/webscr';
$client = new Client(['verify' => false]);
$paypal_request['cmd'] = '_notify-validate';
foreach ($request->toArray() as $key => $value) {
$paypal_request[$key] = urlencode(html_entity_decode($value, ENT_QUOTES, 'UTF-8'));
}
$response = $client->post($url, $paypal_request);
if ($response->getStatusCode() != 200) {
$paypal_log->info('PAYPAL_STANDARD :: CURL failed ', $response->getBody()->getContents());
} else {
$response = $response->getBody()->getContents();
}
if ($setting['debug']) {
$paypal_log->info('PAYPAL_STANDARD :: IPN REQUEST: ', $request->toArray());
}
if ((strcmp($response, 'VERIFIED') != 0 || strcmp($response, 'UNVERIFIED') != 0)) {
$paypal_log->info('PAYPAL_STANDARD :: VERIFIED != 0 || UNVERIFIED != 0 ' . $request->toArray());
return;
}
switch ($request['payment_status']) {
case 'Completed':
$receiver_match = (strtolower($request['receiver_email']) == strtolower($setting['email']));
$total_paid_match = ((double) $request['mc_gross'] == $invoice->amount);
if ($receiver_match && $total_paid_match) {
event(new \App\Events\Income\PaymentReceived($invoice, $request));
}
if (!$receiver_match) {
$paypal_log->info('PAYPAL_STANDARD :: RECEIVER EMAIL MISMATCH! ' . strtolower($request['receiver_email']));
}
if (!$total_paid_match) {
$paypal_log->info('PAYPAL_STANDARD :: TOTAL PAID MISMATCH! ' . $request['mc_gross']);
}
break;
case 'Canceled_Reversal':
case 'Denied':
case 'Expired':
case 'Failed':
case 'Pending':
case 'Processed':
case 'Refunded':
case 'Reversed':
case 'Voided':
$paypal_log->info('PAYPAL_STANDARD :: NOT COMPLETED ' . $request->toArray());
break;
}
}
}

View File

@ -1,164 +0,0 @@
<?php
namespace Modules\PaypalStandard\Http\Controllers;
use App\Events\InvoicePaid;
use Illuminate\Http\Response;
use Illuminate\Routing\Controller;
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
use GuzzleHttp\Client;
use Illuminate\Http\Request;
use App\Http\Requests\Customer\InvoicePayment as PaymentRequest;
use App\Models\Income\Invoice;
class PaypalStandard extends Controller
{
/**
* Show the form for editing the specified resource.
* @param Invoice
* @param PaymentRequest
* @return Response
*/
public function show(Invoice $invoice, PaymentRequest $request)
{
$gateway = setting('paypalstandard');
$gateway['action'] = 'https://www.paypal.com/cgi-bin/webscr';
if ($gateway['mode'] == 'sandbox') {
$gateway['action'] = 'https://www.sandbox.paypal.com/cgi-bin/webscr';
}
$customer = explode(" ", $invoice->customer_name);
$last_name = array_pop($customer);
$first_name = implode(" ", $customer);
$invoice->first_name = $first_name;
$invoice->last_name = $last_name;
$gateway['language'] = \App::getLocale();
$html = view('paypalstandard::show', compact('gateway', 'invoice'))->render();
return response()->json([
'code' => 'paypalstandard',
'name' => $gateway['name'],
'description' => trans('paypalstandard::paypalstandard.description'),
'redirect' => false,
'html' => $html,
]);
}
public function result(Invoice $invoice, Request $request)
{
$success = true;
switch ($request['payment_status']) {
case 'Completed':
$message = trans('messages.success.added', ['type' => trans_choice('general.customers', 1)]);
break;
case 'Canceled_Reversal':
case 'Denied':
case 'Expired':
case 'Failed':
case 'Pending':
case 'Processed':
case 'Refunded':
case 'Reversed':
case 'Voided':
$message = trans('messages.error.added', ['type' => trans_choice('general.customers', 1)]);
$success = false;
break;
}
if ($success) {
flash($message)->success();
} else {
flash($message)->warning();
}
$redirect = url('customers/invoices/' . $invoice->id);
return redirect($redirect);
}
public function callback(Invoice $invoice, Request $request)
{
$gateway = setting('paypalstandard');
$paypal_log = new Logger('Paypal');
$paypal_log->pushHandler(new StreamHandler(storage_path('logs/paypal.log')), Logger::INFO);
if ($invoice) {
$url = 'https://ipnpb.paypal.com/cgi-bin/webscr';
if ($gateway['mode'] == 'sandbox') {
$url = 'https://www.sandbox.paypal.com/cgi-bin/webscr';
}
$client = new Client(['verify' => false]);
$paypal_request['cmd'] = '_notify-validate';
foreach ($request->toArray() as $key => $value) {
$paypal_request[$key] = urlencode(html_entity_decode($value, ENT_QUOTES, 'UTF-8'));
}
$result = $client->post($url, $paypal_request);
if ($result->getStatusCode() != 200) {
$paypal_log->info('PAYPAL_STANDARD :: CURL failed ', $result->getBody()->getContents());
} else {
$result = $result->getBody()->getContents();
}
if ($gateway['debug']) {
$paypal_log->info('PAYPAL_STANDARD :: IPN REQUEST: ', $request->toArray());
//$paypal_log->info('PAYPAL_STANDARD :: IPN RESULT: ', $result);
}
if ((strcmp($result, 'VERIFIED') == 0 || strcmp($result, 'UNVERIFIED') == 0) || true) {
switch ($request['payment_status']) {
case 'Completed':
$receiver_match = (strtolower($request['receiver_email']) == strtolower($gateway['email']));
$total_paid_match = ((float)$request['mc_gross'] == $invoice->amount);
if ($receiver_match && $total_paid_match) {
event(new InvoicePaid($invoice, $request->toArray()));
}
if (!$receiver_match) {
$paypal_log->info('PAYPAL_STANDARD :: RECEIVER EMAIL MISMATCH! ' . strtolower($request['receiver_email']));
}
if (!$total_paid_match) {
$paypal_log->info('PAYPAL_STANDARD :: TOTAL PAID MISMATCH! ' . $request['mc_gross']);
}
break;
case 'Canceled_Reversal':
case 'Denied':
case 'Expired':
case 'Failed':
case 'Pending':
case 'Processed':
case 'Refunded':
case 'Reversed':
case 'Voided':
$paypal_log->info('PAYPAL_STANDARD :: NOT COMPLETED ' . $request->toArray());
break;
}
} else {
$paypal_log->info('PAYPAL_STANDARD :: VERIFIED != 0 || UNVERIFIED != 0 ' . $request->toArray());
}
}
}
}

View File

@ -1,25 +0,0 @@
<?php
Route::group([
'middleware' => 'customer',
'prefix' => 'customers',
'namespace' => 'Modules\PaypalStandard\Http\Controllers'
], function () {
Route::get('invoices/{invoice}/paypalstandard', 'PaypalStandard@show');
});
Route::group([
'prefix' => 'customers',
'namespace' => 'Modules\PaypalStandard\Http\Controllers'
], function () {
Route::post('invoices/{invoice}/paypalstandard/result', 'PaypalStandard@result');
Route::post('invoices/{invoice}/paypalstandard/callback', 'PaypalStandard@callback');
});
Route::group([
'middleware' => ['signed', 'language'],
'prefix' => 'signed',
'namespace' => 'Modules\PaypalStandard\Http\Controllers'
], function () {
Route::post('invoices/{invoice}/paypalstandard', 'PaypalStandard@show');
});

View File

@ -1,23 +0,0 @@
<?php
namespace Modules\PaypalStandard\Listeners;
use App\Events\PaymentGatewayListing;
class Gateway
{
/**
* Handle the event.
*
* @param PaymentGatewayListing $event
* @return void
*/
public function handle(PaymentGatewayListing $event)
{
$setting = setting('paypalstandard');
$setting['code'] = 'paypalstandard';
return [$setting];
}
}

View File

@ -0,0 +1,23 @@
<?php
namespace Modules\PaypalStandard\Listeners;
use App\Events\Module\PaymentMethodShowing as Event;
class ShowPaymentMethod
{
/**
* Handle the event.
*
* @param Event $event
* @return void
*/
public function handle(Event $event)
{
$method = setting('paypal-standard');
$method['code'] = 'paypal-standard';
$event->modules->payment_methods[] = $method;
}
}

View File

@ -0,0 +1,93 @@
<?php
namespace Modules\PaypalStandard\Providers;
use Illuminate\Support\ServiceProvider as Provider;
use Modules\PaypalStandard\Listeners\ShowPaymentMethod;
class Main extends Provider
{
/**
* Boot the application events.
*
* @return void
*/
public function boot()
{
$this->loadTranslations();
$this->loadViews();
$this->loadEvents();
}
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->loadRoutes();
}
/**
* Load views.
*
* @return void
*/
public function loadViews()
{
$this->loadViewsFrom(__DIR__ . '/../Resources/views', 'paypal-standard');
}
/**
* Load translations.
*
* @return void
*/
public function loadTranslations()
{
$this->loadTranslationsFrom(__DIR__ . '/../Resources/lang', 'paypal-standard');
}
/**
* Load events.
*
* @return void
*/
public function loadEvents()
{
$this->app['events']->listen(\App\Events\Module\PaymentMethodShowing::class, ShowPaymentMethod::class);
}
/**
* Load routes.
*
* @return void
*/
public function loadRoutes()
{
if (app()->routesAreCached()) {
return;
}
$routes = [
'guest.php',
'portal.php',
'signed.php',
];
foreach ($routes as $route) {
$this->loadRoutesFrom(__DIR__ . '/../Routes/' . $route);
}
}
/**
* Get the services provided by the provider.
*
* @return array
*/
public function provides()
{
return [];
}
}

View File

@ -1,90 +0,0 @@
<?php
namespace Modules\PaypalStandard\Providers;
use App\Events\PaymentGatewayListing;
use Illuminate\Support\ServiceProvider;
use Modules\PaypalStandard\Listeners\Gateway;
class PaypalStandardServiceProvider extends ServiceProvider
{
/**
* Indicates if loading of the provider is deferred.
*
* @var bool
*/
protected $defer = false;
/**
* Boot the application events.
*
* @return void
*/
public function boot()
{
$this->registerTranslations();
$this->registerViews();
$this->registerEvents();
}
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
//
}
/**
* Register views.
*
* @return void
*/
public function registerViews()
{
$viewPath = resource_path('views/modules/paypalstandard');
$sourcePath = __DIR__.'/../Resources/views';
$this->publishes([
$sourcePath => $viewPath
]);
$this->loadViewsFrom(array_merge(array_map(function ($path) {
return $path . '/modules/paypalstandard';
}, \Config::get('view.paths')), [$sourcePath]), 'paypalstandard');
}
/**
* Register translations.
*
* @return void
*/
public function registerTranslations()
{
$langPath = resource_path('lang/modules/paypalstandard');
if (is_dir($langPath)) {
$this->loadTranslationsFrom($langPath, 'paypalstandard');
} else {
$this->loadTranslationsFrom(__DIR__ .'/../Resources/lang', 'paypalstandard');
}
}
public function registerEvents()
{
$this->app['events']->listen(PaymentGatewayListing::class, Gateway::class);
}
/**
* Get the services provided by the provider.
*
* @return array
*/
public function provides()
{
return [];
}
}

View File

@ -2,20 +2,19 @@
return [
'title' => 'Paypal Standard',
'paypalstandard' => 'Paypal Standard',
'name' => 'PayPal Standard',
'description' => 'Enable the standard payment option of PayPal',
'form' => [
'email' => 'Email',
'mode' => 'Mode',
'debug' => 'Debug',
'transaction' => 'Transaction',
'customer' => 'Show to Customer',
'order' => 'Order',
'email' => 'Email',
'mode' => 'Mode',
'debug' => 'Debug',
'transaction' => 'Transaction',
'customer' => 'Show to Customer',
'order' => 'Order',
],
'test_mode' => 'Warning: The payment gateway is in \'Sandbox Mode\'. Your account will not be charged.',
'description' => 'Pay with PAYPAL',
'confirm' => 'Confirm',
'test_mode' => 'Warning: The payment gateway is in \'Sandbox Mode\'. Your account will not be charged.',
//'description' => 'Pay with PAYPAL',
];

View File

@ -1,26 +1,23 @@
<h2>{{ $gateway['name'] }}</h2>
<h2>{{ $setting['name'] }}</h2>
@if($gateway['mode'] == 'sandbox')
<div class="alert alert-danger"><i class="fa fa-exclamation-circle"></i> {{ trans('paypalstandard::general.test_mode') }}</div>
@if($setting['mode'] == 'sandbox')
<div class="alert alert-danger"><i class="fa fa-exclamation-circle"></i> {{ trans('paypal-standard::general.test_mode') }}</div>
@endif
<div class="well well-sm">
{{ trans('paypalstandard::general.description') }}
{{ trans('paypal-standard::general.description') }}
</div>
<form action="{{ $gateway['action'] }}" method="post">
<form action="{{ $setting['action'] }}" method="post">
<input type="hidden" name="cmd" value="_cart" />
<input type="hidden" name="upload" value="1" />
<input type="hidden" name="business" value="{{ $gateway['email'] }}" />
<input type="hidden" name="business" value="{{ $setting['email'] }}" />
<?php $i = 1; ?>
@foreach ($invoice->items as $item)
<input type="hidden" name="item_name_{{ $i }}" value="{{ $item->name }}" />
@if($item->sku)
<input type="hidden" name="item_number_{{ $i }}" value="{{ $item->sku }}" />
@endif
<input type="hidden" name="amount_{{ $i }}" value="{{ $item->price }}" />
<input type="hidden" name="quantity_{{ $i }}" value="{{ $item->quantity }}" />
<?php $i++; ?>
<input type="hidden" name="item_name_{{ $i }}" value="{{ $item->name }}" />
<input type="hidden" name="amount_{{ $i }}" value="{{ $item->price }}" />
<input type="hidden" name="quantity_{{ $i }}" value="{{ $item->quantity }}" />
<?php $i++; ?>
@endforeach
<input type="hidden" name="currency_code" value="{{ $invoice->currency_code}}" />
<input type="hidden" name="first_name" value="{{ $invoice->first_name }}" />
@ -29,20 +26,21 @@
<input type="hidden" name="address_override" value="0" />
<input type="hidden" name="email" value="{{ $invoice->customer_email }}" />
<input type="hidden" name="invoice" value="{{ $invoice->id . '-' . $invoice->customer_name }}" />
<input type="hidden" name="lc" value="{{ $gateway['language'] }}" />
<input type="hidden" name="lc" value="{{ $setting['language'] }}" />
<input type="hidden" name="rm" value="2" />
<input type="hidden" name="no_note" value="1" />
<input type="hidden" name="no_shipping" value="1" />
<input type="hidden" name="charset" value="utf-8" />
<input type="hidden" name="return" value="{{ url('customers/invoices/' . $invoice->id . '/paypalstandard/result') }}" />
<input type="hidden" name="notify_url" value="{{ url('customers/invoices/' . $invoice->id . '/paypalstandard/callback') }}" />
<input type="hidden" name="cancel_return" value="{{ url('customers/invoices/' . $invoice->id) }}" />
<input type="hidden" name="paymentaction" value="{{ $gateway['transaction'] }}" />
<input type="hidden" name="return" value="{{ route('portal.invoices.paypal-standard.return', $invoice->id) }}" />
<input type="hidden" name="notify_url" value="{{ route('portal.invoices.paypal-standard.complete', $invoice->id) }}" />
<input type="hidden" name="cancel_return" value="{{ $invoice_url }}" />
<input type="hidden" name="paymentaction" value="{{ $setting['transaction'] }}" />
<input type="hidden" name="custom" value="{{ $invoice->id }}" />
<input type="hidden" name="bn" value="Akaunting_1.0_WPS" />
<input type="hidden" name="bn" value="Akaunting_2.0_WPS" />
<div class="buttons">
<div class="pull-right">
<input type="submit" value="{{ trans('paypalstandard::general.confirm') }}" class="btn btn-success" />
<div class="float-right">
<input type="submit" value="{{ trans('paypal-standard::general.confirm') }}" class="btn btn-success" />
</div>
</div>
</form>

View File

@ -0,0 +1,10 @@
<?php
Route::group([
'prefix' => 'portal',
'middleware' => 'guest',
'namespace' => 'Modules\PaypalStandard\Http\Controllers'
], function () {
Route::post('invoices/{invoice}/paypal-standard/return', 'Payment@return')->name('portal.invoices.paypal-standard.return');
Route::post('invoices/{invoice}/paypal-standard/complete', 'Payment@complete')->name('portal.invoices.paypal-standard.complete');
});

View File

@ -0,0 +1,9 @@
<?php
Route::group([
'prefix' => 'portal',
'middleware' => 'portal',
'namespace' => 'Modules\PaypalStandard\Http\Controllers'
], function () {
Route::get('invoices/{invoice}/paypal-standard', 'Payment@show')->name('portal.invoices.paypal-standard.show');
});

View File

@ -0,0 +1,9 @@
<?php
Route::group([
'prefix' => 'signed',
'middleware' => 'signed',
'namespace' => 'Modules\PaypalStandard\Http\Controllers'
], function () {
Route::post('invoices/{invoice}/paypal-standard', 'Payment@show')->name('signed.invoices.paypal-standard.show');
});

View File

@ -1,26 +1,22 @@
{
"name": "PaypalStandard",
"alias": "paypalstandard",
"description": "",
"version": "1.0.0",
"category": "payment-gateway",
"keywords": [],
"alias": "paypal-standard",
"icon": "fab fa-paypal",
"version": "2.0.0",
"category": "payment-method",
"active": 1,
"order": 0,
"providers": [
"Modules\\PaypalStandard\\Providers\\PaypalStandardServiceProvider"
"Modules\\PaypalStandard\\Providers\\Main"
],
"aliases": {},
"files": [
"start.php"
],
"files": [],
"requires": [],
"settings": [
{
"type": "textGroup",
"name": "name",
"title": "general.name",
"icon": "id-card-o",
"icon": "fa fa-font",
"attributes": {
"required": "required"
}
@ -28,8 +24,8 @@
{
"type": "textGroup",
"name": "email",
"title": "paypalstandard::general.form.email",
"icon": "envelope-o",
"title": "paypal-standard::general.form.email",
"icon": "envelope",
"attributes": {
"required": "required"
}
@ -37,7 +33,7 @@
{
"type": "selectGroup",
"name": "mode",
"title": "paypalstandard::general.form.mode",
"title": "paypal-standard::general.form.mode",
"icon": "plane",
"values": {
"live": "Live",
@ -49,8 +45,8 @@
{
"type": "selectGroup",
"name": "transaction",
"title": "paypalstandard::general.form.transaction",
"icon": "exchange",
"title": "paypal-standard::general.form.transaction",
"icon": "exchange-alt",
"values": {
"authorization": "Authorization",
"sale": "Sale"
@ -61,7 +57,7 @@
{
"type": "radioGroup",
"name": "customer",
"title": "paypalstandard::general.form.customer",
"title": "paypal-standard::general.form.customer",
"enable": "general.yes",
"disable": "general.no",
"attributes": {}
@ -69,7 +65,7 @@
{
"type": "radioGroup",
"name": "debug",
"title": "paypalstandard::general.form.debug",
"title": "paypal-standard::general.form.debug",
"enable": "general.yes",
"disable": "general.no",
"attributes": {}
@ -77,7 +73,7 @@
{
"type": "textGroup",
"name": "order",
"title": "paypalstandard::general.form.order",
"title": "paypal-standard::general.form.order",
"icon": "sort",
"attributes": {}
}

View File

@ -1,17 +0,0 @@
<?php
/*
|--------------------------------------------------------------------------
| Register Namespaces And Routes
|--------------------------------------------------------------------------
|
| When a module starting, this file will executed automatically. This helps
| to register some namespaces like translator or view. Also this file
| will load the routes file for each module. You may also modify
| this file as you want.
|
*/
if (!app()->routesAreCached()) {
require __DIR__ . '/Http/routes.php';
}