I'm using two different payment methods in my Stripe checkout, 'card' and 'sofort'.
For statistics purposes, I want to find out which payment method did my customer use after payment succeeded.
I had a look at the session I get back after checkout. But I couldn't find any useful information.
Did anyone solved this issue? Thanks
EDIT (Solution in Java):
RequestOptions requestOptions = RequestOptions.builder().setStripeAccount(retrieveKey("CONNECTED_ACCOUNT_ID")).build();
PaymentIntent paymentIntent = PaymentIntent.retrieve(paymentIntentID, requestOptions);
List<Charge> charges = paymentIntent.getCharges().getData();
for (Charge cg : charges) {
paymentMethodType = cg.getPaymentMethodDetails().getType();
}
If you're using Checkout, the returned session object will include the associated payment_intent ID, which can be used with Retrieve a PaymentIntent.
When retrieving the PaymentIntent you can optionally 'expand' the payment_method field, which will return the full pm_ object associated with the payment. This will include all details, including type field.
This will differ depending on your language/integration. Using Node.js:
stripe.paymentIntents.retrieve('pi_XXX', {
expand: ['payment_method'],
});
Related
I'm using the following code to make a card default:
if ($form_state['input']['default'] == TRUE) {
// Set the current card as default.
try {
$stripe->customers->update(
$customer['id'],
['invoice_settings' => ['default_payment_method' => $card['id']]]
);
} catch (\Stripe\Exception\InvalidRequestException $e) {
watchdog('store', $e->getMessage(), array(), WATCHDOG_ERROR);
}
}
because per documentation on https://stripe.com/docs/api/payment_methods/attach and https://stripe.com/docs/api/customers/update#update_customer-invoice_settings-default_payment_method, it's advised to use the default_payment_method parameter.
And it works fine marking properly the $customer['invoice_settings']['default_payment_method'] array value.
However, when I add a new card via Stripe UI, then $customer['default_source'] gets silently marked for it.
So I wonder what's the difference between them and which one is preferable to use? If the default_source is a outdated legacy parameter, then why Stripe's own UI keeps using it?
UPDATE of January 10, 2023: In addition to the accepted answer, here is the update from Stripe support on the subject matter:
invoice_settings.default_payment_method is the recommended parameter to be set for setting up the default payment method of a customer. default_source is the legacy parameter.
in Stripe version 2020-03-02 I was able to retrieve a subscription and its associated credit_card in one go like this:
stripe_subscription = Stripe::Subscription.retrieve({:id => stripe_subscription_id, :expand => [:customer]})
stripe_customer = stripe_subscription.customer
stripe_credit_card = stripe_customer.sources.data.first
In version 2020-08-27 this seems no longer possible since Stripe won't recognise the sources attribute on customer.
So how can I retrieve a subscription and its credit card with one request only?
Since sources on Customer is not included by default, you have to explicitly include it when you expand the related properties. Your code would look like this:
stripe_subscription = Stripe::Subscription.retrieve({
id: stripe_subscription_id,
expand: ['customer.sources'],
})
stripe_customer = stripe_subscription.customer
stripe_credit_card = stripe_customer.sources.data.first
The expand feature is quite powerful and lets you expand multiple separate properties or chain expansion like we did above. I recommend reading the detailed documentation that Stripe shipped.
I have upgraded the Stripe.net to the latest version which is 20.3.0 and now I don't seem to find the .Last4 for the credit card. I had the following method:
public void CreateLocalCustomer(Stripe.Customer stipeCustomer)
{
var newCustomer = new Data.Models.Customer
{
Email = stipeCustomer.Email,
StripeCustomerId = stipeCustomer.Id,
CardLast4 = stipeCustomer.Sources.Data[0].Card.Last4
};
_dbService.Add(newCustomer);
_dbService.Save();
}
But now the stipeCustomer.Sources.Data[0].Card.Last4 says 'IPaymentSource' does not contain a definition for 'Card'. Does anyone know how I can get the card details now? The flow is that I create the customer by passing the Stripe token to Stripe, then I get the above stripeCustomer. So I expect it to be somewhere in that object. But I can't find it. The release notes can be found here.
Thank you.
In the old world of Stripe, there only used to be one type of payment method you could attach to a Customer; specifically, Card-objects. You would create a Card-object by using Stripe.js/v2 or the Create Token API Endpoint to first create a Token-object and then attach that token to a Customer-object with the Create Card API Endpoint.
Once Stripe expanded to support a number of other payment methods though, Stripe built support for a new object type that encapsulated a number of payment methods (including credit cards) called Source-objects. A Source-object is created either by using Stripe.js/v3 or the Create Source API Endpoint. It can also be attached to a Customer-object in much the same way as the Card-objects mentioned above, except they retain their object type. They're still a Source. You use the Attach Source API Endpoint to do this (that is notably identical to the Create Card API Endpoint mentioned above).
What I'm getting at here, is there are now two different object types (or more) that you can expect to see returned in the sources-array (or Sources in .NET). All of these methods though inherit from the IPaymentSource-interface. So if you know you have a Card-object getting returned, you can simply cast the returned object to the Card-class.
Something like this should get you going:
CardLast4 = ((Card) stipeCustomer.Sources.Data[0]).Last4
You can see what I mean by inheritance by looking at this line in the Card-class file:
https://github.com/stripe/stripe-dotnet/blob/master/src/Stripe.net/Entities/Cards/Card.cs#L7
Good luck!
As of Stripe.net.21.4.1, this is what works:
var chargeService = new ChargeService();
var charge = chargeService.Get(id);
CardLast4 = ((Card)charge.Source).Last4;
It's getting hard not to panic when code breaks because of all the micro-changes Stripe makes.
So after debugging, it looks like the Data[0] needs to be cast as Card to get the card.
So it will be CardLast4 = ((Card)stipeCustomer.Sources.Data[0]).Last4.
We're not seeing external ID included in item.update webhook. The documentation says we should be included:
item.update: When an item is updated. Provides parameter "item_id", "item_revision_id" and "external_id".
The parameters we do see (via requestbin) are:
item_id: 12345
hook_id: 9875
type: item.update
item_revision_id: 2
What do we need to do to have external_id included in the webhook event? Or am I misreading the documentation?
Podio documentation is up-to-date and external_id parameter is sent for item.create and item.update hooks. In order to have it sent, item needs to have it :)
So, if you just create item from Podio web, that item won't have any external_id. But if you create item via API and specify external_id then it will be there.
Here is full example in Ruby:
attr = {:fields => { :title => 'Created with external ID'},
:external_id => 'exernal_id_for_demo' }
item = Podio::Item.create(app_id, attr)
Then webhook item.create will be:
item_id: 720040614
item_revision_id: 0
type: item.create
hook_id: 7243151
external_id: exernal_id_for_demo
I don't think Podio provide external_id with the hook data. What you should do is do another call 'Get item revision difference' with item_revision_id as the revision_to_id. This will give you the current revision details. And you can find the external_id and field_id in this response.
Rather than receive the external_id, we can register a hook to be triggered only against a particular field. This way, the URL that's triggered can encode which external_id was involved.
The gotcha is that you can't do this from the management interface, but you can from the API. For example, using HTTPie, if we had a field with an id of 123...
http POST https://api.podio.com/hook/app_field/123/ \
url=http://your.endpont/123
type=item.update
'Authorization: OAuth2 token-here'
...which returns the hook_id, and you'd validate the hook as usual.
Via: https://stackoverflow.com/a/39782472/154248
I'm trying to update a custom entity field during registration in an SCA app.
the published Netsuite docs indicate I should be able to call:
var webStore = session.getSiteSettings(['displayname', 'id']);
customer = session.getCustomer();
customer.updateProfile({
internalid: internalid,
customfields: {
custentity_registered_site: webstore.id
}
});
but this throws the ever helpful UNEXPECTED_ERROR
Has anyone had this working for custom fields? I am doing this just after registration so that may be the issue though I can get a valid customer internalid. Any luck with alternate syntax of some sort?
Eventually was able to get NS support to give me their internal stack trace.
The issue has to do with some internals from the Rhino Javascript engine that NS uses.
Basically the value returned from the NS API was returning a string like value and NS was not following the 2014 recommendation on its use and was failing in the underlying Java code. So the fix was simple but so frustrating:
var webStore = session.getSiteSettings(['displayname', 'id']);
customer = session.getCustomer();
customer.updateProfile({
internalid: internalid,
customfields: {
custentity_registered_site: webstore.id.toString()
}
});
Hope this helps someone.