Paypal integration controller not working in Laravel - laravel

I create an account at paypal to test in my app.
composer require paypal/rest-api-sdk-php
Added the client ID and secret to the .env
This is what I currently have in my view
#if ($message = Session::get('success'))
<div class="w3-panel w3-green w3-display-container">
<span onclick="this.parentElement.style.display='none'"
class="w3-button w3-green w3-large w3-display-topright">×</span>
<p>{!! $message !!}</p>
</div>
<?php Session::forget('success');?>
#endif
#if ($message = Session::get('error'))
<div class="w3-panel w3-red w3-display-container">
<span onclick="this.parentElement.style.display='none'"
class="w3-button w3-red w3-large w3-display-topright">×</span>
<p>{!! $message !!}</p>
</div>
<?php Session::forget('error');?>
#endif
<form class="w3-container w3-display-middle w3-card-4 " method="POST" id="payment-form" action="{!! URL::to('paypal') !!}">
{{ csrf_field() }}
<h2 class="w3-text-blue">Payment Form</h2>
<p>
<label class="w3-text-blue"><b>Enter Amount</b></label>
<input class="w3-input w3-border" name="amount" type="text"></p>
<button class="w3-btn w3-blue">Pay with PayPal</button></p>
</form>
My PaymentController looks like this:
<?php
namespace App\Http\Controllers;
use Illuminate\Support\Facades\Session;
use Illuminate\Http\Request;
use PayPal\Api\Amount;
use PayPal\Api\Item;
use PayPal\Api\ItemList;
use PayPal\Api\Payer;
use PayPal\Api\Transaction;
use PayPal\Api\Payment;
use PayPal\Api\Details;
use PayPal\Api\ChargeModel;
use PayPal\Api\Currency;
use PayPal\Api\MerchantPreferences;
use PayPal\Api\PaymentDefinition;
use PayPal\Api\Plan;
use PayPal\Api\Patch;
use PayPal\Api\PatchRequest;
use PayPal\Common\PayPalModel;
use PayPal\Rest\ApiContext;
use PayPal\Auth\OAuthTokenCredential;
use PayPal\Api\RedirectUrls;
use PayPal\Api\PaymentExecution;
use URL;
use Redirect;
use Illuminate\Support\Facades\Input;
class PaymentController extends Controller
{
private $apiContext;
private $mode;
private $client_id;
private $secret;
public function __construct()
{
/** PayPal api context **/
$paypal_conf = \Config::get('paypal');
$this->_api_context = new ApiContext(new OAuthTokenCredential(
$paypal_conf['client_id'],
$paypal_conf['secret'])
);
$this->_api_context->setConfig($paypal_conf['settings']);
}
public function payWithpaypal(Request $request){
$payer = new Payer();
$payer->setPaymentMethod('paypal');
$item_1 = new Item();
$item_1->setName('Item 1') /** item name **/
->setCurrency('USD')
->setQuantity(1)
->setPrice($request->get('amount')); /** unit price **/
$item_list = new ItemList();
$item_list->setItems(array($item_1));
$amount = new Amount();
$amount->setCurrency('USD')
->setTotal($request->get('amount'));
$transaction = new Transaction();
$transaction->setAmount($amount)
->setItemList($item_list)
->setDescription('Your transaction description');
$redirect_urls = new RedirectUrls();
$redirect_urls->setReturnUrl(URL::route('status')) /** Specify return URL **/
->setCancelUrl(URL::route('status'));
$payment = new Payment();
$payment->setIntent('Sale')
->setPayer($payer)
->setRedirectUrls($redirect_urls)
->setTransactions(array($transaction));
/** dd($payment->create($this->_api_context));exit; **/
try {
$payment->create($this->_api_context);
} catch (\PayPal\Exception\PPConnectionException $ex) {
if (\Config::get('app.debug')) {
\Session::put('error', 'Connection timeout');
return Redirect::route('paywithpaypal');
} else {
\Session::put('error', 'Some error occur, sorry for inconvenient');
return Redirect::route('paywithpaypal');
}
}
foreach ($payment->getLinks() as $link) {
if ($link->getRel() == 'approval_url') {
$redirect_url = $link->getHref();
break;
}
}
/** add payment ID to session **/
Session::put('paypal_payment_id', $payment->getId());
if (isset($redirect_url)) {
/** redirect to paypal **/
return Redirect::away($redirect_url);
}
\Session::put('error', 'Unknown error occurred');
return Redirect::route('paywithpaypal');
}
public function getPaymentStatus(){
/** Get the payment ID before session clear **/
$payment_id = Session::get('paypal_payment_id');
/** clear the session payment ID **/
Session::forget('paypal_payment_id');
if (empty(Input::get('PayerID')) || empty(Input::get('token'))) {
\Session::put('error', 'Payment failed');
return Redirect::route('/');
}
$payment = Payment::get($payment_id, $this->_api_context);
$execution = new PaymentExecution();
$execution->setPayerId(Input::get('PayerID'));
/**Execute the payment **/
$result = $payment->execute($execution, $this->_api_context);
if ($result->getState() == 'approved') {
/*************************************************
PAYMENT SUCCESSFULL - DO THE REST HERE
/************************************************/
\Session::put('success', 'Payment success');
return Redirect::route('/');
}
\Session::put('error', 'Payment failed');
return Redirect::route('/');
}
}
So now when I enter an amount and try to pay, I get the following error:
Argument 1 passed to PayPal\Rest\ApiContext::setConfig() must be of the type array, null given, called in C:\xampp\htdocs\owlproperty\app\Http\Controllers\PaymentController.php on line 47
I created the paypal file under the config folder and that looks like this:
<?php
return [
'client_id' => env('PAYPAL_CLIENT_ID',''),
'secret' => env('PAYPAL_SECRET',''),
'settings' => array(
'mode' => env('PAYPAL_MODE','sandbox'),
'http.ConnectionTimeOut' => 30,
'log.LogEnabled' => true,
'log.FileName' => storage_path() . '/logs/paypal.log',
'log.LogLevel' => 'ERROR'
),
];
Anything I could have possibly done wrong?

You are not loading the config file correctly:
From the documentation:
The configuration values may be accessed using "dot" syntax, which
includes the name of the file and option you wish to access.
Assuming your confile file is named paypal.php, use this in the constructor:
public function __construct()
{
/** PayPal api context **/
$settings = config('paypal.settings');
$client_id = config('paypal.client_id');
$secret = config('paypal.secret');
$this->_api_context = new ApiContext(new OAuthTokenCredential(
$client_id,
$secret)
);
$this->_api_context->setConfig($settings);
}

Related

when I create a user the user details stored in user table as well as I have to insert the username into another table also

I get this error Illuminate/Database/QueryException with message 'SQLSTATE[HY000]: General error: 1364 Field 'name' doesn't have a default value. But when MySQL turn to false I get my result but how can I do it on following way
User.php
public function deliverydetails()
{
return $this->hasOne(DeliveryDetails::class);
}
protected static function boot()
{
parent::boot();
static::created(function($user){
$user->deliverydetails()->create([
'billname' => $user->name,
]);
});
}
DeliveryDetails.php
public function user()
{
return $this->belongsTo(User::class);
}
viewpage
<div class="form-group">
<input type="text" id="billname" name="billname" value="{{$deliveryDetails->name}}" class="form-control" placeholder="Name">
<span style="color: red;">{{$errors->first('billname')}}</span>
</div>
productController
$deliveryDetailsCount = DeliveryDetails::where('user_id', $userid)->count();
if($deliveryDetailsCount > 0){
$deliveryDetails = DeliveryDetails::where('user_id', $userid)->first();
}
if(request()->isMethod('post')){
$this->validateDetails();
$data = request()->all();
// echo "<pre>"; print_r($data); die;
User::where('id', $userid)->update(['name'=>$data['name'], 'address'=>$data['address'],
'city'=>$data['city'], 'state'=>$data['state'], 'country'=>$data['country'],
'pincode'=>$data['pincode']]);
if($deliveryDetailsCount > 0){
//update address
DeliveryDetails::where('user_id', $userid)->update(['name'=>$data['billname'], 'address'=>$data['billaddress'],
'city'=>$data['billcity'], 'state'=>$data['billstate'], 'country'=>$data['billcountry'],
'pincode'=>$data['billpincode']]);
}
else{
//add new address
$c = new DeliveryDetails;
$c->user_id = $userid;
$c->email = $useremail;
$c->name = $data['billname'];
$c->save();
}
}
how can I solve the issue..

getMimeType() before moving file in Laravel

