diff options
author | Alex Brelsfoard <alex@Alexs-MacBook-Pro.local> | 2015-02-09 22:54:30 -0500 |
---|---|---|
committer | Alex Brelsfoard <alex@Alexs-MacBook-Pro.local> | 2015-02-09 22:54:30 -0500 |
commit | 9a863e4092d480adc90e98f7d620d56d98398d89 (patch) | |
tree | a0b880620d9a6a4a782414b126518d8c84ae20ae | |
parent | 4f046ec058d8516765a96f8e2e37c8cc4310fc4c (diff) |
Converting the XML templating to now use XML::Writer
-rw-r--r-- | Makefile.PL | 2 | ||||
-rwxr-xr-x | extra/test.pl | 2 | ||||
-rw-r--r-- | 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|<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__ |