silverapp / silver

Automated billing and payments for Django with a REST API
https://www.presslabs.com/code/silver/
Other
301 stars 80 forks source link

Poor (out-dated) documentation and lack of a clear application flow #672

Closed thevahidal closed 3 years ago

thevahidal commented 4 years ago

Hey guys, we've been looking for something like this library for a while and finally we found silver which we really appreciate your work. but the problem is that the documentation is not really helpful and everytime we ran into a problem it takes us a lot to figure out how to solve it. (for example braintree payment processor is outdated and we basically forked it, changed a lot of things!)

I'm aware of the fact that changing and improving the docs will take a long time, and since we're in a hurry here, we would appreciate it if you could answer some of our questions here.

(before start asking questions assume that we have a platform with only one provider which is us, and we have some pricing plans, and we basically want our user subscribe to a plan a pay the price, that's it nothing too fancy.)

1. can you explain the whole process of what we want to accomplish (above)? the order of api calls and etc? (priority: high) 2. why do pricing plans need authentication? (priority: low) 3. how is that every authenticated user can activate a subscription via the activate subscription endpoint? Doesn't it supposed to get handled by super admin access or automatically by silver? (priority: high) 4. why is that even though we specified the price and all info in the plan, when creating a subscription we need to again give all of them to the subscription entries? (priority: medium)

bogdanpetrea commented 4 years ago

Hey @thevahidal , thanks for addressing your concerns.

Yes, the documentation is not up to date and not so well written. If you've dealt with certain pain points it would help to mention / document them. It's a chicken and egg problem really: contributors won't join if the documentation is not good enough, and the documentation won't be improved if there are no contributors. At the moment Silver has no active contributors, if you don't count me... but I limit my contributions to bugfixes, and handling Issues and PRs. So please consider contributing if you are making use of the project.

At Presslabs we are using the Braintree Payment Processor just fine, what is outdated about it?

I think a couple of questions (2. and 3.) are pretty similar in nature. We have a second application that solves the authentication/permission problems and is an intermediate between the Billing App and the customers / business logic. If this does not fit your platform, you can write your extra business logic code in the same Billing App where Silver is included (which is mostly how Silver was intended to be used).

For 1., assuming you've already created a provider and plans:

From there invoices will be automatically generated if you've setup Silver correctly. See here.

4. I'm not sure what you mean here. There are these things called MeteredFeatures that can be attached to Plans. They are used to describe the non-fixed fees of a plan. If you were to model a mobile phone subscription, then you'd have a base fee for the Plan and you could have a MeteredFeature to charge extra internet traffic for example.

Subscriptions have logs of these MeteredFeatures, called MeteredFeatureUnitsLogs. They log how many units of that MeteredFeature have been consumed during a billing interval (a month for example).

You can send a PATCH request to /api/customers/<customer_id>/subscriptions/<subscription_id>/metered_features/<metered_feature_product_code> to add or override the consumed units of a specific MeteredFeature. Other than that the Subscription doesn't require mentioning any other details that have been already mentioned in a plan (unless it allows you to override those details for specific a Subscription).

More info

The API has been partially specified for testing (in a python, but declarative way) in this directory: https://github.com/silverapp/silver/tree/master/silver/tests/api/specs. You can look there to understand the API structure, especially for invoices, their entries and transactions... specs for the other resources are for API output-only.

In the end I encourage you to try and upstream your improvements / changes to the project and related projects (Braintree).

thevahidal commented 4 years ago

Thanks for your answer, I'll look into it.

thevahidal commented 4 years ago

Hey man, I did all the steps you mentioned (create customer, subscription, ...) and when i try to issue an invoice, i see this error in celery logs: [2020-02-24 09:49:56,727: WARNING/ForkPoolWorker-9] <ErrorResult 'Unknown or expired payment_method_nonce.' at 7f506ba28950> [2020-02-24 09:49:56,727: WARNING/ForkPoolWorker-9] Couldn't charge Braintree transaction.: {'message': 'Unknown or expired payment_method_nonce.', 'errors': ['91565'], 'customer_id': 6, 'card_verification': None} [2020-02-24 09:49:56,727: ERROR/ForkPoolWorker-9] ['91565']

bogdanpetrea commented 4 years ago

Does the invoice issue fail? How does the PaymentMethod look (payment_method.__dict__)? You can also see https://developers.braintreepayments.com/reference/general/validation-errors/all/php#code-91565.

thevahidal commented 4 years ago

No the invoice issue work just fine. I saw that braintree doc but the question is where we get the payment_method_nonce?

thevahidal commented 4 years ago

This is the created transaction Data: { "error_codes": [ "91565" ], "requested_at": "2020-02-24T09:49:55.425207" }

thevahidal commented 4 years ago

oh, my bad, i creating an invoice instead of subscription!

bogdanpetrea commented 4 years ago

The payment_method_nonce is something the paying customer obtains from Braintree, after submitting his payment information (when redirected to the transaction's pay_url).

See the Braintree documentation for an overview of the entire flow: https://developers.braintreepayments.com/start/overview#how-it-works

thevahidal commented 4 years ago

oh, my bad, i creating an invoice instead of subscription!

But the problem is that no invoice is created automatically, though when i create an invoice, a transaction was build automatically then i assume my celery is working!

bogdanpetrea commented 4 years ago

Make sure the subscription is active. The subscription has a few methods you can use for debugging as well: subscription.should_be_billed(billing_date=date(...)) - tells you if the subscription should generate an invoice subscription.cycle_end_date(billing_date=date(...)) - tells you the end of the current billing cycle

Where billing_date can be today or some arbitrary date.