I develop an eCommerce app with DDD as a microservice.
I have product service, category service, price service.
First question:
I don't store any info about category or price in product service because they are in their own service.
Should I store default value or etc in the product model?
second question:
When CreateProductRequest comes to product service. It includes category and price data in the request model. After creating a product. I fire productCreatedEvent. It stores created product id, category, price info.
Other services consume that event and save its own database related data. For example, pricing service saves price with product id, price. Category service saves product id and category id.
Should I send all data in one event like productCreatedEvent? Or send separated commands like createProductCategory to category service and createProductPrice to price service via rabbitMQ or grpc call.
First of all, you should think if it makes sense to separate product service from price and category services. I dont know what are the responsibilities of each one, but only makes sense to split them if each one has functionality on its own.
I mean, if it is impossible to have a price or a category without its product, the three would be part of the same microservice. There will be a product service wich contains products each of one with its price and category.
In case that this division makes sense because the price and category service have its own functionality and responsibilities independent from the product, these are the answers in my opinion
The first question should be to create categories and prices in first place and when you need to create a product you will reference the price id and category id and pass it to the producto service.
regarding the second question, You should not send price and category info to the product because these are not info that product service have to know, so the proper way to do, as I said before, is first create the price and category calling its own services and then send the createProduct command with the reference.
But once more, I think the best approach is to merge these three services into one because they seem very related
Related
We have a lot of products in our dashboard; each product has just one price.
Each product's price has a graduated pricing model, so if users buy more units they pay less for each unit.
The only way we found to know how much users have to pay is to create the subscription for a given quantity of products so that the invoice will give us the amount.
Is there a way for extracting the graduated pricing ranges for sending it to the client app? We'd like to avoid creating a subscription to know the final price for the given number of units; also, we'd like to avoid replicating the pricing model's logic on our backend.
I have the follow scenario:
You need to create a Request before it to become a Shop and to get a Owner Account.
So one day you register a Request.
2 days after a manager reviews and approves your Request and it means that the system have to create the Shop and Owner Account.
In my model, I thought that Request, Shop and Owner Account were 3 Aggregate Roots, but then I read that I cannot update more than one aggregate in one transaction because they may be (and in fact they are, because Owner Account is in an external authentication service) in separated db servers.
The thing is.. I still have a Request, and when it gets approved I need to create 2 aggregate roots, the Shop (with all the shop attributes, I only have some invariants with the data, like the limit of contact emails or phones) and the Owner Account.
Then one Owner Account can be allowed to edit someone else's Shop (like a collaborator)
How could I model it?
Thanks!
From your requirements, my design would be:
Two bounded contexts:
Shopping: It has two aggregates ( Request and Shop ).
Authentication: One aggregate ( OwnerAcount ).
There exists eventual consistency:
(1) Request aggregate would have a method "aprove". This method creates the RequestAproved event.
(2) Shopping BC publishes the RequestAproved event.
(3) Authentication BC is a subscriber to this event. It reacts to the event creating an OwnerAcount aggregate.
(4) The constructor method of OwnerAcount aggregate creates the OwnerAcountCreated event.
(5) Auth BC publishes the OwnerAcountCreated event.
(6) Shopping BC is a subscriber to this event. It reacts to the event creating a Shop aggregate.
Transaction creating the Shop aggregate is different from the one that created the Request aggregate.
Here's a diagram:
(Note: There's a message queue for each event type. Another option would be just one queue for all event types)
I am integrating my service with Stripe for subscription payment processing.
I want the service to be available in different countries. Therefore I would like to offer my subscription in different currencies in different countries.
For example, say my subscription costs 10 USD / month for American users.
What is the best practice with Stripe when it comes to offering the same product in different currencies depending on the user's location? (for example 12 EUR for Germans, 15 GBP for UK etc.).
One thing that comes to my mind is to have a single Stripe product, with multiple prices defined in different currencies, use some 3rd party IP location service to find out where the request comes from and display different pricing options depending on the user location. So I would have the price_ids mapped to countries on the server side, determine the location on the client side and pass it on to the server when fetching available products.
Is this the best practice or is it normally done differently?
Has this been solved?
I'm using Stripe Checkout (checkout system made by Stripe), which picks up prices for my products and CONVERTS them to user's local currency.
The problem, though, is that €99 gets converted to ~$118.02, but I'd like to specify the price for USD myself (would be $119). Can we do that?
Pretty sure you're right, it should also just convert the currencies through Stripe itself
Once you have created a Product, you can specify the currency when creating Prices. The amount will be converted to your default currency if you don't have a bank account in the specified currency.
I am having some issues currently wrapping my head around the process of adding a customer to a plan.
A very broad idea of the payment type is to think Twitch Streaming. You can follow users for free but pay a small fee to "subscribe" to them.
Currently, when the user fills out the payment form, i create a source in the frontend through react-stripe-elements and then pass the source.id to my backend.
This is where things start to fall apart for me.
Should I create a different product per user so I can very easily view from the stripe dashboard which user/product is doing the best?
A way to go about this is when a user creates an account, my backend automatically creates a product for that specific user as well as a plan and then store the plan_id into the user model.
So when a user subscribes to another user, I can pull out the plan_id and create the subscription that way.
Currently, I create a source whenever a user submits the payment form.
let attach_source = async ( customer_id, source_id ) => {
await stripe.customers.createSource( customer_id, {
source: source_id
} )
}
Do I check if an error happened and see if the error is duplicate source? Or does Stripe take care of everything.
I am also curious how Stripe handles multiple subscriptions on the same customer from different credit cards. I don't see anywhere that states that a subscription takes from a specific source.
Thank you for taking your time to read this. Appreciate the help!
it looks like you are describing a billing user case from Stripe (https://stripe.com/docs/billing/subscriptions/creating)
You can probably get away without creating one plans per one customer. what you could do is to create a Plan with usage (https://stripe.com/docs/billing/subscriptions/quantities) so a min plan of 5 dollars subscription, when they want to contribute more, update the quantity of the plan
Currently stripe source has a fingerprint fields, where it will be unique for the same credit card number (https://stripe.com/docs/api/cards/object#card_object-fingerprint), you could compare fingerprint to determine if the card has been added. Stripe does not perform any duplication checking now
There is a default_source (https://stripe.com/docs/api/subscriptions/create#create_subscription-default_source) parameters where you can set different card for different subscriptions;
I am looking for the best way to support product autoship / subscription which has a validity period (start, end date and shipping interval - (e.g 1 month) and associated product
Customer can subscribe to product autoship.
Products in the customer's order are grouped within the fulfillment group if they share the same autoship the customer has subscribed to.
On every autoship date, the same order is generated in the background.
Suggestions are much appreciated,
Thanks,
Milan
Broadleaf provides an enterprise-compatible module called Subscription that meets these requirements.
If you are looking for something in regards to community edition, you would have to make custom changes.
From a high level, you would want to do the following:
Some indication on your Product or Sku that indicates it is compatible with autoship / subscription.
An entity that holds the fields that you mentioned - start, end date, shipping interval, and also order, customer, customer payment, and status.
During checkout, add a new activity at the end of blCheckoutWorkflow that checks for compatible order items to create your "autoship" entity.
You will need to create some cron job or quarts scheduler that can trigger events. Sounds like you might want this to be set to a daily recurrence. This is provided in enterprise licenses, but you will have to do something custom for community.
Create an endpoint or service that the job/scheduler calls when triggered.
In your endpoint, you will want to create a new workflow with a set of activities. These activities will need to:
Prepare a new order by copying the required entities of the existing order from the "autoship" entity.
Trigger the blCheckoutWorkflow with your newly created order.
Update the "autoship" entity depending on success of the attempted payment.
This should get you to a good place given the requirements.