in my Laravel 8 / with stripe/stripe-php": "^7.75" I try to connect and create account on stripe side
and got error :
No API key provided. Set your API key when constructing the StripeClient instance, or provide it on a per-request basis using the `api_key` key in the $opts argument.
with code:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Session;
use Stripe;
use Stripe\StripeClient;
use App\Http\Controllers\Controller;
use Illuminate\Database\DatabaseManager;
use App\Models\Settings;
use Carbon\Carbon;
use Illuminate\Support\Arr;
use App\Models\User;
use App\Models\StripeToken;
class SellerController extends Controller
{
protected StripeClient $stripeClient;
protected DatabaseManager $databaseManager;
public function __construct(StripeClient $stripeClient, DatabaseManager $databaseManager)
{
\Log::info(varDump($stripeClient, ' -1 SellerController ::'));
$this->stripeClient = $stripeClient;
$this->databaseManager = $databaseManager;
}
public function showProfile($id)
{
\Log::info('-1 showProfile $id ::' . print_r($id, true));
$seller = User::find($id);
if (!$seller) {
abort(404);
}
return view('market.seller', [
'seller' => $seller,
'balance' => null
]); // /_wwwroot/lar/tAdsBack/resources/views/admin/stripe/stripe.blade.php
} // public function showProfile($id)
public function redirectToStripe($id)
{
\Log::info('-1 redirectToStripe $id ::' . print_r($id, true));
$seller = User::find($id);
if (!$seller) {
abort(404);
}
$appEnv = strtolower(config('app.env'));
if ($appEnv == 'local' or $appEnv == 'dev') {
\Log::info('-1 config(app.STRIPE_TEST_KEY)::' . print_r(config('app.STRIPE_TEST_KEY'), true));
\Stripe\Stripe::setApiKey(config('app.STRIPE_TEST_KEY')); // LOOKS LIKE THAT IS NOT APPLIED
$this->stripeClient->apiKey = config('app.STRIPE_TEST_KEY'); // THIS DOES NOT HELP
$this->stripeClient->api_key = config('app.STRIPE_TEST_KEY'); // THIS DOES NOT HELP
}
if ($appEnv == 'production') {
\Stripe\Stripe::setApiKey(config('app.STRIPE_LIVE_KEY'));
$this->stripeClient->opts['api_key'] = config('app.STRIPE_LIVE_KEY');
}
if (!$seller->completed_stripe_onboarding) { // Complete onboarding process
$str = \Str::random();
$stripeToken = new StripeToken();
$stripeToken->token = $str;
$stripeToken->seller_id = $id;
$stripeToken->save();
if (empty($seller->stripe_connect_id)) { // if has no stripe account
// // Create a new Stripe Connect Account object.
\Log::info('-1 $$this->stripeClient ::' . print_r($this->stripeClient, true));
Checking log I see :
[2021-03-22 05:40:30] local.INFO: -1 $$this->stripeClient ::Stripe\StripeClient Object
(
[coreServiceFactory:Stripe\StripeClient:private] =>
[config:Stripe\BaseStripeClient:private] => Array
(
[api_key] =>
[client_id] =>
[stripe_account] =>
[stripe_version] =>
[api_base] => https://api.stripe.com
[connect_base] => https://connect.stripe.com
[files_base] => https://files.stripe.com
)
[defaultOpts:Stripe\BaseStripeClient:private] => Stripe\Util\RequestOptions Object
(
[apiKey] =>
[headers] => Array
(
[Stripe-Account] =>
[Stripe-Version] =>
)
[apiBase] =>
)
[api_key] => sk_test_NNNNNN
How to fix this error ?
I suppose I need to set api_key in some other way, not
$this->stripeClient->apiKey = config('app.STRIPE_TEST_KEY'); // THIS DOES NOT HELP
$this->stripeClient->api_key = config('app.STRIPE_TEST_KEY'); // THIS DOES NOT HELP
but how?
Thanks!
Before using stripe/stripe-php directly, check out Laravel Cashier.
https://laravel.com/docs/8.x/billing
Related
After the API platform upgrade, the decorator from the documentation has stopped working:
https://api-platform.com/docs/core/swagger/#overriding-the-swagger-documentation
Does anyone know if this is a change, is it a bug?
I use Symfony 4.2.2 (probably the problem is due to the Symfony update).
My code adding to swagger input form to change context:
<?php
namespace App\Swagger;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
final class SwaggerDecorator implements NormalizerInterface
{
private $decorated;
public function __construct(NormalizerInterface $decorated)
{
$this->decorated = $decorated;
}
public function normalize($object, $format = null, array $context = [])
{
$docs = $this->decorated->normalize($object, $format, $context);
$customDefinition = [
'name' => 'context',
'definition' => 'Context field',
'default' => '',
'in' => 'query',
];
// Add context parameter
foreach ($docs['paths'] as $key => $value) {
// e.g. add a custom parameter
$customDefinition['default'] = lcfirst($docs['paths'][$key]['get']['tags'][0] ?? '');
$docs['paths'][$key]['get']['parameters'][] = $customDefinition;
if(isset($docs['paths'][$key]['post'])){
$docs['paths'][$key]['post']['parameters'][] = $customDefinition;
}
if(isset($docs['paths'][$key]['put'])){
$docs['paths'][$key]['put']['parameters'][] = $customDefinition;
}
}
return $docs;
}
public function supportsNormalization($data, $format = null)
{
return $this->decorated->supportsNormalization($data, $format);
}
}
Try to use parameter "decoration_priority" in services configuration (https://symfony.com/doc/current/service_container/service_decoration.html#decoration-priority)
For example:
App\Swagger\SwaggerDecorator:
decorates: 'api_platform.swagger.normalizer.documentation'
arguments: [ '#App\Swagger\SwaggerDecorator.inner' ]
decoration_priority: 1000
Or fix version "symfony/dependency-injection": "4.2.1" in composer.json )
See https://github.com/symfony/symfony/issues/29836 for details
I want to customize column names, concatinate data in one column. Can put some condition on data.
Below is sample image, In which format data would show. How to make possible this-
Here you can find how to manipulate columns names:
https://laravel-excel.maatwebsite.nl/3.1/exports/mapping.html
And below its a example from my project in how to use it. Enjoy!
namespace App\Exports;
use App\Aluno;
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\WithStrictNullComparison;
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
class AlunosExport implements FromCollection, WithStrictNullComparison, WithHeadings, ShouldAutoSize
{
/**
* #return \Illuminate\Support\Collection
*/
public function collection()
{
$alunos = Aluno::all();
$dadosAluno = [];
foreach ($alunos as $aluno) {
$textoEtapas = '';
foreach ($aluno->etapas as $etapa) {
$textoEtapas .= "{$etapa->nome}";
if ($etapa->concluido) {
$textoEtapas .= ' (Concluído)';
}
$textoEtapas .= "\n";
}
$dadosAluno[] = [
'nome' => $aluno->cliente->nome,
'telefone' => formatarTelefone($aluno->cliente->telefone),
'instituicao' => $aluno->cliente->turma->unidade->instituicao->nome,
'turma' => $aluno->cliente->turma->nome,
'programa' => $aluno->programa->nome,
'etapas' => $textoEtapas,
'valor' => $aluno->valor,
'orientador' => !is_null($aluno->orientador) ? $aluno->orientador->nome : '(Excluído)',
'status' => $aluno->cliente->status
];
}
$alunoColection = collect($dadosAluno);
return $alunoColection;
}
public function headings(): array
{
return [
'Aluno',
'Telefone',
'Instituição',
'Turma',
'Programa',
'Etapas',
'Valor',
'Orientador',
'Status'
];
}
}
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.
On my User.php library in my login function I create admin sessions by
$create_session = array(
'is_logged' => true,
'user_id' => $row->user_id
);
$this->CI->session->set_userdata('admin', $create_session);
The issue is when I try to unset admin session data individually it does not unset the session I select.
Var Dump:
Array
(
[__ci_last_regenerate] => 1449906266
[admin] => Array
(
[is_logged] => 1
[user_id] => 1
)
)
Logout function on library:
Does not Unset: Preferred Way
public function logout() {
$user_data = $this->CI->session->userdata('admin');
unset($user_data['is_logged']);
unset($user_data['user_id']);
}
But when I use this way below it works
public function logout() {
$this->CI->session->unset_userdata('admin');
}
For some reason will not let me unset session data individually from an array in sessions.
Question How am I able to unset codeigniter session data individually that are in my admin session array?
Full User.php library
<?php
class User {
private $user_id;
private $username;
public function __construct() {
$this->CI =& get_instance();
$this->CI->load->library('session');
}
public function login() {
if ($this->validate_password() == true) {
$this->CI->db->select('*');
$this->CI->db->from($this->CI->db->dbprefix . 'user');
$this->CI->db->where('username', $this->CI->input->post('username'));
$query = $this->CI->db->get();
if ($query->num_rows() > 0) {
$row = $query->row();
$create_session = array(
'is_logged' => true,
'user_id' => $row->user_id
);
$this->CI->session->set_userdata('admin', $create_session);
$this->user_id = $row->user_id;
$this->user_group_id = $row->user_group_id;
$this->username = $row->username;
return true;
} else {
return false;
}
}
}
public function is_logged() {
$get_session = $this->CI->session->userdata('admin');
return $get_session['is_logged'];
}
public function logout() {
$user_data = $this->CI->session->userdata('admin');
unset($user_data['is_logged']);
unset($user_data['user_id']);
}
public function validate_password() {
if (password_verify($this->CI->input->post('password'), $this->stored_hash())) {
return true;
} else {
return false;
}
}
public function stored_hash() {
$this->CI->db->where('username', $this->CI->input->post('username'));
$query = $this->CI->db->get($this->CI->db->dbprefix . 'user');
if ($query->num_rows() > 0) {
$row = $query->row();
return $row->password;
} else {
return FALSE;
}
}
}
Note:
I have two lots of sessions one admin for back end and catalog for front end that's why in array.
Using unset() by itself will not remove the values from the CodeIgniter session. You would need to save those changes to the session using $this->CI->session->userdata('admin', $user_data) again.
For example:
<?php
$user_data = $this->CI->session->userdata('admin');
print_r($user_data);
// Shows: Array ( [is_logged] => 1 [user_id] => 123 )
unset($user_data['is_logged']);
unset($user_data['user_id']);
print_r($user_data);
// Shows: Array ( )
// Check what values are saved in the session:
print_r($this->CI->session->userdata('admin'));
// Shows: Array ( [is_logged] => 1 [user_id] => 123 )
// Save your changes to the session
$this->CI->session->set_userdata('admin', $user_data);
// Check what values are saved in the session (now that we've updated the session)
print_r($this->CI->session->userdata('admin'));
// Shows: Array ( )
So, you need to do the following steps to update arrays stored in your session:
Get values from session: $arr = userdata('userdata')
Remove value(s) from array: unset($arr['key'])
Save changes to session: set_userdata('userdata', $arr)
As a workaround, you may be able to edit the $_SESSION directly, bypassing the CodeIgniter's Session library:
unset($_SESSION['admin']['is_logged']);
unset($_SESSION['admin']['user_id']);
I wouldn't advise bypassing the Session library like this, but it might suit your purposes more than the steps I've listed above.
Thanks to #Kirk Beard for advice I have found way to use CodeIgniter session and unset individually data that is in side my admin array();
I create the admin multidimensional array session
$create_session = array(
'is_logged' => true,
'other_item' => 'something'
);
$this->session->set_userdata('admin', $create_session);
Then if you need to unset a single item in the admin array.
unset($this->session->userdata['admin']['is_logged']);
Works for me.
To get multidimensional array session.
echo $this->session->userdata['admin']['is_logged'];
Or
$userdata = $this->session->userdata('admin');
echo $userdata['user_id'];
Generate sessions as $this->CI->session->set_userdata($create_session); instead of $this->CI->session->set_userdata('admin',$create_session);
such as
$create_session = array(
'is_logged' => true,
'user_id' => $row->user_id
);
$this->CI->session->set_userdata($create_session);
Now unset by name even individually
$this->CI->session->unset_userdata('is_logged');
$this->CI->session->unset_userdata('user_id');
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.