Converting the XML templating to now use XML::Writer
authorAlex Brelsfoard <alex@Alexs-MacBook-Pro.local>
Tue, 10 Feb 2015 03:54:30 +0000 (22:54 -0500)
committerAlex Brelsfoard <alex@Alexs-MacBook-Pro.local>
Tue, 10 Feb 2015 03:54:30 +0000 (22:54 -0500)
Makefile.PL
extra/test.pl
lib/Business/OnlinePayment/vSecureProcessing.pm

index fe27943..a774fdb 100644 (file)
@@ -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', },
index bca3628..50aa857 100755 (executable)
@@ -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(); };
index e7514a3..f957aa9 100644 (file)
@@ -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|<Request >
-    <MerchantData> 
-        <Platform>[% auth.platform %]</Platform>
-        <UserId>[% auth.userid %]</UserId> 
-        <GID>[% auth.gid %]</GID>
-        <Tid>[% auth.tid %]</Tid>
-    </MerchantData>
-    |;
-    
-    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 .= "</Request>";
-    $xml_template =~ s/[\n\t\s]*//g;
-    
-    return $xml_template;
-}
-
-sub _get_xml_template_charge {
-    my $xml_template = q|<ProcessPayment>
-        <Amount>[% payment.amount %]</Amount>
-        <Trk1>[% payment.track1 %]</Trk1>
-        <Trk2>[% payment.track2 %]</Trk2>
-        <TypeOfSale>[% payment.type %]</TypeOfSale>
-        <Cf1>[% payment.cf1 %]</Cf1>
-        <Cf2>[% payment.cf2 %]</Cf2>
-        <Cf3>[% payment.cf3 %]</Cf3>
-        <AccountNumber>[% payment.account_number %]</AccountNumber>
-        <ExpirationMonth>[% payment.exp_month %]</ExpirationMonth>
-        <ExpirationYear>[% payment.exp_year %]</ExpirationYear>
-        <Cvv>[% payment.cvv %]</Cvv>
-        <CardHolderFirstName>[% payment.first_name %]</CardHolderFirstName>
-        <CardHolderLastName>[% payment.last_name %]</CardHolderLastName>
-        <AvsZip>[% payment.postal_code %]</AvsZip>
-        <AvsStreet>[% payment.street_address %]</AvsStreet>
-        <IndustryType>
-            <IndType >[% payment.industry_type %]</IndType >
-            <IndInvoice>[% payment.invoice_num %]</IndInvoice>
-        </IndustryType>
-        <ApplicationId>[% payment.appid %]</ApplicationId>
-        <Recurring>[% payment.recurring %]</Recurring>
-    </ProcessPayment>|;
-    
-    # other options (that we are not using right now):    
-#     <Level2PurchaseInfo>
-#         <Level2CardType>[% level2.card_type %]</Level2CardType >
-#         <PurchaseCode>[% level2.purchase_code %]</PurchaseCode>
-#         <ShipToCountryCode>[% level2.country_code %]</ShipToCountryCode>
-#         <ShipToPostalCode>[% level2.ship_tp_postal_code %]</ShipToPostalCode>
-#         <ShipFromPostalCode>[% level2.ship_from_postal_code %]</ShipFromPostalCode>
-#         <SalesTax>[% level2.sales_tax %]</SalesTax>
-#         <ProductDescription1>[% level2.product_description1 %]</ProductDescription1>
-#         <ProductDescription2>[% level2.product_description2 %]</ProductDescription2>
-#         <ProductDescription3>[% level2.product_description3 %]</ProductDescription3>
-#         <ProductDescription4>[% level2.product_description4 %]</ProductDescription4>
-#     </Level2PurchaseInfo>
-#     <Level3PurchaseInfo>
-#         <PurchaseOrderNumber>[% level3.purchase_order_num %]</PurchaseOrderNumber>
-#         <OrderDate>[% level3.order_date %]</OrderDate>
-#         <DutyAmount>[% level3.duty_amount %]</DutyAmount>
-#         <AlternateTaxAmount>[% level3.alt_tax_amount %]</AlternateTaxAmount>
-#         <DiscountAmount>[% level3.discount_amount %]</DiscountAmount>
-#         <FreightAmount>[% level3.freight_amount %]</FreightAmount>
-#         <TaxExemptFlag>[% level3.tax_exempt %]</TaxExemptFlag>
-#         <LineItemCount>[% level3.line_item_count %]</LineItemCount>
-#         <PurchaseItems>
-#             [% level3.purchase_items %]
-#         </PurchaseItems>
-#     </Level3PurchaseInfo>
-
-    return $xml_template;
-}
-
-sub _parse_line_items {
-    my $self = shift;
-    my %content = $self->content();
-    
-    return '' if (!$content{'items'});
-    
-    my @line_items;
-    my $template = q|            <LineItem>
-                <ItemSequenceNumber>[% seq_num %]</ItemSequenceNumber>
-                <ItemCode>[% code %]</ItemCode>
-                <ItemDescription>[% desc %]</ItemDescription>
-                <ItemQuantity>[% qty %]</ItemQuantity>
-                <ItemUnitOfMeasure>[% unit %]</ItemUnitOfMeasure>
-                <ItemUnitCost>[% unit_cost %]</ItemUnitCost>
-                <ItemAmount>[% amount %]</ItemAmount>
-                <ItemDiscountAmount>[% discount_amount %]</ItemDiscountAmount>
-                <ItemTaxAmount>[% tax_amount %]</ItemTaxAmount>
-                <ItemTaxRate>[% tax_rate %]</ItemTaxRate>
-            </LineItem>|;
-    
-    
-    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|<ProcessVoid>
-        <Amount>[% payment.amount %]</Amount>
-        <AccountNumber>[% payment.account_number %]</AccountNumber>
-        <ExpirationMonth>[% payment.exp_month %]</ExpirationMonth>
-        <ExpirationYear>[% payment.exp_year %]</ExpirationYear>
-        <ReferenceNumber>[% payment.reference_number %]</ReferenceNumber>
-        <TransactionDate/>
-        <IndustryType1>[% payment.industry_type %]</IndustryType1>
-        <ApplicationId>[% payment.appid %]</ApplicationId>
-    </ProcessVoid>|;
-
-    return $xml_template;
-}
-
-sub _get_xml_template_refund {
-    my $xml_template = q|<ProcessRefund>
-        <Amount>[% payment.amount %]</Amount>
-        <AccountNumber>[% payment.account_number %]</AccountNumber>
-        <ExpirationMonth>[% payment.exp_month %]</ExpirationMonth>
-        <ExpirationYear>[% payment.exp_year %]</ExpirationYear>
-        <ApplicationId>[% payment.appid %]</ApplicationId>
-    </ProcessRefund>|;
-
-    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__