What's the difference between stripe default_source and default_payment_method? - stripe-payments

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.

Related

stripe - find out which payment method did customer use

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'],
});

Stripe: Getting Credit Card's Last 4 Digits

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.

Retrieving line items from Braintree Transactions

The Braintree Transaction API has a field for lineItems, but how do I use it? The Transaction response doesn't return line items, and there are no lineitems int the control panel for transactions either.
It looks like the line items aren't actually stored anywhere. Am I right? If so, what's the point of them?
I want to show customers an itemised receipt of the transaction (which is a really obvious use case, right?). Is there anyway to get Braintree to generate this as part of the transaction?
I'm using version 2.5 of the Braintree Node.js SDK.
I'm not sure if this was the case a month ago when you asked the question, but it seems that the transaction response does return line items:
https://developers.braintreepayments.com/reference/response/transaction/node#line_items
UPDATED ANSWER
As of version 2.6.0 of the Braintree Node SDK, lineItems is an attribute of the Transaction response object. See Braintree's associated documentation here.
ORIGINAL ANSWER
You may use gateway.transactionLineItem.findAll(someTransactionId, function(err, response) {}) to retrieve the line items associated with a transaction. This is documented in the tests of the SDK:
specHelper.defaultGateway.transactionLineItem.findAll(response.transaction.id, function (err, response) {
assert.equal(response.length, 1);
let lineItem = response[0];
assert.equal(lineItem.quantity, '1.0232');
assert.equal(lineItem.name, 'Name #1');
assert.equal(lineItem.kind, 'debit');
assert.equal(lineItem.unitAmount, '45.1232');
assert.equal(lineItem.totalAmount, '45.15');
done();
});
We are in the process of updating our developer docs and Control Panel to reflect this behavior.

update customer custom fields from SCA or SSP

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.

Change notification in CouchDB when a field is set

I'm trying to get notifications in a CouchDB change poll as soon as pre-defined field is set or changed. I've already had a look at filters that can be used for filtering change events(db/_changes?filter=myfilter). However, I've not yet found a way to include this temporal information, because you can only get the current version of the document in this filter functions.
Is there any possibility to create such a filter?
If it does not work, I could export my field to a separate database and the only poll for changes in that db, but I'd prefer to keep together my data for obvious reasons.
Thanks in advance!
You are correct: filters and _changes feeds can only see snapshots of a document. What you need is a function which can see the old document and the new document and act correctly. But that is unavailable in _filters and _changes.
Obviously your client code knows if it updates that field. You might update your client code however there is a better solution.
Update functions can access both documents. I suggest you make an _update
function which notices the field change and flags that in the document. Next you
have a simple filter checking for that flag. The best part is, you can use a
rewrite function to make the HTTP API exactly the same as before.
1. Create an update function to flag interesting updates
Your _design/myapp would be {"updates", "smart_updater": "(see below)"}.
Update functions are very flexible (see my recent update handlers
walkthrough). However we only want to mimic the normal HTTP/JSON API.
Your updates.smart_updater field would look like this:
function (doc, req) {
var INTERESTING = 'dollars'; // Set me to the interesting field.
var newDoc = JSON.parse(req.body);
if(newDoc.hasOwnProperty(INTERESTING)) {
// dollars was set (which includes 0, false, null, undefined
// values. You might test for newDoc[INTERESTING] if those
// values should not trigger this code.
if((doc === null) || (doc[INTERESTING] !== newDoc[INTERESTING])) {
// The field changed or created!
newDoc.i_was_changed = true;
}
}
if(!newDoc._id) {
// A UUID generator would be better here.
newDoc._id = req.id || Math.random().toString();
}
// Return the same JSON the vanilla Couch API does.
return [newDoc, {json: {'id': newDoc._id}}];
}
Now you can PUT or POST to /db/_design/myapp/_update/[doc_id] and it will feel
just like the normal API except if you update the dollars field, it will add
an additional flag, i_was_changed. That is how you will find this change
later.
2. Filter for documents with the changed field
This is very straightforward:
function(doc, req) {
return doc.i_was_changed;
}
Now you can query the _changes feed with a ?filter= parameter. (Replication
also supports this filter, so you could pull to your local system all documents
which most recently changed/created the field.
That is the basic idea. The remaining steps will make your life easier if you
already have lots of client code and do not want to change the URLs.
3. Use rewriting to keep the HTTP API the same
This is available in CouchDB 0.11, and the best resource is Jan's blog post,
nice URLs in CouchDB.
Briefly, you want a vhost which sends all traffic to your rewriter (which itself
is a flexible "bouncer" to all design doc functionality based on the URL).
curl -X PUT http://example.com:5984/_config/vhosts/example.com \
-d '"/db/_design/myapp/_rewrite"'
Then you want a rewrites field in your design doc, something like (not
tested)
[
{
"comment": "Updates should go through the update function",
"method": "PUT",
"from": "db/*",
"to" : "db/_design/myapp/_update/*"
},
{
"comment": "Creates should go through the update function",
"method": "POST",
"from": "db/*",
"to" : "db/_design/myapp/_update/*"
},
{
"comment": "Everything else is just like normal",
"from": "*",
"to" : "../../../*"
}
]
(Once again, I got this code from examples and existing code I have laying
around but it's not 100% debugged. However I think it makes the idea very clear.
Also remember this step is optional however the advantage is, you never have to
change your client code.)

Resources