Net-Async-Webservice-UPS
view release on metacpan or search on metacpan
lib/Net/Async/Webservice/UPS.pm view on Meta::CPAN
my ($self) = @_;
$self->_clear_base_url;
}
sub _build_base_url {
my ($self) = @_;
return $base_urls{$self->live_mode ? 'live' : 'test'};
}
has user_id => (
is => 'ro',
isa => Str,
required => 1,
);
has password => (
is => 'ro',
isa => Str,
required => 1,
);
has access_key => (
is => 'ro',
isa => Str,
required => 1,
);
has account_number => (
is => 'ro',
isa => Str,
);
has customer_classification => (
is => 'rw',
isa => CustomerClassification,
);
has pickup_type => (
is => 'rw',
isa => PickupType,
default => sub { 'ONE_TIME' },
);
has cache => (
is => 'ro',
isa => Cache|Undef,
);
sub does_caching {
my ($self) = @_;
return defined $self->cache;
}
sub _build_ssl_options {
eval "require IO::Socket::SSL; require IO::Socket::SSL::Utils; require Mozilla::CA;"
or return {};
my $cert = IO::Socket::SSL::Utils::PEM_string2cert(<<'PEM');
-----BEGIN CERTIFICATE-----
MIICPDCCAaUCEHC65B0Q2Sk0tjjKewPMur8wDQYJKoZIhvcNAQECBQAwXzELMAkGA1UEBhMCVVMx
FzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmltYXJ5
IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2MDEyOTAwMDAwMFoXDTI4MDgwMTIzNTk1OVow
XzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAz
IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUA
A4GNADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhEBarsAx94
f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/isI19wKTakyYbnsZogy1Ol
hec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0GCSqGSIb3DQEBAgUAA4GBALtMEivPLCYA
TxQT3ab7/AoRhIzzKBxnki98tsX63/Dolbwdj2wsqFHMc9ikwFPwTtYmwHYBV4GSXiHx0bH/59Ah
WM1pF+NEHJwZRDmJXNycAA9WjQKZ7aKQRUzkuxCkPfAyAw7xzvjoyVGM5mKf5p/AfbdynMk2Omuf
Tqj/ZA1k
-----END CERTIFICATE-----
PEM
return {
SSL_verify_mode => IO::Socket::SSL::SSL_VERIFY_PEER(),
SSL_ca => [ $cert ],
SSL_ca_file => Mozilla::CA::SSL_ca_file(),
};
}
with 'Net::Async::Webservice::Common::WithUserAgent';
with 'Net::Async::Webservice::Common::WithConfigFile';
around BUILDARGS => sub {
my ($orig,$class,@args) = @_;
my $ret = $class->$orig(@args);
if ($ret->{cache_life}) {
require CHI;
if (not $ret->{cache_root}) {
require File::Spec;
$ret->{cache_root} =
File::Spec->catdir(File::Spec->tmpdir,'naws_ups'),
}
$ret->{cache} = CHI->new(
driver => 'File',
root_dir => $ret->{cache_root},
depth => 5,
expires_in => $ret->{cache_life} . ' min',
);
}
return $ret;
};
sub transaction_reference {
my ($self,$args) = @_;
no warnings 'once';
return {
CustomerContext => ($args->{customer_context} // "Net::Async::Webservice::UPS"),
XpciVersion => "".($Net::Async::Webservice::UPS::VERSION||0),
};
}
sub access_as_xml {
my $self = shift;
return XMLout({
AccessRequest => {
AccessLicenseNumber => $self->access_key,
Password => $self->password,
UserId => $self->user_id,
}
}, NoAttr=>1, KeepRoot=>1, XMLDecl=>1);
}
sub request_rate {
state $argcheck = compile(Object, Dict[
from => Address|Shipper,
to => Address,
packages => PackageList,
lib/Net/Async/Webservice/UPS.pm view on Meta::CPAN
A L<URI> object, coercible from a string. The base URL to use to send
API requests to (actual requests will be C<POST>ed to an actual URL
built from this by appending the appropriate service path). Defaults
to the standard UPS endpoints:
=over 4
=item *
C<https://onlinetools.ups.com/ups.app/xml> for live
=item *
C<https://wwwcie.ups.com/ups.app/xml> for testing
=back
See also L</live_mode>.
=head2 C<user_id>
=head2 C<password>
=head2 C<access_key>
Strings, required. Authentication credentials.
=head2 C<account_number>
String. Used in some requests as "shipper number".
=head2 C<customer_classification>
String, usually one of C<WHOLESALE>, C<OCCASIONAL>, C<RETAIL>. Used
when requesting rates.
=head2 C<pickup_type>
String, defaults to C<ONE_TIME>. Used when requesting rates.
=head2 C<cache>
Responses are cached if this is set. You can pass your own cache
object (that implements the C<get> and C<set> methods like L<CHI>
does), or use the C<cache_life> and C<cache_root> constructor
parameters to get a L<CHI> instance based on L<CHI::Driver::File>.
=head2 C<user_agent>
A user agent object, looking either like L<Net::Async::HTTP> (has
C<do_request> and C<POST>) or like L<LWP::UserAgent> (has C<request>
and C<post>). You can pass the C<loop> constructor parameter to get a
default L<Net::Async::HTTP> instance.
=head2 C<ssl_options>
Optional hashref, its contents will be passed to C<user_agent>'s
C<do_request> method.
If L<IO::Socket::SSL> and L<Mozilla::CA> are installed, the default
value sets full TLS validation, and makes sure that the Verisign
certificate currently (as of 2015-02-03) used by the UPS servers is
recognised (see L<UPS SSL/TLS notes>).
=head1 METHODS
=head2 C<does_caching>
Returns a true value if caching is enabled.
=head2 C<new>
Async:
my $ups = Net::Async::Webservice::UPS->new({
loop => $loop,
config_file => $file_name,
cache_life => 5,
});
Sync:
my $ups = Net::Async::Webservice::UPS->new({
user_agent => LWP::UserAgent->new,
config_file => $file_name,
cache_life => 5,
});
In addition to passing all the various attributes values, you can use
a few shortcuts.
=over 4
=item C<loop>
a L<IO::Async::Loop>; a locally-constructed L<Net::Async::HTTP> will be registered to it and set as L</user_agent>
=item C<config_file>
a path name; will be parsed with L<Config::Any>, and the values used as if they had been passed in to the constructor
=item C<cache_life>
lifetime, in I<minutes>, of cache entries; a L</cache> will be built automatically if this is set (using L<CHI> with the C<File> driver)
=item C<cache_root>
where to store the cache files for the default cache object, defaults to C<naws_ups> under your system's temporary directory
=back
A few more examples:
=over 4
=item *
no config file, no cache, async:
->new({
( run in 1.994 second using v1.01-cache-2.11-cpan-39bf76dae61 )