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

Last change on this file since 12721 was 12720, checked in by uli, 10 years ago

Rename contract_id.

  • Property svn:keywords set to Id
File size: 8.4 KB
Line 
1## $Id: interfaces.py 12720 2015-03-10 16:02:22Z uli $
2##
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##
18import decimal
19from zc.sourcefactory.basic import BasicSourceFactory
20from zope import schema
21from zope.component import getUtilitiesFor
22from zope.container.interfaces import IContainer
23from zope.container.constraints import contains
24from zope.interface import Interface, Attribute
25from waeup.ikoba.interfaces import (
26    IIkobaObject, SimpleIkobaVocabulary, ContextualDictSourceFactoryBase)
27from waeup.ikoba.interfaces import MessageFactory as _
28from waeup.ikoba.payments.currencies import ISO_4217_CURRENCIES_VOCAB
29
30#: Possible states of payments
31STATE_UNPAID = 1
32STATE_PAID = 2
33STATE_FAILED = 4
34
35payment_states = SimpleIkobaVocabulary(
36    (_('Not yet paid'), STATE_UNPAID),
37    (_('Paid'), STATE_PAID),
38    (_('Failed'), STATE_FAILED),
39    )
40
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
90    def create_payment(payer, payment_item_list, payee):
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
104    def next_step(payment_id):
105        """Returns a payment (as context) and a view name.
106
107        May result in (None, None).
108        """
109
110
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
121class PaymentCategorySource(ContextualDictSourceFactoryBase):
122    """A payment category source delivers all categories of payments.
123
124    """
125    #: name of dict to deliver from ikoba utils.
126    DICT_NAME = 'PAYMENT_CATEGORIES'
127
128
129class IPaymentsContainer(IIkobaObject):
130    """A container for all kind of payment objects.
131
132    """
133
134
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 IPayableFinder(Interface):
147    """Finds payables.
148    """
149    def get_payable_by_id(item_id):
150        """Get an item by its Id, or none.
151        """
152
153
154class IPaymentItem(Interface):
155    """Something to sell.
156    """
157    item_id = schema.TextLine(
158        title=u'Payment Item ID',
159        required=True,
160        )
161
162    title = schema.TextLine(
163        title=u'Title',
164        description=u'A short title of the good sold.',
165        required=True,
166        default=u'Unnamed'
167        )
168
169    amount = schema.Decimal(
170        title=u'Amount',
171        description=u'Total amount, includung any taxes, fees, etc.',
172        required=True,
173        default=decimal.Decimal('0.00'),
174        )
175
176
177class IPayment(IContainer, IIkobaObject):
178    """A base representation of payments.
179
180    In a payment, a payer payes someone (the payee) for something, the
181    item to pay.
182
183    We currently support only the case where one payer pays one payee
184    for one item. The item might include taxes, handling,
185    shipping, etc.
186
187    As in RL any payment is actually performed by some financial
188    service provider (like paypal, interswitch, etc.), each of which
189    might provide several types of payments (credit card, scratch
190    card, you name it).
191
192    In Ikoba we call financial service providers 'gateway' and their
193    types of services are handled as gateway types. Therefore PayPal
194    handling a credit card payment is different from PayPal handling a
195    regular PayPal account transaction.
196
197    A payment can be approve()d, which means the act of paying was
198    really performed. It can also fail for any reason, in which case
199    we mark the payment 'failed'.
200    """
201    contains(IPaymentItem)
202
203    payment_id = schema.TextLine(
204        title=u'Payment Identifier',
205        default=None,
206        required=True,
207        )
208
209    payer_id = schema.TextLine(
210        title=u'Payer',
211        default=None,
212        required=True,
213        )
214
215    payee_id = schema.TextLine(
216        title=u'Payee',
217        default=None,
218        required=False,
219        )
220
221    payable_id = schema.TextLine(
222        title=u'ID of item/good being paid',
223        default=None,
224        required=False,
225        )
226
227    gateway_service = schema.Choice(
228        title=u'Payment Gateway',
229        description=u'Payment gateway that handles this transaction.',
230        source=PaymentGatewayServicesSource(),
231        default=None,
232        required=True,
233        )
234
235    state = schema.Choice(
236        title=_(u'Payment State'),
237        default=STATE_UNPAID,
238        vocabulary=payment_states,
239        required=True,
240        )
241
242    creation_date = schema.Datetime(
243        title=_(u'Creation Datetime'),
244        readonly=False,
245        required=False,
246        )
247
248    payment_date = schema.Datetime(
249        title=_(u'Payment Datetime'),
250        required=False,
251        readonly=False,
252        )
253
254    currency = schema.Choice(
255        title=u'Currency',
256        source=ISO_4217_CURRENCIES_VOCAB,
257        required=True,
258        default='USD',
259        )
260
261    amount = Attribute("Sum of amounts of items contained")
262
263    def approve():
264        """Approve a payment.
265
266        The payment was approved and can now be considered payed. This
267        kind of approvement means the final one (in case there are
268        several instances to ask).
269        """
270
271    def mark_failed(reason=None):
272        """Mark the payment as failed.
273
274        A failed payment was canceled due to technical problems,
275        insufficient funds, etc.
276        """
277
278    def add_payment_item(item):
279        """Payments contain payment items.
280
281        Add one
282        """
283
284
285class IPayer(Interface):
286    """A payer.
287    """
288    payer_id = schema.TextLine(
289        title=u'Payer ID',
290        required=True,
291        )
292
293    first_name = schema.TextLine(
294        title=u'First Name',
295        required=True,
296        )
297
298    last_name = schema.TextLine(
299        title=u'Last Name',
300        required=True,
301        )
302
303
304class IPayee(Interface):
305    """A person or institution being paid.
306    """
307    payee_id = schema.TextLine(
308        title=u'Payee ID',
309        required=True
310        )
Note: See TracBrowser for help on using the repository browser.