I am working on a SAAS project where users can create various projects. With each project, they can choose from 5 different plans. Each plan has its own costs per month. Hotjar is a kind of equal concept.
Now I want to arrange the subscription with Stripe. The problem with that was that a user can have a maximum x subscription, which of course was a shame. Then I decided to take 1 subscription that has several plans. But now I have a dilemma, to update the subscription you have to change the number via SubscriptionItem. Then you have to save yourself which plan has which SubscriptionItem_id for which user. That is quite a detour and can cause many problems.
Someone is a better way with Stripe or another payment software.
You don't necessarily need to store the subscritpion_item IDs, you can look it up via the subscription_item list API. All you need to do is store the subscription_id for your customers, and based on that ID you can retrieve the list of subscription_items:
\Stripe\Stripe::setApiKey("sk_test_9GavlLpfiKewqeCBXvRvmVgd");
\Stripe\SubscriptionItem::all(["subscription" => "sub_EQlPGjVj4o5luH"]);
Then you can handle the data part of the returned JSON object and update / delete / etc these subscription items.
If you only have the customer_id handy, then you can use the subscription list API (with status as well on the GET params) to retrieve the list of active subscriptions.
Related
I need to create a report on my custom Laravel web application to view customers campaigns and each cost and first visited customers count.
In that way user can make the decision campaign success or not.
is is possible to get these data with Google analytics "reports:batchGet" API or any other available API ?
I tried with below dimension
ga:acquisitionCampaign
But it's not clear what values I'm receiving with that dimension.
Let's say we have a simple food delivery app. Where client order the food, then restaurant start preparing the food and gives it to the courier who delivery it to the client.
So here we have three different domains and each of this domain have their own order:
client - here client order the food and have the status of the food in preparation | in delivery | delivered
restaurant - here restaurant got its order and has their own status in queue | in preparation | ready to pick up
courier - courier has only two status delivering | delivered
Moreover each of this domain has their own price and other attribute about order:
client - total price (food price + delivery cost + fee)
restaurant - price of food, time of production to give a hind to the client when food will be delivery
courier - cost of delivery
All I want to highlight is that each of the domain has its own order aggregate, so according to DDD we have to keep it in different aggregates even in different microservices:
client - /orders/:id provides the general status of the order and total price to the client.
restaurant - /restaurants/:restaurantId/orders/:id provides the status of the food in restaurant domain and cost.
courier - /couriers/:courierId/orders/:id provides information how much courier earn from this order and how long it took to delivier
But now I met another problem, because client order combines information from other domains (is food still in restaurant or it's being delivery) so I have to gather this information when client asks about its order, but it means that client doesn't have its domain (its own aggregate, total price, discount etc), but if I create order aggregate for the client then I will not keep all information about order in one place (when restaurant give the food to the courier it should also change status of the order in client domain) what is not really according to microservices, because we keep information about the same order in different microservices.
Should I just create one order domain or should I split it to different domain and make these domains communicate between, when something will change in one domain?
One useful approach is to leverage domain events. When the restaurant's view of the state of the order changes, an event describing that change is published. The other services can then update their model of the event (assuming that that change is relevant to that service).
So for instance, we might have:
user creates order via the client service => OrderCreated event emitted
restaurant service consumes OrderCreated event, translates the order for the restaurant (e.g. uses the prices which the delivery app pays the restaurant vs. the prices the delivery app charges the user) => OrderSentToRestaurant event emitted
courier service consumes OrderCreated and begins trying to figure out which courier will be assigned the order and the approximate transport time from pickup to delivery => DeliveryLatencyEstimateMade event emitted
client service consumes OrderSentToRestaurant and updates its order status (for presentation to the user) to in preparation
courier service ignores OrderSentToRestaurant
restaurant service ignores DeliveryLatencyEstimateMade event
client service consumes DeliveryEstimateLatencyEstimateMade and updates its model (delivery time remains unknown)
restaurant informs restaurant service of expected completion time => OrderReadyForPickupAt event emitted
courier service consumes OrderReadyForPickup, refines courier assignment decisions
client service consumes OrderReadyForPickupAt event, combines with the latest latency estimate to present a predicted delivery time to the user
and so forth. Each service is autonomous and in control of its data representation and free to ignore or interpret the events as it sees fit. Note that this implies eventual consistency (the restaurant service will know about when the order is expected to be ready for pickup before the courier or client services know about that), though microservice autonomy already effectively ruled out strong consistency.
When looking at aggregate design in each bounded context (BC), you have to include only the data required to provide the functionality that belongs to that BC. The fact that the restaurant endpoint needs to return some extra data is not a good enough reason to add that data to the order aggregate in that BC.
You can resolve the need for more data in different ways:
The API client can call multiple endpoints to fetch all the data it needs
The API can implement Data Aggregation, by internally querying multiple BCs/microservices and combining them to produce a single more complete response object
Create Read models, which store data from multiple sources into a single "table" in a way that simplifies querying and returning this data. This approach is more complex, but it's very useful when you need to filter and sort by fields belonging to multiple BCs, which is not possible with the previous two approaches.
Another consideration to make is double-checking if your boundaries are correct. Do you really need a Client BC? What business logic does it implement? Maybe Orders are created directly into Restaurant and there is no Client order? Client order could just be a "façade" providing all Restaurant orders belonging to a single client Id?
As a final note, I completely agree with Levi Ramsey's answer that events are the right way to coordinate the different aggregates. They would also be used to create the read models I mentioned above.
Let’s assume I’m in the context of an admin panel for a webshop. I have a list of orders. Those orders are payed for and are ready to ship. The (admin) user would like to start making shipments based on the items ordered.
Imagine there are 2 microservices. One for orders and one for shipments. In order to create a shipment, i will send a request with a couple of items to be shipped and an order ID to the shipment service. The shipment service will then check whether the items are present in the order by querying the order service. Because i don’t want to create a shipment with items that are not present in the order.
I’d like to have immediate consistency because the shipment data will be send to a third-party application after creation. Thereby it also feels weird to allow shipments to be created if the data is not correct.
I’m also using GraphQL mutations. Which means i have to return the updated state to the user, which also makes eventual consistency a lot harder.
What is the recommended approach for these situations? Could this be a sign that these 2 microservices need to be merged? I can imagine this situation can occur multiple times.
In the iOS App Store, you can create subscription groups, which I believe allows the app to (if coded as such) display different subscription options to different groups of users. For example, grouping magazine subscriptions by genre.
Is there anything like this for the Google Play store, or would I need to do the groupings myself within the app?
Although I am not sure at this time, but I don't think Google Play provides the equivalent of a Subscription group. At the time of this writing, I am working on the same and new updates will publish edits here.
There is a catch here,
which I believe allows the app to (if coded as such) display different subscription options to different groups of users
Although, subscription groups can be used for the purpose described above, they are not inherently meant for the same. Subscription groups are meant to group different subscription products so that the user can purchase only one of them at the same time.
You can view a subscription group as a product/ service your app offers and the subscription products under them as the Plans under the same. For example, for a news app, you may offer a subscription product to your users with different plans like Single Category Monthly, All Monthly, Single Category Annual, All Annual. The single category app may provide news only in one single chosen category like sports, entertainment, politics etc. The user can choose to change between plans any time but can subscribe to only ONE plan at a time.
Also, as you would comprehend, some of these plans are higher levels of services than others. Based on your business definition, you can put these plans at different levels. That will determine if the user is upgrading/downgrading/cross grading while changing a plan. For example, in this case you may have two levels:
Level 1 may have All Monthly and All annual.
Level 2 may have both the single plans.
1 -> 2 will be downgrade, 2 -> 1 will be upgrade, 1 -> 1, 2 -> 2 will be cross grade.
In Google Play Billing, an upgrade or downgrade will be performed by setting the oldSku while making a purchase. If the oldSku is set, Google Play Store will consider it as an upgrade/downgrade.
However, I am not sure at this point how the App Store determines if it's a upgrade/ downgrade / crossgrade. May be based on the price (unlike Apple).
Grouping may not be required for Playstore. In Appstore, since all the subscription options are listed, we need to group a set of items together. For example, if user subscribes within a 10 days of registration, 10% reduction in monthly, annual cost can be provided. In such cases, if they cancel the subscription, they can re-subscribe from store. They will be listed with only those group to which they subscribed before (monthly, annually for within 10 day plan). So they continue to get 10% reduction if they re-subscribe to any plan (monthly, annually).
In Playstore, user can re-subscribe to the same subscription that user opted before. So such case won't arise.
Set update subscription param as specified here
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