File Coverage

blib/lib/Net/Artera.pm
Criterion Covered Total %
statement 13 15 86.6
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 18 20 90.0


line stmt bran cond sub pod time code
1             package Net::Artera;
2              
3 1     1   7522 use 5.005;
  1         3  
  1         35  
4 1     1   38 use strict;
  1         2  
  1         34  
5 1     1   2647 use Data::Dumper;
  1         10981  
  1         83  
6 1     1   5624 use LWP::UserAgent;
  1         94086  
  1         41  
7 1     1   7691 use XML::Simple;
  0            
  0            
8             use Locale::Country;
9              
10             #require Exporter;
11             use vars qw($VERSION @ISA $DEBUG @login_opt); #$WARN );
12             # @EXPORT @EXPORT_OK %EXPORT_TAGS);
13             #@ISA = qw(Exporter);
14              
15             # This allows declaration use Net-Artera ':all';
16             # If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
17             # will save memory.
18             #%EXPORT_TAGS = ( 'all' => [ qw(
19             #
20             #) ] );
21              
22             #@EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
23              
24             #@EXPORT = qw();
25              
26             $VERSION = '0.01';
27              
28             #$WARN = 0;
29             $DEBUG = 0;
30              
31             =head1 NAME
32              
33             Net::Artera - Perl extension for Artera XML API.
34              
35             =head1 SYNOPSIS
36              
37             use Net::Artera;
38              
39             my $connection = new Net::Artera (
40             'rid' => 'reseller_id',
41             'username' => 'reseller_username',
42             'password' => 'reseller_password',
43             'production' => 0,
44             );
45              
46             my $result = $artera->newOrder(
47             'email' => $email,
48             'cname' => $name,
49             'ref' => $refnum,,
50             'aid' => $affiliatenum,
51             'add1' => $address1,
52             'add2' => $address2,
53             'add3' => $city,
54             'add4' => $state,
55             'zip' => $zip,
56             'cid' => $country,
57             'phone' => $phone,
58             'fax' => $fax,
59             );
60              
61             if ( $result->{'id'} == 1 ) {
62             #Success!
63             $serialnum = $result->{'ASN'};
64             $keycode = $result->{'AKC'};
65             } else {
66             #Failure
67             die $result->{'message'};
68             }
69              
70             # etc...
71              
72             =head1 DESCRIPTION
73              
74             This is a Perl module which speaks the Artera XML API.
75             See . Artera Resellers can use this module
76             to access some features of the API.
77              
78             =head1 METHODS
79              
80             =over 4
81              
82             =item new [ OPTIONS_HASHREF | OPTION => VALUE ... ]
83              
84             Constructor. Options can be passed as a hash reference or a list. Options are
85             case-insensitive.
86              
87             Available options are:
88              
89             =over 4
90              
91             =item username - Reseller username
92              
93             =item password - Reseller password
94              
95             =item rid - Reseller ID (RID)
96              
97             =item pid - Product ID (PID).
98              
99             =item production - if set true, uses the production server instead of the staging server.
100              
101             =back
102              
103             =cut
104              
105             @login_opt = qw( RID Username Password );
106              
107             sub new {
108             my $proto = shift;
109             my $class = ref($proto) || $proto;
110             my $self = {};
111             bless ($self, $class);
112              
113             my $opt = $self->_lc_hash_or_hashref(@_);
114             $self->{$_} = $opt->{$_} for map lc($_), @login_opt;
115              
116             if ( defined($opt->{'production'}) && $opt->{'production'} ) {
117             $self->{'url'} = 'https://secure.arteragroup.com/';
118             } else {
119             $self->{'url'} = 'http://staging.arteragroup.com/';
120             }
121             $self->{'url'} .= 'Wizards/wsapi/31/APIService.asmx';
122              
123             $self->{'ua'} = LWP::UserAgent->new;
124              
125             warn "\n$self created: ". Dumper($self) if $DEBUG;
126              
127             $self;
128             }
129              
130             sub _lc_hash_or_hashref {
131             my $self = shift;
132             my $opt = ref($_[0]) ? shift : {@_};
133             my $gratuitous = { map { lc($_) => $opt->{$_} } keys %$opt };
134             $gratuitous;
135             }
136              
137             =item newTrial [ OPTIONS_HASHREF | OPTION => VALUE ... ]
138              
139             Options can be passed as a hash reference or a list. Options are
140             case-insensitive.
141              
142             Available options are:
143              
144             =over 4
145              
146             =item email (required)
147              
148             =item cname (required) - Customer's name
149              
150             =item ref (required) - Reseller's own order reference
151              
152             =item pid (required) - Artera Product ID
153              
154             =item priceid (required) - Artera Price ID
155              
156             =item aid - Affiliate ID number used when the Reseller wants to track some type of sales channel beneath them.
157              
158             =item add1*
159              
160             =item add2
161              
162             =item add3* - City
163              
164             =item add4* - State
165              
166             =item zip*
167              
168             =item cid* - Country ID. Defaults to 2 (USA). Can be specified as a numeric CID or as an ISO 3166 two-letter country code or full name.
169              
170             =item phone
171              
172             =item fax
173              
174             =back
175              
176             *These fields are optional, but must be supplied as a set.
177              
178             Returns a hash reference with the following keys (these keys B
179             case-sensitive):
180              
181             =over 4
182              
183             =item id - This is the Result ID to indicate success or failure: 1 for success, anything else for failure
184              
185             =item message - Some descriptive text regarding the success or failure
186              
187             =item ASN - The Artera Serial Number
188              
189             =item AKC - The Artera Key Code
190              
191             =item TrialID - The Artera Trial Number
192              
193             =item Ref - The Reseller Reference
194              
195             =item CustomerID - Artera's CustomerID
196              
197             =item TrialLength - Trial Length
198              
199             =cut
200              
201             sub newTrial {
202             my $self = shift;
203             my $opt = $self->_lc_hash_or_hashref(@_);
204             $self->_newX('Trial', $opt);
205             }
206              
207             =item newOrder [ OPTIONS_HASHREF | OPTION => VALUE ... ]
208              
209             Available options are the same as B. Additionally the I and
210             I fields may be specified to convert a trial to an order.
211              
212             =cut
213              
214             sub newOrder {
215             my $self = shift;
216             my $opt = $self->_lc_hash_or_hashref(@_);
217             push @{$opt->{'optional_params'}}, qw( ASN AKC );
218             $self->_newX('Order', $opt);
219             }
220              
221             sub _newX {
222             my( $self, $x, $opt ) = @_;
223              
224             if ( defined($opt->{'cid'}) ) {
225             $opt->{'cid'} = $self->_country2cid($opt->{'cid'});
226             } else {
227             $opt->{'cid'} = 2 if grep defined($_), qw(Add1 Add3 Add4 Zip);
228             }
229              
230             push @{$opt->{'required_params'}},
231             qw( Email CName Ref PID PriceID );
232             push @{$opt->{'optional_params'}},
233             qw( AID Add1 Add2 Add3 Add4 Zip CID Phone Fax );
234              
235             $self->_submit( "new$x", $opt );
236              
237             }
238              
239             my %country2cid = (
240             'uk' => 1,
241             'gb' => 1,
242             'us' => 2,
243             'in' => 3,
244             'jp' => 4,
245             'ru' => 5,
246             'fr' => 6,
247             'pl' => 7,
248             'gr' => 8,
249             'ug' => 9,
250             'lk' => 10,
251             'sa' => 11,
252             'nl' => 12,
253             'pe' => 13,
254             'ca' => 14,
255             'nz' => 15,
256             'kr' => 16,
257             'it' => 17,
258             'es' => 18,
259             'il' => 19,
260             'se' => 20,
261             'de' => 21,
262             'ie' => 22,
263             'mx' => 23,
264             'au' => 24,
265             'to' => 25,
266             'eg' => 26,
267             'tr' => 27,
268             'am' => 28,
269             'az' => 29,
270             'by' => 30,
271             'ee' => 31,
272             'ge' => 32,
273             'kz' => 33,
274             'kg' => 34,
275             'lt' => 35,
276             'md' => 36,
277             'tj' => 38,
278             'tm' => 39,
279             'ua' => 40,
280             'uz' => 41,
281             '' => 42, #BOSNIA
282             '' => 43, #HERZEGOVINA
283             'hr' => 44,
284             'mk' => 45,
285             '' => 46, #SERBIA
286             '' => 47, #MONTENEGRO
287             'si' => 48,
288             'er' => 49,
289             'mh' => 51,
290             'pw' => 52,
291             'fm' => 53,
292             'na' => 54,
293             'lv' => 56,
294             'za' => 57,
295             'jm' => 58,
296             );
297              
298             sub _country2cid {
299             my( $self, $country ) = @_;
300             if ( $country =~ /^\s*(\d+)\s*$/ ) {
301             $1;
302             } elsif ( $country =~ /^\s*(\w\w)\s*$/ ) {
303             $country2cid{$1};
304             } elsif ( $country !~ /^\s*$/ ) {
305             $country2cid{country2code($country)};
306             } else {
307             '';
308             }
309             }
310              
311             =item statusChange [ OPTIONS_HASHREF | OPTION => VALUE ... ]
312              
313             Options can be passed as a hash reference or a list. Options are
314             case-insensitive.
315              
316             Available options are:
317              
318             =over 4
319              
320             =item ASN (required) - Artera Serial Number
321              
322             =item AKC (required) - Artera Key Code
323              
324             =item StatusID (required) - Possible StatusID values are as follows:
325              
326             =over 4
327              
328             =item 15 - Normal Unrestricted: re-enable a disabled Serial Number (e.g. a payment dispute has been resolved so the Serial Number needs to be re-enabled).
329              
330             =item 16 - Disable: temporarily prohibit an end-user's serial number from working (e.g. there is a payment dispute, so you want to turn off the Serial Number until the dispute is resolved).
331              
332             =item 17 - Terminate: permanently prohibit an end-user's Serial Number from working (e.g. subscription cancellation)
333              
334             =back
335              
336             =item Reason - Reason for terminating
337              
338             =back
339              
340             Returns a hash reference with the following keys (these keys B
341             case-sensitive):
342              
343             =over 4
344              
345             =item id - This is the Result ID to indicate success or failure: 1 for success, anything else for failure
346              
347             =item message - Some descriptive text regarding the success or failure
348              
349             =back
350              
351             =cut
352              
353             sub statusChange {
354             my $self = shift;
355             my $opt = $self->_lc_hash_or_hashref(@_);
356              
357             push @{$opt->{'required_params'}},
358             qw( ASN AKC StatusID );
359             push @{$opt->{'optional_params'}}, 'Reason';
360              
361             $self->_submit('statusChange', $opt );
362             }
363              
364             =item getProductStatus [ OPTIONS_HASHREF | OPTION => VALUE ... ]
365              
366             Options can be passed as a hash reference or a list. Options are
367             case-insensitive.
368              
369             Available options are:
370              
371             =over 4
372              
373             =item ASN (required) - Artera Serial Number
374              
375             =item AKC (required) - Artera Key Code
376              
377             =back
378              
379             Returns a hash reference with the following keys (these keys B
380             case-sensitive):
381              
382             =over 4
383              
384             =item id - This is the Result ID to indicate success or failure: 1 for success, anything else for failure
385              
386             =item message - On failure, descriptive text regarding the failure
387              
388             =item StatusID (required) - Possible StatusID values are as follows:
389              
390             =over 4
391              
392             =item 15 - Normal Unrestricted: re-enable a disabled Serial Number (e.g. a payment dispute has been resolved so the Serial Number needs to be re-enabled).
393              
394             =item 16 - Disable: temporarily prohibit an end-user's serial number from working (e.g. there is a payment dispute, so you want to turn off the Serial Number until the dispute is resolved).
395              
396             =item 17 - Terminate: permanently prohibit an end-user's Serial Number from working (e.g. subscription cancellation)
397              
398             =back
399              
400             =item Description - Status description
401              
402             =back
403              
404             =cut
405              
406             sub getProductStatus {
407             my $self = shift;
408              
409             my $opt = $self->_lc_hash_or_hashref(@_);
410              
411             push @{$opt->{'required_params'}}, qw( ASN AKC );
412              
413             my $result = $self->_submit('getProductStatus', $opt );
414              
415             # munch results, present as flat list
416             $result->{$_} = $result->{'Status'}->{$_} foreach (qw(StatusID Description));
417             delete $result->{'Status'};
418              
419             $result;
420              
421             }
422              
423             =item updateContentControl [ OPTIONS_HASHREF | OPTION => VALUE ... ]
424              
425             Options can be passed as a hash reference or a list. Options are
426             case-insensitive.
427              
428             Available options are:
429              
430             =over 4
431              
432             =item ASN (required) - Artera Serial Number
433              
434             =item AKC (required) - Artera Key Code
435              
436             =item UseContentControl (required) - 0 for off, 1 for on
437              
438             =back
439              
440             Returns a hash reference with the following keys (these keys B
441             case-sensitive):
442              
443             =over 4
444              
445             =item id - This is the Result ID to indicate success or failure: 1 for success, anything else for failure
446              
447             =item message - Some descriptive text regarding the success or failure
448              
449             =back
450              
451             =cut
452              
453             sub updateContentControl {
454             my $self = shift;
455              
456             my $opt = $self->_lc_hash_or_hashref(@_);
457              
458             push @{$opt->{'required_params'}}, qw( ASN AKC UseContentControl );
459              
460             $self->_submit('updateContentControl', $opt );
461             }
462              
463             =item orderListByDate [ OPTIONS_HASHREF | OPTION => VALUE ... ]
464              
465             Unimplemented.
466              
467             =cut
468              
469             #--
470              
471             sub _submit {
472             my( $self, $method, $opt ) = @_;
473             my $ua = $self->{'ua'};
474              
475             my $param = {
476             ( map { $_ => $self->{lc($_)} }
477             @login_opt,
478             ),
479             ( map { $_ => $opt->{lc($_)} }
480             @{$opt->{'required_params'}}
481             ),
482             ( map { $_ => ( exists $opt->{lc($_)} ? $opt->{lc($_)} : '' ) }
483             @{$opt->{'optional_params'}}
484             ),
485             };
486             warn "$self url $self->{url}/$method\n" if $DEBUG;
487             warn "$self request parameters: ". Dumper($param). "\n" if $DEBUG;
488              
489             #POST
490             my $response = $ua->post( "$self->{'url'}/$method", $param );
491              
492             warn "$self raw response: ". $response->content. "\n" if $DEBUG;
493              
494             #unless ( $response->is_success ) {
495             # die $response->content;
496             #}
497              
498             my $xml = XMLin( $response->content );
499             warn "$self parsed response: ". Dumper($xml) if $DEBUG;
500              
501             #warn "\n".$xml->{'message'}."\n" unless $xml->{'id'} == 1 or not $WARN;
502              
503             $xml;
504              
505             }
506              
507             =back
508              
509             =head1 BUGS
510              
511             orderListByDate is unimplemented.
512              
513             =head1 SEE ALSO
514              
515            
516              
517             =head1 AUTHOR
518              
519             Ivan Kohler, Eivan-net-artera@420.amE
520              
521             Freeside, open-source billing for ISPs:
522              
523             Not affiliated with Artera Group, Inc.
524              
525             =head1 COPYRIGHT AND LICENSE
526              
527             Copyright (C) 2004 Ivan Kohler
528              
529             This library is free software; you can redistribute it and/or modify
530             it under the same terms as Perl itself.
531              
532             =cut
533              
534             1;
535