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