error callbacks, more structure for parse/format methods
[Business-BatchPayment.git] / BatchPayment / Item.pm
1 package Business::BatchPayment::Item;
2
3 use strict;
4 use Moose;
5 use Moose::Util::TypeConstraints;
6 use MooseX::UndefTolerant;
7 use DateTime;
8
9 =head1 NAME
10
11 Business::BatchPayment::Item
12
13 =head1 DESCRIPTION
14
15 A Business::BatchPayment::Item represents a single payment request or 
16 reply (approval or rejection).  When submitting a batch, the merchant 
17 system constructs B::BP::Item objects for each attempted payment in 
18 the batch.  Results downloaded from the gateway are returned as a 
19 list of Items with the 'approved' field set to a true or false value. 
20
21 =head1 REQUIRED ATTRIBUTES
22
23 =over 4
24
25 =item action
26
27 "payment" or "credit".  Most processors support only "payment".
28 "payment" is defined as "money transfer FROM the account identified in the 
29 Item TO the account identified by the Processor object's login settings."
30 "credit" is the other direction.
31
32 =cut
33
34 enum 'Action' => qw(payment credit);
35 coerce 'Action', from 'Str', via { lc $_ };
36 has action => (
37   is  => 'rw',
38   isa => 'Action',
39   default => 'payment',
40   required => 1,
41   coerce => 1,
42 );
43
44 =item payment_type
45
46 "CC" or "ECHECK".  Most processors will only support 
47 one or the other, and if set on the BBP::Processor object, this is not
48 required.
49
50 =cut
51
52 # are we okay with these names?
53 enum 'PaymentType' => qw( CC ECHECK );
54 has payment_type => ( is  => 'rw', isa => 'PaymentType' );
55
56 =item amount
57
58 the amount, as a decimal number.  Required only in request
59 items.
60
61 =cut
62
63 # perhaps we should apply roles that distinguish request and reply items?
64 # they have different required fields.
65 has amount => (
66   is  => 'rw',
67   isa => 'Num',
68 );
69
70 =item tid
71
72 transaction identifier.  Requests must provide this.  It's a token of 
73 some kind to be passed to the gateway and used to identify the reply.  
74 For now it's required to be an integer.  An invoice number would be 
75 a good choice.
76
77 =cut
78
79 has tid => ( is  => 'rw', isa => 'Int' );
80
81 =back
82
83 =head1 OPTIONAL ATTRIBUTES
84
85 =head2 Customer Information
86
87 =over 4
88
89 =item customer_id
90
91 A customer number or other identifier, for the merchant's use.
92
93 =item first_name
94
95 First name.
96
97 =item last_name
98
99 Last name.
100
101 =item company
102
103 Company name.
104
105 =item address, address2, city, state, country, zip
106
107 Billing address fields.  Credit card processors may use these (especially
108 zip) for authentication.
109
110 =cut
111
112 has [ qw(
113   customer_id
114   first_name
115   last_name
116   company
117   address
118   address2
119   city
120   state
121   country
122   zip
123 ) ] => ( is => 'rw', isa => 'Str', default => '' );
124
125 =back
126
127 =head2 Transaction Information
128
129 =over 4
130
131 =item process_date
132
133 The date requested for processing.
134
135 =item invoice_number
136
137 An invoice number, for your use.
138
139 =cut
140
141 class_type 'DateTime';
142 coerce 'DateTime', from 'Int', via { DateTime->from_epoch($_) };
143 has process_date    => ( is => 'rw', isa => 'DateTime', coerce => 1 );
144
145 has invoice_number  => ( is => 'rw', isa => 'Str' );
146
147 =back
148
149 =head2 Bank Transfer / ACH / EFT
150
151 =over 4
152
153 =item account_number
154
155 Bank account number.
156
157 =item routing_code
158
159 Bank's routing code.
160
161 =item account_type
162
163 Can be 'personal checking', 'personal savings', 'business checking', 
164 or 'business savings'.
165
166 =cut
167
168 enum 'Account_Type' => [
169   'personal checking',
170   'personal savings',
171   'business checking',
172   'business savings',
173 ];
174 coerce 'Account_Type', from 'Str', via { lc $_ };
175
176 has account_number  => ( is => 'rw', isa => 'Str' );
177 has routing_code    => ( is => 'rw', isa => 'Str' );
178 has account_type    => ( is => 'rw', isa => 'Account_Type', coerce => 1 );
179
180 =back
181
182 =head2 Credit Card
183
184 =over 4
185
186 =item card_number
187
188 Credit card number.
189
190 =item expiration
191
192 Credit card expiration, MMYY format.
193
194 =cut
195
196 has card_number     => ( is => 'rw', isa => 'Str' );
197 has expiration      => ( is => 'rw', isa => 'Str' );
198
199 =back
200
201 =head2 Tokenized Payment
202
203 =over 4
204
205 =item pay_by_token
206
207 If your gateway supports it, this may be 
208 provided instead of card_number/account_number.  See also 
209 C<assigned_token> below.
210
211 =cut
212
213 has pay_by_token    => ( is => 'rw', isa => 'Str' );
214
215 =back
216
217 =head1 REPLY ATTRIBUTES
218
219 =over 4
220
221 =item approved 
222
223 Boolean field for whether the item was approved.  This 
224 will always be set on replies.
225
226 =item payment_date 
227
228 The date the payment was processed, as a DateTime
229 object.
230
231 =item order_number 
232
233 The transaction identifier returned by the gateway
234 (not to be confused with 'tid', which is a transaction identifier assigned
235 by the merchant system).  This is usually the identifier for performing 
236 other operations on the transaction, like voiding or refunding it.
237
238 =item authorization
239
240 The authorization code, probably only meaningful for credit cards.  
241 Should be undef (or not present) if the transaction wasn't approved.
242
243 =item assigned_token
244
245 In tokenized systems which store the customer's account number or 
246 credit card for future transactions, this is the token assigned to 
247 identify that account.  Pass it as 'pay_by_token' to use that payment 
248 account again.
249
250 =item error_message
251
252 The message returned by the gateway.  This may contain a value even 
253 if the payment was successful (use C<approved> to determine that.)
254
255 =back
256
257 =cut
258
259 has approved        => ( is => 'rw', isa => 'Maybe[Bool]' );
260
261 has payment_date    => ( is => 'rw', isa => 'DateTime' );
262
263 has [qw( 
264   authorization
265   error_message
266   order_number
267   assigned_token
268 )] => ( is => 'rw', isa => 'Str');
269
270 __PACKAGE__->meta->make_immutable;
271
272 1;