How to authorise a subscription |
Quite often we are asked "How to I determine if a customer has a subscription, I need to authorise access to resource X based on it". Unfortunately our answer is somewhat vague in that there is a lot of ways a customer can be considered to have a subscription. This "How To" attempts to outline several ways to determine if a customer has a subscription.
A subscription has a series of parameters that might be relevant when authorising, typically these relates to the product, the term and the offer. For instance it might be relevant to give access to a specific resource only if a customer has purchased a specific product (or a specific combination of products), or deny access if the subscription is on a specific offer. Additionally, the requirements might be such that any product is valid as long as the produc is a product marked as electronic.
In general a customer can have either no subscriptions or at max one per title. A subscription can have a state which can roughly be divided into three categories
Passive. That is, the subscription has been stopped and should not be paid for.
Active. That is, the subscription is running and should be paid for.
Ordered. That is, a subscription has been ordered and should become active within a short time period.
Neither of these is a simple as depicted above, but that is the general idea. There are a multitude of actual states, but each can roughly be grouped into the above.
The following is an outline of the most general authorisation method. It is the most flexible and varied of the authorisation methods, but also a bit complex. It is also the only authorisation type to consider subscriptions that have yet to be processed/imported, a nessecary step to grant immediate access for customers signing up via eltronic channels (website orders).
It is up to the client to consider which change types are considered active and which are considered passive in this variant. This might even be different from client to client depending on the resource.
Verify the customer/user using either VerifyUserNameAndPasswordExtended(String, String) or VerifyCustomerNumberExtended. Both methods allows login for customers that have yet to be imported.
Get information from the subscription in a given timeframe using the method GetSubscriptionElements. Specify a time range that is reasonable in order to avoid too many results. The GetSubscriptionElements method includes the output of items that have been order using webservices, but have yet to be imported, as well as the information from the production system.
Get the next distribution date for each title you want to authenticate for, or determine the authorisation date you want to use. Use the method GetNextDistributionDate to get the distribution date
Analyze each element in the output to make sure it has the correct title, product, term and change type and that the access time (either today or the next distribution date) is within the timespan (start date and end date). Valid values for the change type can be found by loooking at the type ChangeType. Note that the types NONE and ALL are not exactly types that an element can have, but just used for query operations.
This method for verifying that a customer has a specific subscription will work for most cases. Depending on the access time this method can be used to grant access to historical archives if a subscriber was active when the original product was produced. It can be simplified ignore parameters such as the term or the product, or it can be expanded to lookup parameters on the product.
The following example depicts an authorisation using the above guidelines where the product P1 grants access if for current subscribers, and new subscribers starting on the next distribution date
string titleCode = "IS"; // Use your title code here int customerNumber = 123456; // The customernumber you want to check bool parseCallresultOrders = true; // Allow parsing of orders that have yet to be processed/imported var xmlServiceClient = new InfoWebXMLWebServiceSoapClient(); InfoWebLoginInfo verificationResult = xmlServiceClient.VerifyCustomerNumberExtended(customerNumber, parseCallresultOrders); var nextDistributionDate = xmlServiceClient.GetNextDistributionDate(titleCode); bool authorised = false; // Determine if the customer is authorised for the valid product P1 if (string.Equals(verificationResult.StatusCode, "00")) { InfoWebSubscriptionElementCollection elementsResult = xmlServiceClient.GetSubscriptionElements(customerNumber, DateTime.Now.AddDays(-7), nextDistributionDate.AddDays(1)); foreach (InfoWebSubscriptionElement element in elementsResult.Elements) { // Check if element covers the current date or the next distribution date if ( (element.StartDate <= DateTime.Now && element.StopDate >= DateTime.Now) || (element.StartDate <= nextDistributionDate && element.StopDate >= nextDistributionDate)) { // Element covers the desired time period. Now check for delivery type and product P1. Everything is considered active but permanent stop elements if (element.TitleCode == titleCode && element.ProductCode == "P1" && (element.ChangeType != "STOP")) { // The subscription is authorised for access "now", because an order exists in the given time period. authorised = true; break; } } } } return authorised;
The following example depicts an authorisation for products that are marked as electronic.
bool authorised = false; // Determine if the customer is authorised for any product that is electronic. Does not look at delivery type or specific timespan of the given element. InfoWebProduct[] products = xmlServiceClient.GetProducts2(titleCode, false); InfoWebSubscriptionElementCollection elementsResult = xmlServiceClient.GetSubscriptionElements(customerNumber, DateTime.Now.AddDays(-7), DateTime.Now.AddDays(1)); foreach (InfoWebSubscriptionElement element in elementsResult.Elements) { foreach(var product in products) { if(product.Code == element.ProductCode && product.IsElectronic) { authorised = true; break; } } }
Note |
---|
These examples are just that, examples. Consider the code you are writing before blindly copy/pasting as the result might not be exactly what you desire |
Consider caching the distribution date for each title across all sessions. The distribution date changes once, or twice a day at maximum, depending on the business of the newspaper.
Consider carefully the time period you want to investigate active subscriptions for. The longer specified period, the more data have to be handled and returned. In essence increasing the response/view time for the user.