Taking an example of hotel booking system, when a user click on reserve the system holds the room for few minutes, say 20mins, so that the user can fill information and do the payment during that time period. If the user is not able to complete the booking within 20 mins, the system releases the room for new bookings.
How is this timeout implemented and how do we display the timer to the user?
Do we save key-value pair in redis for the reservation with ttl set to 20 mins and then display it to the user in the UI somehow? And when the ttl expires, redis notifies the system which then releases the room? But what if the user is on a third party payments page(stripe/paypal) and redis ttl is reached. If the user makes the payment but we have already released the room by then?
You could store the reservations in one table. Whenever a new reservation is created, an expiration entry is put to a second table or first-in-first-out queue. The expiration entries include the reservation ID. Additionally, they include the expiration time. This could be retrieved from the reservation as well.
The expiration queue is checked once per minute by looking at the eldest entry. All expired reservations are cancelled, unless they carry a confirmed payment. Outdated expiration entries are popped off the queue.
Depending on the volume of reservations, you could simply query the reservation table for reservations which have been created during the last 21..30 minutes without subsequent payment. However, in a no-SQL database, such a query might be too costly to be practical.
The remaining time until expiration can always be determined by looking at the reservation timestamp.
Related
I'm working on e-learning academy system like udemy every instructor have wallets and wallets have three type of balance
1- total balance and it present total earning
2- available balance and it present earning that he can make payout or transfer it to his bank account
3- hold balance and it present earning that is not available for specific time then will be available to transfer it.
Project build by Laravel my issue how can I hold money for 14 days and after that make this money available without any action from my side I need logical idea to make it
can use cron job, or is anyone have this experience before ?
Let me break down the issue as per my understanding so we make sure I'm answering the correct question;
You have a system that has a wallet feature.
This wallet needs to hold some money and make the money unavailable to be paid out (hold status)
Then after 14 days, the money gets paid automatically without any interaction.
If I'm correct, then keep reading the answer below. If i'm not, correct me with a comment and I'll update my answer accordingly.
Answer:
We will create a new table. Let's call it pending_payments. It'll have the following information: user_id, payment_amount, pay_at
That table will hold information about pending payments and to which user they should be paid as well as the amount and the date it should be paid at.
We'll have a Laravel job that can be automated ( read this for more information: https://laravel.com/docs/9.x/scheduling) which will do the following:
a. Run daily on a specific time. Let's say at 13:00 daily for ease.
b. It'll check the pending_payments table for payments that should be paid today.
c. Pay them ( which means run whatever function/task you have to run in order to process the payment).
d. On a successful payment, remove the row from pending_payments table. And on a failure payment, log the error and insert the row again with a later date to be retried again later.
That's it.
i have created a booking system which synchronizes with Google Calendar every 5 minutes and also truncates and old data and fetches new one from calendar, this process takes about 2-3 seconds.
What i want to do is, when the event to fetch data from Google Calendar fires, i want to disable access to the route of the booking system for these 2-3 seconds then enable it again when the event ends, i want to do this because it truncates the old data and fetches new one, so if a person is looking at the booking system this 2-3 seconds all the book schedule times will be free and i don't want this to happen.
Is this kind of thing possible?
Thanks and regards!
Well, my suggestion is to create a new field in your users table something like : is_google_sync_active and route middleware.
Then just before you will start sync. you change that field to true and in your new middleware you may check whether your sync. is active or not, then when your sync. ends you just change the value of field again to false. So, every time when user tries to pass to your sync route he will be passing your middleware which wil handle all job.
In addition, you can redirect user to page which shows status or progress if the sync. is processing.
I don't know how exactly handle this situation. I have a directory where I count the pageviews for each item. For authenticated users I only count as new pageview after a delay of 200 seconds between requests. For unauthenticated users I use the IP and also 200 seconds of delay.
I use a redis SETEX to verify and then the key will expire after 200 seconds. If the key doesn't exist, then insert a new page view.
Something like this
item_id:user_id (authenticated users)
item_id:ip (unauthenticated users)
Well, this works fine until a user try to increment intentionally the page views for a specific item. I have almost 3000 views for a specific item only yesterday (in last year the page has only 150 views...). So, he created some bot to visit the page with a delay to avoid my validation.
I need to register legit pageviews, but I need to avoid the type of fraud. Any idea?
As far as I know, the best way for handling bots is a way like Google Analytics.
Google Analytics works by inserting a JavaScript snippet into the
header of your website. This snippet counts a page view whenever a
visitor triggers that JavaScript, and most bots do not process
JavaScript.
You can integrate some kind of CAPTCHA in your application to limit the number of times a user can view the page within a specific amount of time.
Upon a set number of views within a given duration (say, 20 views in under 3 minutes) from the same user or IP, make them verify the CAPTCHA each subsequent time they try to view the page.
Issue a Token for every page view request. Store the token in the Cookie.
User your already available IP or USER_ID as a filtering mechanism.
After page loaded, User the token, old_token from the cookie, Operating System, Browser Name and IP / User_ID to validate the request.
Give two different timings, like 200 second expiration time and 3600 seconds of grace time, if any of the above data matches within the grace time, don't count the page view.
You can also extend this by keeping track of page views within grace time and create some methods to validate pageview request.
I usually register the Request Time together with the Request to measure the Visit Frequency and the Visiter Count per certain Time Span.
When you register all the Request that come in with with the item_id, user_id, ip and timestamp you can afterwards process the Registers by grouping them by user_id, ip and timestamp.
That way you can find out the amount of Hits per Second and identify and exclude those who clear surpass the normal Activity Pattern without loosing Data.
Often I use the Web Service Logs to generate Statistics about Visit Frequency to certain URLs on a hourly, daily or even monthly basis.
In our app, we create subscriptions for users which is working good, subscription can vary on type of plan. But I am not able to figure out how to cancel subscription after user has fully paid.
Is there any parameter we can tell stripe at the time of creation of subscription that tells it when subscription should cancel OR tell it to cancel it after n number of payments?
So essentially if customer bought a product which costs 1000, we would charge him 100 a month but then automatically cancel subscription once he has fully paid.
Thanks for the help
I answered this here: Stripe cancel subscription at specific date
Stripe just added this to their API and I happened to stumble upon it. They have a field called "cancel_at" that can be set to a date in the future. They don't have this attribute listed in their documentation since it is so new. You can see the value in the response object here:
https://stripe.com/docs/api/subscriptions/create?lang=php
I've tested this using .NET and can confirm it sets the subscription to expire at value you provide.
When you create a subscription in Stripe, there is no way to tell Stripe to stop the subscription after N months or when a given amount in reached.
From the documentation:
By default, a subscription continues, and the customer continues to be
billed, until it’s canceled
So what you could do is to cancel the subscription once a given condition is met.
You could use webhooks to get notified every time the customer is billed, at the end of every billing cycle, using the invoice.payment_succeeded event (documentation here).
Somehow you could keep track of the total amount paid by the customer in your database and the amount that is left before the item you sell is "fully paid".
Everytime you get the webhook, you increment the total and, if the required amount in reached, you cancel the subscription so that the customer will not be billed the next month.
I'm trying to create a recurring payment on Square, ala Stripe subscriptions. However, I am having trouble retrieving a customer's card information (specifically customer_card_id) to pass into Charge.
Our flow is such:
A customer visits to our store and subscribes to a membership, which we process via the point of sale app.
We continuously poll Square to retrieve payment information, and create membership records appropriately.
When the user's membership period expires, charge them for the next month's membership.
When researching RetrieveCustomer, I find that there is a cards property under Customer, but iterating through all the Customers under our account, they all have cards = None despite us having taken card payments via the point of sale app.
Also, looking at ListTransactions, there doesn't seem to be anything that might be customer_card_id. The IDs I see there are tender ID, location ID, and transaction ID. The card_fingerprint also looks promising but that doesn't seem right either, since a card can have both an ID and a fingerprint.
Am I missing something? Where might I find customer_card_id?
EDIT
Looks like I was dumb and my local instance of our application was just out of date with transactions from Square. After updating my data with customers we've processed since the last time I updated, customers with a non-None card property now show up. tristansokol's answer below is still valid however.
How do you process the first charge? You need to explicitly add the card on file, it won't be added by default from processing a transaction from a customer. See: https://squareup.com/help/us/en/article/5770-use-card-on-file-with-the-square-point-of-sale-app