This a part of my app I'm using to put a section that admin can choose the category of the file from...
File Model
namespace App\Models;
use App\Traits\Categorizeable;
use Illuminate\Database\Eloquent\Model;
class File extends Model
{
use Categorizeable;
protected $primaryKey = 'file_id';
protected $guarded = ['file_id'];
public function packages()
{
return $this->belongsToMany(Package::class, 'package_file');
}
}
Anyway I used a trait for it...
after that it is my view:
<div class="form-group">
<label for="categorize"> categories :</label>
<select name="categorize[]" id="categorize" class="select2 form-control" multiple>
#foreach($categories as $cat)
<option value="{{$cat->category_id}}"
{{isset($file_categories) && in_array($cat->category_id,$file_categories) ? 'selected' :'' }}>
{{$cat->category_name}}</option>
#endforeach
</select>
</div>
at last this is my FilesController:
public function store(Request $request)
{
// $this->validate();....
//after validation
$new_file_name = str_random(45) . '.' . $request->file('fileItem')->getClientOriginalExtension();
$result = $request->file('fileItem')->move(public_path('files'), $new_file_name);
if ($result instanceof \Symfony\Component\HttpFoundation\File\File) {
$new_file_data['file_name'] = $new_file_name;
$new_file_data = File::create([
'file_title' => $request->input('file_title'),
'file_description' => $request->input('file_description'),
'file_type' => $request->file('fileItem')->getMimeType(),
'file_size' => $request->file('fileItem')->getClientSize(),
]);
if ($new_file_data) {
if ($request->has('categorize')) {
$new_file_data->categories()->sync($request->input('categorize'));
}
return redirect()->route('admin.files.list')->with('success', 'message');
}
}
}
Now what my problem is that as you see file() saves a .tmp file first and I need to use getMimeType() before I move it, how to modify my code?
What is the best way to do that?
App is giving me an Error
Save the mime type as a variable before you move the file and use it in the create function
$new_file_name = str_random(45) . '.' . $request->file('fileItem')->getClientOriginalExtension();
$mime_type = $request->file('fileItem')->getMimeType();
$file_size = $request->file('fileItem')->getClientSize();
$result = $request->file('fileItem')->move(public_path('files'), $new_file_name);
if ($result instanceof \Symfony\Component\HttpFoundation\File\File) {
$new_file_data['file_name'] = $new_file_name;
$new_file_data = File::create([
'file_title' => $request->input('file_title'),
'file_description' => $request->input('file_description'),
'file_type' => $mime_type,
'file_size' => $file_size,
]);

Voyager - Can we send e-mail when admin add user?

I am trying send information e-mail to user when admin add user. But i don't know how can i intervene the Userpage in Adminpanel?
For example: Welcome "$user->name", your username is "$user->username" and your password is "$user->password".
I think about a lot. But can't progress. Still can not send any email. Do we have a way to make this e-mailing system easier in voyager tables?
edit: Added Registercontroller
public function register(Request $request)
{
$this->validation($request);
$customer = new Customer();
$customer->name = $request->name;
$customer->surname = $request->surname;
$customer->phone = $request->phone;
$customer->email = $request->email;
$customer->password = bcrypt($request->password);
$customer->description = $request->password;
$customer->save();
Auth::guard('customer')->login($customer);
Session::flash('success', __('messages.success'));
return redirect('/');
edit: Added CustomerObserve.php
<?php
namespace App\Helper\Observers;
use App\Customer;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Support\Facades\Mail;
class CustomerObserve implements ShouldQueue
{
public function created()
{
$customer = Customer::latest();
Mail::send('user_login_informations', ['customer' => $customer], function($message) use($customer) {
$message->to($customer->email, $customer->name)
->subject('account update');
})->delay(30);
}
}
create an email template in view folder
email.blade.php
#section('content')
<h2>Hello {{ ucfirst($customer->name) }},</h2>
<p>
Your email '{{ $customer->email }}' and password {{ $customer->password }}.
</p>
#stop
Reviewer controller
$this->validation($request);
$customer = new Customer();
$customer->name = $request->name;
$customer->surname = $request->surname;
$customer->phone = $request->phone;
$customer->email = $request->email;
$customer->password = bcrypt($request->password);
$customer->description = $request->password;
$customer->save();
Auth::guard('customer')->login($customer);
Session::flash('success', __('messages.success'));
Mail::send('email', ['customer' => $customer], function($message) use($customer) {
$message->to($customer->email, $customer->name)
->subject('account update');
});
return redirect('/');

how to i print session on view page in zend framework

I am very new to zend framework, and going to add session in my small application but i dont know how to print session variable to my header.phtml page.
UsersTable.php
public function fetchbyWhere($where) {
$rowset = $this->tableGateway->select($where);
$row = $rowset->current();
if (!$row) {
return;
}
return $row;
}
IndexController.php
<?php
namespace Application\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Application\Model\Users; // <-- Add this import
use Zend\Session\Container; // We need this when using sessions
class IndexController extends AbstractActionController {
protected $usersTable;
public function getUsersTable() {
if (!$this->usersTable) {
$sm = $this->getServiceLocator();
$this->usersTable = $sm->get('Application\Model\UsersTable');
}
return $this->usersTable;
}
public function indexAction() {
$request = $this->getRequest();
if ($request->isPost()) {
$user = $request->getPost('txtuser');
$pass = $request->getPost('txtpassword');
$wher = array('username' => $user, 'password' => $pass);
$resultSet = $this->getUsersTable()->fetchbyWhere($wher);
//var_dump($resultSet);
if($resultSet)
{
$user_session = new Container('user');
$user_session->ses_user = $resultSet->username;
return new ViewModel(array(
'msg' => 'valid user',
'sesuser' => $user_session->ses_user,
));
}
else {
return new ViewModel(array(
'msg' => 'not a valid user',
));
}
} else {
return new ViewModel();
}
}
}
now i dont know how to print this session on header.phtml page.
You need to add session container in your header file as well.
Add following line in your header file.
<?php
use Zend\Session\Container; // We need this when using sessions
$user_session = new Container('user');
if(isset($user_session->ses_user))
echo "user:".$user_session->ses_user;
?>

CakePHP 3.1 : My validation for translate behaviour fields, need some help in review/comment

I have worked on a hook for validate my translated fields, based on this thread : https://stackoverflow.com/a/33070156/4617689. That i've done do the trick, but i'm looking for you guys to help me to improve my code, so feel free to comment and modify
class ContentbuildersTable extends Table
{
public function initialize(array $config)
{
$this->addBehavior('Tree');
$this->addBehavior('Timestamp');
$this->addBehavior('Translate', [
'fields' => [
'slug'
]
]);
}
public function validationDefault(Validator $validator)
{
$data = null; // Contain our first $context validator
$validator
->requirePresence('label')
->notEmpty('label', null, function($context) use (&$data) {
$data = $context; // Update the $data with current $context
return true;
})
->requirePresence('type_id')
->notEmpty('type_id')
->requirePresence('is_activated')
->notEmpty('is_activated');
$translationValidator = new Validator();
$translationValidator
->requirePresence('slug')
->notEmpty('slug', null, function($context) use (&$data) {
if (isset($data['data']['type_id']) && !empty($data['data']['type_id'])) {
if ($data['data']['type_id'] != Type::TYPE_HOMEPAGE) {
return true;
}
return false;
}
return true;
});
$validator
->addNestedMany('translations', $translationValidator);
return $validator;
}
}
I'm not proud of my trick with the $data, but i've not found a method to get the data of the validator into my nestedValidator...
Important part here is to note that i only rule of my nestedValidator on 'translations', this is very important !
class Contentbuilder extends Entity
{
use TranslateTrait;
}
Here basic for I18ns to work
class BetterFormHelper extends Helper\FormHelper
{
public function input($fieldName, array $options = [])
{
$context = $this->_getContext();
$explodedFieldName = explode('.', $fieldName);
$errors = $context->entity()->errors($explodedFieldName[0]);
if (is_array($errors) && !empty($errors) && empty($this->error($fieldName))) {
if (isset($errors[$explodedFieldName[1]][$explodedFieldName[2]])) {
$error = array_values($errors[$explodedFieldName[1]][$explodedFieldName[2]])[0];
$options['templates']['inputContainer'] = '<div class="input {{type}} required error">{{content}} <div class="error-message">' . $error . '</div></div>';
}
}
return parent::input($fieldName, $options);
}
}
With that formHelper we gonna get the errors of nestedValidation and inject them into the input, i'm not confortable with the templates, so that's why it's very ugly.
<?= $this->Form->create($entity, ['novalidate', 'data-load-in' => '#right-container']) ?>
<div class="tabs">
<?= $this->Form->input('label') ?>
<?= $this->Form->input('type_id', ['empty' => '---']) ?>
<?= $this->Form->input('is_activated', ['required' => true]) ?>
<?= $this->Form->input('translations.fr_FR.slug') ?>
<?= $this->Form->input('_translations.en_US.slug') ?>
</div>
<?php
echo $this->Form->submit(__("Save"));
echo $this->Form->end();
?>
Here my fr_FR.slug is required when type_id is not set to Type::TYPE_HOMEPAGE, yeah my homepage has not slug, note that the en_US.slug is not required at all, because i only required 'translations.xx_XX.xxxx' and not '_translations.xx_XX.xxxx'.
And the last part of the code, the controller
$entity = $this->Contentbuilders->patchEntity($entity, $this->request->data);
// We get the locales
$I18ns = TableRegistry::get('I18ns');
$langs = $I18ns->find('list', [
'keyField' => 'id',
'valueField' => 'locale'
])->toArray();
// Merging translations
if (isset($entity->translations)) {
$entity->_translations = array_merge($entity->_translations, $entity->translations);
unset($entity->translations);
}
foreach ($entity->_translations as $lang => $data) {
if (in_array($lang, $langs)) {
$entity->translation($lang)->set($data, ['guard' => false]);
}
}
Here a .gif of the final result om my side : http://i.giphy.com/3o85xyrLOTd7q0YVck.gif

Resources