Is it possible to get card brand from payment element - stripe-payments

So I am using Stripe-Js Payment elements and need to get the card brand (e.g visa, mastercard)
But it seems that brand is only available on cardElement's onChange. I only get the payment method type when onChange is triggered
paymentElement.on('change', function(event) {
// event.brand
});
Now I know I could get the brand details if I do confirmPayment but I need this brand first before doing a payment due to some business-related logic that needs to be done before placing the payment.
Is there a way to get the card brand of what user entered before doing confirmPayment using Payment Elements?
Thanks a lot

Payment Element does not return card brand in any event of StripeJS. This is only possible in Card Element with onChange event as you mentioned.
Another possible way in Payment Element is to go with server-side confirmation instead of using client-side confirmation. At step 6 of the doc, make an extra call to PaymentMethod Retrieval API to get card information including card brands from the PaymentMethod ID (pm_xxx) in the response of stripe.updatePaymentIntent. After checking the card brand, then make a PaymentIntent confirmation call at the server.
Please note that sign up is required to use server-side confirmation since it is currently in beta.

Related

How to use stripe checkout for first come, first served buying experience

I'm trying to use Stripe checkout in a first-come, first-served buying process. Multiple buyers may be trying to buy the same item at the same time, and only the one who completes the stripe checkout process first should get it. At the moment, the stripe checkout session duration requires me to 'book' the stock item and only release them back into stock once the session duration expires (even if they close the tab).
Is there a way to set up Stripe Checkout in a way that would detect whether the item has already been purchased by another buyer (e.g. the stock is no longer available), and for example show an error when the user tries to pay?
If not, any suggestions as to alternative ways of implementing this functionality while still using Stripe?
You can listen for checkout.session.completed events and add some event handler logic to retrieve the Session object while expanding the line_items:
https://stripe.com/docs/payments/checkout/fulfill-orders
https://stripe.com/docs/api/expanding_objects
This will allow you to inspect the price and product IDs for the completed Session. You could then have some logic to expire any other Checkout sessions so no other customers are able to go through the payment flow:
https://stripe.com/docs/payments/checkout/managing-limited-inventory
https://stripe.com/docs/api/checkout/sessions/expire
You can use the paymentIntent that allows you to confirm or reject the payment later. You can create the paymentIntent for all the customers are trying at the same time and next take the first one and confirm only this paymentIntent and reject the others
Read the Stripe documentation:
Stripe | PaymentIntent

Can I redirect customer back to my store from Stripe Hosted Invoice page?

I'm generating Invoice object in Stripe and then redirecting customer to the hosted_invoice_url (https://stripe.com/docs/api/invoices/object#invoice_object-hosted_invoice_url)
After customer completes the payment, in the final step they are presented with two buttons - Download Invoice and Download Receipt, but there is no button/link for going back to my store. So it's a dead end. Customer can only close their browser tab.
Is there a way to specify something like success_url or home_url that would add a button for getting the customer back to my store?
Right now as a workaround I'm forcing hosted_invoice_url to open in a new tab. Customer closes the tab after they are finished and they get back to my store in the original tab.
From what I know, this is not possible with hosted invoices pages. I'd recommend relaying this use case/feedback directly to Stripe.
However, if you were to use Stripe Checkout you can pass success_url and cancel_url parameters which will fulfil your requirements in this case. Perhaps Checkout might be a better product for your use case?

How do you permanently delete a payment method from Stripe?

Is it possible to delete a payment method from Stripe? I can't seem to find that functionality described anywhere in the docs. You can create a payment method, attach it to a customer, and detach it from that customer, but how do you delete the payment method from Stripe's system entirely?
If you can't, then that means once you send your credit card info to Stripe, you can't ever take it back...
I think the good way to do so is to detach the paymentMethod from a customer:
const paymentMethod = await stripe.paymentMethods.detach(
'pm_xxx'
);
Api reference
Like #Rasmus Christoffer Nielsen said in comments, "the payment method cannot be attached to any customer again thus serving the purpose of deletion"
you can scan the list:
get the customer lists by type cards:
cards = stripe.Customer.list_payment_methods(customer_id, type="card")
then loop and find the same fingerprint used on the client card to be removed. Remember fingerprint can be retrieved on payment_method;
for card in cards['data']:
card['fingerprint'] == removable_card:
stripe.Customer.delete_source(customer_id, card['id'])
that should be all

How to prevent shopping cart alterations when payments are asynchronous

The steps below illustrate my problem with Stripe's PaymentIntent flow, but you could come up with something similar for the other payment gateways I've looked at where the final notification of a successful payment is sent asynchronously from the payment gateway to the merchant site.
Customer adds 10 x item A to their shopping cart, total now $100
Customer goes to checkout page. Server creates a Stripe PaymentIntent for the $100 total and sends the 'client_secret' to the browser.
Customer's browser displays the checkout page, showing $100 total, and Stripe's payment form.
Customer opens a new tab, and adds 10 x item B to their shopping cart, total now $200.
Customer returns to checkout tab, and completes $100 payment with Stripe (nothing the site can do to prevent this - it's all happening client side)
Asynchronously, Stripe notifies the site via webhooks that we've got a $100 payment. What do we do now?
The payment total no longer matches the cart total. Do we have to refund the payment and cancel the order? How do we notify the customer? We've probably already shown them an 'order complete - thank you' page, because we had no way of knowing the total was wrong until the asynchronous notification arrived. The customer's probably left our site already. What do we do with their shopping cart?
-- Some further background to all this:
I used to always turn to Stripe whenever my clients wanted to take online payments on their websites, because Stripe's synchronous model made my code nice and easy. The customer would enter their card details, Stripe would then return a token representing the payment, finally my server side code would check all the details were correct, use Stripe's API to collect the money, and return a 'thank you' message to the customer's browser.
But now it seems Stripe are moving away from this model to an asynchronous model (PaymentIntents), where your server is supposed to listen for notifications for completed payments, before fulfilling orders. In Stripe's terminology, we should set up 'webhooks' listening for the 'payment_intent.succeeded' event.
All the other payment gateways I've used in the past also have an asynchronous model, in the sense that your webserver has to wait for some kind of callback from the gateway notifying us of the payment, before we can safely start processing the order. PayPal calls it 'Instant Payment Notification', Worldpay called it 'Order Webhooks', Adflex called it 'Server2ServerNotification'... etc.
Where I'm struggling, is trying to cope with things that might happen during the gap between checkout starting, and payment notification being received. Given that these payment gateways are all using these kind of asynchronous models, there must be a simple solution to this (and similar) problems, but I'm really stuck - any suggestions would be much appreciated.
I think the main point you're missing here is that the PaymentIntent amount is set server-side. This means that when your customer opens a new tab and adds more items to their cart, you should be updating the PaymentIntent on your server to reflect the new amount. Then when they switch back to the other tab and complete the payment, you should have the total amount reflected in your PaymentIntent.
Your customer might still see the checkout process for an amount different to what is actually being charged, in which case I suggest you look at implementing websockets to make sure they always see the total amount in their shopping cart.

Security: Passing payment amount to PayPal

From what I understand, using the PayPal api, you can pass your payment amount by populating a hidden HTML input field which will be submitted to PayPal.
What I've got so far looks somewhat like this:
<input type="hidden" name="amount" value="60.00">
My question is - isn't this super unsafe? What's there to stop someone from changing the payment value in the element inspector for instance?
You may want to use PayPal ButtonManager API operation in order to programatically create, manage, edit, and delete PayPal Payment Standard buttons, which are the same kind of buttons that you can create from the PayPal Profile.
Hosted buttons created by this API reside on PayPal and can use all features, including inventory management; however, you can use this API to create code for non-hosted Standard buttons as well.
The button you will create from this API request will look like:
https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=19218
As you can see no values like "business", "amount" or others are visible and for this reason this would be a safe solution and personally I'd recommend it.
Back to your question "What's there to stop someone from changing the payment value in the element inspector for instance?"
We recommend to use API requests (see ExpressCheckout or ButtonManager to create Standard buttons) and Instant Payment Notifications service (IPN), which is a message service that notifies you of events related to PayPal transactions. You can use IPN messages to automate back-office and administrative functions, such as fulfilling orders, tracking customers, and providing status and other transaction-related information.

Resources