source: main/waeup.ikoba/branches/uli-fake-gw-provider/src/waeup/ikoba/payments/interfaces.py @ 12640

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

Make payment items real subobjects of payments.

  • Property svn:keywords set to Id
File size: 7.9 KB
Line 
1## $Id: interfaces.py 12640 2015-03-01 22:50:48Z 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 containers, contains
24from zope.interface import Interface
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,  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
105class PaymentCategorySource(ContextualDictSourceFactoryBase):
106    """A payment category source delivers all categories of payments.
107
108    """
109    #: name of dict to deliver from ikoba utils.
110    DICT_NAME = 'PAYMENT_CATEGORIES'
111
112
113class IPaymentsContainer(IIkobaObject):
114    """A container for all kind of payment objects.
115
116    """
117
118
119class ICreditCard(Interface):
120    """A credit card.
121
122    A credit card is connected to a Payer.
123    """
124    credit_card_id = schema.TextLine(
125        title=u'Internal Credit Card ID',
126        required=True,
127        )
128
129
130class IPaymentItem(Interface):
131    """Something to sell.
132    """
133    item_id = schema.TextLine(
134        title=u'Payment Item ID',
135        required=True,
136        )
137
138    title = schema.TextLine(
139        title=u'Title',
140        description=u'A short title of the good sold.',
141        required=True,
142        default=u'Unnamed'
143        )
144
145    amount = schema.Decimal(
146        title=u'Amount',
147        description=u'Total amount, includung any taxes, fees, etc.',
148        required=True,
149        default=decimal.Decimal('0.00'),
150        )
151
152    currency = schema.Choice(
153        title=u'Currency',
154        source=ISO_4217_CURRENCIES_VOCAB,
155        required=True,
156        default='USD',
157        )
158
159
160class IPayment(IContainer):
161    """A base representation of payments.
162
163    In a payment, a payer payes someone (the payee) for something, the
164    item to pay.
165
166    We currently support only the case where one payer pays one payee
167    for one item. The item might include taxes, handling,
168    shipping, etc.
169
170    As in RL any payment is actually performed by some financial
171    service provider (like paypal, interswitch, etc.), each of which
172    might provide several types of payments (credit card, scratch
173    card, you name it).
174
175    In Ikoba we call financial service providers 'gateway' and their
176    types of services are handled as gateway types. Therefore PayPal
177    handling a credit card payment is different from PayPal handling a
178    regular PayPal account transaction.
179
180    A payment can be approve()d, which means the act of paying was
181    really performed. It can also fail for any reason, in which case
182    we mark the payment 'failed'.
183    """
184    contains(IPaymentItem)
185
186    payment_id = schema.TextLine(
187        title=u'Payment Identifier',
188        default=None,
189        required=True,
190        )
191
192    payer_id = schema.TextLine(
193        title=u'Payer',
194        default=None,
195        required=True,
196        )
197
198    payee_id = schema.TextLine(
199        title=u'Payee',
200        default=None,
201        required=False,
202    )
203
204    gateway_service = schema.Choice(
205        title=u'Payment Gateway',
206        description=u'Payment gateway that handles this transaction.',
207        source=PaymentGatewayServicesSource(),
208        default=None,
209        required=True,
210        )
211
212    state = schema.Choice(
213        title=_(u'Payment State'),
214        default=STATE_UNPAID,
215        vocabulary=payment_states,
216        required=True,
217        )
218
219    creation_date = schema.Datetime(
220        title=_(u'Creation Datetime'),
221        readonly=False,
222        required=False,
223        )
224
225    payment_date = schema.Datetime(
226        title=_(u'Payment Datetime'),
227        required=False,
228        readonly=False,
229        )
230
231    amount = schema.Decimal(
232        title=_(u'Amount'),
233        description=_(
234            'The overall sum payed, including all taxes fees, etc.'),
235        default=decimal.Decimal("0.00"),
236        required=True,
237        readonly=False,
238        )
239
240    def approve():
241        """Approve a payment.
242
243        The payment was approved and can now be considered payed. This
244        kind of approvement means the final one (in case there are
245        several instances to ask).
246        """
247
248    def mark_failed(reason=None):
249        """Mark the payment as failed.
250
251        A failed payment was canceled due to technical problems,
252        insufficient funds, etc.
253        """
254
255    def add_payment_item(item):
256        """Payments contain payment items.
257
258        Add one
259        """
260
261
262class IPayer(Interface):
263    """A payer.
264    """
265    payer_id = schema.TextLine(
266        title=u'Payer ID',
267        required=True,
268        )
269
270    first_name = schema.TextLine(
271        title=u'First Name',
272        required=True,
273        )
274
275    last_name = schema.TextLine(
276        title=u'Last Name',
277        required=True,
278        )
279
280
281class IPayee(Interface):
282    """A person or institution being paid.
283    """
284    payee_id = schema.TextLine(
285        title=u'Payee ID',
286        required=True
287        )
Note: See TracBrowser for help on using the repository browser.