Metered billing with Laravel Cashier - laravel-5

I'm using Laravel 5's Cashier, and would like to add additional fees to a user's monthly bill.
Stripe has this functionality available through their API: https://stripe.com/docs/subscriptions#metered-billing-and-one-time-charges
However, it does not look like Cashier is setup to handle this. Any ideas on how this could be added with Cashier?

I ended up creating a custom class to add an invoice item.
class AddStripeInvoiceItem
{
public static function execute($user, $amount)
{
Stripe::setApiKey(xxxxxx);
$invoiceItem = ['customer' => $user->stripe_id,
'currency' => 'USD',
'amount' => $amount,
'description' => '+ '.$amount
];
InvoiceItem::create($invoiceItem);
}
}

Related

Using Payment-Element in Stripe and Laravel

We have everything working in Laravel using Stripes card-element. We want to start using the new payment-element. We are currently using the setup intent.
Following the guide: https://stripe.com/docs/payments/payment-element/migration
Stripe says to add payment methods like so:
$intent = \Stripe\SetupIntent::create([
'customer' => $customer->id,
'payment_method_types' => ['card', 'bancontact', 'ideal'],
]);
In Laravel we currently have it setup like so:
return view('payment.payment')->with([
'services' => $services,
'intent' => $user->createSetupIntent()
]);
How do we pass payment_method_types to the Laravel cashier's createSetupIntent() method?

Laravel avoid duplicate entry from model

