initial commit
[Business-BatchPayment.git] / BatchPayment / Item.pm
1 package Business::BatchPayment::Item;
2
3 use Moose;
4 use Moose::Util::TypeConstraints;
5 use MooseX::UndefTolerant;
6 use DateTime;
7
8 =head1 NAME
9
10 Business::BatchPayment::Item
11
12 =head1 DESCRIPTION
13
14 A Business::BatchPayment::Item represents a single payment request or 
15 reply (approval or rejection).  When submitting a batch, the merchant 
16 system constructs B::BP::Item objects for each attempted payment in 
17 the batch.  Results downloaded from the gateway are returned as a 
18 list of Items with the 'approved' field set to a true or false value. 
19
20 =head1 REQUIRED ATTRIBUTES
21
22 =over 4
23
24 =item action
25
26 "payment" or "credit".  Most processors support only "payment".
27 "payment" is defined as "money transfer FROM the account identified in the 
28 Item TO the account identified by the Processor object's login settings."
29 "credit" is the other direction.
30
31 =cut
32
33 enum 'Action' => qw(payment credit);
34 coerce 'Action', from 'Str', via { lc $_ };
35 has action => (
36   is  => 'rw',
37   isa => 'Action',
38   default => 'payment',
39   required => 1,
40   coerce => 1,
41 );
42
43 =item payment_type
44
45 "CC" or "ECHECK".  Most processors will only support 
46 one or the other, and if set on the BBP::Processor object, this is not
47 required.
48
49 =cut
50
51 # are we okay with these names?
52 enum 'PaymentType' => qw( CC ECHECK );
53 has payment_type => ( is  => 'rw', isa => 'PaymentType' );
54
55 =item amount
56
57 the amount, as a decimal number.  Required only in request
58 items.
59
60 =cut
61
62 # perhaps we should apply roles that distinguish request and reply items?
63 # they have different required fields.
64 has amount => (
65   is  => 'rw',
66   isa => 'Num',
67 );
68
69 =item tid
70
71 transaction identifier.  Requests must provide this.  It's 
72 a token of some kind to be passed to the gateway and used to identify the 
73 reply.  For now it's required to be an integer.  An invoice number would
74 be a good choice.
75
76 =cut
77
78 has tid => ( is  => 'rw', isa => 'Int' );
79
80 =back
81
82 =head1 OPTIONAL ATTRIBUTES
83
84 =head2 Customer Information
85
86 =over 4
87
88 =item customer_id
89
90 A customer number or other identifier, for the merchant's
91 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'
164 'business checking', 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 
253 contain a value even if the payment was successful (use C<approved> 
254 to determine that.)
255
256 =back
257
258 =cut
259
260 has approved        => ( is => 'rw', isa => 'Maybe[Bool]' );
261
262 has payment_date    => ( is => 'rw', isa => 'DateTime' );
263
264 has [qw( 
265   authorization
266   error_message
267   order_number
268   assigned_token
269 )] => ( is => 'rw', isa => 'Str');
270
271 __PACKAGE__->meta->make_immutable;
272
273 1;