How To Get Two Separate Nonces with Accept.js? - javascript

I'm using Authorize.Net Accept.js for a custom cart with subscriptions using the ARBCreateSubscriptionRequest API, where we pass it the payment nonce as an opaque data element.
Although this works, it has these 3 faults that occur on ARBCreateSubscriptionRequest (subscriptions) but do not occur on CreateTransactionRequest (single payments):
It does not confirm CVC (card code).
It does not confirm valid card expiration date.
It does not confirm available funds to start the subscription.
Working with Authorize.Net tech support, they confirmed that the proper procedure is to:
Use CreateTransactionRequest to create the initial payment of the subscription, thereby giving an immediate response and getting around the listed problems above.
Then, they said to follow this with a ARBCreateSubscriptionRequest where the start date is the next term of their subscription.
Granted, yes, even without a CreateTransactionRequest, but solely using ARBCreateSubscriptionRequest when the subscription initial payment kicks in 24 hours later, the card will fail and a webhook message can be sent to my cart to let me know to disable whatever I enabled. However, an immediate response would be more suitable and would certainly alleviate potential customer frustration and merchant frustration. Plus, if one is shipping something with the purchase, it is crucial for the merchant to know that the purchase worked.
So, for instance, let's say I charge $9 a month on a subscription. The first payment would be with CreateTransactionRequest for $9 for the current month. Then, create ARBCreateSubscriptionRequest with a delay to start on the first day of the next month, and an interval of every month. So, the customer gets processed (pass/fail) on the initial $9 immediately on purchase. Then, when the next month kicks in, their subscription engages for $9/month thereafter.
Okay, I understand this 100%. But here's where I'm not getting a clear answer in the docs or in a support ticket. The CreateTransactionRequest and the ARBCreateSubscriptionRequest both need their own unique payment nonce.
Key Problem: If Accept.js is used to generate a single nonce, how do I get two nonces? If I use Accept.js to generate the second nonce, does it invalidate the prior one? I'm confused and the documentation doesn't explain.

If you want to validate card information from an Accept.js nonce, process an initial transaction and then create a subscription, you might try the following sequence:
Use createTransactionRequest with the nonce and set createProfile=true. The gateway will process your transaction including validating the card number, expiration and CCV. If successful, a customer profile is created.
Use the customer profile to create your subscription.

Related

Update Stripe credit card that was saved with SetupIntent

I've saved the credit card for later usage with SetupIntent to the customer. Let's say that the user wants to edit his card (expiration/cvc/billing, etc..) after 5 days.
What would be the workflow for it?
Documentation got me confused because they propose to create a new SetupIntent and attach it to the customer. If that's so, what should we do with the previously added card?
For very good privacy reasons, there's very little you can "edit" on a user's payment methods. Stripe allows an almost unlimited number of paymentMethods attached to a customer. The recommended flow (as I also answered on Discord) is to attach the new paymentMethod - you can simply delete the previous one(s). When you query the API for a customer's payment Methods (list), they are returned in reverse chronological order - the first one is the most recent.

How to prevent shopping cart alterations in another tab when paymentintent is already created

