I'm implementing a events booking site. From the shop point of view, the seat must reduce from database only when the seat was actually booked to the customer.
My question is about concurrency. For example, suppose there is a event whose available seat quantity is 1.
If 2 users are trying to purchase the same event seat at the same time, when one of those customers has successfully payed for the seat I want the second customer not to be able to pay for the
seat because the seat is already booked.
Is it possible to make such a reservation so that other customers cannot book?
If your database does not guarantee you such concurrency support (and I am not an expert on those), I would suggest implementing a special internal service for your application which would be responsible for booking seats.
All asynchronous booking requests would be put into a synchronized queue, which would be consumed by the BookingService. Then the result message would be sent to the issuer.
That way, with a single booking entity, there will be no races possible and therefore no double booking.
Related
I am trying to learn how blockchain works. I know that blockchain is nothing but list of blocks containing transactions, what I cannot understand is how do we then know how much money is contained in each account, since we are only maintaining list of transactions?
In distributed platforms, 2 models of accounting for account balances are most commonly used:
a state model, when each of the nodes, after the execution (or reception) of the transaction, accordingly changes the account state record in its local database (Ethereum, Hyperleger Fabric)
model of unspent remainings (UTXO), when the account balance is formed from the sum of the balances of "unused" transactions (Bitcoin, Corda)
I use Stripes' webhooks and want to get notified, if the customer successfully "paid the bill". I came across two webhooks, which in my opinion both could do the job:
Webhook "invoice.paid" - According to Stripe doc: Occurs whenever an invoice payment attempt succeeds or an invoice is marked as paid out-of-band.
Webhook "checkout.session.completed" - According to Stripe doc: Occurs when a Checkout Session has been successfully completed.
My questions are:
I don't understand the second part of the "invoice.paid" webhook: "invoice is marked as paid out-of-band" -> What does "out-of-band" mean? Is this to be considered a successful payment?
Regarding "checkout.session.complete" -> This can also occur, if payment fails - correct?
Which webhooks shall I consider (or are there other webhooks) to see the status "customer paid the bill successfully"?
What is more, I don't really know if disputes should be considered as successful payments or not: On one hand, I get a invoice.paid webhook, on the other hand, I get a charge.dispute.created webhook. geeezus...
I appreciate your help! Thanks.
I don't understand the second part of the "invoice.paid" webhook: "invoice is marked as paid out-of-band" -> What does "out-of-band" mean? Is this to be considered a successful payment?
This is specifically referring to marking an invoice paid out of band (ie, the customer paid you outside of Stripe and you want to mark the Stripe invoice paid without collecting a payment). This will not involve an actual payment, but does transition the invoice to status=paid so this event fires.
Regarding "checkout.session.complete" -> This can also occur, if payment fails - correct?
This event signals only that the Checkout session is complete. Depending on the mode use for Checkout, this may or may not involve a payment. If an immediate payment is expected, the session will only complete if that payment is successful. For example mode=setup or mode=subscription with a free trial will not involve an immediate payment. A subscription with trial, though, will create a $0 invoice and fire invoice.paid.
Which webhooks shall I consider (or are there other webhooks) to see
the status "customer paid the bill successfully"?
This depends on what you mean by "paid" and "bill". If you mean specifically for invoices (whether related to subscriptions or not), then invoice.paid is a good choice. You can then filter for amounts greater than $0 etc to further constrain was "paid" means.
What is more, I don't really know if disputes should be considered as
successful payments or not: On one hand, I get a invoice.paid webhook,
on the other hand, I get a charge.dispute.created webhook.
Disputes are not payments, and should be an entirely separate discussion. You can only have a dispute after a payment. Suggest starting by reading the docs on disputes.
To summarize: What are you really trying to do? These events are related and sometimes overlap, but not always. It highly depends on what you're doing.
What's going on?
When you create a checkout session it will have an id, which you'll store in your database next to the user who started the checkout session.
When you receive an invoice.paid webhook event, it does not have any link back to the checkout session! (so you'll know someone paid, but you won't know who paid!)
checkout.session.completed solves this because it contains the id of the checkout session and the stripe customer id, which allows you to link the two, so you basically have a mapping from your customer ids to stripe's customer ids.
So simply grab the customer id from the checkout.session.completed event and store it in your database next to the relevant user, that way you'll be able to tell which one of your users is paying you when you receive an invoice.paid event!
How can this be implemented?
When a checkout session is started, store the checkout session id next to the user who started the session so you can look it up later
When you see checkout.session.completed, look at the accompanying JSON and take the stripe customer number and store it in your database (e.g. a column like stripe_id in users table). To figure out which of your users it's for, use the checkout session id to look it up in your database (i.e. the data you stored in step 1)
Now that you have the stripe customer id stored in your users table, whenever you see invoice.paid, look at the accompanying JSON, take the stripe customer number, look it up in your users table to find who paid, and update the expiry date of their subscription to 1 month into the future.
That's it!
Also good to know
Both checkout.session.completed and invoice.paid events are triggered when someone new subscribes, and only invoice.paid is triggered each month thereafter (presuming the user had enough funds and didn't cancel)
You can get to the stripe customer number in both webhook events like so (this is ruby, but should be similar with js or python):
payload = request.body.read
data = JSON.parse(payload, symbolize_names: true)
data.object.customer
=> "cus_Lvyv721cJGpYB1"
I have successfully charge the customer payment profile. These transactions can be viewed in the unsettled transaction. I want to ask why these not settled automatically.
Because when a user pay the value through his credit card. I want to show that the amount has been deducted and the client has received the payment. Or i have to suppose that unsettled transaction is also a successful case?
Unsettled transactions are successful transactions. Unsettled just means the transactions have not been sent to the bank for settlement which is what starts the process of capturing those funds. This is to allow you the opportunity to void those transactions if necessary.
Settlement happens nightly so those transactions will show as settled within 24 hours of being processed.
I'am trying to model hotel room booking system in actor pattern. just for information i'am using akka.net for this in .Net.
For now i have created following actors.
1. HotelActorRoomsActor (An Aggregate of RoomActor)
3. BookingsActor (An Aggregate of BookingActor)
4. EmployeesActor (An aggregate of EmployeeActor)
4. UIActor
Currently as i have planned iam creating the system as follows.
1. UIActor Takes the BookingInformation (Checkin, Checkout, No of rooms)
2. Tell the BookingsActor about the information.
3. BookingsActor creates / starts a new BookingActor and passes on the information
4. On BookingActor Start it will
4a. Schedule Rooms for the Booking
4b. Tell the Rooms about the schedule so that they block themselves
4c. Schedule Employee Tasks for the rooms
4d. Tell the selected employees about their tasks
4e. Tell the system that the booking as been created
4f. Tell the BookingsActor to restart the BookingActor at some specific time in
the future (24 hours before actual booking checkin) and shut down.
Problems im facing are
1. How to keep the UIActor in sync of the booking information
2. The UIActor Should also be able to Save information about multiple bookings (For a partiular customer etc) how and where should it be done inside an Actor Pattern?
3. Lets say i want the information about multiple bookings From Date1 to Date2 where should i persist this information to later retrieve it?
ad 1. you can see example of sync dispatcher in akka bootcamp
and example source:
dispatcher = akka.actor.synchronized-dispatcher
#causes ChartingActor to run on the UI thread for WinForms
ad 2. the UI actor should only collect data from user and display results, all other actions need to be pushed down for processing to let say storage actor
ad 3. you need a storage provider - that can be mongoDB or SQL solution. Passing a message to storage actor you can persist reservation data or retrive when needed.
i am about to start work on a group-buying site. it works like this: a phone costs 100USD, but if 50 people buy it together , u get a price of 70USD.
so the website launches this offer, waits for 50 people to deposit money . once the threshold is reached, everyone is sent a coupon and that person can go and get his phone.
the problem.. there will be few offers which will be time-limited. for example, total of 100 mobile phones available only. the first 100 users can only buy it. the offer starts on 5th janissary at 11am.
now, how we can detect any suspicious attempts. like a person writing a script and buying all the 100 units.
i dont think IP based limits is a good enough criteria as REAL BUYERS may access the website using the same IP.
environment is LAMP.
why should you care , the more you sell the more you make money :) if the transaction is made you can enforce that user can't buy with same payment method and credentials twice. And as you said user must deposit money before he can make the purchase. You can ask user credit card data before the sale is opened, that is rather good limit as scammer must use 50 different credit cards