Laravel Cashier with 2 prices, one metered - php

I am using Laravel 9 and cashier 14.x
On the billing page, I execute the following:
$checkoutPlan1 = Auth::user()->currentTeam->checkout(getenv('STRIPE_PRODUCT_BASIC'), [
'success_url' => route('dashboard'),
'cancel_url' => route('dashboard'),
'mode' => 'subscription'
]);
I read that with checkout, you can send an array of prices so:
$checkoutPlan1 = Auth::user()->currentTeam->checkout([getenv('STRIPE_PRODUCT_BASIC'),getenv('STRIPE_PRODUCT_ADDON')], [...]);
however, when you do, both should be a normal subscription (if not QTY specified, it sends 1, and if specified must be >0)
at the moment, I add a metered subscription this way, which generates a second subscription, and a second invoice, rather than a new item on same invoice.
$team->newSubscription('default')->meteredPrice(getenv('STRIPE_PRODUCT_API'))->create();;
I tried with only $team->subscription()... but it didn't work, I can't remember why right now.
I am sure there is a way, so I am clearly missing something. Someone have a clue which way to point me?
I might be missing something, but so far, each document or tutorial I found you add it on the create method, but current code using checkout() results in the "qty" issue above
EDIT: I used https://dev.to/cearls/laravel-jetstream-subscription-billing-with-stripe-checkout-and-customer-portal-3hkg to change cashier to use Jetstream teams, and this tutorial was great, just needed one extra step of adding to AppServiceProvider

Related

How to calculate dynamic shipping amount based on address in Magento 2.4

In my shopping card build using Magento2.4.2 , I need a dynamic calculation of shipping amount after going to next step after entering the shipping address. What I need is to make a third party API call to calculate shipping value based on address entered. I begin with the following URL but It gives a static shipping value only. I have attached the screenshot of step1 and step2 which will make some sense of what I need. I want to customise the module given in the link to achieve this. I have referenced many articles but could not find a solution. Someone please help to achieve this. The code I have added in same as in the link here
Step 1 : After entering address
Step 2 : Before finalising payment. Here the shipping should not be 0 it should vary according to the address value
Note: I can manage to do the third party call, leave it for me, What I need is to get is where to hook the Magento to modify the shipping value.
There is a good module to handle this kind of things that you may want to take a look at. I think it answer perfectly what you are trying to achieve. Owebia Shipping methods : https://owebia.com/doc/en/magento2-module-advanced-shipping
It's allowing you to add a config file that determines all available shipping methods, specify the prices using all the information you want from the cart and much more.

How to add tax to Stripe subscription using Laravel Cashier (4.2)

I'd like to apply tax to the subscription I have just swapped the user to. Here is my attempt:
protected function swapToYearlyPlan(){
$company = Auth::user()->company;
$customer = $company->subscription()->getStripeCustomer();
$company->subscription('Gold Annual Plan')->swap();
// This doesn't seem to work -- no error message or anything.
$company->subscription()->tax_percent = 5;
return 'Upgraded to Gold Annual Plan w/ tax!!';
}
I looked through the Laravel Cashier files and wasn't able to find any code relating to taxes whatsoever in the StripeGateway.php file. My ultimate fear is that it can't be done in this version of Laravel Cashier.
After more research, it looks like 4.2 doesn't seem to support this feature out of the box. You must separately add tax to an invoice as a separate line item.
I found this post helpful.

Custom Shipping Rate

I'm trying to customize my onepage checkout in magento. The process is to place orders to the company. Apparently I have set a custom table rate in magento where in I have 2 choices. First choice is Victoria (Australia), where in depending on item size there is a fixed rate for that, while the rest of Australia has the same rate.
Apparently when I use my onepage checkout, I encounter 2 errors:
1st error is that when I am in guest mode, when I fill up the billing information, after I go to the shipping method, it says that my shipping method is unavailable, even if I had already inputted the correct address.
My second error is that when I am using a customer account, everything works fine for the 1st time, then if I try to place another order, it shows the error.
I'm thinking of two ways right now to solve it:
Since I need to fix the problem right away, could I remove the shipping method altogether and just create my own computation at the review tab and save the shipping fee in the end?
Or I try to fix the problem on how the shipping method works?
I found matrix-rate free plugin for magento online. A great alternative instead of manipulating it in the backend. I tried it and it immediately worked, though you need to check if you have the data you need in your database. Use the same steps as you were in modifying table rates, as there will be a new tab for the matrix-rate plugin in the configuration->shipping methods tab.

Custom Add to Cart

I want to add an item to the cart, but if this item is already in the cart, Magento by default just increases the quantity of this item. I want to add a new row in the database table sales_flat_quote_item where magento saves its cart items. The reason why I want to do this is to show in the cart page the 2 or more items in different rows, for some reason.
I tried to track the flow of magento in saving the cart, but I ended up with this code: Mage::dispatchEvent('sales_quote_product_add_after', array('items' => $items));
I'm trying to find where is this method, but I cant find it. I hope that the solution that I've been searching for is here. Does anyone know where this method is located? Or, if I'm wrong with my assumption, what might be the solution to my problem?
This is the call of magento event which calls other module methods one by one that have registered for listen to that event. So you need to look every config.xml file of every module for sales_quote_product_add_after string under <events> tag. For more about events and observers in magento go to:
http://www.magentocommerce.com/wiki/5_-_modules_and_development/0_-_module_development_in_magento/customizing_magento_using_event-observer_method
Default magento implementation has no observers for this event and it wouldn't lead you to the solution. Check this blog post about the cart flow, especially the part entitled 'Quote Model Adds a New Item or Changes Existing One Qty'

