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

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

Let currency be a payment attribute, not a payment item attribute. Should give more consistency.

  • Property svn:keywords set to Id
File size: 7.7 KB
RevLine 
[7195]1## $Id: interfaces.py 12649 2015-03-02 01:04:18Z 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
[12636]22from zope.container.interfaces import IContainer
[12642]23from zope.container.constraints import contains
[12645]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
[12645]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
104
[9405]105class PaymentCategorySource(ContextualDictSourceFactoryBase):
[9864]106    """A payment category source delivers all categories of payments.
107
[9405]108    """
[11949]109    #: name of dict to deliver from ikoba utils.
[9405]110    DICT_NAME = 'PAYMENT_CATEGORIES'
[7627]111
[12311]112
[11949]113class IPaymentsContainer(IIkobaObject):
[6861]114    """A container for all kind of payment objects.
115
116    """
[6864]117
[12311]118
[12636]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
153class IPayment(IContainer):
[6864]154    """A base representation of payments.
155
[12311]156    In a payment, a payer payes someone (the payee) for something, the
157    item to pay.
158
159    We currently support only the case where one payer pays one payee
160    for one item. The item might include taxes, handling,
161    shipping, etc.
162
163    As in RL any payment is actually performed by some financial
164    service provider (like paypal, interswitch, etc.), each of which
165    might provide several types of payments (credit card, scratch
166    card, you name it).
167
168    In Ikoba we call financial service providers 'gateway' and their
169    types of services are handled as gateway types. Therefore PayPal
170    handling a credit card payment is different from PayPal handling a
171    regular PayPal account transaction.
172
173    A payment can be approve()d, which means the act of paying was
174    really performed. It can also fail for any reason, in which case
175    we mark the payment 'failed'.
[6864]176    """
[12636]177    contains(IPaymentItem)
178
[12311]179    payment_id = schema.TextLine(
180        title=u'Payment Identifier',
181        default=None,
182        required=True,
183        )
[6864]184
[12311]185    payer_id = schema.TextLine(
186        title=u'Payer',
187        default=None,
188        required=True,
[6864]189        )
190
[12640]191    payee_id = schema.TextLine(
192        title=u'Payee',
[12311]193        default=None,
[12640]194        required=False,
195    )
[6864]196
[12311]197    gateway_service = schema.Choice(
198        title=u'Payment Gateway',
199        description=u'Payment gateway that handles this transaction.',
200        source=PaymentGatewayServicesSource(),
201        default=None,
202        required=True,
[9984]203        )
204
[12311]205    state = schema.Choice(
206        title=_(u'Payment State'),
207        default=STATE_UNPAID,
208        vocabulary=payment_states,
209        required=True,
[7020]210        )
211
[8170]212    creation_date = schema.Datetime(
[12311]213        title=_(u'Creation Datetime'),
214        readonly=False,
215        required=False,
[6864]216        )
217
[8170]218    payment_date = schema.Datetime(
[12311]219        title=_(u'Payment Datetime'),
220        required=False,
221        readonly=False,
[6864]222        )
223
[12649]224
225    currency = schema.Choice(
226        title=u'Currency',
227        source=ISO_4217_CURRENCIES_VOCAB,
228        required=True,
229        default='USD',
230        )
231
[12645]232    amount = Attribute("Sum of amounts of items contained")
[6864]233
[12311]234    def approve():
235        """Approve a payment.
236
237        The payment was approved and can now be considered payed. This
238        kind of approvement means the final one (in case there are
239        several instances to ask).
240        """
241
242    def mark_failed(reason=None):
243        """Mark the payment as failed.
244
245        A failed payment was canceled due to technical problems,
246        insufficient funds, etc.
247        """
248
[12640]249    def add_payment_item(item):
250        """Payments contain payment items.
251
252        Add one
253        """
254
255
[12311]256class IPayer(Interface):
257    """A payer.
258    """
259    payer_id = schema.TextLine(
260        title=u'Payer ID',
261        required=True,
262        )
263
264    first_name = schema.TextLine(
265        title=u'First Name',
[12319]266        required=True,
[12311]267        )
268
269    last_name = schema.TextLine(
270        title=u'Last Name',
[12319]271        required=True,
[12311]272        )
273
274
275class IPayee(Interface):
276    """A person or institution being paid.
277    """
278    payee_id = schema.TextLine(
279        title=u'Payee ID',
280        required=True
281        )
Note: See TracBrowser for help on using the repository browser.