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