Handling successful payment processing but database update failure - javascript

I am trying to implement a stripe checkout process in one of my express.js routes. To do this, I have:
Official Node.js Stripe module
Official client-side Stripe module
A json logger I use to log things like javascript errors, incoming requests and responses from external services like stripe, mongodb, etc…
An Order model defined using mongoose - a MongoDB ODM
My steps are as follows:
Client:
Submit order details which include a stripe payment token
Server:
Create an unpaid order and save to database (order.status is created)
Use stripe client to charge user's credit/debit card
Update order and save to database (order.status is accepted or failed depending on response from Stripe)
Question: If payment is successful after step 2 but an error occurs updating the order in step 3 (due to database server error, outage or similar), what are some appropriate ways to handle this failure scenario and potentially recover from it?

With payment systems, you always need a consolidation process (hourly, daily, monthly) based on sane accounting principles that will check that every money flow is matched.
In your case, I suggest that every external async call logs the sent parameters and the received response. If you do not have a response within a certain time, you know that something has gone wrong on the external system (Stripe, in your case) or on the way back from the external system (you mention a database failure on your side)
Basically, for each async "transaction" that you spawn, you know when you start it and have to decide of a reasonable amount of time before it ends. Thus you have an expected_end_ts in the database.
If you have not received an answer after expected_end_ts, you know that something is wrong. Then you could ask for the status to Stripe or another PSP. Hopefully the API will give you a sane answer as to whether the payment went through or not.
Also note that you should add a step between 1. and 2 : re-read the database. You want to make sure that every payment request you make is really in the database, stored exactly as you are going to send it.

Related

How to Capture paypal_fee in Paypal Smart Button/JS SDK (Laravel 8)

I want to retrieve the paypal_fee when paying an order using PayPal smart buttons/ Javascript SDK .
PayPal Smart Payment Button
This is to compute the order net income before saving it in my database. I want to know how to retrieve the value of paypal_fee in every order and store it in a variable.
The JS SDK actions.order.create / actions.order.capture are for very simple use cases. If you are going to do anything automated with the order information after capture, including saving it to a database, create and capture the order from a server.
Use the v2/checkout/orders API and make two routes (url paths) on your server, one for 'Create Order' and one for 'Capture Order'. You could use one of the (recently deprecated) Checkout-*-SDKs for the routes' API calls to PayPal, or your own HTTPS implementation of first getting an access token and then doing the call. Both of these routes should return/output only JSON data (no HTML or text). Inside the 2nd route, when the capture API is successful you should verify the amount was correct and store its resulting payment details in your database (particularly purchase_units[0].payments.captures[0].id, which is the PayPal transaction ID) and perform any necessary business logic (such as reserving product or sending an email) immediately before forwarding return JSON to the frontend caller. In the event of an error forward the JSON details of it as well, since the frontend must handle such cases.
Pair those 2 routes with this frontend approval flow: https://developer.paypal.com/demo/checkout/#/pattern/server . (If you need to send any additional data from the client to the server, such as an items array or selected options, add a body parameter to the fetch with a value that is a JSON string or object)

Making really simple app including front & backend skills (js, node.js, psql, react...)

