use Template;
use XML::Simple;
use Data::Dumper;
+use MIME::Entity;
use Business::OnlinePayment;
use Business::OnlinePayment::HTTPS;
+use Net::SSLeay qw(post_http post_https make_headers make_form);
use vars qw($VERSION $DEBUG @ISA $me);
@ISA = qw(Business::OnlinePayment::HTTPS);
# void => void
);
+BEGIN{
+eval 'use bytes; sub blength ($) { length $_[0] }';
+$@ and eval ' sub blength ($) { length $_[0] }' ;
+}
+sub Net::SSLeay::do_httpx3 {
+ my ($method, $usessl, $site, $port, $path, $headers,
+ $content, $mime_type, $crt_path, $key_path) = @_;
+ my ($response, $page, $h,$v);
+ my $CRLF = "\x0d\x0a"; # because \r\n is not fully portable
+ if ($content) {
+ $mime_type = "";#application/x-www-form-urlencoded" unless $mime_type;
+ my $len = blength($content);
+ #$content = "$mime_type${CRLF}Content-Length: $len$CRLF$CRLF$content";
+ $content = "Cache-Control: no-cache$CRLF"
+ . "Content-Type: multipart/form-data; boundary=----FormBoundaryE19zNvXGzXaLvS5C$CRLF"
+ . "Accept: */*$CRLF"
+ . "Content-Length: $len$CRLF$CRLF$content";
+ } else {
+ $content = "$CRLF$CRLF";
+ }
+ my $req = "$method $path HTTP/1.1$CRLF";
+ unless (defined $headers && $headers =~ /^Host:/m) {
+ $req .= "Host: $site";
+ unless (($port == 80 && !$usessl) || ($port == 443 && $usessl)) {
+ $req .= ":$port";
+ }
+ $req .= $CRLF;
+ }
+ $req .= (defined $headers ? $headers : '') . "$content";
+
+ warn "do_httpx3($method,$usessl,$site:$port)" if $DEBUG;
+ my ($http, $errs, $server_cert)
+ = Net::SSLeay::httpx_cat($usessl, $site, $port, $req, $crt_path, $key_path);
+ return (undef, "HTTP/1.0 900 NET OR SSL ERROR$CRLF$CRLF$errs") if $errs;
+
+ $http = '' if !defined $http;
+ ($headers, $page) = split /\s?\n\s?\n/, $http, 2;
+ warn "headers >$headers< page >>$page<< http >>>$http<<<" if $DEBUG>1;
+ ($response, $headers) = split /\s?\n/, $headers, 2;
+ return ($page, $response, $headers, $server_cert);
+};
+
+sub Net::SSLeay::make_form {
+ my (@fields) = @_;
+ my $form;
+ while (@fields) {
+ my ($name, $data) = (shift(@fields), shift(@fields));
+# $data =~ s/([^\w\-.\@\$ ])/sprintf("%%%2.2x",ord($1))/gse;
+# $data =~ tr[ ][+];
+ $form .= "$name=$data&";
+ }
+ chop $form;
+ return $form;
+}
sub set_defaults {
my $self = shift;
$DEBUG = exists($options{debug}) ? $options{debug} : $DEBUG;
- $self->port($options{'port'});
+
$self->server($options{'url'});
$self->appid($options{'appid'});
- $self->env($options{'env'}) if (defined($options{'env'})); # 'live'/'test'
+ $self->env((defined($options{'env'})) ? $options{'env'} : 'live'); # 'live'/'test'
+# $self->port(($options{'env'} eq 'test') ? 80 : 443);
+ $self->port(443);
}
if (!$content{'first_name'} || !$content{'last_name'} && $content{'name'}) {
($content{'first_name'}, $content{'last_name'}) = split(' ', $content{'name'}, 2);
}
+
+ if ($content{'address'} =~ m/[\D ]*(\d+)\D/) {
+ $content{'street_number'} = $1;
+ }
}
warn "Content after cleaning:\n".Dumper(\%content)."\n" if ($DEBUG >2);
$self->content(%content);
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{'address'}) ? $content{'address'} : '',
+ 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(),
my $xml_data;
$tt->process( \$xml_template, $template_vars, \$xml_data ) || croak $tt->error();
- 44rewdwarn "XML:\n$xml_data\n" if $DEBUG > 2;
+ warn "XML:\n$xml_data\n" if $DEBUG > 2;
- my $opts = {'headers' => {}, 'Content-Type' => 'multipart/form-data'};
+# my $opts = {'Content-Type' => 'multipart/form-data'};
+ my $opts = {'Cache-Control' => 'no-cache', 'Content-Type' => 'multipart/form-data; boundary=----FormBoundaryE19zNvXGzXaLvS5C'};
my $params = {param => $xml_data};
- my ( $page, $server_response, %headers ) = $self->https_post( $opts, $params );
+ my $content = qq|----FormBoundaryE19zNvXGzXaLvS5C
+Content-Disposition: form-data; name="param"
+
+${xml_data}
+----FormBoundaryE19zNvXGzXaLvS5C|;
+ my ( $page, $server_response, %headers ) = $self->https_post( $opts, $content );
# store the server response.
$self->server_response($server_response);
my $xml_template = q|<Request >
<MerchantData>
<Platform>[% auth.platform %]</Platform>
- <UserID>[% auth.userid %]</UserId>
+ <UserId>[% auth.userid %]</UserId>
<GID>[% auth.gid %]</GID>
<Tid>[% auth.tid %]</Tid>
</MerchantData>
$xml_template .= _get_xml_template_update_token();
}
- $xml_template .= "\n</Request>";
+ $xml_template .= "</Request>";
+ $xml_template =~ s/[\n\t\s]*//g;
return $xml_template;
}
</IndustryType>
<ApplicationId>[% payment.appid %]</ApplicationId>
<Recurring>[% payment.recurring %]</Recurring>
- </ProcessPayment>
- <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>|;
+ </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;
}
<AccountNumber>[% payment.account_number %]</AccountNumber>
<ExpirationMonth>[% payment.exp_month %]</ExpirationMonth>
<ExpirationYear>[% payment.exp_year %]</ExpirationYear>
- <ReferenceNumber>[% payment.ref_num %]</ReferenceNumber>
+ <ReferenceNumber>[% payment.reference_number %]</ReferenceNumber>
<TransactionDate/>
<IndustryType1>[% payment.industry_type %]</IndustryType1>
<ApplicationId>[% payment.appid %]</ApplicationId>