I want to store every invoice that a customer pays on a subscription. I wrote a database query to be executed when "invoice.payment_succeeded" event is fired. But what I did by mistake is that I took the latest invoice and stored its status in the Database:
$subscription_id = $response->data->object->subscription;
$subscription_obj = \Stripe\Subscription::retrieve($subscription_id);
$invoice_obj = \Stripe\Invoice::retrieve($subscription_obj->latest_invoice);
$latest_invoice_status = $invoice_obj->status;
Instead of doing :
$invoice_obj = \Stripe\Invoice::retrieve($response->data->object->id);
Is there a problem in what I did or the latets invoice is just identical to the invoice captured in the event ?
In my opinion, this may not give some issue, unless you are allowing users some grace period post invoice not paid. And if this duration is long enough to generate a new invoice, you can get some issue tracking here.
This can be resolved if you keep the track of invoice and payments so late in any case if required you can analyse payments for the invoice.
Related
I am listening to Stripe's invoice.payment_failed webhook with my web app and I would like to get the default_payment_method from each invoice but for some reason it always returns nothing but an empty array!
When I query for a Stripe invoice on the command line and expand on the default_payment_method like this...
Stripe::Invoice.retrieve('in_3K6dIY2KgYRkshw2LAzya63P', :expand => "default_payment_method")
...I also get empty arrays. This surprises me because all my Stripe customers do have a default payment method associated with them.
What am I missing here?
Thanks for any help.
There are three independent places a default payment method can be set. From more specific to less specific they go :
invoice.default_payment_method (which you are looking at)
subscription.default_payment_method
customer.invoice_settings.default_payment_method
Stripe charges the most specific one if it's set. When reading from the API, those values don't inherit from the level above, they can all be set individually, if they are not set explicitly then they are null. So that's why you see it as null on the Invoice level.
Instead you likely want to look at the Subscription object or the Customer object(and can leverage the expand feature for that), depending on how you built your integration and which one it sets.
Overall though, you probably actually want the PaymentMethod used in the invoice payment though? That would be from the last_payment_error.
inv = Stripe::Invoice.retrieve({
id: 'in_1K8iiKJoUivz182DMzSkuBgp',
expand: ["customer.invoice_settings.default_payment_method",
"subscription.default_payment_method",
"payment_intent"]
}
)
print("invoice : #{inv.default_payment_method} \n")
print("subscription : #{inv.subscription.default_payment_method} \n")
print("customer : #{inv.customer.invoice_settings.default_payment_method} \n")
print("failed charge : #{inv.payment_intent.last_payment_error.payment_method} \n")
I am currently developing an appointment calendar with React and NodeJS using the Google Calendar API. The goal is to archive the following:
Step 1: User selects the desired Date in Calendar (done)
Step 2: Show Free 30 Minutes Timeslots in between the opening hours (done)
Step 3: Book Appointment and add to Calendar (done)
But now the problem is, that each timeslot can have 10 individual bookings and I want to show how much is left (e.g 3 People booked the slot at 15:30, I want to show that there are 7 Slots left) Currently if one booked the 15:30 slot it is removed. That is because I use a FreeBusy Query, and this only shows me the busy time not how many events there are.
My first thought was to save the bookings also in a database and then look for every timeslot how many people booked before, but this seems like not the best solution.
Do you have any better ideas on how to solve this problem?
Thanks in advance
Just a suggestion but maybe for each of the event placed on the calendar you could attach an extended property to mark the event as booked.
"extendedProperties": {
"shared": {
"booked": "false",}
}
https://developers.google.com/calendar/v3/reference/events#resource
Then whenever someone books an event, you could mark that event as booked by changing the extended property mentioned. To display the amount of event that are free to book you could filter the list of events by timeMin, timeMax of the selected Timeslot and count the number of events that are marked free or booked.
We are using Stripe as the payment gateway, and we have a yearly plan i.e .billing cycle of the plan is 1 year.
Within the billing cycle, the user can update opt for more seats which will result in increasing the quantity for the subscribed plan.
Subscription subscription = Subscription.retrieve(paymentDetails.getSubscriptionId());
int currentQuentity = subscription.getQuantity();
Map<String, Object> updateParams = new HashMap<String, Object>();
updateParams.put("quantity", (currentQuentity + changeInQuantity));
subscription.update(updateParams);
So for any update stripe refunds(if quantity reduces) and charges(if quantity increases) at the end of billing cycle prorated.
In our business logic, we need immediate payment (charges or refunds) on each quantity update rather then on end of billing cycle. Is there any way in the stripe to achieve so.
I spent a lot of time trying to figure this one out, I hope I can save someone else some time. To take payment for a change of quantity or subscription plan, you need to do the following:
Update subscription with the new changes.
Create an invoice.
The thing that confused me by this is that Stripe magically knows to only invoice for the updated subscription items, and not for upcoming billing cycle items.
Retrieve the newly created invoice
Finalise the invoice
Take payment for the invoice This assumes that your customer has a payment method stored.
Only when all of the steps have been completed, you've successfully charged for the subscription change (and charged for the change only). You can do it all of it in one go. The customer should get an invoice email from Stripe at the end of it.
What makes matters complicated for me, is that reading from the documentation, I got the impression that Stripe will automatically do all of this for me as long as the subscription is set to "billing": "charge_automatically". This is not the case, and in Stripe's defence, they mention it at the bottom of the documentation page related to upgrading and downgrading plans:
If you want the customer to immediately pay the price difference when switching to a more expensive plan on the same billing cycle, you need to generate an invoice after making the switch.
To charge immediately after subscription update, you need to create an invoice just after the subscription update. This will result in an immediate charge
To create invoice you can simply call:
Stripe.apiKey = "sk_test_BQokikJOvBiI2HlWgH4UWQfQ2";
Map<String, Object> invoiceParams = new HashMap<String, Object>();
invoiceParams.put("customer", "cus_D2XUIsncG7YUX");
Invoice.create(invoiceParams);
Ref (https://stripe.com/docs/api#update_subscription):
The accepted answer is the solution if you want to maintain the same billing dates for the subscription.
A simpler solution if you need to push the billing cycle forward to that of the date of the change is to simply set the 'billing_cycle_anchor' to 'now' when updating the subscription. Stripe will immediately charge the user and apply and prorations.
example in python
stripe.Subscription.modify(
subscription_id,
billing_cycle_anchor = 'now',
......
)
You can also set proration_behavior to always_invoice and Stripe will apply both a proration and immediately invoice your customer (source).
Here's an example in curl:
curl https://api.stripe.com/v1/subscriptions/sub_HE... \
-u "sk_test_MI...:" \
-d "items[0][id]=si_Il3Z..." \
-d "items[0][quantity]"=2 \
-d "proration_behavior=always_invoice"
On signing up a user to a subscription, I would like to charge a different rate if the user has credit in my system. However, when the user signs up for the subscription, Stripe is charging them right away instead of waiting for me to mutate the invoice object on the invoice created webhook.
My understanding based on the docs is that charging the user will wait until after invoice create returns with a 200. However, my invoice created webhook is returning 500's so I know this isn't true.
My current code looks like this:
stripe.Subscription.create(
customer=user.stripe_customer_id,
plan=subscription_plan.stripe_product_id,
trial_period_days=trial_period,
idempotency_key=key)
My webhook looks like:
def invoice_created(request, *args, **kwargs):
user = request.user
invoice = request.data['data']['object']
stripe_customer = stripe.Customer.retrieve(user.stripe_customer_id)
if request.user.credit:
stripe_customer.add_invoice_item(
amount=-user.credit,
currency='usd',
description='Applied ${:.2f} of credit for subscription.'.format(user.credit),
invoice=invoice['id'],
)
return Response(status=200)
When I try to update the invoice, it says the invoice can't be modified. The error I'm getting is:
stripe.error.InvalidRequestError: Request "": Invalid invoice: This invoice is no longer editable
What am I supposed to do here?
My understanding based on the docs is that charging the user will wait until after invoice create returns with a 200.
This is not true for the first Invoice of a Subscription, which is always charged immediately.
If you want to add items to that first one, you'll want to create the Invoice Items on the Customer first, before you create the Subscription.
After a new Customer Refund record is saved (After Submit user event) I need to communicate with an external web service and then update 2 fields in the record. When this code is executed to load the Customer Refund
var o = nlapiLoadRecord("customerrefund", 1906);
This error message is returned:
INVALID_TRANS_TYP
Transaction type specified is incorrect.
I found a list of supported records in the "Chapter 60 SuiteScript Supported Records" of SuiteScript Developer & Reference Guide which says the Customer Refund is only available in a server side script.
How should I go about updating the Customer Refund record?
Without seeing more code, it looks ok. I would double check that the internalId of 1906 is correct.
Also, if you're just submitting two fields, I would use nlapiSubmitField(), this will take less governance points and be quicker for NetSuite rather than nlapiLoadRecord / nlapiSubmitRecord.
Your code looks correct, if you are updating the current record I would recommend using below code to avoid incorrect internalid:
var o = nlapiLoadRecord("customerrefund", nlapiGetRecordId());
Also, I would recommend that if you need to update the fields, consider using before submit user event script on customer refund and you can update the fields using nlapiSetFieldValue(FIELD_ID, FIELD_VALUE). No need to submit the record in case of before submit.
If your script is deployed in the customer refund record, you can also do nlapiGetRecordType().