Updating and Invoicing Stripe Subscription Quantity with Invoice description laravel cashier - php

Good Day,
I'm working on a project involving Laravel Cashier. I want to give user's the ability to update their subscription quantity and get charged immediately (which I have been able to achieve, using the code below)
$user = Auth::user()
$user->subscription('main')->incrementAndInvoice(10000);
As much as the above works as expected, the invoice returned doesn't include a description indicating the changes instead the invoice description is blank. But when I checked the Event Data on stripe the two descriptions are there [see below image]
The above images shows a user who was currently on a subscription plan with 5000 quantities but increased to 15000 quantities. Is there a way to include these descriptions in the invoice generated.
After i checked the incrementAndInvoice() method , it only accepts two parameter (1. count, 2. Plan) as seen below;
no option to include description like we have for the charge() method. Is there any workaround to this? Any ideas or pointers in the right direction would be really appreciated.
Thanks for your help in advance.

At the time being there is no implementation to include the description in incrementAndInvoice().
So we have to implement it and before we do that please checkout Update an invoice.
First change this line: $user->subscription('main')->incrementAndInvoice(10000); to $subscription = $user->subscription('main')->incrementAndInvoice(10000); (we are assigning it to $subscription variable)
then get the invoice as below:
$new_invoice = $user->invoices()->filter(function($invoice) use ($subscription) {
return $invoice->subscription === $subscription->stripe_id;
});
After updating the subscription quantity we will add the following:
$client = new \GuzzleHttp\Client();
$request = $client->post('https://api.stripe.com/v1/invoices/' . $invoice_id, [
'auth' => [$secret_key, null]
'json' => ['description' => 'your description']
]);
$response = json_decode($request->getBody());
Or the following:
$stripe = new \Stripe\StripeClient(
$secret_key
);
$stripe->invoices->update(
$invoice_id,
['description' => 'your description']
);
Please note that:
the $invoice_id is the id of the invoice.
the $secret_key is the API key.

Related

applying promotion code instead of coupon in laravel/cashier

i am trying to use Promotion code instead of coupon code in laravel cashier/stripe official package but i couldn't find any help in there on how to apply promotion code instead of coupon on subscription as i know how to apply coupon but i want to apply promotion code, how can i do it.
below is my code for applying coupon when creating new subscription but i don't know how can i achieve it using promotion code:
$subscription = $user->newSubscription($plan->name, $selectedPlan);
// Add the trial days if any
if ($plan->trial_days) {
$subscription = $subscription->trialDays($plan->trial_days);
}
// Add the coupon id if any
if ($request->input('coupon_id')) {
$subscription = $subscription->withCoupon($request->input('coupon_id'));
}
$subscription->create($paymentMethod->id, [
'email' => $user->email
]);
You can add promotion code by using the ->withPromotionCode() e.g.
if ($request->input('promotion_code_id')) {
$subscription = $subscription->withPromotionCode($request->input('promotion_code_id'));
}
However, this function requires the promotion code ID instead of the code, and most likely you want your user to key in the code, not the ID. In such case, you can retrieve all active promotion codes and match the code.
if ($request->has('promotion_code')) {
$stripeClient = new \Stripe\StripeClient(config('cashier.secret'));
$result = $this->stripe->promotionCodes->all(
['code' => $request->get("promotion_code"), 'active' => true]
);
if($result->isEmpty()){
// handle invalid promo code here
}
$promoCodeID = $result->first()->id;
$subscription = $subscription->withPromotionCode($promoCodeID);
}

update another collection from a custom hook Directus

Good afternoon colleagues ...
I need to be able to update another collection from a custom hook,
The following happens that if I use ItemsService or TableGatewayFactory it uses the acl of the container ... in this case the user will be from a customer role, but this does not have the permission to edit orders, I would like to keep it that way ...
It doesn't matter if I have to update the item with another user using their token, or any other alternative ...
Thanks in advance....
'item.update.transactionlog' => function ($data) { <br>
$container = Application::getInstance()->getContainer(); <br>
$itemsService = new \Directus\Services\ItemsService($container);<br>
$acl = $container->get('acl');<br>
$params = [];<br>
$orden = ['status' => 'paid'];<br>
$orderUpdate = $itemsService->update('orders', $data['orderid'], $orden, $params);<br>
}

How To Get ID of Order Deleted from Shopify Webhook - Laravel & Shopify

In my tutorial, I realised that I am able to get the number/id of the order during every event except orders/delete. In my controller below, I try to retrieve the order number just as I do for every topic ('orders/create', 'orders/paid')etc, but then I get an error saying:
Undefined index: number in Controller
Controller
public function registerOrderDeleteWebhook()
{
$shop = Auth::user()->site;
$token = Auth::user()->access_token;
$shopify = Shopify::setShopUrl($shop)->setAccessToken($token);
Shopify::setShopUrl($shop)->setAccessToken($token)->post("admin/webhooks.json", ['webhook' =>
['topic' => 'orders/delete',
'address' => 'https://example.domain.com/order-delete-webhook',
'format' => 'json'
]
]);
}
public function orderDeleteWebhook(Request $request)
{
$order = $request->getContent();
$order = json_decode($order, true);
$order_id = $order['number'];
//send notification to Admin with order number deleted below
}
Why could this be happening for only orders/delete?
the undefinded index error
occurs because there is no number field in Shopify Order Delete webhook response. Moreover, it is always a good idea to check if the field exists in the first place.
If you look at the Delete Order response sent by Shopify, it only includes,
{
"id": 777859760246
}
where id is the Order Id. But as the order is deleted you cannot get anymore details later even via API. According to this forum post an order cannot be deleted until it is cancelled first. So a workaround is to listen to Order Cancel hook too and save this information somwehere in your Laravel application ( database etc ) and use it later when Order Delete webhook is recieved.

