Skip to content
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

application flow documentation #626

Open
Nielssie opened this issue Dec 24, 2018 · 1 comment
Open

application flow documentation #626

Nielssie opened this issue Dec 24, 2018 · 1 comment

Comments

@Nielssie
Copy link

We spent some time figuring out the working of Silver (installed, docs and sources) but we are not complete sure about the application flow.

Our case:
We have multiple intances of a Learning platform where we want to use (a single instance of) Silver for billing an payment processing.
We spent some time in figuring out the working of Silver (installed, docs and sources) but we are not complete sure about the application flow.

Maybe you guys can help us with some clarification. Or is there documentation which explains the flow?

after a customers clicks the 'buy course' button we assume the following Silver:

  1. create a customer
  2. create a subscription
  3. activate a subscription
  4. create document (and pdf)
  5. create transaction (?) It will return a payment URL
  6. make payment (?)
  7. Check transaction status and determine if customer payed the course and is allowed to use the course.

questions:

  • Should a subscription not become active after payment?
  • Can we only create an invoice on an active subscription?
  • It looks like a transaction can only be created when invoice is payed and only for issued documents, which contradicts.
  • Should a subscription not become active after payment?
@bogdanpetrea
Copy link
Contributor

bogdanpetrea commented Dec 31, 2018

Afaik there is no documentation regarding use cases and flows, but they would be useful indeed.

Before answering your questions, I think the most important thing to state about Silver is that it was never really meant to be used as a standalone app. It was thought to be more like a framework on which you can add your custom business logic code.
Also, Silver first started as a billing app, the payments part being added a few years after release.

So, to answer your questions, subscriptions need to be active in order to generate invoices, and you need an invoice in order to start making transactions. You can't make transactions for no reason.

What you can do now, that might resemble the behavior you want, is:

  • create a subscription, set a start_date, but don't activate it yet
  • generate an invoice based on it
  • pay the invoice
  • activate the subscription

To do that you'll need to use the DocumentGenerator to generate the invoice from an inactive subscription.

plan.prebill_plan = True
plan.save()
s = Subscription.objects.create(plan=plan, start_date=timezone.now().date(), ...)

d = DocumentsGenerator()
# d.generate doesn't actually return the documents (it should though), but that can be easily implemented
# it's mostly a wrapper over _bill_subscription_into_document, so you can use that instead for the moment
doc = d._bill_subscription_into_document(s, billing_date=timezone.now().date())
doc.issue()

# now you can create a transaction for the issued document (the part where the customer is involved)

# you'll also have to add some code that activates the subscription when the document is paid:

@receiver(post_transition)
def post_document_transition_callback(sender, instance, name, source, target, **kwargs):
    if not isinstance(instance, BillingDocumentBase):
        return
    # Be wary that although the document is automatically saved to DB after a state transition,
    # it might not be saved at this point and inconsistencies may appear if the program 
    # terminates etc.
    # So you might want to hook to a post_save signal and check if the document has just
    # been transitioned; you can do that by setting a flag in the post_transition callback and
    # checking the flag in the post_save callback, then removing the flag.

    if instance.state == transaction.STATES.PAID and \
       instance.subscription.state == instance.subscription.STATES.INACTIVE:
        try:
            instance.subscription.activate()
         ...

You will also have to handle the cleanup in case the payment is not fulfilled.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants