From 9a863e4092d480adc90e98f7d620d56d98398d89 Mon Sep 17 00:00:00 2001 From: Alex Brelsfoard Date: Mon, 9 Feb 2015 22:54:30 -0500 Subject: [PATCH] Converting the XML templating to now use XML::Writer --- Makefile.PL | 2 +- extra/test.pl | 2 +- lib/Business/OnlinePayment/vSecureProcessing.pm | 353 +++++------------------- 3 files changed, 77 insertions(+), 280 deletions(-) diff --git a/Makefile.PL b/Makefile.PL index fe27943..a774fdb 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -15,7 +15,7 @@ WriteMakefile( 'Test::More' => 0, 'Business::OnlinePayment' => 3.01, 'XML::Simple' => 0, - 'Template' => 0, + 'XML::Writer' => 0, 'Data::Dumper' => 0, }, dist => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', }, diff --git a/extra/test.pl b/extra/test.pl index bca3628..50aa857 100755 --- a/extra/test.pl +++ b/extra/test.pl @@ -66,7 +66,7 @@ sub main { sub ProcessTransaction { my $transaction = shift; - print "Processing transaction with content:\n".Dumper(\%content)."\n"; + #print "Processing transaction with content:\n".Dumper(\%content)."\n"; $transaction->content(%content); eval { $transaction->submit(); }; diff --git a/lib/Business/OnlinePayment/vSecureProcessing.pm b/lib/Business/OnlinePayment/vSecureProcessing.pm index e7514a3..f957aa9 100644 --- a/lib/Business/OnlinePayment/vSecureProcessing.pm +++ b/lib/Business/OnlinePayment/vSecureProcessing.pm @@ -2,7 +2,7 @@ package Business::OnlinePayment::vSecureProcessing; use strict; use Carp; -use Template; +use XML::Writer; use XML::Simple; use Data::Dumper; @@ -16,20 +16,23 @@ $DEBUG = 0; $VERSION = '0.01'; $me = 'Business::OnlinePayment::vSecureProcessing'; - -# $server: http://dvrotsos2.kattare.com - # mapping out all possible endpoints # but this version will only be building out "charge", "void", & "credit" my %payment_actions = ( 'charge' => { path => '/vsg2/processpayment', + process => 'ProcessPayment', + fields => [qw/ Amount Trk1 Trk2 TypeOfSale Cf1 Cf2 Cf AccountNumber ExpirationMonth ExpirationYear Cvv CardHolderFirstName CardHolderLastName AvsZip AvsStreet IndustryType ApplicationId Recurring /] }, 'void' => { path => '/vsg2/processvoid', + process => 'ProcessVoid', + fields => [qw( Amount AccountNumber ExpirationMonth ExpirationYear ReferenceNumber TransactionDate IndustryType ApplicationId )] }, 'refund' => { path => '/vsg2/processrefund', + process => 'ProcessRefund', + fields => [qw( Amount AccountNumber ExpirationMonth ExpirationYear ApplicationId )] }, 'authorize' => { path => '/vsg2/processauth', @@ -175,98 +178,96 @@ sub submit { croak "'$action' is not supported at this time."; } - # fill out the template vars - my $template_vars = { - + # fill in the xml vars + my $xml_vars = { auth => { - platform => $self->platform, - userid => $self->userid, - gid => $self->gid, - tid => $self->tid + Platform => $self->platform, + UserId => $self->userid, + GID => $self->gid, + Tid => $self->tid }, payment => { - amount => $content{'amount'}, - track1 => ($content{'track1'}) ? $content{'track1'} : '', - track2 => ($content{'track2'}) ? $content{'track2'} : '', - type => ($content{'description'}) ? $content{'description'} : '', - cf1 => ($content{'UDField1'}) ? $content{'UDField1'} : '', - cf2 => ($content{'UDField2'}) ? $content{'UDField2'} : '', - cf3 => '', - account_number => ($content{'card_number'}) ? $content{'card_number'} : '', - exp_month => $content{'exp_month'}, - exp_year => $content{'exp_year'}, - cvv => ($content{'cvv'}) ? $content{'cvv'} : ($content{'cvv2'}) ? $content{'cvv2'} : '', - first_name => ($content{'first_name'}) ? $content{'first_name'} : '', - last_name => ($content{'last_name'}) ? $content{'last_name'} : '', - postal_code => ($content{'zip'}) ? $content{'zip'} : '', - street_address => ($content{'street_number'}) ? $content{'street_number'} : '', - industry_type => ($content{'IndustryInfo'} && lc($content{'IndustryInfo'}) eq 'ecommerce') ? 'ecom_3' : '', - invoice_num => ($content{'invoice_number'}) ? $content{'invoice_number'} : '', - appid => $self->appid(), - recurring => ($content{'recurring_billing'} && $content{'recurring_billing'} eq 'YES' ) ? 1 : 0, - response_code => ($content{'response_code'}) ? $content{'response_code'} : '', - reference_number=> ($content{'ref_num'}) ? $content{'ref_num'} : '', - token => ($content{'token'}) ? $content{'token'} : '', - receipt => ($content{'receipt'}) ? $content{'receipt'} : '', - transaction_date=> ($content{'txn_date'}) ? $content{'txn_date'} : '', - merchant_data => ($content{'merchant_data'}) ? $content{'merchant_data'} : '', - }, - - # we won't be using level2 nor level3. So I'm leaving them blank for now. - level2 => { - card_type => '', - purchase_code => '', - country_code => '', - ship_tp_postal_code => '', - ship_from_postal_code => '', - sales_tax => '', - product_description1 => '', - product_description2 => '', - product_description3 => '', - product_description4 => '' - }, - - level3 => { - purchase_order_num => '', - order_date => '', - duty_amount => '', - alt_tax_amount => '', - discount_amount => '', - freight_amount => '', - tax_exempt => '', - line_item_count => '', - purchase_items => $self->_parse_line_items() + Amount => $content{'amount'}, + Trk1 => ($content{'track1'}) ? $content{'track1'} : '', + Trk2 => ($content{'track2'}) ? $content{'track2'} : '', + TypeOfSale => ($content{'description'}) ? $content{'description'} : '', + Cf1 => ($content{'UDField1'}) ? $content{'UDField1'} : '', + Cf2 => ($content{'UDField2'}) ? $content{'UDField2'} : '', + Cf3 => '', + AccountNumber => ($content{'card_number'}) ? $content{'card_number'} : '', + ExpirationMonth => $content{'exp_month'}, + ExpirationYear => $content{'exp_year'}, + Cvv => ($content{'cvv'}) ? $content{'cvv'} : ($content{'cvv2'}) ? $content{'cvv2'} : '', + CardHolderFirstName => ($content{'first_name'}) ? $content{'first_name'} : '', + CardHolderLastName => ($content{'last_name'}) ? $content{'last_name'} : '', + AvsZip => ($content{'zip'}) ? $content{'zip'} : '', + AvsStreet => ($content{'street_number'}) ? $content{'street_number'} : '', + IndustryType => { + IndType => ($content{'IndustryInfo'} && lc($content{'IndustryInfo'}) eq 'ecommerce') ? 'ecom_3' : '', + IndInvoice => ($content{'invoice_number'}) ? $content{'invoice_number'} : '' + }, + ApplicationId => $self->appid(), + Recurring => ($content{'recurring_billing'} && $content{'recurring_billing'} eq 'YES' ) ? 1 : 0, + ReferenceNumber => ($content{'ref_num'}) ? $content{'ref_num'} : '', + Token => ($content{'token'}) ? $content{'token'} : '', + Receipt => ($content{'receipt'}) ? $content{'receipt'} : '', + TransactionDate => ($content{'txn_date'}) ? $content{'txn_date'} : '' } + # we won't be using level2 nor level3. So I'm leaving them out for now. }; - # create the list of required fields based on the action - my @required_fields = qw/ amount /; + my @required_fields = qw/ Amount /; if ($action eq 'charge') { - push(@required_fields, $_) foreach (qw/ account_number cvv exp_month exp_year /); + push(@required_fields, $_) foreach (qw/ AccountNumber Cvv ExpirationMonth ExpirationYear /); }elsif ($action eq 'void') { - push(@required_fields, $_) foreach (qw/ reference_number transaction_date /); + push(@required_fields, $_) foreach (qw/ ReferenceNumber TransactionDate /); }elsif ($action eq 'refund') { - push(@required_fields, $_) foreach (qw/ amount account_number exp_month exp_year /); + push(@required_fields, $_) foreach (qw/ Amount AccountNumber ExpirationMonth ExpirationYear /); } # check the requirements are met. my @missing_fields; foreach my $field (@required_fields) { - push(@missing_fields, $field) if (!$template_vars->{payment}{$field}); + push(@missing_fields, $field) if (!$xml_vars->{payment}{$field}); } if (scalar(@missing_fields)) { croak "Missing required fields: ".join(', ', @missing_fields); } - # read in the appropriate xml template - my $xml_template = _get_xml_template( $action ); - # create a template object. - my $tt = Template->new(); - # populate the XML template. + my $process_action = $action; + $process_action =~ s/\b([a-z])/\u$1/g; + $process_action = 'Process'.$process_action; my $xml_data; - $tt->process( \$xml_template, $template_vars, \$xml_data ) || croak $tt->error(); + my $writer = new XML::Writer( OUTPUT => \$xml_data, + DATA_MODE => 0, + DATA_INDENT => 0, + ENCODING => 'utf-8', + ); + $writer->xmlDecl(); + $writer->startTag('Request'); + $writer->startTag('MerchantData'); + foreach my $key ( keys ( %{$xml_vars->{auth}} ) ) { + $writer->dataElement( $key, $xml_vars->{auth}{$key} ); + } + $writer->endTag('MerchantData'); + $writer->startTag($payment_actions{ $self->action }{process}); + foreach my $key ( @{$payment_actions{ $self->action }{fields}} ) { + next if (!$xml_vars->{payment}{$key}); + if (ref $xml_vars->{payment}{$key} eq '') { + $writer->dataElement( $key, $xml_vars->{payment}{$key}); + }else { + $writer->startTag($key); + foreach my $key2 (keys %{$xml_vars->{payment}{$key}}) { + $writer->dataElement( $key2, $xml_vars->{payment}{$key}{$key2} ); + } + $writer->endTag($key); + } + } + $writer->endTag($payment_actions{ $self->action }{process}); + $writer->endTag('Request'); + $writer->end(); warn "XML:\n$xml_data\n" if $DEBUG > 2; @@ -348,212 +349,8 @@ sub parse_response { return; } - -} - -sub _get_xml_template { - my $action = shift; - - my $xml_template = q| - - [% auth.platform %] - [% auth.userid %] - [% auth.gid %] - [% auth.tid %] - - |; - - if ($action eq 'charge') { - $xml_template .= _get_xml_template_charge(); - }elsif($action eq 'void') { - $xml_template .= _get_xml_template_void(); - }elsif($action eq 'authorize') { - $xml_template .= _get_xml_template_auth(); - }elsif($action eq 'authorize_cancel') { - $xml_template .= _get_xml_template_auth_cancel(); - }elsif($action eq 'refund') { - $xml_template .= _get_xml_template_refund(); - }elsif($action eq 'capture') { - $xml_template .= _get_xml_template_capture(); - }elsif($action eq 'create_token') { - $xml_template .= _get_xml_template_create_token(); - }elsif($action eq 'delete_token') { - $xml_template .= _get_xml_template_delete_token(); - }elsif($action eq 'query_token') { - $xml_template .= _get_xml_template_query_token(); - }elsif($action eq 'update_exp_date') { - $xml_template .= _get_xml_template_update_exp_date(); - }elsif($action eq 'update_token') { - $xml_template .= _get_xml_template_update_token(); - } - - $xml_template .= ""; - $xml_template =~ s/[\n\t\s]*//g; - - return $xml_template; -} - -sub _get_xml_template_charge { - my $xml_template = q| - [% payment.amount %] - [% payment.track1 %] - [% payment.track2 %] - [% payment.type %] - [% payment.cf1 %] - [% payment.cf2 %] - [% payment.cf3 %] - [% payment.account_number %] - [% payment.exp_month %] - [% payment.exp_year %] - [% payment.cvv %] - [% payment.first_name %] - [% payment.last_name %] - [% payment.postal_code %] - [% payment.street_address %] - - [% payment.industry_type %] - [% payment.invoice_num %] - - [% payment.appid %] - [% payment.recurring %] - |; - - # other options (that we are not using right now): -# -# [% level2.card_type %] -# [% level2.purchase_code %] -# [% level2.country_code %] -# [% level2.ship_tp_postal_code %] -# [% level2.ship_from_postal_code %] -# [% level2.sales_tax %] -# [% level2.product_description1 %] -# [% level2.product_description2 %] -# [% level2.product_description3 %] -# [% level2.product_description4 %] -# -# -# [% level3.purchase_order_num %] -# [% level3.order_date %] -# [% level3.duty_amount %] -# [% level3.alt_tax_amount %] -# [% level3.discount_amount %] -# [% level3.freight_amount %] -# [% level3.tax_exempt %] -# [% level3.line_item_count %] -# -# [% level3.purchase_items %] -# -# - - return $xml_template; -} - -sub _parse_line_items { - my $self = shift; - my %content = $self->content(); - - return '' if (!$content{'items'}); - - my @line_items; - my $template = q| - [% seq_num %] - [% code %] - [% desc %] - [% qty %] - [% unit %] - [% unit_cost %] - [% amount %] - [% discount_amount %] - [% tax_amount %] - [% tax_rate %] - |; - - - my @items = $content{'items'}; - foreach my $item (@items) { - # fille in the slots from $template with details in $item - # push to @line_items - } - - return join("\n", @line_items); -} - -sub _get_xml_template_void { - my $xml_template = q| - [% payment.amount %] - [% payment.account_number %] - [% payment.exp_month %] - [% payment.exp_year %] - [% payment.reference_number %] - - [% payment.industry_type %] - [% payment.appid %] - |; - - return $xml_template; -} - -sub _get_xml_template_refund { - my $xml_template = q| - [% payment.amount %] - [% payment.account_number %] - [% payment.exp_month %] - [% payment.exp_year %] - [% payment.appid %] - |; - - return $xml_template; -} - -sub _get_xml_template_auth { - my $xml_template = ''; - - return $xml_template; -} - -sub _get_xml_template_auth_cancel { - my $xml_template = ''; - - return $xml_template; -} - -sub _get_xml_template_capture { - my $xml_template = ''; - - return $xml_template; } -sub _get_xml_template_create_token { - my $xml_template = ''; - - return $xml_template; -} - -sub _get_xml_template_delete_token { - my $xml_template = ''; - - return $xml_template; -} - -sub _get_xml_template_query_token { - my $xml_template = ''; - - return $xml_template; -} - -sub _get_xml_template_update_exp_date { - my $xml_template = ''; - - return $xml_template; -} - -sub _get_xml_template_update_token { - my $xml_template = ''; - - return $xml_template; -} - - 1; __END__ -- 2.11.0