How to add multiple cards in same customer in stripe payment gateway using php

i was implementing stripe payment in testing mode.Here i got an error like Same token is used again. is there any different way to add multiple cards.
or i need to call retrive function in a separate page so that conflict of same token never come again.And how should i set a card default.
public function createToken($data)
{
$TokenResult=Token::create(array(
"card" => array(
"name" => $data['name'],
"number" => $data['card_number'],
"exp_month" => $data['month'],
"exp_year" => $data['year'],
"cvc" => $data['cvc']
)));
//echo "<pre>";;
//print_r($TokenResult);
$this->token=$TokenResult['id'];//store token id into token variable
$this->chargeCard($this->token); //call chargecard function via passing token id
}
/*
* function to create customer
*/
public function createCustomer($data,$token=null)//pass form data and token id
{
$customer=Customer::create(array(
"email"=>$data['email'],
"description" => $data['name'],
"source" => $token // obtained with Stripe.js
));
$customerId=$customer['id'];
$this->retriveCustomer($customerId,$token);
}
/*
* function to retrive current customers for adding multiple cards to same customers*/
public function retriveCustomer($customerid,$token)
{
echo $this->token;
//die('here');
$retriveResult=Customer::retrieve($customerid);
$retriveResult->sources->create(array("source" =>$this->token));
return $retriveResult;
}
First, please note that unless you are PCI certified and allowed to directly manipulate card data, you should never have access to card numbers in your server-side code.
Card tokens should be created client-side, via Checkout or Elements. Your server should only deal with client-side created card tokens and never with PCI-sensitive information (card numbers and CVCs). This will greatly decrease the burden of PCI compliance and make you eligible for PCI SAQ A.
In PHP, this is how you'd add a card to an existing customer object:
$customer = \Stripe\Customer::retrieve("cus_...");
$card = $customer->sources->create(array(
"source" => $token // token created by Checkout or Elements
));
I think you dont need to create a token in case of adding new card. It helps while you update certain card. So the flow of addition will be same as you created for first card.
I dont know which stripe version you are using, I am using bit old:
$card_array = array(
'card' => array(
'number' => $number,
'exp_month' => $exp_month,
'exp_year' => $exp_year,
'cvc' => $cvc,
'name' => $name
)
);
$card_obj = $this->setData("\Stripe\Customer", "retrieve", $customer_id, TRUE);
$card = $card_obj->sources->create($card_array);
Stripe's docs don't explain a lot of the more nuanced procedures so you have to do a lot of testing.
Assuming you have a customer object $cu, with the token you get from checkout or whatever you use:
$card = $cu->sources->create(['source'=>$token]);
will add a card to the customer. It just adds the card to the list; subsequent calls will add cards to the list. Note that it does not check for duplicates, so the same card can be on the list multiple times. It will also not set the new card to the active card. To make a card the default (or active), use
$cu->default_source = $card
$cu->save();
Using the older card interface:
$cu->card = $token;
$cu->save();
The new card will replace the default card. It will NOT make the previously default card inactive; it will delete the current default and make the new card the active default. The card interface is the easiest if you're just allowing 1 card to be attached to a customer at a time.

Getting Last4 Digits of Card using Customer Object - Stripe API with PHP

I want to get the last 4 digits of a customers card using Stripe.
I have already stored the Customer using:
// Get the credit card details submitted by the form
$token = $_POST['stripeToken'];
// Create a Customer
$StripeCustomer = \Stripe\Customer::create(array(
"description" => "$username",
"card" => $token
));
Now I'd like to access and then store the card's last 4 digits. (For context, I want to show users which card they have stored using Stripe for future payments - this is not a subscription service).
I have searched for a solution but a lot of the posts are saving the last4 digits AFTER a charge, and pull the information from the charge like:
$last4 = null;
try {
$charge = Stripe_Charge::create(array(
"amount" => $grandTotal, // amount in cents, again
"currency" => "usd",
"card" => $token,
"description" => "Candy Kingdom Order")
);
$last4 = $charge->card->last4;
I would like to do the same BEFORE the charge , so I want to pull the last 4 from the Customer Object. The Stripe API documentation shows the attribute path for last4 from Customers,
customer->sources->data->last4
However, this does not seem to give me the correct last 4 digits.
$last4 = $StripeCustomer->sources->data->last4;
I think I am misunderstanding how to use attributes in the Stripe API. Could someone point me in the right direction?
$last4 = $StripeCustomer->sources->data[0]->last4;
sources->data is an array so you'd have to select the first card.
Side note: You're using the token twice, once to create the customer, and the second to create the charge, this will result in an error as the token can only be used once. You'd have to charge the customer instead of the token.
For any one else who lands here from search engines, here's a link to the Stripe docs on how to get the last 4 digits of a card saved to the customer https://stripe.com/docs/api/customers/object#customer_object-sources-data-last4
If you use Laravel Cashier, this code will be helpful for you.
$data = User::find(auth()->user()->id);
$payment = $data->defaultPaymentMethod();
$last4 = $payment->last4;
$brand = $payment->brand;
dd($payment);
You can get all information from this object.
This API has changed since this was first answered. For API version 2020-08-27 you need to use the ListPaymentsMethod API on the Customer object.
The path to access via JSON would look like this
$paymentMethods = $stripe->paymentMethods->all([
'customer' => 'cus_123',
'type' => 'card',
]);
$last4 = $paymentMethods->data[0]->card->last4

Categories