Charging existing card and customer with security code on stripe - stripe-payments

We are using Stripe to process payments on a website we are working on
Whenever a customer signs up we create a customer on Stripe and save the customer_Id in the DB against against the customer.
Also when a customer places an order on the website we give the option to save the card for future uses. So we save the card against the customer as a payment source on stripe.
This is the code we use to create the payment source:
public void CreatePaymentSource(int customerId, string paymentToken)
{
var customer = _customerProvider.GetLoggedInCustomer(customerId);
//returns the customer_id e.g. cux_XXXXXXX from the customers table in our DB
var userStripeId = _customerProvider.GetCustomerStripeId(customerId);
var customerService = new StripeCustomerService();
// paymentToken is the secure token provided by Stripe.js in the card details entry form
var updateOptions = new StripeCustomerUpdateOptions()
{
Email = customer.Email,
SourceToken = paymentToken
};
// update customer to create a payment source
var stripeCustomer = customerService.Update(userStripeId, updateOptions);
}
Now in the documentation it says that if we want to charge an existing card all we have to do is pass the card_id, 'customer_id' and 'amount' - based on this example: https://stripe.com/docs/charges#saving-credit-card-details-for-later
What I want is something like this:
1 - I want to show that a card is saved with last 4 digits
I can do this using the information returned from stripe for a card -
My Question
2 - I want the user to enter the security number every time they want to use the card to place an order. But how do we verify the security number against the card?
EDIT - MY NEW QUESTION
As it has been pointed out in the comment and the other Question that CVC check is not possible with Stripe - So what is the alternative to check if the user is owner of the card?
Note: We are using stripe.net - but answer in any platform or
programming language will be helpful.

Related

Given a Stripe payment intent ID, how can I find the checkout session ID?

For a successful payment, how can I find the related checkout session ID given the payment intent ID?
In that case you would just use the Checkout Session List API and pass in the Payment Intent ID for the payment_intent parameter. That will return an array with the related Checkout Session in it.
Given a Stripe payment intent ID, you can find the checkout session ID like so:
From Stripe CLI
stripe checkout sessions list --payment-intent=pi_abc --limit=1 --expand=data.line_items
Line items
Taking it a step further, this PHP example will return the line items for a given payment intent:
/**
* Returns an array of line items. On each, can access properties `price`,
* `quantity` and more. e.g.:
* - getLinesItemsFromPaymentIntent('pi_3MCJzWBkWO5ojRjq1zBX6gA3')[0]->price->id
* - getLinesItemsFromPaymentIntent('pi_3MCJzWBkWO5ojRjq1zBX6gA3')[0]->quantity
*/
function getLinesItemsFromPaymentIntent($payment_intent_id) {
$stripe = new \Stripe\StripeClient(
getenv('STRIPE_API_SECRET_KEY')
);
// https://stripe.com/docs/api/checkout/sessions/list?lang=cli#list_checkout_sessions-payment_intent
$session = $stripe->checkout->sessions->all([
'limit' => 1,
'payment_intent' => $payment_intent_id,
'expand' => ['data.line_items'],
]);
return $session->data[0]->line_items->data ?? false;
}
Limitations
In passing, note that this will only work with products ordered through a Stripe Payment Link AKA Stripe-hosted payment page AKA checkout sessions in the API.
If/when using your own payment form, you will need to use yet another approach to retrieve line items / what was ordered by your customer 🙄
Ergo, the way to make things more consistent when using multiple types of order forms is to set/read metadata on the Subscription, payment_intent_data or whatever handles your orders.

How to charge a Card that is both Credit and Debt with Stripe

I'm using Stripe to charge the user in a food ordering app, I can save theyr card and charge them just fine.
But I'm facing a problem, I'm from Brazil and here we have cards that can be both Credit and Debit. I can't figure out how to tell the payment method which funding to use.
Here's how I'm creating the payment method:
var options = new PaymentMethodCreateOptions
{
Card = new PaymentMethodCardOptions
{
Number = number,
Cvc = cvc,
ExpMonth = long.Parse(expMonth),
ExpYear = long.Parse(expYear)
},
Type = "card",
};
I'm using 'card' as the type right now, but it seems to default to charging the card as Credit Card.
Looking through the api documentation I can specify the type as:
alipay, au_becs_debit, bacs_debit, bancontact, card, eps, fpx, giropay,
grabpay, ideal, oxxo, p24, sepa_debit, sofort
I can't find a way to tell Stripe to charge the card as a Debit Card.
Is it possible for me to tell stripe which type of funding should be used to process the payment in this situation?
There isn't a way to ask Stripe to charge a card as a "debit" or a "credit" card. There also isn't really a difference in charging either a debit/credit card when you create a Charge, Stripe just charges both cards the same way.

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.

Stripe: Get card information so customer can update their card

My app uses subscriptions with Stripe.
I want to create a standard "account" page, which will list the customer's current card information (like "MasterCard" and last 4 of card number), and give the customer the option of updating that information.
I'm stuck on the first piece--getting back the current card information. To do this, I need the current card_id. I have tried the "listSources" method, but this returns blank data where the card info is supposed to be. What do I need to do to get that card info?
Here is what I've tried:
(I'm using Node, and running this server side)
The closest method I have found is here:
var stripe = require('stripe')(STRIPE_TOKEN);
stripe.customers.listSources(
CUSTOMER_ID,
{object: 'bank_account', limit: 3},
function(err, cards) {
// asynchronously called
}
);
This returns information (there's no error), but the docs say this method should return a data array of the cards that includes the card id for each. In testing, the data array keeps coming back empty.
I am testing with a customer id that has a valid subscription and a card that I can see on my Stripe dashboard.
Why is the data array coming back empty?
Note: there's also a retrieve source method, which should give back card details, but this method requires you have the id of the card you want info on, and that's what I am not able to get right now.
Converting this to an answer...
Stripe has recently rolled out PaymentMethods, which replace (and are separate from) the older Tokens and Sources API.
OP's issue is that their integration creates PaymentMethod objects, which won't show up in the sources list, but can instead be accessed via stripe.paymentMethods.list.

How to get customer billing address in blCheckoutWorkflow in broadleaf?

I would like to the get customer billing address details and would like to log them in an activity class in the blCheckoutWorkflow.
I have tried the following.
Order order=context.getOrder();
Customer c=order.getCustomer();
c.getCustomerPayments().get(0).getBillingAddress();
But here the size of the list returned by getCustomerPayments() is 0. So I am getting ArrayIndexOutOfBoundsException.
Is there a way to get the billing address that is entered by the customer in the /checkout.
Kindly, reply me.
getCustomerPayments() is designed to hold saved payment information for a particular Customer and is not really applicable to the current Order. This is used when a Customer wants to save payment information for checking out next time (the 'token' property on CustomerPaymentImpl is used to look up the PCI-sensitive data from the payment gateway).
If you are using Broadleaf 3.1.0-GA+ then you should do:
Order order = context.getOrder();
Address billingAddress = order.getOrderPayments().get(0).getBillingAddress();
If you are using Broadleaf 3.0.10-GA or below you should do:
Order order = context.getOrder();
Address billingAddress = order.getPaymentInfos().get(0).getAddress();

Resources