I'm trying to make a simple todo app in order to understand how frontend and backend are connected. I read some of the websites showing a tutorial for using and connecting rest API, express server, and database, but still, I was not able to get the fake data from a database. Anyway, I wanted to check if my understanding of how they are connected and talk to each other is correct or not. So could you give some advice please?
First of all, I'm planning to use either Javascript & HTML or React for frontend, Express for server, and Postgres for the database. My plan is a user can add & delete his or her task. I have already created a server in my index.js file and created a database using psql command. Now if I type "" it takes me to the page saying "Hello" (I made this endpoint), and I'm failing to seed my data to the database. Here are my questions↓
After I was able to seed my fake data into the database, how should I get the data from the database and send to the frontend? I think in my index.js file, create a new endpoint something like "app.get("/api/todo", (res, req) => ..." and inside of the callback function, I should write something like "select * from [table name]". Also, form the front end, I should probably access certain endpoints using fetch. Is this correct?
Also, how can I store data which is sent from the frontend? For example, if I type my new todo to <input> field and click the add <button>, what is the sequence of events looks like? Adding event listener to button and connect to the server, then create post method in the server and insert data, kind of (?) <= sorry this part it's super unclear for me.
Displaying task on the frontend is also unclear for me. If I use an object like {task: clean up my room, finished: false (or 0 ?)} in the front end, it makes sense but, when I start using the database, I'm confused about how to display items that are not completed yet. In order to display each task, I won't use GET method to get the data from the database, right?
Also, do I need to use knex to solve this type of problem? (or better to have knex and why?)
I think my problem is I kind of know what frontend, server, database for, but not clear how they are connected with each other...
I also drew some diagrams as well, so I hope it helps you to understand my vague questions...
how should I get the data from the database and send to the frontend?
I think in my index.js file, create a new endpoint something like
"app.get("/api/todo", (res, req) => ..." and inside of the callback
function, I should write something like "select * from [table name]".
Typically you use a controller -> service -> repository pattern:
The controller is a thin layer, it's basically the callback method you refer to. It just takes parameters from the request, and forwards the request to the service in the form of a method call (i.e. expose some methods on the service and call those methods). It takes the response from the service layer and returns it to the client. If the service layer throws custom exceptions, you also handle them here, and send an appropriate response to the client (error status code, custom message).
The service takes the request and forwards it to the repository. In this layer, you can perform any custom business logic (by delegating to other isolated services). Also, this layers will take care of throwing custom exceptions, e.g. when an item was not found in the database (throw new NotFoundException)
The repository layer connects to the database. This is where you put the custom db logic (queries like you mention), eg when using a library like https://node-postgres.com/. You don't put any other logic here, the repo is just a connector to the db.
Also, form the front end, I should probably access certain endpoints
using fetch. Is this correct?
Yes.
Also, how can I store data which is sent from the frontend? For
example, if I type my new todo to field and click the add , what is
the sequence of events looks like? Adding event listener to button and
connect to the server, then create post method in the server and
insert data, kind of (?) <= sorry this part it's super unclear for me.
You have a few options:
Form submit
Ajax request, serialize the data in the form manually and send a POST request through ajax. Since you're considering a client library like React, I suggest using this approach.
Displaying task on the frontend is also unclear for me. If I use an
object like {task: clean up my room, finished: false (or 0 ?)} in the
front end, it makes sense but, when I start using the database, I'm
confused about how to display items that are not completed yet. In
order to display each task, I won't use GET method to get the data
from the database, right?
If you want to use REST, it typically implies that you're not using backend MVC / server rendering. As you mentioned React, you're opting for keeping client state and syncing with the server over REST.
What it means is that you keep all state in the frontend (in memory / localstorage) and just sync with the server. Typically what is applied is what is referred to as optimistic rendering; i.e. you just manage state in the frontend as if the server didn't exist; yet when the server fails (you see this in the ajax response), you can show an error in the UI, and rollback state.
Alternatively you can use spinners that wait until the server sync is complete. It makes for less interesting user perceived performance, but is just as valid technical wise.
Also, do I need to use knex to solve this type of problem? (or better
to have knex and why?) I think my problem is I kind of know what
frontend, server, database for, but not clear how they are connected
with each other...
Doesn't really matter what you use. Personally I would go with the stack:
Node Express (REST), but could be Koa, Restify...
React / Redux client side
For the backend repo layer you can use Knex if you want to, I have used node-postgres which worked well for me.
Additional info:
I would encourage you to take a look at the following, if you're doubtful how to write the REST endpoints: https://www.youtube.com/watch?v=PgrP6r-cFUQ
After I was able to seed my fake data into the database, how should I get the data from the database and send to the frontend? I think in my index.js file, create a new endpoint something like "app.get("/api/todo", (res, req) => ..." and inside of the callback function, I should write something like "select * from [table name]". Also, form the front end, I should probably access certain endpoints using fetch. Is this correct?
You are right here, you need to create an endpoint in your server, which will be responsible for getting data from Database. This same endpoint has to be consumed by your Frontend application, in case you are planning to use ReactJS. As soon as your app loads, you need to get the current userID and make a fetch call to the above-created endpoint and fetch the list of todos/any data for that matter pertaining to the concerned user.
Also, how can I store data which is sent from the frontend? For example, if I type my new todo to field and click the add , what is the sequence of events looks like? Adding event listener to button and connect to the server, then create post method in the server and insert data, kind of (?) <= sorry this part it's super unclear for me.
Okay, so far, you have connected your frontend to your backend, started the application, user is present and you have fetched the list of todos, if any available for that particular user.
Now coming to adding new todo the most minimal flow would look something like this,
User types the data in a form and submits the form
There is a form submit handler which will take the form data
Check for validation for the form data
Call the POST endpoint with payload as the form data
This Post endpoint will be responsible for saving the form data to DB
If an existing todo is being modified, then this should be handled using a PATCH request (Updating the state, if task is completed or not)
The next and possibly the last thing would be to delete the task, you can have a DELETE endpoint to remove the todo item from the list of todos
Displaying task on the frontend is also unclear for me. If I use an object like {task: clean up my room, finished: false (or 0 ?)} in the front end, it makes sense but, when I start using the database, I'm confused about how to display items that are not completed yet. In order to display each task, I won't use GET method to get the data from the database, right?
Okay, so as soon as you load the frontend for the first time, you will make a GET call to the server and fetch the list of TODOS. Store this somewhere in the application, probably redux store or just the application local state.
Going by what you have suggested already,
{task: 'some task name', finished: false, id: '123'}
Now anytime there has to be any kind of interaction with any of the TODO item, either PATCH or DELETE, you would use the id for each TODO and call the respective endpoint.
Also, do I need to use knex to solve this type of problem? (or better to have knex and why?) I think my problem is I kind of know what frontend, server, database for, but not clear how they are connected with each other...
In a nutshell or in the most minimal sense, think of Frontend as the presentation layer and backend and DB as the application layer.
the overall game is of sending some kind of request and receiving some response for those sent requests. Frontend is what enables any end-user to create these so-called requests, the backend (server & database) is where these requests are processed and response is sent back to the presentational layer for the end user to be notified.
These explanations are very minimal to make sure you get the gist of it. Since this question almost revolves around the entire scope of web development. I would suggest you read a few articles about both these layers and how they connect with each other.
You should also spend some time understanding what is RESTful API. That should be a great help.

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