Installation
============

#. Install django-payments

   .. code-block:: bash

      $ pip install web-payments-connector

#. (Django) Add the callback processor to your URL router::

      # urls.py
      from django.urls import include, url

      urlpatterns = [
          url('^payments/', include('web_payments.urls'))]

#. Define a :class:`Payment` model by subclassing :class:`web_payments.django.models.BasePayment`::

      # mypaymentapp/models.py
      from decimal import Decimal

      from payments import PurchasedItem
      from payments.models import BasePayment

      class Payment(BasePayment):

          def get_failure_url(self):
              return 'http://example.com/failure/'

          def get_success_url(self):
              return 'http://example.com/success/'

          def get_purchased_items(self):
              # you'll probably want to retrieve these from an associated order
              yield PurchasedItem(name='The Hound of the Baskervilles', sku='BSKV',
                                  quantity=9, price=Decimal(10), currency='USD')

   The :meth:`get_purchased_items` method should return an iterable yielding instances of :class:`payments.PurchasedItem`.

#. Write a view that will handle the payment. You can obtain a form instance by passing POST data to ``payment.get_form()``::

      # mypaymentapp/views.py
      from django.shortcuts import get_object_or_404, redirect
      from django.template.response import TemplateResponse
      from web_payments import RedirectNeeded
      from web_payments.core import get_payment_model

      def payment_details(request, payment_id):
          payment = get_object_or_404(get_payment_model(), id=payment_id)
          try:
              form = payment.get_form(data=request.POST or None)
          except RedirectNeeded as redirect_to:
              return redirect(str(redirect_to))
          return TemplateResponse(request, 'payment.html',
                                  {'form': form, 'payment': payment})

   .. note::

      Please note that :meth:`Payment.get_form` may raise a :exc:`RedirectNeeded` exception.

#. Prepare a template that displays the form using its *action* and *method*:

   .. code-block:: html

      <!-- templates/payment.html -->
      <form action="{{ form.action }}" method="{{ form.method }}">
          {{ form.as_p }}
          <p><input type="submit" value="Proceed" /></p>
      </form>


#. Configure your ``settings.py``::

      # settings.py
      INSTALLED_APPS = [
          # ...
          'web_payments',
          # or
          'web_payments.django',
          ]

      PAYMENT_HOST = 'localhost:8000'
      PAYMENT_PROTOCOL = "https"
      PAYMENT_MODEL = 'mypaymentapp.Payment'
      PAYMENT_VARIANTS_API = {
          'default': ('web_payments_dummy.DummyProvider', {}, {"name": "default", "icon": "ll"})}

   Variants are named pairs of payment providers and their configuration.

   .. note::

      Variant names are used in URLs so it's best to stick to ASCII.

   .. note::

      PAYMENT_HOST can also be a callable object.
