Processor Backends
There always needs to be a special Organization
, the processor in your
database. The processor represents the payment processor backend in charge
and deposit transactions.
Organization
with pk=1 will be considered to be the default processor.
This can be overridden by defining PROCESSOR_ID
in the settings block.
$ cat settings.py
SAAS = {
'PROCESSOR_ID': 1
}
Flutterwave configuration
Beware the Flutterwave backend is currently experimental!
Install Flutterwave pip package
$ pip install rave_python
Go to your Flutterwave dashboard “API Keys”, then copy/paste the keys into your project settings.py
SAAS = {
'PROCESSOR': {
'BACKEND': 'saas.backends.flutterwave_processor.FlutterwaveBackend',
'PRIV_KEY': "...",
'PUB_KEY': "...",
}
}
The backend relies on Flutterwave Inline such that credit cards numbers are never posted to the application server running djaodjin-saas (PCI compliance).
Razorpay configuration
Install Razorpay pip package
$ pip install razorpay
Go to your Razorpay dashboard “API Keys”, click on “Generate Key”, then copy/paste the keys into your project settings.py
SAAS = {
'PROCESSOR': {
'BACKEND': 'saas.backends.razorpay_processor.RazorpayBackend',
'PRIV_KEY': "...",
'PUB_KEY': "...",
}
}
Stripe configuration
The Stripe backend works in 3 different modes:
LOCAL
FORWARD
REMOTE
In LOCAL mode, Stripe Customer and Charge objects are created on the Stripe Account identified by settings.PROCESSOR[‘PRIV_KEY’]. All transfers are made to the bank account associated to that account. Stripe fees are paid by the broker.
In FORWARD mode, Stripe Customer and Charge objects are also created on the Stripe account identified by settings.PROCESSOR[‘PRIV_KEY’] but each Charge is tied automatically to a Stripe Transfer to a Stripe Connect Account. Stripe fees are paid by the broker.
In REMOTE mode, Stripe Customer and Charge objects are created on the Stripe Connect Account. Stripe fees are paid by the provider.
To configure Stripe Connect, follow the instructions at https://stripe.com/docs/connect,
Go to “Account Settings” > “Connect”
Edit the redirect_url and copy/paste the keys into your project settings.py
SAAS = {
'PROCESSOR': {
'BACKEND': 'saas.backends.stripe_processor.StripeBackend',
'PRIV_KEY': "...",
'PUB_KEY': "...",
# optional
'CLIENT_ID': "...",
'MODE': "...",
}
}
Writing a new processor backend
To get started, you can look at the saas.backends.fake_processor.FakeProcessorBackend which is a mockup of the methods a payment processor backend is expected to implement. As seen on the diagram below, the first two methods that are important to implement are get_payment_context and create_payment.
Most modern payment processors return a processor token to the browser client when passed credit card information (card number, ccv, street address, etc.) that you post to your backend (running djaodjin-saas) to effect the charge.
get_payment_context returns the information that the browser client will need to pass to the payment processor to authenticate your application, while create_payment will effect the payment when payments are handled in a two steps process. You will need to refer to the specific payment processor documentation to decide what goes into get_payment_context and what goes into create_payment (See saas.backends.stripe_processor.base.StripeBackend.get_payment_context and saas.backends.stripe_processor.base.StripeBackend.create_payment for examples).
How to debug “__name__ is not associated to an account on the processor and no token was passed.”
There are two ways a charge is created through saas.AbstractOrganization.checkout:
A processor token representing the credit card is passed to the method
The organization/profile has a credit card on file (processor_card_key is not None).
The error is raised when neither of the conditions above are true.
Unless you collect credit card information before hand to charge at a later date, the most likely case is that you will pass a processor token the first time a billing profile is charged through a checkout page.
First is to check the processor token is passed properly to the backend by using your favorite debugger to look at CheckoutFormMixin.form_valid.processor_token, or CheckoutAPIView.post.token if you use the checkout page or checkout API respectively. You can also look through the DevTools in your browser to find out what payload is passed to the POST request. It is highly likely there are no processor token passed, or the processor token is passed under a different name that the expected one.
Assuming you have written the Javascript interacting with the payment processor to retrieve a one-time token (see djaodjin-stripe.js for example), you would most likely receive an browser error if get_payment_context did not pass the correct public key and other expected identifiers to pass to the processor to create a payment token.