Has anyone figured out a solution to this? I seem to have gotten to the same conclusion with no solution.
If I were to go the my app's checkout page, the payintent is created in the backend (explained the process below). So no after the payIntent is created, if i open a new tab and go the menu and add a new menu item, firestore will show the new (correct) total, but since the payment intent is created stripe charges the old (wrong) total.
What I am doing is
Every time the page loads, I send a GET request to my backend which verifies the identity of the user (using firestore/firebase).
Checks if there is a payment intent (payement intents are stored in firestore corresponding to the user)
A. if payintent does not exist under user create one
B. if payintent does exist retrieve payintent from stripe and check if it has .status===succeeded. IF it has succeeded create a new one and if it has not succeeded update the old one. The amount for all payIntents is calculated using total in firestore
(and ofc if the users cart is empty a payintent is not created)
Send back to the frontend the payInent.clienSecret and cart items to populate page
From the front end using stripe elements and confirmPayment confirm the payment
(using ngrok the page loads in about 800-1200ms so not too bad i think)
Possible solutions are using webhooks, when payintent is processing check and update the pricing but that seems like duct taped solution (if it were to even work). OR using webhooks when payment has succeeded update the payment, again seems like a duct tape solution (if it were to even work).
EDIT: possible solution 3 cofirmPayment in the backend but according to documentation that takes away 3ds authentication which is the reason I am doing confirmPayment in the front end anyways
SOLUTION: The missing piece is that you need to update the Payment Intent's amount when something is added to their cart. Once you add that I think that will solve your issue.
So a function to create payment intent and update payment intent (when there is already a payment intent created) on add to cart. And then a final update paymentIntent on the checkout page whenever they delete an item or if they edit the item
Thank you Justin Michael
I'm not sure I completely understand your question. If you confirm a Payment Intent client-side using its client secret the Payment Intent will attempt to charge whatever the current amount set on it is. Stripe will never use a previous or "old" amount.
As far as a solution, I recommend you retrieve the Payment Intent client-side using Stripe.js when your customer clicks on your "pay" button and see if the currently-set amount on the Payment Intent matches what you're currently displaying to them. If it doesn't match abort the payment process, update your state client-side based on the latest version of the Payment Intent you just retrieved, prompt the customer to confirm the new amount, and ask them to click on "pay" again.

Retrieve Stripe charge status from used source token - Node + MongoDB

Let's say my user submits a credit card token to my server to complete a purchase. Then I save this token in my user's cart, and in the sequence, I charge it.
I receive a success response with the charge id and, suddenly, my server stops working just before I can store this charge id in my user's cart.
The charge was definitely made, but I couldn't save it in my database to generate the user's order and make the products available, so I don't know if it succeeded or not.
What I want to do is to mitigate any possibility of duplicate payments. I've looked into the entire Stripe's API but I just couldn't find any information about if it's possible to retrieve a charge using the card token that was used to create it.
Every time when my server reboots, some processes are triggered to verify database integrity (I'm using MongoDB, by the way), and one of those processes tries to make charges for all user carts (with already generated card tokens) that were left in a "waiting payment" state. If a card token wasn't charged yet, everything works well, but if it was charged already, I just don't know if the charge succeeded or not, so I can't update my cart to a consistent state.
I can retrieve the card token by using "stripe.tokens.retrieve(token).then(...", but I just know if it was used or not. I have to find a way to discover if it was charged and if it succeeded.
I've tried to store the card token as a metadata of my charge, so I'd be able to retrieve charges that contain this card token as metadata, but it seems that this kind of query is not possible.
Does anyone know how to overcome this issue or any better logic to grant payment consistency in a MongoDB payment implementation?
As #karllekko commented, this is the answer to my question:
"You can generate and save a unique ID at the beginning of the cart checkout attempt, and use this as an idempotency key when making the charge request : stripe.com/docs/api#idempotent_requests Then if you have a crash, you can safely retry the request, and if you use the same key, it won't create a duplicate charge(you just get the original response back)"
And following my logic, I'm making those failed payments attempts to be executed again without the need of the user to retry it manually, so I'm storing the card-token generated client-side in my user's cart and in the sequence I'm charging this same token and using it as the idempotency key to avoid duplicate payments, as they are unique within Stripe's DB.
This is the request that avoids duplicate payments and always gives me the same response, successful or not, for the same card-token, and makes it possible to grant a consistent state to my user's cart:
stripe.charges.create(
{
amount: amount,
currency: 'usd',
source: token
},
{
idempotency_key: token
}
).then(
res => resolve(res),// Proceed to a success card/order state and allow products/services to be accessed by user. If an attempt of make duplicate payments using the same card-token happens, you'll receive the same success response and will be able to proceed to the same success card/order state.
err => reject({e: err, m: 'PAYMENT_ERROR', i: 'STRIPE_CHARGE_ERROR'})// An error occurred with the original charge request, so you'll have to rollback to the pre-checkout cart state. Even if you couldn't get the original error response, using an idempotency key will give you the exactly same error response in this step when you retry the charge attempt for this same card-token, so you know you have to rollback.
)
Thanks, #karllekko!

Stripe API call is producing multiple subscriptions when using Node.js

I am implementing the stripe api in my node application. The problem i am having is that if i click the submit button very fast multiple times, the api is called multiple times and the stripe customer suddenly has multiple subscriptions and charges.
The scenario is when a user has a stripe customer account without a subscription since they have previously unsubscribed. Now they would like to resubscribe with a new plan since the old one is deleted.
The logic of my code is as follows:
1. Submit form
2. I retrieve the user from my mongo db
3. I retrieve the customer from stripe using a stored customer id (api call)
4. I create a customer subscription (api call)
5. I update the stripe customer object with their credit card (api call)
6. Respond back to user
All of the above is done using async waterfall, each subsequent asynchronous call is in a separate function
What I want:
Between steps 3 and 4 i want to retrieve the customer and check if he or she is already subscribed and prevent 4 and 5 from occurring if the user already has an active subscription.
The Issue:
I am testing the scenario where the user clicks the submit button multiple times and ends up being charged for several subscriptions. I believe that it has to do with how node sends several requests at once due to its asynchronous nature and me wanting to check make an api call to check if something is set takes too long and node doesn't wait when it sends all of the requests.
How do i go about solving this.
Note: Of course i have the front end handling this to prevent user from submitting the form multiple times but this is not ideal and don't want this to be my only line of defense.
Thanks
use a powerful rate limiter library
https://github.com/jhurliman/node-rate-limiter
var RateLimiter = require('limiter').RateLimiter;
// Allow 1 requests per minute
var limiterPayments = new RateLimiter(1, 'minute');
exports.payWithStripe = function(req,res){
limiterPayments.removeTokens(1,function(err,remainingRequests){
if (err){
return res.sendStatus(429);
} else {
// continue with stripe payment
}
}
This will throttle per session (per user browser)
One way is to keep a cache (in Redis or similar) of recent transactions, indexed by a hash derived from key transaction values (e.g. customer id, date, time, amount.)
Before submitting the subscription request to stripe, compare the current transaction to the cache. If you get a hit, you can either show an error, automatically ignore the transaction, or let the user choose whether to proceed.
Disable the button in your frontend using javascript as soon as it's clicked the first time.
Stripe has built in functionality to help you prevent this. https://stripe.com/docs/api/idempotent_requests
You need to generate a unique string and send it along with the stripe request.
Putting it in the HTML in a hidden form, a la your CORS token, then reading it out and putting it in the Stripe call will prevent double click / retries.

payone integration with creditcardcheck

I have read almost everything there is on the Internet (almost no examples) and studied the (very limited and confusing) documentation.
I have a client were I am integrating payone, and I am not getting any further.
So I used the API client documentation and integrated the iframe client api example with creditcardcheck on page 35 (chapter 3.1.5.5). This works fine I receive the answer and a pseudocardpan.
As explained in the quick start guide, I then start the "preauthorization", using the server api with the pseudocardpan. I send all the necessary parameters again, and I end up on the server payone with status = approved .
I assume this is then successfull. However, what or how should I proceed? What is the transactionUrl for? Maybe someone has experience with payone.
sorry to hear you're having a tough time implementing a Payone interface. We are currently working on providing more insightful examples. Please bear with us for a little longer.
Meanwhile, I'll gladly help you with continuing your integration. After the successful preauthorization, you'll need to store the txid for further reference to this transaction. To collect the money from the creditcard, you'll need to send a capture request with the amount you wish to collect and the txid as a reference (see the docs for a full list of required parameters).
If you don't want to send a capture request afterwards (for instance if you want to collect the entire amount immediately after the customer completed their order) you can send an authorization request instead of the preauthorization and leave out the capture part.
The transaction status URL is used to asynchronously inform your application about status changes in Payone transactions. For instance in a prepayment setting we'll send a PAID notification as soon as the customer paid the amount to your bank account.
Best,
Florian (Technical Partner Manager # Payone)
I understand that once the response comes back that it has been approved, then it is approved - all the details were correct and authorisation was successful.
If you are doing a preauthorization then you will need to follow that with a capture to actually take the payment. In some legislative environments, for example many US states, you cannot capture the payment until you finally ship the goods from an online shop.
If that is not a problem (e.g. paying invoices, running an online shop in the UK), then use authorization, which does a preauthorization and capture all in one step. Apart from the name of the request, the details of the message you send is identical.

Categories