Communication between node.js app and worker on IronWorker. How to properly poll a task status and receive task response? - node.js

The application is as follows:
First of all, I`m using a node.js app with the express.js framework as web server. On the front-end, when the user sends a payment via a POST form, the express.js routes this task via 'app.post' and calls an external API for payment. This API request should ideally return the URL for which the user should be redirected for payment. Then, the express.js should redirect the user via the 'app.post' response variable (res):
res.redirect(307, url);
Since this payment API request takes some time and since I am using Heroku, the API request times out and an error is returned. To solve this, I know I would need to set a worker on an worker Heroku add-on (according to https://stackoverflow.com/a/11438381/2859410), such as IronWorker. However, I am having trouble to understand what would be the proper mechanism to communicate the URL returned by the external API request made in the worker back to the node.js app.
To make things clearer:
- The user submits the payment form.
- The node.js app processes the POST data and calls a worker ("enqueues" a task on a worker).
- The worker requests an external payment API, which returns an URL.
- The worker should communicate this URL back to the node.js app.
- The node.js app should receive this URL and redirect the user.
Yet, these operations have to be non-blocking.
I can think of 2 alternatives for the communication:
Alternative 1 - When the front-end user requests a payment via POST, the node.js app calls the specific worker (also via POST), with the payment data as the payload. The worker process the data, requests the payment API and gets the payment URL. Meanwhile, the node.js performs a polling of the worker status and, when receives the "completed" status, redirects the user.
Fallacy: The difficulty here for me is to perform constant polling in a asynchronous manner. Since I need to redirect the user to the payment URL, I would need to have the URL inside the "app.post('/form', function(req,res) {" method, such that I can the response ("res") to redirect the user.
For this, I took a look at async.whilst(test, fn, callback), but I don`t know how could I use a test function that is synchronous. My immediate idea would be a test function that issues a status request and a callback function that redirects the user. However, this test function is an asynchronous operation (for example using 'request' module).
Alternative 2 - The worker also receives the payment data as payload, process the data, requests the payment API and gets the payment URL. When it finishes, it communicates the URL back to the node.js app via an HTTP request.
Fallacy: How would I tie the URL communicated back to the node.js app to the user that requested the payment? In my understanding, the HTTP request with the payment URL would have an independent route than the form POST route. In another words, this way I would not be able to have the payment URL inside the "app.post('/orderform', function(req,res) {" method, and, therefore, would not be able to use response variable ("res") to redirect the user.
Tha node.js app would be structured as follows:
app.post('/order', function(req, res) {
// user data on req.body
// process data and request payment API
// Wait until URL is communicated to the endpoint belo '/url'
// receive URL from the other endpoint and redirect user
}
app.post('/url', function(req, res) {
// receive payment URL on req.body
// communicate the URL to the '/order/ endpoint
}
What would be recommended in this case?
Thanks in advance.

I would suggest using a service like pubnub for this (http://www.pubnub.com/) . When you get a request from the user add to the queue to process it and create and return a token to identify this work request. Send that token back to the client. Use that token as the pubnub channel to listen on. When the worker finishes, send a message to that same token to let the client know that the work is done.

I'd suggest to use something in between these two alternatives.
You receive request from user and queue worker to process it.
You start polling some internal storage (e.g. database) for the results of request.
When worker need to store result, it calls back your app (different endpoint) which stores data in the local storage (that place where polling operation looks for it).
When data is available, you'll be able to redirect users.

Related

How to process payment on the backend side using Stripe?

I am new to Stripe and payments in general. I've found few articles on the internet with the examples and guidelines eg. this one. As i noticed the algorithm for creating the payment looks like this:
Client app fetches the publishable Stripe key from the server
Server application creates the checkout session, client app fetches the checkout session id using retrieved publishable key
Client app redirects to checkout
User finishes the payment and being redirect back to client app
Please correct me if i'm wrong. In general i don't understand one thing - how the server application knows that the payment is completed successfully or not? Should i redirect the flow from stripe checkout to backend first, process the result and the from the backend call the frontend again? Or should i somehow use the checkout session to check has it been completed? Shall i use some kind of cron then to process pending checkout sessions? Thanks in advance for any help. Regards
Basically, what you lay out is viable. You can check the Session status when the client is directed back to your server, but you will want to check this status at least one other way, either via a webhook or the cron job you mention.
Should i redirect the flow from stripe checkout to backend first, process the result and the from the backend call the frontend again?
This is possible. Stripe allows you to add the {CHECKOUT_SESSION_ID} template parameter to your Checkout's success URL, when the user is redirected after their checkout, that template will be replaced with the actual Checkout Session ID which you can use to retrieve the Session and its status.
That being said, it is possible for a Customer to make a payment but have their connection cut out before navigating back to your page. So, if you rely on that redirect the customer will be charged but you will never know to fulfill their order. That leads to unhappy customers so Stripe typically recommends setting up a webhook endpoint on your server[2] so that they can send you a checkout.session.completed event to notify you that the customer has finished their Checkout Session. That way, even if a customer never gets to your success page, you will know to fulfill their order.
[1] https://stripe.com/docs/payments/checkout/custom-success-page#modify-success-url
[2] https://stripe.com/docs/payments/checkout/fulfill-orders

Is it possible to receive a Stripe Webhook for a payment event before I can hit my servers controller to finish processing?

In my app, on the client side, I'm calling Stripe's "confirmCardPayment()" to finish the purchase. When the result comes back I take the result, if successful, and then call my server controller to finish the processing (DB entry).
QUESTION - Would it be possible to confirm the payment on the client side with Stripe and then receive the Stripe Webhook on the server side before I have time to post back to the controller to finish the payment processing? Or put another way, is the Webhook sent immediately or does it wait for some time before it's sent to the endpoint?
Stripe does not guarantee delivery of events in the order in which they are generated. You can read about it in more detail here : https://stripe.com/docs/webhooks/best-practices#event-ordering
You would want to always rely on the webhook to update your database or execute business logic as relying on requests triggered from the browser isn't reliable. E.g. Your customer could close the browser after the payment is authorised but before you are able to post to your server to update your database.

How do I Notify the Client when a Payment Systems sends a Request to my API callback URL?

I'm currently building a website with Vue.JS as my static frontend and writing a separate backend API hosted in the cloud using Node and Express.
Currently, I want to integrate payments with a payment provider called Swish. The way this API works is that a payment request is issued from the client with a Callback URL that Swish calls when the payment Errors or is Paid. This URL will be a post request to my API. I want to know how the "Create Payment Request" can asynchronously wait for the post request to be issued by my payment provider so that it returns when Swish (payment provider) is done processing the payment and I can then update the status of the payment in Vue to the user.
I haven't managed to solve this without polling yet. A simple solution would be to have the Post request that Swish visits update some state in my SQL database and have the "Create Payment Request" wake up every 10 seconds or so to check if the database has been changed. Is there a way to do this without polling? Could I somehow emit some event to wake up a sleeping Express endpoint from another Express endpoint? Or could I pass to the callback URL some webhook or something so that the Swish callback can directly notify my Vue frontend when it's called?
For timescales, it takes a maximum of 3 minutes for Swish to call the callback URL.
I think Websockets should work for your problem. As you already said you should persist the state of the payment in your database. When the Swish app calls your callback url you send an websocket request with the new state and needed information. The state is needed when the websocket connection is recreated due errors in the communication.
Some links which may be usefull:
websockets/ws
nathantsoi/vue-native-websocket
sockjs/sockjs-client
stomp-js/stompjs

Edit request in js before sending it to fullfillment endpoint

I need to edit request before sending it to endpoint.
Using Web Demo integration I'm able to send request to the endpoint.
But I can't edit the request in order to provide some extra data to request. Extra data is stored in localStorage so I need to do this in javascript.
I've already connected the agent to an endpoint that handle the request using fullfillment. The problem is that request misses data I can retrieve only from the browser. From fullfillment I can set headers and basic auth but statically and it is not enough.
So I need to add a step in request building/sending:
User write or tell something to embedded chat (Web Demo integration)
Dialogflow recognize intent, params, generate the request.
Additional step: Update the request in javascript
Forward cutomized request to the endpoint
Maybe it's not possible using Web Demo integration. In Documentation can't find a way to just send string or audio in order to receive the generated request.
First of all you will need a custom chat integration, not the default Dialogflow one. Something like Smooch or Kommunicate. The default web demo should only be used for testing your bot. There is NO way you would want to use that in a production environment.
I would save whatever is in the local storage in a database such as Firestore. Once that data is in the database you can use it to modify your request in your fulfillment.
So what I would do:
Have a way to identify a user and save its local storage to the database (as soon as someone clicks on your chat window or opens the chat window)
Once an intent is triggered you check which user is contacting you (through the way that you identified the user) and get all data from the database
Request the data in your fulfillment server
There is no other way in which this is possible. You can't change requests before your query hits Dialogflow.

Right way to implement calling a callback URL in Azure

If I have an API-only app in Azure App Service where users can send a callback URL in the request. The app sends a POST request to the callback URL upon completion.
There are some complexities in implementing calling a callback URL, for example: retries, time between retries, etc.
Is there a service, or set of services, in Azure that can help me implement a callback URL? For example, in AWS the Simple Notification Service (SNS) allows me to send a "push" to a HTTPS endpoint with retries, etc.
Without knowing what sort of context you might need for your callback, you could drop a message in a service bus queue or topic and then write a simple logic app or function which is triggered by the presence of a new message in the queue or topic.
A logic app would provide a solution with no code, only config. A function would require some very basic coding. Logic apps have built in retry features.
Here is an example which somewhat resembles what I think you're after.

Resources