In app purchase subscription vs consumable - iphone

I'm making an app which will allow the user to purchase either a subscription or consumable which allows them to access data on a monthly basis. Once the new data for the next month is available they will download that and the previous data is invalid and actually illegal to use so it will be removed. So I'm not sure which to choose. A subscription model or a consumable model? From what I see either one would work. Any reason to choose one over another?

I'd go with consumable in this case. Although it sounds like a monthly subscription model, it is not as the access to the previous item essentially runs-out or is consumed. The consumable model makes more sense.
Plus from a developers point of view, not having to make the content available across multiple devices (a requirement of the subscription model) can make things a little easier.

a consumable item, if the user makes a restore the item will not be restored. Whereas subscription it can be if it is still valid.

Related

Event-Sourcing how to change business rules

My application use cqrs and event sourcing. It's already in production.
Now i must add a business rules. My business rules are in my aggregate root UserAggregate.
My commands :
public class CallUserForMarketingPlanCommand
{
public Guid UserId {get;set;}
public DateTime CallDate {get;set;}
public Guid PlanId {get;set;}
}
public class AcceptMarketingPlanCommand
{
public Guid UserId {get;set;}
public Date AswerDate {get;set;}
public Guid PlanId {get;set;}
}
... the same thing for RefuseMarketingPlanCommand
these commands are applied on my aggregate root which generate events stored in event store
Now if 50 days after the call, the user do not give answer, the user must be recalled by operator. To do this, i think generate event UserDoNotRepliedInDelayEvent and use it to project to a read model with recall informations.
My solution is to create a deferred command (from UserCalledForMarketingPlanEvent handler) CheckUserAnswerCommand which check the call date and generate UserDoNotRepliedInDelayEvent if necessary across the aggregate. Ok.
My problem is how to deffered this command on users already in my event store (before this change) ?
EDIT :
Without considering deferred message, how to change business rules (or a business rules parameter) affecting the state of an aggregate. Simple example :
Disable account if two payments are not permformed.
this rule come with the first deployement. Ok, now there are 1000 accounts disabled. The boss change the rule because the business is impacted, and want disable account if 5 payments are not performed.
How to enable account having less than 5 payments not performed ?
Thanks for your help.
Now if 50 days after the call, the user do not give answer, the user must be recalled by operator. To do this, i think generate event UserDoNotRepliedInDelayEvent and use it to project to a read model with recall informations.
If I undestood your question correctly, the main point here, is that the user "not replying" in time is not an action (command) of your domain, quite the contrary, it is the absence of an action. So in this scenario, I don't think you need an event at all.
You simply need a read model which will register all sent invitations and their statuses (whether they're replied, their reply dates and how long did they stand unanswered). Then, you can check this read model for unanswered invitations that exceed your deadline of 50 days (which should be simple enough at this point).
So, up to this point, no new events are generated in your "Invitations" event store. You're simply interpreting the store into a specific read model that will answer you a question you have (which invitations were not answered).
From this point, it depends on your architecture.
You might want a recurring process to check this read model for invitations that exceed your deadline, having those specific invitations trigger a "InvitationExpiredEvent" or something to notify the interested parties (those who will resend them, for instance)
Or you simply might want a more passive approach, not needing an extra event, simply reading this Read Model when appropriate (on the GUI, maybe) and listing the expired invitations.
This will then fix itself... since you can generate the read model retroactively (finding users from any given point in the that never answered their invitations) and put them through the re-invitation pipeline.
Without considering deferred message, how to change business rules (or a business rules parameter) affecting the state of an aggregate. Simple example :
Disable account if two payments are not permformed.
this rule come with the first deployement. Ok, now there are 1000 accounts disabled. The boss change the rule because the business is impacted, and want disable account if 5 payments are not performed.
How to enable account having less than 5 payments not performed ?
This part of your question is more confusing. From what I understood, you once had a rule that stated "Accounts with two or more expired payments should be inactivated" and you want to change this rule to "Accounts with five or more expired payments should be inactivated". If that's the case, you have to deal with this on multiple levels...
First, you must first implement the new rule on your command model, the same way it always have been but with the updated parameter.
Second, you cannot retroactively reactivated accounts with 2,3,4 expired payments by ignoring their "deactivation events". From your event store point of view, this happened and you must abide by the rules that an event store is a "push only" storage. So, you must use compensating events to reactivate them after the rule change.
So, if you took care of the first topic (and your domain is up and running with the new rule) and since you can't take a shortcut because of the second topic, one of your easier options is to simply develop a one-shot operation that will find accounts with 2,3,4 expired payments that are currently disabled and append to their event stores a reactivation event. At this point you will have to regenerate any affected read models if your architecture doesn't do this automatically.
That way, the next time commands are executed against these accounts, their event stores will reflect the fact that they have been reactivated and thus are currently active.
From an event store point of view... each of these accounts will have something like this on their event streams:
... > Payment Expired > Account Disabled > (maybe other stuff happened) > Account Re-Enabled
So your event store will be a pretty accurate representation of your business scenario... once you chose to disable accounts with only 2 expired payments, so a certain account was disabled by that... later you changed your mind, and even without paying their debts, these accounts were re-enabled.
EDIT:
In fact, i think the problem can be summarized by "how to integrate retroactive rules in event sourced system"
If that's the case, than the answer will be more focused on the lines of "there shouldn't be retroactive actions in an event-sourced domain".
As I said in my original answer, an event stream should be a "push-only" storage and that's mainly because only the exact order of events, as they happened, can guarantee the integrity of your rules as they were when those events happened. In that sense, an event storage is less flexible than a traditional one as it will be way more sensitive to external interference and that will sometimes be a pain (were used to meddling with the data sources directly to fix stuff).
However, we should really try to keep the rule and acknowledge that whatever happened, happened and can't be changed. What you can do, is add, to the end of event stream "compensation events" that is, new events that will register a change of state at a given time to reflect your rules-changing. And then you will need a one-shot process to go through your entities and decide which of them are eligible for such a compensating event.
Now, of course, rules are meant to be broken when needed and with enough consideration, you can go wild into the event store. Just know the risks. If you choose to go "full time machine mode" into the event store, the main risks you will face (and should guard against) are:
Entities going into invalid states in their lifetime. It doesn't matter the entity "ends" the event stream in a valid state. You must validate it never enters an invalid state as that is a prerequisite of event streams. So, for each entity affected by your editing, you will need to evaluate its validity step by step through the new event stream.
Mismatches between source code and event stream. This is a little trickier. But one of the maneuvers you can pull with an event sourced system is rollback your source code repository to a given date and "discard" events from that date forward. That way, you can re-execute actions as they would have happened in the past. If you edit past events though, you might face situations where the recorded events don't match what would have happened in the past based on source code. That might be critical and extremely misleading in the future. You should monitor that.
If your architecture integrates different contexts/domains/microservices, that might also need further evaluation. Say context-A issued a cross-boundary message to context-B because of a given state of an entity. Moving forward, you change the entity state by meddling with the event stream. Now there's a chance these contexts might be left inconsistent between them as context-B believes that entity had a state it no longer has. This might be very relevant in your scenario.
you could also use a Saga that keeps track of the process and than create a command like "recallneeded" when the time is up. it also keeps track of events that tells the Saga to complete if there was a call within the 50 days. (Keep in mind that a Saga is part of your Domain logic and acts as an AR if doing DDD)

How can I get info on products set for apple in-app purchase on my server?

Here's the thing.
were doing some cross-platform game, selling some virtual currency to be used on our game, and life are awesome. Until came the requirements for BI.
The requirements are completely legible - no magic here. Only that with Apple, it's (how to say gently) ...hell.
Here I have to report for every package that was purchased, what is the price that was presented to the user, and what of it was passed to us.
So, OK, after I get a report of a successful purchase and get a receipt
I pass it to my server
I check the receipt with apple, get it decoded
in the receipt I find the package ID - awesome.
But there is no information about sums :o
All this is available when doing billing integration for credit-cards. What would be the equivalent for Apple In-App Purchases?
More info? Ok.
I could cheat a little and solve half of the problem, naming packages like
com.example.vc100
com.example.vc100_promo1
where in both packages the user buys 100 coins of VC, but
vc100 is sold in the usuall case, by the price of some tier that makes sense to our game-balancers, and
vc100_promo1 is sold by promotions by the price of a cheaper tier that makes sense to our marketting.
So, the fallback would be to maintain two lists. one on our servers, and one on the apple back-end, repeating in both ends the relations between a pack and a tier.
Another fallback would be to encode both the VC-sum and the tier in the name. But that would be a partial solution, because we still don't know what price was presented to the user, AND need to maintain a list on our side that would update every-time a price tier is redefined.
Yuck. I refuse to believe there's no better way to do it!
My goal is that marketers can create whatever product-SKU they wish to sell in one place. Obviously, Apple wont let me do that, so at least let it be one list per platform: apple-skus on the iTunes backend, and cross-billing-provider skus in our integration layer for our billing partners, who are much more cooperative than the ...appholes in apple.
Basically, if clients can pull this information and present it to the users - there has to be a way to do it on our servers, and collect this information for BI events.
Having the commission that apple cuts a constant percent from the US price - all we need is to have on our servers the prices for the sold SKU in local currency and USD.
Anybody?
Unfortunately -- incredibly -- Apple doesn't include the price tier as part of the receipt, so the approaches you've outlined are the only options:
The client can store the price tier + local currency price and send it up to the server at time of purchase
The server can maintain a separate list of [product ids -> price tiers], and [price tiers -> local currency price] per tier, both of which need to be kept in sync with iTunes.
It looks like iTunes connect has an (unofficial) JSON API, which could be used to automate #2 (keeping the server in sync with iTunes). I haven't tried it though!
See iTunes Connect API and https://github.com/fastlane/itc-api-docs
so, no long - no answer.
We could not find a way to get this info from Apple in a peer-to-peer request.
What we ended up doing is collect the sums on the client and pass them to the server together with the receipt, protect the values with hashing signature, and send it over ssl.
If there is a better solution - I'd still want to learn about it

Apple In-App Purchases: Generating New Products by Attaching Identifiers

I am making an iPhone App which loads many objects from an external database and displays them to the user. The user has the option to purchase any one of these objects for $.99; when an object is purchased, more information about it is displayed to the user.
The database is large and gets several objects added to it daily. That's why it would be impractical to register each object as its own product on iTunes Connect. I think the best way to go about this would be to register only one type of product on iTunes Connect, and every time the user buys any object he will just be buying another copy of this product. Since the objects are all different, I'd need a way of identifying which is which. The objects all have unique codes in the database, but I have not seen anything in the documentation on how to attach them to products/purchases. Any ideas on how I'd do this?
EDIT: The objects I mention are simply collections of variables. It does not matter what they are exactly; I just want to know how to sell distinct objects using just one product associated with some sort of identifier.
You has to add each object independently in iTunes Connect. Inserting only one IAP into iTunes Connect and sell different objects is not accepted by Apple

Using consumable items with In-App Purchase for permanent items

For my upcoming iPhone application I'd like to offer In-App purchases of expansion content (things like additional unit types), but I'd like to offer them in a booster-style format, i.e., you buy a booster pack and get X new unit types out of Y total units. Units can stack and are useful in duplicate, so you can get some of the same units you already have. I have a few questions about this model:
Will this rub against Apple's "Be clear about what's included in the item"? I can be clear that you are receiving a random set of units and that you may receive duplicates according to a specific distribution mix, but I'm still not sure about this one.
While these booster pack-style purchases will be consumable for the sole reason that I want to allow the user to repeat them, the items they receive are not truly 'consumable'. I'm thinking I can store the user's purchases on my server to allow them to always access and backup their purchased content, but again, I'm not sure if this will get the app rejected or not.
Thanks for any info!
Answering my own question here after forever; I found the application Urban Rivals which apparently employs this approach successfully.

Licensing iPhone software by "number of items supported"

Let's say that I have an application that helps people "manage" a certain number of "items". Normally they'd have to manage information about these items on paper, but my application will let them do it on the phone.
I want to sell my application by the number of items it supports. For example, I might charge $10 for the version that has a limit of 20 items, and $15 for the version that lets you manage 40 items.
What's the best way to do this? Ideally I'd like to let users download the application for free as a sort of trial that only supports a very small number of items like 2 or 3, then they'd have to use in-app purchases or something to buy additional capacity.
I also need them to be able to "re-download" their license from the app store if they wipe their phone or it gets destroyed.
I also want people to be able to buy upgrades as they go along. So once they find they need to manage more than 20 items or whatever, I want them to be able to buy an upgrade for 40 without having to reinstall the app or something.
Installing extra application bundles for each license or license upgrade seems like a bad way to do things, though I'm sure I could have them all use the same bundle seed ID and have them insert license info into the keychain or something.
Anyway, ideas?
You could use in-app purchase to add extra “items” to the user’s list. That will survive a phone restore and you could support adding as many “items” as possible.
I think the best way is to manage this via some sort of subscription where the 'items' are stored on your server rather than the phone. Then you can control the number of them and use the app to access each item.
So, you run the app, it manages these 'items' and each item is stored on your backend database. Depending on their subscription, you can allow/deny attempts to add items.
Alternatively, I guess you could do a similar thing on the iPhone using the built in database but you'll still need a backend somewhere to keep control of the number of items they can manage, whether that's via some sort of certificate or whatever.