I'm trying to implement the PayPal API
namespace App\Http\Controllers;
use PayPal;
use Redirect;
class PaypalPaymentController extends Controller{
private $_apiContext;
public function __construct()
{
$this->_apiContext = PayPal::ApiContext(
config('services.paypal.client_id'),
config('services.paypal.secret'));
$this->_apiContext->setConfig(array(
'mode' => 'sandbox',
'service.EndPoint' => 'https://api.sandbox.paypal.com',
'http.ConnectionTimeOut' => 30,
'log.LogEnabled' => true,
'log.FileName' => storage_path('logs/paypal.log'),
'log.LogLevel' => 'FINE'
));
}
public function getCheckout()
{
$payer = PayPal::Payer();
$payer->setPaymentMethod('paypal');
$amount = PayPal:: Amount();
$amount->setCurrency('EUR');
$amount->setTotal(500); // This is the simple way,
// you can alternatively describe everything in the order separately;
// Reference the PayPal PHP REST SDK for details.
$transaction = PayPal::Transaction();
$transaction->setAmount($amount);
$transaction->setDescription('Altaro VM Backup');
$redirectUrls = PayPal:: RedirectUrls();
$redirectUrls->setReturnUrl(action('PaypalPaymentController#getDone'));
$redirectUrls->setCancelUrl(action('PaypalPaymentController#getCancel'));
$payment = PayPal::Payment();
$payment->setIntent('sale');
$payment->setPayer($payer);
$payment->setRedirectUrls($redirectUrls);
$payment->setTransactions(array($transaction));
$response = $payment->create($this->_apiContext);
$redirectUrl = $response->links[1]->href;
return Redirect::to( $redirectUrl );
}
public function getDone(Request $request)
{
$id = $request->get('paymentId');
$token = $request->get('token');
$payer_id = $request->get('PayerID');
$payment = PayPal::getById($id, $this->_apiContext);
$paymentExecution = PayPal::PaymentExecution();
$paymentExecution->setPayerId($payer_id);
$executePayment = $payment->execute($paymentExecution, $this->_apiContext);
// Clear the shopping cart, write to database, send notifications, etc.
// Thank the user for the purchase
return "Merci pour votre achat";
}
public function getCancel()
{
// Curse and humiliate the user for cancelling this most sacred payment (yours)
return "Erreur";
}
}
As you can see in the controller i'm trying to call other function of the controller i'm in :
$redirectUrls->setReturnUrl(action('PaypalPaymentController#getDone'));
$redirectUrls->setCancelUrl(action('PaypalPaymentController#getCancel'));
But i have the following error :
InvalidArgumentException in UrlGenerator.php line 602:
Action App\Http\Controllers\PaypalPaymentController#getDone not defined.
I don't understand how it is even possible... I checked multiple times the spelling, everything's correct here.
Any thoughts ?
EDIT:
I also tried this :
$redirectUrls->setReturnUrl(route('paypal.done'));
$redirectUrls->setCancelUrl(route('paypal.cancel'));
with these routes:
Route::get('done', [
'as' => 'paypal.done',
'uses' => 'PaypalPaymentController#getDone'
]);
Route::get('cancel', [
'as' => 'paypal.cancel',
'uses' => 'PaypalPaymentController#getCancel'
]);
It works !
I think you also have to define a route to the methods, otherwise the URL cannot be build and returns an error.
Related
i have a problem in my project. How to create a flash session in class request / validation ? I haven't found a way.
This my Request class code
class UserRequest extends FormRequest {
public function authorize()
{
return TRUE;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
$rules = [
"user_fullname" => "required|alpha_spaces",
"user_email" => "required|email|unique,list_user,user_email",
"user_phone" => "nullable|numeric",
"access_id" => "required|alpha_num_spaces",
"user_password" => "required|min:6|regex:/^.*(?=.{3,})(?=.*[a-zA-Z])(?=.*[0-9]).*$/|confirmed",
"warehouse_id" => "alpha_num_spaces|nullable",
];
if ($this->method() == "POST") {
$rules["province_id"] = "alpha_num_spaces|nullable";
$rules["district_id"] = "alpha_num_spaces|nullable";
$rules["subdistrict_id"] = "alpha_num_spaces|nullable";
$rules["kode_pos"] = "alpha_num_spaces|nullable";
$rules["user_address"] = "alpha_num_spaces|nullable";
}
return $rules;
}
public function messages()
{
return [
"user_password.regex" => "Password wajib terdiri dari huruf & angka!"
];
}
}
This my controller
public function process_user_add(UserRequest $user_request)
{
$user_request->validated();
$request = \request();
$input = (object) \request()->all();
$check = User::add_user_from_owner($input);
if ($check->success) {
return \redirect()->to("administrator/user/" . \encrypt_url($check->id))->with("message", "<script>sweet('success', 'Success!', '$check->message')</script>");
} else {
return \redirect()->back()->with("message", "<script>sweet(\"error\", \"Failed!\", \"$check->message\")</script>")->withInput($request->all());
}
}
How to i check if validation failed, i create a flash message? To my knowledge, class request is auto redirect goback url if validation error
You can use die Validator Facade. Validator::make() After then you can rescieve the fails with the fails() Method. Take a look in the code below:
$rules = array(
"user_fullname" => "required|alpha_spaces",
"user_email" => "required|email|unique,list_user,user_email",
"user_phone" => "nullable|numeric",
"access_id" => "required|alpha_num_spaces",
"user_password" => "required|min:6|regex:/^.*(?=.{3,})(?=.*[a-zA-Z])(?=.*[0-9]).*$/|confirmed",
"warehouse_id" => "alpha_num_spaces|nullable",
);
$validator = Validator::make($request->all(), $rules);
if ($validator->fails())
{
return Redirect::to('/your_url')->withInput()->withErrors($validator);
}
This section from the documentation will point you to the right direction
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
How to call an API from a controller using a helper in laravel without using curl and guzzle because both returing nothing. I have tested in postman the api is working fine but not in laravel.
I need to call several API's from different controllers so what would be a good way to do this? Should i build a helper?
I used curl but it is always giving me a false response.
EDIT:
I am looking for a reliable way to make api calls to various url's without having to rewrite the sending and receiving code for each api I want to use.
Preferably a solution that implements "dry" (don't repeat yourself) principles and would serve as a base for any api specific logic, (parsing the response /translating for a model). That stuff would extend this base.
Update For Laravel 7.x and 8.x. Now we can use inbuilt Http(Guzzle HTTP) client.
docs:: https://laravel.com/docs/8.x/http-client#making-requests
use Illuminate\Support\Facades\Http;
$response = Http::get('https://jsonplaceholder.typicode.com/posts');
$response = Http::post('https://jsonplaceholder.typicode.com/posts', [
'title' => 'foo',
'body' => 'bar',
'userId' => 1
]);
$response = Http::withHeaders([
'Authorization' => 'token'
])->post('http://example.com/users', [
'name' => 'Akash'
]);
$response->body() : string;
$response->json() : array|mixed;
$response->object() : object;
$response->collect() : Illuminate\Support\Collection;
$response->status() : int;
$response->ok() : bool;
$response->successful() : bool;
$response->failed() : bool;
$response->serverError() : bool;
$response->clientError() : bool;
$response->header($header) : string;
$response->headers() : array;
For Laravel < 7 you need to install Guzzle pacakge
docs: https://docs.guzzlephp.org/en/stable/index.html
Installation
composer require guzzlehttp/guzzle
GET
$client = new \GuzzleHttp\Client();
$response = $client->get('https://jsonplaceholder.typicode.com/posts');
return $response;
POST
$client = new \GuzzleHttp\Client();
$body = [
'title' => 'foo',
'body' => 'bar',
'userId' => 1
];
$response = $client->post('https://jsonplaceholder.typicode.com/posts', ['form_params' => $body]);
return $response;
Some Usefull Methods
$response->getStatusCode();
$response->getHeaderLine('content-type');
$response->getBody();
we can also add headers
$header = ['Authorization' => 'token'];
$client = new \GuzzleHttp\Client();
$response = $client->get('example.com', ['headers' => $header]);
Helper For this Method
we can create a common helper for these methods.
Create a Helpers folder in app folder
app\Helpers
then create a file Http.php inside Helpers folder
app\Helpers\Http.php
add this code in Http.php
<?php
namespace App\Helpers;
use GuzzleHttp;
class Http
{
public static function get($url)
{
$client = new GuzzleHttp\Client();
$response = $client->get($url);
return $response;
}
public static function post($url,$body) {
$client = new GuzzleHttp\Client();
$response = $client->post($url, ['form_params' => $body]);
return $response;
}
}
Now in controller you can use this helper.
<?php
namespace App\Http\Controllers;
use Illuminate\Routing\Controller as BaseController;
use App\Helpers\Http;
class Controller extends BaseController
{
/* ------------------------ Using Custom Http Helper ------------------------ */
public function getPosts()
{
$data = Http::get('https://jsonplaceholder.typicode.com/posts');
$posts = json_decode($data->getBody()->getContents());
dd($posts);
}
public function addPost()
{
$data = Http::post('https://jsonplaceholder.typicode.com/posts', [
'title' => 'foo',
'body' => 'bar',
'userId' => 1
]);
$post = json_decode($data->getBody()->getContents());
dd($post);
}
}
Without Helper
In Main controller we can create these functions
<?php
namespace App\Http\Controllers;
use Illuminate\Routing\Controller as BaseController;
class Controller extends BaseController
{
public function get($url)
{
$client = new GuzzleHttp\Client();
$response = $client->get($url);
return $response;
}
public function post($url,$body) {
$client = new GuzzleHttp\Client();
$response = $client->post($url, ['form_params' => $body]);
return $response;
}
}
Now in controllers we can call
<?php
namespace App\Http\Controllers;
class PostController extends Controller
{
public function getPosts()
{
$data = $this->get('https://jsonplaceholder.typicode.com/posts');
$posts = json_decode($data->getBody()->getContents());
dd($posts);
}
public function addPost()
{
$data = $this->post('https://jsonplaceholder.typicode.com/posts', [
'title' => 'foo',
'body' => 'bar',
'userId' => 1
]);
$post = json_decode($data->getBody()->getContents());
dd($post);
}
}
So I have a create function in my controller as shown below and my routes is as such, my question is is there a way for me to put a condition to different create and edit in the same function as both have quite similar coding. Can someone enlighten me pls?
class ManageAccountsController extends Controller
{
public function index() {
$users = User::orderBy('name')->get();
$roles = Role::all();
return view('manage_accounts', compact('users', 'roles'));
}
public function update()
{
// process the form here
// create the validation rules ------------------------
$rules = array(
'name' => 'required', // just a normal required validation
'email' => 'required|email|unique:users', // required and must be unique in the user table
'password' => 'required|min:8|alpha_num',
'password_confirm' => 'required|same:password', // required and has to match the password field
'mobile' => 'required',
'role_id' => 'required'
);
// do the validation ----------------------------------
// validate against the inputs from our form
$validator = Validator::make(Input::all(), $rules);
// check if the validator failed -----------------------
if ($validator->fails()) {
// redirect our user back to the form with the errors from the validator
$input = Input::except('password', 'password_confirm');
$input['autoOpenModal'] = 'true'; //Add the auto open indicator flag as an input.
return redirect()
->back()
->withInput($input)
->withErrors($validator);
} else {
// validation successful ---------------------------
// user has passed all tests!
// let user enter the database
// create the data for our user
$user = new User;
$user->name = Input::get('name');
$user->email = Input::get('email');
$user->password = Hash::make(Input::get('password'));
$user->mobile = Input::get('mobile');
$user->role_id = Input::get('role_id');
// save our user
$user->save();
// redirect ----------------------------------------
// redirect our user back to the form so they can do it all over again
Session::flash('flash_message', 'User successfully added!');
return redirect()->back();
}
}
}
routes.php
Route::get('manage_accounts', 'ManageAccountsController#index');
Route::post('manage_accounts', 'ManageAccountsController#update');
UPDATE OR CREATE
Try the updateOrCreate() in Eloquent to create or update a record matching the attributes.
Read API docs udateOrCreate()
Your code will be like:
Model::updateOrCreate( ['id' => $id], ['firstField' => 'value', 'secondField' => 'value'] );
Note: first parameter is the match to be found and second the data's to be saved.
Hope this is helpful.
Why don't you try moving some of this code out of your controller. If you were to use Repositories, then you would be able to encapsulate some of your logic in order to use it for both functions.
Also you can handle all this validation without writing all the extra code into your controller - see http://laravel.com/docs/5.0/validation#form-request-validation.
This may all seem a bit overkill at first, but once you get the hang of it, your code will be much more manageable and extendable.
(for more on these I would thoroughly recommend Jeffery Way's Laracasts https://laracasts.com/ - this helped me a lot when I was learning Laravel)
// routes.php
// http://laravel.com/docs/5.0/controllers#restful-resource-controllers
Route::resource('manage_accounts', 'ManageAccountsController');
// ManageAccountsController.php
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
class ManageAccountsController extends Controller
{
public $userRepository;
public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
}
public function index() {
$users = User::orderBy('name')->get();
$roles = Role::all();
return view('manage_accounts', compact('users', 'roles'));
}
public function store(StoreUserRequest $request)
{
// validation already handled using this: http://laravel.com/docs/5.0/validation#form-request-validation
$this->userRepository->upsert($request)
Session::flash('flash_message', 'User successfully added!');
return redirect()->back();
}
public function update(StoreUserRequest $request, $id)
{
// validation already handled using this: http://laravel.com/docs/5.0/validation#form-request-validation
$this->userRepository->upsert($request, $id)
Session::flash('flash_message', 'User successfully updated!');
return redirect()->back();
}
}
// UserRepository.php
class UserRepository {
public function upsert($data, $id = null)
{
// You will also need something like this
if(isset($data['id']))
{
$user = $this->user->find($data['id']);
}
else {
$user = new User;
}
$user->name = $data['name'];
$user->email = $data['email'];
$user->password = Hash::make($data['password']);
$user->mobile = $data['mobile'];
$user->role_id = $data['role_id'];
// save our user
$user->save();
return $user;
}
}
}
Please use the code here as a guide (I have written this in a hurry and it will certainly contain errors). Have a quick read up on repositories and I think it should all make sense.
The basic premise here is to separate out code that you want to re-use rather than squashing it all into the same function.
Hope this helps!
For some reason PayPal isn't receiving the total price I'm assigning to the transaction.
I'm using NetShell's PayPal module.
I have my controller that looks like this:
class PayPalController extends Controller {
private $_apiContext;
public function __construct() {
$this->_apiContext = PayPal::ApiContext(
config('services.paypal.client_id'),
config('services.paypal.secret'));
$this->_apiContext->setConfig(array(
'mode' => 'sandbox',
'service.EndPoint' => 'https://api.sandbox.paypal.com',
'http.ConnectionTimeOut' => 30,
'log.LogEnabled' => true,
'log.FileName' => storage_path('logs/paypal.log'),
'log.LogLevel' => 'FINE'
));
}
public function getCheckout() {
$payer = PayPal::Payer();
$payer->setPaymentMethod('paypal');
$amount = PayPal::Amount();
$amount->setCurrency('USD');
$amount->setTotal(42); // This is the simple way,
// you can alternatively describe everything in the order separately;
// Reference the PayPal PHP REST SDK for details.
$transaction = PayPal::Transaction();
$transaction->setAmount($amount);
$transaction->setDescription('What are you selling?');
$redirectUrls = PayPal::RedirectUrls();
$redirectUrls->setReturnUrl(action('PayPalController#getDone'));
$redirectUrls->setCancelUrl(action('PayPalController#getCancel'));
$payment = PayPal::Payment();
$payment->setIntent('sale');
$payment->setPayer($payer);
$payment->setRedirectUrls($redirectUrls);
$payment->setTransactions(array($transaction));
$response = $payment->create($this->_apiContext);
$redirectUrl = $response->links[1]->href;
return Redirect::to( $redirectUrl );
}
// Other functions here. Removed for question.
}
getCheckout() gets called at the route `/paypal/checkout'
When I go to /paypal/checkout there is no price.
Have I missed something? Any help would be appreciated.
Thanks!
It could be about the price type.Price must be declared in float.
Try,
floatval($price)
And check this out,I wrote about integrating paypal express to laravel,
Paypal express integration
I have implemented this oauth server http://bshaffer.github.io/oauth2-server-php-docs/
It has a Laravel implementation : http://bshaffer.github.io/oauth2-server-php-docs/cookbook/laravel/
This guide you and gives that code for routes :
App::singleton('oauth2', function() {
$storage = new OAuth2\Storage\Pdo(array('dsn' => 'mysql:dbname=oauth2;host=localhost', 'username' => 'root', 'password' => 'root'));
$server = new OAuth2\Server($storage);
$server->addGrantType(new OAuth2\GrantType\ClientCredentials($storage));
$server->addGrantType(new OAuth2\GrantType\UserCredentials($storage));
return $server;
});
Route::get('private', function()
{
$bridgedRequest = OAuth2\HttpFoundationBridge\Request::createFromRequest(Request::instance());
$bridgedResponse = new OAuth2\HttpFoundationBridge\Response();
// fix for laravel
$bridgedRequest->request = new \Symfony\Component\HttpFoundation\ParameterBag();
$rawHeaders = getallheaders();
if (isset($rawHeaders["Authorization"])) {
$authorizationHeader = $rawHeaders["Authorization"];
$bridgedRequest->headers->add([ 'Authorization' => $authorizationHeader]);
}
if (App::make('oauth2')->verifyResourceRequest($bridgedRequest, $bridgedResponse)) {
$token = App::make('oauth2')->getAccessTokenData($bridgedRequest);
return Response::json(array(
'private' => 'stuff',
'user_id' => $token['user_id'],
'client' => $token['client_id'],
'expires' => $token['expires'],
));
}
else {
return Response::json(array(
'error' => 'Unauthorized'
), $bridgedResponse->getStatusCode());
}
});
It works perfectly well like that. Now I want to transform that check function in the "private" route to a middleware I could apply to each necessary route. I created the middleware using
php artisan make:middleware AuthChecker
Added it to the kernel.php, and pasted the code of the verification function inside of it. And I immediately got an error :
FatalErrorException in AuthChecker.php line 17:
Class 'Oauth2\HttpFoundationBridge\Request' not found
So, I guess I will have to "use" things, but since I'm still a beginner I don't really know what to do...
Thanks ahead for your help !
[EDIT] the content of the middleware currently look like this :
namespace App\Http\Middleware;
use Closure;
class OauthCheck {
public function handle($request, Closure $next)
{
$bridgedRequest = OAuth2\HttpFoundationBridge\Request::createFromRequest($request);
$bridgedResponse = new OAuth2\HttpFoundationBridge\Response();
// fix for laravel
$bridgedRequest->request = new \Symfony\Component\HttpFoundation\ParameterBag();
$rawHeaders = getallheaders();
if (isset($rawHeaders["Authorization"])) {
$authorizationHeader = $rawHeaders["Authorization"];
$bridgedRequest->headers->add([ 'Authorization' => $authorizationHeader]);
}
if (App::make('oauth2')->verifyResourceRequest($bridgedRequest, $bridgedResponse)) {
$token = App::make('oauth2')->getAccessTokenData($bridgedRequest);
return Response::json(array(
'private' => 'stuff',
'user_id' => $token['user_id'],
'client' => $token['client_id'],
'expires' => $token['expires'],
));
return $next($request);
}
else {
return Response::json(array(
'error' => 'Unauthorized'
), $bridgedResponse->getStatusCode());
}
}
}
Thanks again
FatalErrorException in AuthChecker.php line 17:
Class 'Oauth2\HttpFoundationBridge\Request' not found
So you want to use the Request class from Oauth2\HttpFoundationBridge namespace to your OauthCheck class from App\Http\Middleware.
You can do it in either ways:
Import the class
namespace App\Http\Middleware;
use Oauth2\HttpFoundationBridge\Request;
class OauthCheck {
public function handle($request, Closure $next)
{
$bridgedRequest = Request::createFromRequest($request);
....
}
}
Use the class explicitly
namespace App\Http\Middleware;
class OauthCheck {
public function handle($request, Closure $next)
{
$bridgedRequest = \Oauth2\HttpFoundationBridge\Request::createFromRequest($request);
....
}
}
Take note of the backslash before Oauth2\HttpFoundationBridge\Request. If you just say $bridgedRequest = Oauth2\HttpFoundationBridge\Request, then PHP will look for App\Http\Middleware\Oauth2\HttpFoundationBridge\Request.