Magento - Single Coupon marked as used when payment pending

I have got a problem with Magento single coupon code that is marked as having been used at the time the customer clicks on the Place Order button. If the Paypal payment fails or the client leaves the page before the order is complete, he won't able to go back and re-order with this coupon which is set to be only used once, and has been marked already been used.
I have found a piece of code that decreases the number of times the coupons has been used by the user and allows him to reuse the coupon. Unfortunately, he gets an error when trying to connect the Paypal page when clicking the place order button. In order to be able to use the coupon another time and access the Paypal page, I have to delete the lines in SQL database in tables salesrule_coupon_usage and salesrule_customer with this customer's ID.
Here is the code I need to change to automatically delete coupon usage information for a customer ID:
public function cancel($observer)
{
$order = $observer->getEvent()->getPayment()->getOrder();
if ($order->canCancel()) {
if ($code = $order->getCouponCode()) {
$coupon = Mage::getModel('salesrule/coupon')->load($code, 'code');
if ($coupon->getTimesUsed() > 0) {
$coupon->setTimesUsed($coupon->getTimesUsed() - 1);
$coupon->save();
}
$rule = Mage::getModel('salesrule/rule')->load($coupon->getRuleId());
error_log("\nrule times used=" . $rule->getTimesUsed(), 3, "var/log/debug.log");
if ($rule->getTimesUsed() > 0) {
$rule->setTimesUsed($rule->getTimesUsed()-1);
$rule->save();
}
if ($customerId = $order->getCustomerId()) {
if ($customerCoupon = Mage::getModel('salesrule/rule_customer')->loadByCustomerRule($customerId, $rule->getId())) {
$couponUsage = new Varien_Object();
Mage::getResourceModel('salesrule/coupon_usage')->loadByCustomerCoupon($couponUsage, $customerId, $coupon->getId());
if ($couponUsage->getTimesUsed() > 0) {
/* I can't find any ##$!#$ interface to do anything but increment a coupon_usage record */
$resource = Mage::getSingleton('core/resource');
$writeConnection = $resource->getConnection('core_write');
$tableName = $resource->getTableName('salesrule_coupon_usage');
$query = "UPDATE {$tableName} SET times_used = times_used-1 "
. "WHERE coupon_id = {$coupon->getId()} AND customer_id = {$customerId} AND times_used > 0";
$writeConnection->query($query);
}
if ($customerCoupon->getTimesUsed() > 0) {
$customerCoupon->setTimesUsed($customerCoupon->getTimesUsed()-1);
$customerCoupon->save();
}
}
}
}
}
}
I believe this was an old bug from around 1.4 to maybe 1.6. But whether you've got an old version or not, this can fairly easily be fixed in place if you know your way around Magento.
The problem is, you have code that is updating the salesrule_coupon_usage table right when they click the pay button. This isn't really what you want at all. You want this to be wrapped into the payment transaction. I don't know if this bug is happening because you have custom code or are using a older version of Magento, but I'll tell you how I would fix the problem. Then I'll give you a fix similar to what you proposed:
Magento already has an abstraction called a "transaction". A transaction is used to put and group of objects together that need to either all succeed or all fail, no half-measures. Magento will go through the transaction and attempt to save each of the objects you have placed in it. If any of them fail (for example, payment doesn't go through), all the events that have been already saved are "rolled back".
Luckily, Magento already creates a transaction object to handle payment for the various things that need to update together on successful payment. You can tap into that transaction and use it to update the coupon usage correctly.
Here is the 10,000 foot view of what you need to do.
Find whatever is updating the salesrule_coupon_usage table too early and kill it. We are going to add in our own transaction-safe version, so we don't want it being saved anywhere else. Easiest way to do this is to figure out what model connects to that table and search for the creation of that model. For 1.7 and 1.8, that is the rule/customer model.
Create an observer to catch the start of a payment transaction. In most modern versions of magento this event is called sales_order_payment_place_start and can be witnessed in app/code/core/Mage/Sales/Model/Order/Payment.php
Pull the order out of the event and pull the coupon code out of the event.
Pull the actual model you want to update. It looks like someone couldn't find it in your code, but there should be some model that uses the salesrule_coupon_usage table hiding somewhere. Search though the .xml files for "salesrule_coupon_usage" and see which model using that table. Again, for me, on 1.7, that is the rule/customer model.
Load that model up, with the customer change the value where your coupon code is concerned to indicate that the customer has used the coupon, but don't save yet.
Get the transaction out of the event and register your updated coupon object with the addObject method.
And your done. The transaction will automatically try to save all of the objects that have been added to it. If any part fails (including a failed payment), it'll rollback the whole process and your coupon won't be used. Yay!
Now, in my opinion, the above is the best way to handle the issue, but if you are having issues for some reason, here is an alternative based on catching an unsuccessful payment and then using your code.
Again, here is the 10,000 foot view:
Create an observer to catch the failed payment event. In most versions the event you want is sales_order_payment_cancel.
Run the code you've got... it should do it. But to clarify for others:
Pull the order out of the event, pull the coupon code and customer id out of that.
Update the customer, rule and salesrule_coupon_usage table. (Although there really should be a model for that, I'm sure you can find it)
Now when a sale fails, you go back through and unwind everything manually. This isn't as clean as my first solution, but might be easier for you depending on your familiarity with Magento.
I'm fairly sure that new, clean versions of Magento don't have this issue, so let me offer a fairly obvious suggestion as a third solution.
Update Magento
If Magento is up to date, test disabling any custom modules, because something broke it. I've noticed that Amasty coupon plugins are particularly buggy.
If you've made custom changes to Magento core... good luck with that.
Good luck!

Categories