I'm building a Laravel API. I have a models called Reservations. I want to avoid that a user creates two reservations for the same product and time period.
I have the following:
$reservation = Reservation::firstOrCreate([
'listing_id' => $request->listing_id,
'user_id_from' => $request->user_id_from,
'start_date' => $request->start_date,
'end_date' => $request->end_date,
]);
Edit after comments:
I'm also using validation
$validator = Validator::make($request->all(), [
'listing_id' => 'required|exists:listings,id',
'user_id_from' => 'required|exists:users,id',
'start_date' => 'required|date_format:"Y-m-d"|after:today',
'end_date' => 'required|date_format:"Y-m-d"|after:start_date'
]);
if ($validator->fails()) {
return response()->json(['error' => 'Validation failed'], 403);
}
Validation is working properly.
End of Edit
In my model I have casted the start_date and end_date as dates.
class Reservation extends Model
{
protected $fillable = ['listing_id', 'start_date', 'end_date'];
protected $dates = [
'start_date',
'end_date'
];
....
....
Documentation says:
The firstOrCreate method will attempt to locate a database record
using the given column / value pairs
However I notice that I'm still able to insert entries with the same attributes.
Any idea what I'm doing wrong or suggestions to fix it?
Probably there's a better way than this, but you can create an static method on Reservation to do this, like:
public static function createWithRules($data) {
$exists = $this->where('product_id', $data['product_id'])->whereBetween(*date logic that i don't remember right now*)->first();
if(!$exists) {
* insert logic *
} else {
* product with date exists *
}
}
So you can call Reservation::createWithRules($data)
You can achieve this using Laravel's built in ValidateRequest class. The most simple use-case for this validation, is to call it directly in your store() method like this:
public function store(){
$this->validate($request, [
'listing_id' => 'required|unique,
'start_date' => 'required|unique,
//... and so on
], $this->messages);
$reservation = Reservation::firstOrCreate([
'listing_id' => $request->listing_id,
'user_id_from' => $request->user_id_from,
'start_date' => $request->start_date,
'end_date' => $request->end_date,
]);
}
With this, you're validating users $request with by saying that specified columns are required and that they need to be unique, in order for validation to pass.
In your controller, you can also create messages function to display error messages, if the condition isn't met.
private $messages = [
'listing_id.required' => 'Listing_id is required',
'title.unique' => 'Listing_id already exists',
//... and so on
];
You can also achieve this by creating a new custom validation class:
php artisan make:request StoreReservation
The generated class will be placed in the app/Http/Requests directory. Now, you can add a few validation rules to the rules method:
public function rules()
{
return [
'listing_id' => 'required|unique,
'start_date' => 'required|unique,
//... and so on
];
}
All you need to do now is type-hint the request on your controller method. The incoming form request is validated before the controller method is called, meaning you do not need to clutter your controller with any validation logic:
public function store(StoreReservation $request)
{
// The incoming request is valid...
// Retrieve the validated input data...
$validated = $request->validated();
}
If you have any additional question about this, feel free to ask. Source: Laravel official documentation.

Laravel Email Verification in custom registeration controller not working

I have made a registration form in my frontend ( Not a laravel default registration form ) . I have used Laravel Email Verification
I have implements MustVerifyEmail in User Model
But In that custom registraion form in my frontend when i hit submit it redirects the page to /admin/home but email is not been sending when i register but If I click on resend email again it sends the email . I want to fix that
Does anyone know how ?
Do I have to implements MustVerifyEmail to that controller too or what ?
IGNORE THAT CITY AND ROOM IN THE FUNCTION !!!!!
class QuickRegisterController extends Controller
{
public function quickList(Request $request)
{
$this->validate($request ,[
'features' => 'required',
'rommies' => 'required',
'price' => 'required',
'avaiability' => 'required',
'utility' => 'required',
'owner_working_email' => 'required',
'address' => 'required',
'exact_address' => 'required',
'owner_of_the_room' => 'required',
]);
$user = User::firstOrCreate([
'name' => $request->owner_of_the_room,
'email' => $request->owner_working_email,
'password' => bcrypt($request->password),
'role_id' => config('quickadmin.default_role_id'),
]);
\Auth::loginUsingId($user->id);
if (\Auth::check()) {
$city = TotalCity::firstOrCreate([
'name' => $request->city,
'created_by_id' => \Auth::user()->id,
]);
if ($city) {
$room = new MyRoom;
$room->location_id = $city->id;
$room->features = $request->features;
$room->rommies = $request->rommies;
$room->price = $request->price;
$room->utility = $request->utility;
$room->avaiability = $request->avaiability;
$room->owner_woring_email = $request->owner_working_email;
$room->address = $request->address;
$room->exact_address = $request->exact_address;
$room->owner_of_the_room = $request->owner_of_the_room;
$room->save();
}
return redirect('/admin/home');
}
else {
return redirect()->back()->with('Form Submission Failed . Try Again Later');
}
}
}
If you look into the RegisterController that Laravel provides with its auth scaffolding, not sure if you are using that or not, it implements the RegistersUsers trait. That trait implements an event that is triggered upon registration. You can use the RegistersUsers trait in your class or create your own custom event.
I'll show you how to use the trait.
At the top of your file:
use Illuminate\Foundation\Auth\RegistersUsers;
Right inside your class:
use RegistersUsers;
For Example:
use Illuminate\Foundation\Auth\RegistersUsers;
class QuickRegisterController extends Controller
{
use RegistersUsers;
// ....
}
You'll need to set up the route as well.
// The register method is coming from the trait
Route::post('/register', 'QuickRegisterController#register');
Also,
You'll want to update your method name to create, the trait calls a create method from the implementor, which is where the user gets created and then the event is triggered, and in that create a method just return the new user, instead of redirecting back.
This might not be all you need to do to get this working, but it will get you started. If you are interested in creating your own event:
https://laravel.com/docs/5.8/events
Or, as #Bipin Regmi pointed out you can just use the event that is being used in the trait
event(new \Illuminate\Auth\Events\Registered($user = $this->create($request->all())));

iDeal not listed in omnipay-rabobank library - [Laravel Framework]

I'm currently using the Omnipay extension library to simply handle my Rabobank omnikassa transactions. Now when i use the code below i get a selection of all credit card methods but IDEAL and MINITIX are not listed on the page. Not sure what i'm doing wrong, first time i'm using an external library to handle my payments. Rabobank Omnikassa should display all available payment methods on default.
The Library:
https://github.com/thephpleague/omnipay-rabobank
My Code: iDealController
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use Omnipay\Omnipay;
class iDealController extends Controller
{
public function loadPage()
{
$sOrderId = 'WEB' . time(); // This should be unique - Order id
$sTransactionReference = $sOrderId . date('His'); // This should be unique - Identifier of transaction
$amount = 10.00;
$gateway = Omnipay::create('Rabobank');
$request = $gateway->purchase(array(
'testMode' => true,
'merchantId' => '002020000000001',
'keyVersion' => '1',
'secretKey' => '002020000000001_KEY1',
'amount' => $amount,
'returnUrl' => 'http://localhost:8888/',
'automaticResponseUrl' => 'http://localhost:8888/',
'currency' => 'EUR',
'transactionReference' => $sTransactionReference,
'orderId' => $sOrderId,
'customerLanguage' => "EN"
)
);
$data = $request->getData();
$response = $request->sendData($data);
if ($response->isSuccessful()) {
// payment was successful: update database
print_r($response);
} elseif ($response->isRedirect()) {
// redirect to offsite payment gateway
$response->redirect();
} else {
// payment failed: display message to customer
echo $response->getMessage();
}
return view('omnikassa');
}
}
When i add: 'PaymentMethod' => 'IDEAL' to the request array it gives the following error: Technical problem : code=03 message=None of the merchant's payment means is compliant with the transaction context. So definitely something is going wrong.

Laravel - Payone

Is there an easy wrapper for the payone(https://www.payone.de/) API for Laravel? I only found one company who sells a package but nothing that is open source. I would appreciate any help.
You should consider Omnipay: http://omnipay.thephpleague.com/
Because:
It is gateway independent.
It is framework independent. It works well with Laravel but also Symfony, Yii, etc.
There is an Omnipay plugin for PayOne: https://github.com/academe/OmniPay-Payone
The code to make a purchase via Omnipay is pretty much the same regardless of the gateway. Here is some sample code that should work, although you should check the details of the Payone classes for other information that you need to send. The Payone gateway can work in multiple different ways depending on how your account is set up.
$gateway = Omnipay::create('Payone_ShopServer');
$card = new CreditCard(array(
'firstName' => 'Example',
'lastName' => 'User',
'number' => '4111111111111111',
// ... etc
));
$transaction = $gateway->purchase(array(
'amount' => '10.00',
'currency' => 'USD',
'description' => 'This is a test purchase transaction.',
'card' => $card,
));
$response = $transaction->send();
if ($response->isSuccessful()) {
echo "Purchase transaction was successful!\n";
}
// At this point you should get $response->getTransactionReference()
// and store that or something similar.

Resources