Net::Artera - Perl extension for Artera XML API.


Net-Artera documentation Contained in the Net-Artera distribution.

Index


Code Index:

NAME

Top

Net::Artera - Perl extension for Artera XML API.

SYNOPSIS

Top

  use Net::Artera;

  my $connection = new Net::Artera (
    'rid'        => 'reseller_id',
    'username'   => 'reseller_username',
    'password'   => 'reseller_password',
    'production' => 0,
  );

  my $result = $artera->newOrder(
    'email' => $email,
    'cname' => $name,
    'ref'   => $refnum,,
    'aid'   => $affiliatenum,
    'add1'  => $address1,
    'add2'  => $address2,
    'add3'  => $city,
    'add4'  => $state,
    'zip'   => $zip,
    'cid'   => $country,
    'phone' => $phone,
    'fax'   => $fax,
  );

  if ( $result->{'id'} == 1 ) {
    #Success!
    $serialnum = $result->{'ASN'};
    $keycode   = $result->{'AKC'};
  } else {
    #Failure
    die $result->{'message'};
  }

  # etc...

DESCRIPTION

Top

This is a Perl module which speaks the Artera XML API. See <http://www.arteraturbo.com>. Artera Resellers can use this module to access some features of the API.

METHODS

Top

new [ OPTIONS_HASHREF | OPTION => VALUE ... ]

Constructor. Options can be passed as a hash reference or a list. Options are case-insensitive.

Available options are:

username - Reseller username
password - Reseller password
rid - Reseller ID (RID)
pid - Product ID (PID).
production - if set true, uses the production server instead of the staging server.

newTrial [ OPTIONS_HASHREF | OPTION => VALUE ... ]

Options can be passed as a hash reference or a list. Options are case-insensitive.

Available options are:

email (required)
cname (required) - Customer's name
ref (required) - Reseller's own order reference
pid (required) - Artera Product ID
priceid (required) - Artera Price ID
aid - Affiliate ID number used when the Reseller wants to track some type of sales channel beneath them.
add1*
add2
add3* - City
add4* - State
zip*
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.
phone
fax

*These fields are optional, but must be supplied as a set.

Returns a hash reference with the following keys (these keys are case-sensitive):

id - This is the Result ID to indicate success or failure: 1 for success, anything else for failure
message - Some descriptive text regarding the success or failure
ASN - The Artera Serial Number
AKC - The Artera Key Code
TrialID - The Artera Trial Number
Ref - The Reseller Reference
CustomerID - Artera's CustomerID
TrialLength - Trial Length
newOrder [ OPTIONS_HASHREF | OPTION => VALUE ... ]

Available options are the same as newTrial. Additionally the asn and akc fields may be specified to convert a trial to an order.

statusChange [ OPTIONS_HASHREF | OPTION => VALUE ... ]

Options can be passed as a hash reference or a list. Options are case-insensitive.

Available options are:

ASN (required) - Artera Serial Number
AKC (required) - Artera Key Code
StatusID (required) - Possible StatusID values are as follows:

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).
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).
17 - Terminate: permanently prohibit an end-user's Serial Number from working (e.g. subscription cancellation)

Reason - Reason for terminating

Returns a hash reference with the following keys (these keys are case-sensitive):

id - This is the Result ID to indicate success or failure: 1 for success, anything else for failure
message - Some descriptive text regarding the success or failure

getProductStatus [ OPTIONS_HASHREF | OPTION => VALUE ... ]

Options can be passed as a hash reference or a list. Options are case-insensitive.

Available options are:

ASN (required) - Artera Serial Number
AKC (required) - Artera Key Code

Returns a hash reference with the following keys (these keys are case-sensitive):

id - This is the Result ID to indicate success or failure: 1 for success, anything else for failure
message - On failure, descriptive text regarding the failure
StatusID (required) - Possible StatusID values are as follows:

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).
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).
17 - Terminate: permanently prohibit an end-user's Serial Number from working (e.g. subscription cancellation)

Description - Status description

updateContentControl [ OPTIONS_HASHREF | OPTION => VALUE ... ]

Options can be passed as a hash reference or a list. Options are case-insensitive.

Available options are:

ASN (required) - Artera Serial Number
AKC (required) - Artera Key Code
UseContentControl (required) - 0 for off, 1 for on

Returns a hash reference with the following keys (these keys are case-sensitive):

id - This is the Result ID to indicate success or failure: 1 for success, anything else for failure
message - Some descriptive text regarding the success or failure

orderListByDate [ OPTIONS_HASHREF | OPTION => VALUE ... ]

Unimplemented.

BUGS

Top

orderListByDate is unimplemented.

SEE ALSO

Top

<http://www.arteraturbo.com>

AUTHOR

Top

Ivan Kohler, <ivan-net-artera@420.am>

Freeside, open-source billing for ISPs: <http://www.sisd.com/freeside>

Not affiliated with Artera Group, Inc.

COPYRIGHT AND LICENSE

Top


Net-Artera documentation Contained in the Net-Artera distribution.
package Net::Artera;

use 5.005;
use strict;
use Data::Dumper;
use LWP::UserAgent;
use XML::Simple;
use Locale::Country;

#require Exporter;
use vars qw($VERSION @ISA $DEBUG @login_opt); #$WARN );
         # @EXPORT @EXPORT_OK %EXPORT_TAGS);
#@ISA = qw(Exporter);

# This allows declaration	use Net-Artera ':all';
# If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
# will save memory.
#%EXPORT_TAGS = ( 'all' => [ qw(
#	
#) ] );

#@EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );

#@EXPORT = qw();

$VERSION = '0.01';

#$WARN = 0;
$DEBUG = 0;

@login_opt = qw( RID Username Password );

sub new {
  my $proto = shift;
  my $class = ref($proto) || $proto;
  my $self = {};
  bless ($self, $class);

  my $opt = $self->_lc_hash_or_hashref(@_);
  $self->{$_} = $opt->{$_} for map lc($_), @login_opt;

  if ( defined($opt->{'production'}) && $opt->{'production'} ) {
    $self->{'url'} = 'https://secure.arteragroup.com/';
  } else {
    $self->{'url'} = 'http://staging.arteragroup.com/';
  }
  $self->{'url'} .= 'Wizards/wsapi/31/APIService.asmx';

  $self->{'ua'} = LWP::UserAgent->new;

  warn "\n$self created: ". Dumper($self) if $DEBUG;

  $self;
}

sub _lc_hash_or_hashref {
  my $self = shift;
  my $opt = ref($_[0]) ? shift : {@_};
  my $gratuitous = { map { lc($_) => $opt->{$_} } keys %$opt };
  $gratuitous;
}

sub newTrial {
  my $self = shift;
  my $opt = $self->_lc_hash_or_hashref(@_);
  $self->_newX('Trial', $opt);
}

sub newOrder {
  my $self = shift;
  my $opt = $self->_lc_hash_or_hashref(@_);
  push @{$opt->{'optional_params'}}, qw( ASN AKC );
  $self->_newX('Order', $opt);
}

sub _newX {
  my( $self, $x, $opt ) = @_;

  if ( defined($opt->{'cid'}) ) {
    $opt->{'cid'} = $self->_country2cid($opt->{'cid'});
  } else {
    $opt->{'cid'} = 2 if grep defined($_), qw(Add1 Add3 Add4 Zip);
  }

  push @{$opt->{'required_params'}},
       qw( Email CName Ref PID PriceID );
  push @{$opt->{'optional_params'}},
       qw( AID Add1 Add2 Add3 Add4 Zip CID Phone Fax );

  $self->_submit( "new$x", $opt );

}

