-
Notifications
You must be signed in to change notification settings - Fork 45
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Define operations and usage scenarios clearly #25
Comments
I agree that we need to document scenarios, it will help define the API. One customer in #15 has already described their scenario. Internally I know we have a few scenarios that we'd like to cover, let's document them! |
Could we use the same schema and scenarios format as https://github.com/matin/balanced-api/tree/revision1 ? |
The scenarios I mean here are basically the requirements of this system. I prefer to do it in a more human readable way to express it. I just want to create some clear direction and goals of this system, with big pictures thing can be done easily and correctly. I think I just write down everything came to my mind and clean them up later. I am writing these also for making sure my understanding to the system is correct. If youguys see anything wrong please correct me. Big pictureThis system should be the backend for recurring payments. Most of them are subscription type service, for instance, hosting service is one kind of subscription services. Customers can choose different hosting plans and subscript to them. The subscription fee can be debited from either customer's bank account or credit card periodically. Although I think the major cases there would be charging customers periodically, still, as we are running a payment gateway for marketplace, there might be some recurring payout case, such as Gittip. However, I think I should focus on the common cases and try to reach more special case later. A more long term goal could be to provide some more complex recurring payment processing. There will be two major ways customer of balanced can employ this system, one is to host this system by themselves, the other is to use the hosted by us. This service is provided in RESTful API form mainly, maybe we can create a dashboard for it later. Entity definitionsCompanyAs this system should be used by different users while it is hosted by us, it should provide multi-user service rather than serving single user solely. So, the In short, the user to billy system Customer
Plan
Subscription
Transaction
Invoice
The ERD diagramUsage scenarioLet's envision some possible usage cases here. Say, John is running a web hosting service, he wants to use Balanced for processing the payment. He has 3 plans,
At very first, he will need to register a company in the system to get an API key for accessing billy, he also need to give his balanced API key to let billy do the recurring processing for him. import billy
api_key = billy.create_company(
balanced_key='1234567890abcdef',
name="John's Awesome Hosting Plans",
) With the api key for billy, he can then create the plans billy.configure(api_key)
plan1_id = billy.create_plan(
name='Small',
description='Small hosting plan, 5GB storage, 1024MB, $5 USD / mo',
amount=5,
frequency=billy.FREQ_MONTHLY,
user_data='hd=5GB,mem=1024MB',
type=billy.PLAN_TYPE_CHARGE,
)
plan2_id = billy.create_plan(
name='Middle',
description='Middle hosting plan, 10GB storage, 2048MB, $10 USD / mo',
amount=10,
frequency=billy.FREQ_MONTHLY,
user_data='hd=10GB,mem=2048MB',
type=billy.PLAN_TYPE_CHARGE,
)
plan3_id = billy.create_plan(
name='Big',
description='Big hosting plan, 15GB storage, 4096MB, $15 USD / mo',
amount=15,
frequency=billy.FREQ_MONTHLY,
user_data='hd=15GB,mem=4096MB',
type=billy.PLAN_TYPE_CHARGE,
) Great, he got 3 plans now. Then, Tom wants to purchase his middle size hosting service, so here the code goes customer_id = billy.create_customer(
name='Tom',
payment_uri='/v1/credit_card/55667788abcdefg',
email='[email protected]'
)
billy.subscribe(
customer_id=customer_id,
plan_id=plan2_id,
) Okay, here we are, for now, billy will charge Tom's bank account (or credit card) 10 USD every month. Cancel subscriptionDaniel is also a customer of John's hosting server, he subscribed Small plan for 3 months, and he want to cancel his hosting plan in the middle of 4th month. John's hosting policy is to refund user prorate in middle of subscription period, so here the code goes billy.cancel_subscription(
sub_id='SUBabcdefgh1234',
prorated_refund=True,
) In that way, billy will mark this subscription as canceled, also, it will generate a prorated refund transaction back to Daniel's account. If we want to just cancel the subscription, but no refund is issue, then we can call it like this billy.cancel_subscription(
sub_id='SUBabcdefgh1234',
) the DiscountTom is a happy user so far, he decided to purchase another hosting plan. As he is the first customer to John's hosting, John wants to give him some discount for his new plan. So, here the code goes customer = billy.get_customer_by_external_id(' customer id in their own database goes here')
billy.subscribe(
customer_id=customer.id,
plan_id=plan2_id,
discount=0.3
) As the the price of middle plan is $10 USD per month, 0.3 discount means 30% price off, so he will be changed for $7 USD per month instead of $10 USD. Start subscription at a specific date timeSay, Linda have a violin course for students to attend. She would like to have all the recurring payments be processed at 1st of month (easier to manage). Here she can use billy.subscribe(
customer_id=customer.id,
plan_id=voilin_course_id,
started_at=datetime.datetime(2013, 9, 1)
) By doing this, the very first transaction will only be processed at 2013/Sep/1st, and transactions will be scheduled at 1st for all following months. Multiple interval periodMichael has some apartments for rental. He'd like to collect his fee for every 6 months, so here he can write plan_id = billy.create_plan(
name='Small apartment rental',
amount=2000 * 6,
frequency=billy.FREQ_MONTHLY,
type=billy.PLAN_TYPE_CHARGE,
interval=6,
) In this case, his customer will be charged every 6 months. |
Is this direction looking fine for you guys? |
@victorlin I don't know what interface you are going to build for the billy api, but in the next revision of the balanced api we are going to support jsonapi. We are already building tooling around running scenarios of this form. It is currently set up to validate all requests and responses against jsonschema |
@matthewfl i believe this is the internal interface, not the external API interface. @victorlin that's a great base. do you think we need to define edge cases at this level such as
|
These are just the way I think how user will use them. They are not final API design, just a rough way to express how it should work. I need to make sure this direction (big picture) is correct before I get started on this, otherwise that would be a trail and error. We can always write these human readable scenario into JSON for running tests later. Yeah, that would be helpful, I see PayPal recurring payment has refund option, some edge cases like that would be nice to have. I can make better design decision with those scenarios. |
@victorlin - you definitely have the model down correctly. When do you want to work on the scenarios? Ping me on Google chat or IRC channel |
I have already updated the scenario, see if this meet the requirement. However, I cannot understand your second scenario,
Could you clarify this? |
Let's say you have a monthly recurring plan. Tom, our customer, subscribes to the medium plan, he gets billed for the first month. Half way through that month he decides he needs another plan and changes his subscription. Ideally the change would go into action instantly but the price of the plans is different. Do we refund half (2/4 weeks) of the first plan and then charge half (2/4 weeks) of the second plan in this case? It sounds like the customer_id = billy.create_customer(
name='Tom',
payment_uri='/v1/credit_card/55667788abcdefg',
email='[email protected]'
)
billy.subscribe(
customer_id=customer_id,
plan_id=plan2_id,
)
# wait 2 weeks ...
billy.cancel_subscription(
customer_id=customer_id,
plan_id=plan2_id,
prorated_refund=True,
)
billy.subscribe(
customer_id=customer_id,
plan_id=plan1_id,
) |
@mjallday Yeah, that could do. I prefer to provide minimum and complete interface, i.e, you can do anything you like to do (you should be able to do) with minimum interfaces. But I will also provide sugar if that can ease some work and reduce error chance. |
To make it more flexible, I made some changes to the usage and the models. 1. Add an
|
@whit537 do the proposed changes mentioned in @victorlin's last message help accommodate Gittip's use-case outlined in #15? |
@mahmoudimus
As mentioned section 4 in #24, I think we need some definitions about what kind of operations this service should provide and what kind of scenarios to use them. I think one of reasons I have no idea how to contribute on this project is that I cannot find documents about this in the project. What is a plan, what is subscription and so on.
I see you have wrote
in readme file. I feel that could be helpful as it provides a scenario how it would work. But still lack some important details (who to charge, what kind of method should be used with balanced API? what is the trial period here?). I need your input. Could you envision more about how this service should be used?
The text was updated successfully, but these errors were encountered: