source: main/waeup.ikoba/branches/uli-payments/src/waeup/ikoba/payments/interfaces.py @ 12711

Last change on this file since 12711 was 12703, checked in by uli, 10 years ago

Make IPayments IkobaObjects?, for breadcrumbs sake.

  • Property svn:keywords set to Id
File size: 8.1 KB
RevLine 
[7195]1## $Id: interfaces.py 12703 2015-03-09 06:18:33Z uli $
[6861]2##
[7195]3## Copyright (C) 2011 Uli Fouquet & Henrik Bettermann
4## This program is free software; you can redistribute it and/or modify
5## it under the terms of the GNU General Public License as published by
6## the Free Software Foundation; either version 2 of the License, or
7## (at your option) any later version.
8##
9## This program is distributed in the hope that it will be useful,
10## but WITHOUT ANY WARRANTY; without even the implied warranty of
11## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12## GNU General Public License for more details.
13##
14## You should have received a copy of the GNU General Public License
15## along with this program; if not, write to the Free Software
16## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17##
[12311]18import decimal
19from zc.sourcefactory.basic import BasicSourceFactory
[6864]20from zope import schema
[12311]21from zope.component import getUtilitiesFor
[12671]22from zope.container.interfaces import IContainer
23from zope.container.constraints import contains
24from zope.interface import Interface, Attribute
[11949]25from waeup.ikoba.interfaces import (
[12311]26    IIkobaObject, SimpleIkobaVocabulary, ContextualDictSourceFactoryBase)
[11949]27from waeup.ikoba.interfaces import MessageFactory as _
[12311]28from waeup.ikoba.payments.currencies import ISO_4217_CURRENCIES_VOCAB
[6861]29
[12311]30#: Possible states of payments
31STATE_UNPAID = 1
32STATE_PAID = 2
33STATE_FAILED = 4
34
[11949]35payment_states = SimpleIkobaVocabulary(
[12311]36    (_('Not yet paid'), STATE_UNPAID),
37    (_('Paid'), STATE_PAID),
38    (_('Failed'), STATE_FAILED),
[7627]39    )
40
[12311]41
42class PaymentGatewayServicesSource(BasicSourceFactory):
43    """A source that lists available payment services.
44
45    Suitable for forms etc. Token and value correspond to the name the
46    respective IPaymentGatewayService utility is registered with.
47    """
48
49    _services = None
50
51    @classmethod
52    def services(cls):
53        """Cache the services registered on startup.
54
55        We assume that services do not change after startup.
56        """
57        if cls._services is None:
58            cls._services = dict(getUtilitiesFor(IPaymentGatewayService))
59        return cls._services
60
61    def getValues(self):
62        """Get payment gateway registration names.
63        """
64        return sorted(PaymentGatewayServicesSource.services().keys())
65
66    def getTitle(self, value):
67        """Get title of the respective service, if it exists.
68        """
69        service = PaymentGatewayServicesSource.services().get(value, None)
70        if service is not None:
71            return service.title
72
73
74class IPaymentGatewayService(Interface):
75    """A financial gateway service.
76
77    Any gateway provider might provide several services. For instance
78    payments by credit card, scratch card, bank transfer, etc. An
79    `IPaymentGatewayService` represents one of those services.
80
81    Payment services are normally registered as a named global
82    utility.
83    """
84    title = schema.TextLine(
85        title=u'Title',
86        description=u'Human readable name of gateway service.',
87        required=True,
88        )
89
[12671]90    def create_payment(payer, payment_item_list,  payee):
[12311]91        """Create a payment.
92
93        For all parameters we expect an object, that implements
94        `IPayer`, `IPaymentItem`, or `IPayee` respectively. If not,
95        then the given objects must be at least adaptable to the
96        respective interface.
97
98        Therfore you can pass in some `Customer` as long as there is
99        some `IPayer` adapter for `Customer` objects defined.
100
101        Returns an `IPayment` object.
102        """
103
[12701]104    def next_step(payment_id):
105        """Returns a payment (as context) and a view name.
[12311]106
[12701]107        May result in (None, None).
108        """
109
110
[12671]111class IPaymentGatewayServicesLister(Interface):
112    """A utility that lists all valid payment gateways.
113
114    This is a subset of the available payment methods, as some might
115    be disabled in some site.
116
117    Register your own lister in customized sites!
118    """
119
120
[9405]121class PaymentCategorySource(ContextualDictSourceFactoryBase):
[9864]122    """A payment category source delivers all categories of payments.
123
[9405]124    """
[11949]125    #: name of dict to deliver from ikoba utils.
[9405]126    DICT_NAME = 'PAYMENT_CATEGORIES'
[7627]127
[12311]128
[11949]129class IPaymentsContainer(IIkobaObject):
[6861]130    """A container for all kind of payment objects.
131
132    """
[6864]133
[12311]134
[12671]135class ICreditCard(Interface):
136    """A credit card.
137
138    A credit card is connected to a Payer.
139    """
140    credit_card_id = schema.TextLine(
141        title=u'Internal Credit Card ID',
142        required=True,
143        )
144
145
146class IPaymentItem(Interface):
147    """Something to sell.
148    """
149    item_id = schema.TextLine(
150        title=u'Payment Item ID',
151        required=True,
152        )
153
154    title = schema.TextLine(
155        title=u'Title',
156        description=u'A short title of the good sold.',
157        required=True,
158        default=u'Unnamed'
159        )
160
161    amount = schema.Decimal(
162        title=u'Amount',
163        description=u'Total amount, includung any taxes, fees, etc.',
164        required=True,
165        default=decimal.Decimal('0.00'),
166        )
167
168
[12703]169class IPayment(IContainer, IIkobaObject):
[6864]170    """A base representation of payments.
171
[12311]172    In a payment, a payer payes someone (the payee) for something, the
173    item to pay.
174
175    We currently support only the case where one payer pays one payee
176    for one item. The item might include taxes, handling,
177    shipping, etc.
178
179    As in RL any payment is actually performed by some financial
180    service provider (like paypal, interswitch, etc.), each of which
181    might provide several types of payments (credit card, scratch
182    card, you name it).
183
184    In Ikoba we call financial service providers 'gateway' and their
185    types of services are handled as gateway types. Therefore PayPal
186    handling a credit card payment is different from PayPal handling a
187    regular PayPal account transaction.
188
189    A payment can be approve()d, which means the act of paying was
190    really performed. It can also fail for any reason, in which case
191    we mark the payment 'failed'.
[6864]192    """
[12671]193    contains(IPaymentItem)
194
[12311]195    payment_id = schema.TextLine(
196        title=u'Payment Identifier',
197        default=None,
198        required=True,
199        )
[6864]200
[12311]201    payer_id = schema.TextLine(
202        title=u'Payer',
203        default=None,
204        required=True,
[6864]205        )
206
[12671]207    payee_id = schema.TextLine(
208        title=u'Payee',
[12311]209        default=None,
[12671]210        required=False,
211    )
[6864]212
[12311]213    gateway_service = schema.Choice(
214        title=u'Payment Gateway',
215        description=u'Payment gateway that handles this transaction.',
216        source=PaymentGatewayServicesSource(),
217        default=None,
218        required=True,
[9984]219        )
220
[12311]221    state = schema.Choice(
222        title=_(u'Payment State'),
223        default=STATE_UNPAID,
224        vocabulary=payment_states,
225        required=True,
[7020]226        )
227
[8170]228    creation_date = schema.Datetime(
[12311]229        title=_(u'Creation Datetime'),
230        readonly=False,
231        required=False,
[6864]232        )
233
[8170]234    payment_date = schema.Datetime(
[12311]235        title=_(u'Payment Datetime'),
236        required=False,
237        readonly=False,
[6864]238        )
239
[12671]240    currency = schema.Choice(
241        title=u'Currency',
242        source=ISO_4217_CURRENCIES_VOCAB,
[12311]243        required=True,
[12671]244        default='USD',
[6864]245        )
246
[12671]247    amount = Attribute("Sum of amounts of items contained")
248
[12311]249    def approve():
250        """Approve a payment.
251
252        The payment was approved and can now be considered payed. This
253        kind of approvement means the final one (in case there are
254        several instances to ask).
255        """
256
257    def mark_failed(reason=None):
258        """Mark the payment as failed.
259
260        A failed payment was canceled due to technical problems,
261        insufficient funds, etc.
262        """
263
[12671]264    def add_payment_item(item):
265        """Payments contain payment items.
[12311]266
[12671]267        Add one
268        """
[6864]269
270
[12311]271class IPayer(Interface):
272    """A payer.
273    """
274    payer_id = schema.TextLine(
275        title=u'Payer ID',
276        required=True,
277        )
278
279    first_name = schema.TextLine(
280        title=u'First Name',
[12319]281        required=True,
[12311]282        )
283
284    last_name = schema.TextLine(
285        title=u'Last Name',
[12319]286        required=True,
[12311]287        )
288
289
290class IPayee(Interface):
291    """A person or institution being paid.
292    """
293    payee_id = schema.TextLine(
294        title=u'Payee ID',
295        required=True
296        )
Note: See TracBrowser for help on using the repository browser.