Setting proration_behavior to none in Stripe - stripe-payments

I am trying to update my subscription in such a way to remove the prorartion behaviour. Here's what I did, (It didn't work and while printing the $subscription_object I didn't see any proration_behavior field despite what it is written in the API documentation of a subscription object)
$subscription_obj = \Stripe\Subscription::retrieve($checkout_session->subscription);
\Stripe\Subscription::update($subscription_obj->id, [
'proration_behavior' => 'none',
]);
I also tried :
$subscription_obj->proration_behavior = 'none';
$subscription_obj->save();

This is only relevant when you are making another change to the subscription, such as upgrading/downgrading the plan, changing the billing cycle anchor or canceling. If you're otherwise not changing the subscription, there is nothing to prorate and this will have no effect.
If you are trying to disable prorations for some other change, you should provide proration_behavior=none with that update request.

Related

How to get default payment method from Stripe invoice?

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")

stripe first time the user pays for a subscription

If this is the first time this specific customer pays for this specific subscription.
I must set the cancel_at field of the subscription based on the chosen plan ID. (I don't want to set it upon the creation of the subscription). To tackle this first time , I have captured the invoice.payment_succeeded event and I did the following:
$invoices = \Stripe\Invoice::all([
"limit" => 3, //no need to get all of the invoices just checking if their number is = 1.
"status" => 'paid',
"customer" => $customer_id,
"subscription" => $subscription_id,
"expand" => ["data.charge"],
]);
if ( count($invoices->data) == 1 ) {
//First time this user pays for this specific subscription;
Can You just tell me if it is right or if I missed anything as I am new to php as well as stripe. should I be doing count($invoices) instead of what i did ?
Your code looks fine, but the only way to tell if it'll work or not is for you to run it and see if it does what you expect it to do. You can use your test mode API keys and the Stripe CLI to test the flow:
stripe trigger customer.subscription.created
This will create a test customer, a plan and a subscription. The latter will immediately create and pay an invoice, so you should get a invoice.payment_succeeded webhook event to test with.

Get Default Payment Source (default card) for Stripe Customer?

I created a POC with a customer/credit card in Stripe and I logged into my dashboard within Stripe and was able to see this customer has a default source (the test credit card I added) associated correctly. It shows this card is the default source.
When I run this .Net code:
var customerService = new CustomerService();
var stripeCustomer = await customerService.GetAsync(customerId);
To get that customer, it returns everything correctly except his source. All of the fields I had hoped I can find it from are empty! I want to know his default payment source so I can show it on the front end with a little icon to indicate it's default.
DefaultSource, DefaultSourceId, and Sources properties are all blank/null.
Is there a way to have Stripe return it, or do I need to do something else? I tried the 'expand' property for the GetAsync method but that threw an error saying the above properties are not expandable (i.e. I can't ask Stripe to expand/return Source).
Any ideas what I can do?
FYI I also tried this:
var paymentMethodService = new PaymentMethodService();
var cards = await paymentMethodService.ListAsync(new PaymentMethodListOptions { Customer = customerId, Type = "card"});
and there doesn't seem to be a property anywhere that says the card is default (although it does correctly return all cards). I believe Stripe documentation states the Customer is the holder of the default source, not the card object. What gives?
Thanks in advance!
It looks like you're using Payment Methods, since your payment method list call has the results you expect, which means the customer likely doesn't have any sources. You can try that again with the properly pluralized expand[]=sources if you do know your Customer has Sources attached.
For Payment Methods, there is no general default for the Customer. For one-time Payment Intents, you must always specify the payment_method from among those attached to the Customer for future payments.
For paying invoices (related to recurring subscriptions, eg), you can set the invoice_settings.default_payment_method for Customer. This only applies to invoices.

How to suppress customer class update

My custom graph will create a new customer. The new customer will not use a default customer class. Each time my method saves the Customer record, the base event CustomerClass_FieldVerifying happens. That event expects a user input, in order to accept & update the billing settings. In my case, always the new customer should accept the billing setting updates. I believe that I can override the base event, and simply step over:
if (BAccount.Ask(Messages.Warning, Messages.CustomerClassChangeWarning, MessageButtons.YesNo) == WebDialogResult.No)
I'm curious if there is a better approach.
You should be able to set the answer in some way following this post:
How to pass value to confirmation popup from custom screen
Sample:
BAccount.Answer = WebDialogResult.Yes;

Clearing the "Group by" drop down on the Application Insights portal

I have a new Windows Application that I am adding Application Insights to. Adding a new chart gives the ability to Group on specific custom properties using a drop down. This drop down has 65 properties that AI must have added at some point. There were not specifically added.
We have a main AppInsights that takes all events. We've also created a AppInsight for development. The list of custom properties in the drop down is different between these two, even though the source code is the same.
It makes me suspect that there is some process that creates the drop down contents based on the incoming data.
The problem here is that the code has changed, and some properties are no longer available. We want to eliminate these values from the drop down, and add the new ones.
I am perfectly happy just deleting the entire list. Is there a way to do this?
The items that are available in the group by are properties that have ever been received by the back end in data you've sent, and aren't editable.
for custom properties/metrics, there's a limit on how many properties the backend will allow before it stops collecting new named custom properties. Conceptually, think of it as the backend storing an array of 200 elements for each telemetry item you sent, and mapping each custom property name to an index, and that mapping lasts forever. (i believe at the current time that limit is 200 each, but we're working on expanding that)
so if developers did things in your dev portal, even sent one item with custom property "foo", then that property will be there forever, and takes up one of those 200 slots. They can't be deleted or cleared at the moment.
Also, the contents of the group by box is also limited to events that have sent less than some threshold of distinct values, too. (I'm not sure on that exact value, but i believe it < 100 distinct values.) So fields like Id fields, or guids, etc, will eventually stop showing up as group by options, because the group by would create N distinct buckets of 1 item.
It seems like this would be something already mentioned in the App Insights UserVoice site, or documented in the azure documentation for group by but i'm not seeing it.
The only real workaround at this time is to create a new application insights resource in azure, and start submitting data to that new resource instead of your old one. And then you have to be proactive about never submitting custom properties that you're never going to use, or mixing case, as "Property1" and "property1" will be distinct properties...
If this is a big issue for you, i'd suggest submitting it to microsoft connect as a bug, or entering a uservoice suggestion above. I'll pass this on as something that really needs to be documented in the group by thing in the azure docs, too.

Resources