IDT payment type, RT#39868
[freeside.git] / FS / FS / payby.pm
1 package FS::payby;
2
3 use strict;
4 use vars qw(%hash %payby2bop);
5 use Tie::IxHash;
6 use Business::CreditCard;
7
8
9 =head1 NAME
10
11 FS::payby - Object methods for payment type records
12
13 =head1 SYNOPSIS
14
15   use FS::payby;
16
17   #for now...
18
19   my @payby = FS::payby->payby;
20
21   my $bool = FS::payby->can_payby('cust_main', 'CARD');
22
23   tie my %payby, 'Tie::IxHash', FS::payby->payby2longname
24
25   my @cust_payby = FS::payby->cust_payby;
26
27   tie my %payby, 'Tie::IxHash', FS::payby->cust_payby2longname
28
29 =head1 DESCRIPTION
30
31 Payment types.
32
33 =head1 METHODS
34
35 =over 4 
36
37 =item
38
39 =cut
40
41 # paybys can be any/all of:
42 # - a customer payment type (cust_main.payby)
43 # - a payment or refund type (cust_pay.payby, cust_pay_batch.payby, cust_refund.payby)
44 # - an event type (part_bill_event.payby)
45
46 tie %hash, 'Tie::IxHash',
47   'CARD' => {
48     tinyname  => 'card',
49     shortname => 'Credit card',
50     longname  => 'Credit card (automatic)',
51     realtime  => 1,
52   },
53   'DCRD' => {
54     tinyname  => 'card',
55     shortname => 'Credit card',
56     longname  => 'Credit card (on-demand)',
57     cust_pay  => 'CARD', #this is a customer type only, payments are CARD...
58     realtime  => 1,
59   },
60   'CHEK' => {
61     tinyname  => 'check',
62     shortname => 'Electronic check',
63     longname  => 'Electronic check (automatic)',
64     realtime  => 1,
65   },
66   'DCHK' => {
67     tinyname  => 'check',
68     shortname => 'Electronic check',
69     longname  => 'Electronic check (on-demand)',
70     cust_pay  => 'CHEK', #this is a customer type only, payments are CHEK...
71     realtime  => 1,
72   },
73   'LECB' => {
74     tinyname  => 'phone bill',
75     shortname => 'Phone bill billing',
76     longname  => 'Phone bill billing',
77     realtime  => 1,
78   },
79   'BILL' => {
80     tinyname  => 'billing',
81     shortname => 'Billing',
82     payname   => 'Check',
83     longname  => 'Billing',
84   },
85   'PPAL' => {
86     tinyname  => 'PayPal',
87     shortname => 'PayPal',
88     longname  => 'PayPal',
89     cust_main => '', #not yet a customer type, but could be once we can do
90                      # invoice presentment via paypal
91   },
92   'PREP' => {
93     tinyname  => 'prepaid card',
94     shortname => 'Prepaid card',
95     longname  => 'Prepaid card',
96     cust_main => 'BILL', #this is a payment type only, customers go to BILL...
97   },
98   'CASH' => {
99     tinyname  => 'cash',
100     shortname => 'Cash', # initial payment, then billing
101     longname  => 'Cash',
102     cust_main => 'BILL', #this is a payment type only, customers go to BILL...
103   },
104   'WEST' => {
105     tinyname  => 'western union',
106     shortname => 'Western Union', # initial payment, then billing
107     longname  => 'Western Union',
108     cust_main => 'BILL', #this is a payment type only, customers go to BILL...
109   },
110   'IDTP' => {
111     tinyname  => 'IDT',
112     shortname => 'IDT Payment Services',
113     longname  => 'IDT Payment Services',
114     cust_main => '', #this is a payment type only
115   },
116   'MCRD' => { #not the same as DCRD
117     tinyname  => 'card',
118     shortname => 'Manual credit card', # initial payment, then billing
119     longname  => 'Manual credit card', 
120     cust_main => 'BILL', #this is a payment type only, customers go to BILL...
121   },
122   'MCHK' => { #not the same as DCHK
123     tinyname  => 'card',
124     shortname => 'Manual electronic check', # initial payment, then billing
125     longname  => 'Manual electronic check', 
126     cust_main => 'BILL', #this is a payment type only, customers go to BILL...
127   },
128   'APPL' => {
129     tinyname  => 'apple store',
130     shortname => 'Apple Store',
131     longname  => 'Apple Store',
132     cust_main => 'BILL', #this is a payment type only, customers go to BILL...
133   },
134   'ANRD' => {
135     tinyname  => 'android market',
136     shortname => 'Android Market',
137     longname  => 'Android Market',
138     cust_main => 'BILL', #this is a payment type only, customers go to BILL...
139   },
140   'EDI' => {
141     tinyname  => 'EDI',
142     shortname => 'Electronic Debit (EDI)',
143     longname  => 'Electronic Debit (EDI)',
144     cust_main => '', #not a customer type
145   },
146   'WIRE' => {
147     tinyname  => 'Wire',
148     shortname => 'Wire transfer',
149     longname  => 'Wire transfer',
150     cust_main => '', #not a customer type
151   },
152   'COMP' => {
153     tinyname  => 'comp',
154     shortname => 'Complimentary',
155     longname  => 'Complimentary',
156     cust_pay  => '', # (free) is depricated as a payment type in cust_pay
157   },
158   'CBAK' => {
159     tinyname  => 'chargeback',
160     shortname => 'Chargeback',
161     longname  => 'Chargeback',
162     cust_main => '', # not a customer type
163   },
164 ;
165
166 sub payby {
167   keys %hash;
168 }
169
170 sub can_payby {
171   my( $self, $table, $payby ) = @_;
172
173   #return "Illegal payby" unless $hash{$payby};
174   return 0 unless $hash{$payby};
175
176   $table = 'cust_pay' if $table =~ /^cust_(pay_pending|pay_batch|pay_void|refund)$/;
177   return 0 if exists( $hash{$payby}->{$table} );
178
179   return 1;
180 }
181
182 sub realtime {  # can use realtime payment facilities
183   my( $self, $payby ) = @_;
184
185   return 0 unless $hash{$payby};
186   return 0 unless exists( $hash{$payby}->{realtime} );
187
188   return $hash{$payby}->{realtime};
189 }
190
191 sub payby2shortname {
192   my $self = shift;
193   map { $_ => $hash{$_}->{shortname} } $self->payby;
194 }
195
196 sub payby2longname {
197   my $self = shift;
198   map { $_ => $hash{$_}->{longname} } $self->payby;
199 }
200
201 sub shortname {
202   my( $self, $payby ) = @_;
203   $hash{$payby}->{shortname};
204 }
205
206 sub payname {
207   my( $self, $payby ) = @_;
208   #$hash{$payby}->{payname} || $hash{$payby}->{shortname};
209   exists($hash{$payby}->{payname})
210     ? $hash{$payby}->{payname}
211     : $hash{$payby}->{shortname};
212 }
213
214 sub longname {
215   my( $self, $payby ) = @_;
216   $hash{$payby}->{longname};
217 }
218
219 %payby2bop = (
220   'CARD' => 'CC',
221   'CHEK' => 'ECHECK',
222   'MCRD' => 'CC', #?  but doesn't MCRD mean _offline_ card?  i think it got
223                   # overloaded for third-party card payments -- but no one is
224                   # doing those other than paypal now
225   'PPAL' => 'PAYPAL',
226 );
227
228 sub payby2bop {
229   my( $self, $payby ) = @_;
230   $payby2bop{ $self->payby2payment($payby) };
231 }
232
233 sub payby2payment {
234   my( $self, $payby ) = @_;
235   $hash{$payby}{'cust_pay'} || $payby;
236 }
237
238 sub cust_payby {
239   my $self = shift;
240   grep { ! exists $hash{$_}->{cust_main} } $self->payby;
241 }
242
243 sub cust_payby2longname {
244   my $self = shift;
245   map { $_ => $hash{$_}->{longname} } $self->cust_payby;
246 }
247
248 =item payment_payby
249
250 Returns all values of payby that can be used by payments.
251
252 =cut
253
254 sub payment_payby {
255   my $self = shift;
256   grep { ! exists $hash{$_}->{cust_pay} } $self->payby;
257 }
258
259 =item payment_payby2longname
260
261 Returns hash, keys are L</payment_payby> types, values are payby longname.
262
263 =cut
264
265 sub payment_payby2longname {
266   my $self = shift;
267   map { $_ => $hash{$_}->{longname} } $self->payment_payby;
268 }
269
270 =item payment_payby2payname
271
272 Returns hash, keys are L</payment_payby> types, values are payby payname.
273
274 =cut
275
276 sub payment_payby2payname {
277   my $self = shift;
278   map { $_ => $self->payname($_) } $self->payment_payby;
279 }
280
281 =back
282
283 =head1 BUGS
284
285 This should eventually be an actual database table, and all tables that
286 currently have a char payby field should have a foreign key into here instead.
287
288 =head1 SEE ALSO
289
290 =cut
291
292 1;
293