my %country2cid = (
  'uk' => 1,
  'gb' => 1,
  'us' => 2,
  'in' => 3,
  'jp' => 4,
  'ru' => 5,
  'fr' => 6,
  'pl' => 7,
  'gr' => 8,
  'ug' => 9,
  'lk' => 10,
  'sa' => 11,
  'nl' => 12,
  'pe' => 13,
  'ca' => 14,
  'nz' => 15,
  'kr' => 16,
  'it' => 17,
  'es' => 18,
  'il' => 19,
  'se' => 20,
  'de' => 21,
  'ie' => 22,
  'mx' => 23,
  'au' => 24,
  'to' => 25,
  'eg' => 26,
  'tr' => 27,
  'am' => 28,
  'az' => 29,
  'by' => 30,
  'ee' => 31,
  'ge' => 32,
  'kz' => 33,
  'kg' => 34,
  'lt' => 35,
  'md' => 36,
  'tj' => 38,
  'tm' => 39,
  'ua' => 40,
  'uz' => 41,
  '' => 42, #BOSNIA
  '' => 43, #HERZEGOVINA
  'hr' => 44,
  'mk' => 45,
  '' => 46, #SERBIA
  '' => 47, #MONTENEGRO
  'si' => 48,
  'er' => 49,
  'mh' => 51,
  'pw' => 52,
  'fm' => 53,
  'na' => 54,
  'lv' => 56,
  'za' => 57,
  'jm' => 58,
);

sub _country2cid {
  my( $self, $country ) = @_;
  if ( $country =~ /^\s*(\d+)\s*$/ ) {
    $1;
  } elsif ( $country =~ /^\s*(\w\w)\s*$/ ) {
    $country2cid{$1};
  } elsif ( $country !~ /^\s*$/ ) {
    $country2cid{country2code($country)};
  } else {
    '';
  }
}

sub statusChange {
  my $self = shift;
  my $opt = $self->_lc_hash_or_hashref(@_);

  push @{$opt->{'required_params'}},
       qw( ASN AKC StatusID );
  push @{$opt->{'optional_params'}}, 'Reason';

  $self->_submit('statusChange', $opt );
}

sub getProductStatus {
  my $self = shift;

  my $opt = $self->_lc_hash_or_hashref(@_);

  push @{$opt->{'required_params'}}, qw( ASN AKC );

  my $result = $self->_submit('getProductStatus', $opt );

  # munch results, present as flat list
  $result->{$_} = $result->{'Status'}->{$_} foreach (qw(StatusID Description));
  delete $result->{'Status'};

  $result;

}

sub updateContentControl {
  my $self = shift;

  my $opt = $self->_lc_hash_or_hashref(@_);

  push @{$opt->{'required_params'}}, qw( ASN AKC UseContentControl );

  $self->_submit('updateContentControl', $opt );
}

#--

sub _submit {
  my( $self, $method, $opt ) = @_;
  my $ua = $self->{'ua'};

  my $param = {
    ( map { $_ => $self->{lc($_)} }
          @login_opt,
    ),
    ( map { $_ => $opt->{lc($_)} }
          @{$opt->{'required_params'}}
    ),
    ( map { $_ => ( exists $opt->{lc($_)} ? $opt->{lc($_)} : '' ) }
          @{$opt->{'optional_params'}}
    ),
  };
  warn "$self url $self->{url}/$method\n" if $DEBUG;
  warn "$self request parameters: ". Dumper($param). "\n" if $DEBUG;

  #POST
  my $response = $ua->post( "$self->{'url'}/$method", $param );

  warn "$self raw response: ". $response->content. "\n" if $DEBUG;

  #unless ( $response->is_success ) {
  #  die $response->content;
  #}

  my $xml = XMLin( $response->content );
  warn "$self parsed response: ". Dumper($xml) if $DEBUG;

  #warn "\n".$xml->{'message'}."\n" unless $xml->{'id'} == 1 or not $WARN;

  $xml;

}

1;