summaryrefslogtreecommitdiff
path: root/FS/FS/part_export/ez_prepaid.pm
diff options
context:
space:
mode:
authorMark Wells <mark@freeside.biz>2012-07-25 16:16:57 -0700
committerMark Wells <mark@freeside.biz>2012-07-25 16:16:57 -0700
commitbd647f16de5352722baed016b45baa4e7c695278 (patch)
tree51fd2c8c445bba06162b4ff8e1069cddfd568ff7 /FS/FS/part_export/ez_prepaid.pm
parent74c9101d79b0dfd2f2d3a2996bd3d3575ada9252 (diff)
EZ-Prepaid PIN export, #16172
Diffstat (limited to 'FS/FS/part_export/ez_prepaid.pm')
-rw-r--r--FS/FS/part_export/ez_prepaid.pm183
1 files changed, 183 insertions, 0 deletions
diff --git a/FS/FS/part_export/ez_prepaid.pm b/FS/FS/part_export/ez_prepaid.pm
new file mode 100644
index 0000000..d171eb1
--- /dev/null
+++ b/FS/FS/part_export/ez_prepaid.pm
@@ -0,0 +1,183 @@
+package FS::part_export::ez_prepaid;
+
+use base qw( FS::part_export );
+
+use strict;
+use vars qw(@ISA %info $version $replace_ok_kludge $product_info);
+use Tie::IxHash;
+use FS::Record qw( qsearchs );
+use FS::svc_external;
+use SOAP::Lite;
+use XML::Simple qw( xml_in );
+use Data::Dumper;
+
+$version = '01';
+
+my $product_info;
+my %language_id = ( English => 1, Spanish => 2 );
+
+tie my %options, 'Tie::IxHash',
+ 'site_id' => { label => 'Site ID' },
+ 'clerk_id' => { label => 'Clerk ID' },
+# 'product_id' => { label => 'Product ID' }, use the 'title' field
+# 'amount' => { label => 'Purchase amount' },
+ 'language' => { label => 'Language',
+ type => 'select',
+ options => [ 'English', 'Spanish' ],
+ },
+
+ 'debug' => { label => 'Debug level',
+ type => 'select', options => [0, 1, 2 ] },
+;
+
+%info = (
+ 'svc' => 'svc_external',
+ 'desc' => 'Purchase EZ-Prepaid PIN',
+ 'options' => \%options,
+ 'notes' => <<'END'
+<P>Export to the EZ-Prepaid PIN purchase service. If the purchase is allowed,
+the PIN will be stored as svc_external.id.</P>
+<P>svc_external.title must contain the product ID, and should be set as a fixed
+field in the service definition. For a list of product IDs, see the
+"Merchant Info" tab in the EZ Prepaid reseller portal.</P>
+END
+ );
+
+$replace_ok_kludge = 0;
+
+sub _export_insert {
+ my ($self, $svc_external) = @_;
+
+ # the name on the certificate is 'debisys.com', for some reason
+ local $ENV{PERL_LWP_SSL_VERIFY_HOSTNAME}=0;
+
+ my $pin = eval { $self->ez_prepaid_PinDistSale( $svc_external->title ) };
+ return $@ if $@;
+
+ local($replace_ok_kludge) = 1;
+ $svc_external->set('id', $pin);
+ $svc_external->replace;
+}
+
+sub _export_replace {
+ $replace_ok_kludge ? '' : "can't change PIN after purchase";
+}
+
+sub _export_delete {
+ "can't delete PIN after purchase";
+}
+
+# possibly options at some point to relate these to agentnum/usernum
+sub site_id { $_[0]->option('site_id') }
+
+sub clerk_id { $_[0]->option('clerk_id') }
+
+sub ez_prepaid_PinDistSale {
+ my $self = shift;
+ my $product_id = shift;
+ $self->ez_prepaid_init; # populate product ID cache
+ my $info = $product_info->{$product_id};
+ if ( $info ) {
+ if ( $self->option('debug') ) {
+ warn "Purchasing PIN product #$product_id:\n" .
+ $info->{Description}."\n".
+ $info->{CurrencyCode} . ' ' .$info->{Amount}."\n";
+ }
+ } else { #no $info
+ die "Unknown PIN product #$product_id.\n";
+ }
+
+ my $response = $self->ez_prepaid_request(
+ 'PinDistSale',
+ $version,
+ $self->site_id,
+ $self->clerk_id,
+ $product_id,
+ '', # AccountID, not used for PIN sale
+ $product_info->{$product_id}->{Amount},
+ $self->svcnum,
+ ($language_id{ $self->option('language') } || 1),
+ );
+ if ( $self->option('debug') ) {
+ warn Dumper($response);
+ # includes serial number and transaction ID, possibly useful
+ # (but we don't have a structured place to store it--maybe in
+ # a customer note?)
+ }
+ $response->{Pin};
+}
+
+sub ez_prepaid_init {
+ # returns the SOAP client object
+ my $self = shift;
+ my $wsdl = 'https://webservice.ez-prepaid.com/soap/webServices.wsdl';
+
+ if ( $self->option('debug') >= 2 ) {
+ SOAP::Lite->import(+trace => [transport => \&log_transport ]);
+ }
+
+ if ( !$self->client ) {
+ $self->set(client => SOAP::Lite->new->service($wsdl));
+ # I don't know if this can happen, but better to bail out here
+ # than go into recursion.
+ die "Error creating SOAP client\n" if !$self->client;
+ }
+
+ if ( !defined($product_info) ) {
+ # for now we only support the 'PIN' type
+ my $response = $self->ez_prepaid_request(
+ 'GetTransTypeList', $version, $self->site_id, '', '', '', ''
+ );
+ my %transtype = map { $_->{Description} => $_->{TransTypeId} }
+ @{ $response->{TransType} };
+
+ if ( !exists $transtype{PIN} ) {
+ warn "'PIN' transaction type not available.\n";
+ # or else your site ID is wrong
+ return;
+ }
+
+ $response = $self->ez_prepaid_request(
+ 'GetProductList',
+ $version,
+ $self->option('site_id'),
+ $transtype{PIN},
+ '', #CarrierId
+ '', #CategoryId
+ '', #ProductId
+ );
+ $product_info = +{
+ map { $_->{ProductId} => $_ }
+ @{ $response->{Product} }
+ };
+ } #!defined $product_info
+}
+
+sub log_transport {
+ my $in = shift;
+ if ( UNIVERSAL::can($in, 'content') ) {
+ warn $in->content."\n";
+ }
+}
+
+my @ForceArray = qw(TransType Product); # add others as needed
+sub ez_prepaid_request {
+ my $self = shift;
+ # takes a method name and param list,
+ # returns a hashref containing the unpacked response
+ # or dies on error
+
+ $self->ez_prepaid_init if !$self->client;
+
+ my $method = shift;
+ my $xml = $self->client->$method(@_);
+ # All of their response data types are one part, a string, containing
+ # an encoded XML structure, containing the fields described in the docs.
+ my $response = xml_in($xml, ForceArray => \@ForceArray);
+ if ( exists($response->{ResponseCode}) && $response->{ResponseCode} > 0 ) {
+ die "[$method] ".$response->{ResponseMessage};
+ }
+ $response;
+}
+
+1;