Table of Contents

X-Cart AusPost integration

Preparation

The Australian postal service has got the ability to integrate it's services with the X-Cart back-end. Which will allow to use only the X-Cart admin area to make all of the actions related with the posting goods.

According the “eParcel Integration: Accessing eParcel using customers' own systems” document, the integration is including the following steps:

· Produce an eParcel barcoded label and get it tested and approved by Australia Post. (Sections 4 and 0, and
  particularly section 5.4 have mode details)
· Produce a hard copy manifest and get it approved by Australia Post. (See section 6 for further details)
· Produce an XML manifest and get it tested and approved by Australia Post. (See section 6 and Appendix 1
  for further details)
· Demonstrate successful transmissions of the XML manifest via the SOAP interface.

In practice, the SOAP interface is not working and the sftp file transfer for the manifest is required.

Generally the following changes should be done in X-Cart:

Changes

There are a few hard thing in the eParcel integration. It's label generation, pdf generation, xml generation and xml file sending to eParcel server. Let's look at it.

Labels generation for eParcel

According the documentation, each label has got it's own barcode for the eParcel system. The format is described in the integration manual, starting from:

4.3 Barcode format
    The domestic eParcel barcode is a Code 128 barcode using the 128 Code A and 128 Code C character sets
    with the following components...

But generally the barcode is constructed from the eParcel account data, label information and customer information. Here the example of the code:

        $product_codes = array(
            'S1' => '60',
            'S5' => '60',
            'X1' => '61',
            'X2' => '61',
        );
        $service_codes = array(
            'S1' => '14',
            'S5' => '14',
            'X1' => '14',
            'X2' => '14',
        );

        foreach($labels['labels'] as $index=>$label) {
            $i = $index+1;
            $pc = $product_codes[$labels['service']];
            $sc = $service_codes[$labels['service']];

            $as = sprintf('%02s', $i);
            
            $article_num = $config['EParcel']['merchant_location_id'].$cons.$as.$sc.(count($labels['labels']) == 1?'2':(count($labels['labels']) == $i?'1':'0')).'0'.$customer['s_zipcode'];
            
            $hrd = $config['EParcel']['merchant_location_id'].$cons.$as.$sc.(count($labels['labels']) == 1?'2':(count($labels['labels']) == $i?'1':'0'));
            $hrdc = func_eparcel_hrd_get($hrd);
            
            $barcode = '997'.'001'.$pc.$hrd.$hrdc.'0'.$customer['s_zipcode'];
        }

In the code above the special eParcel check char is used ($hrdc). Since it will be used in a few places, the generation is moved to the special function.

function func_eparcel_hrd_get($hrd) {
    $toa = str_split($hrd);
    foreach($toa as $k => $ch) {
        $tmp = ord($ch);
        if ($tmp >= 65 and $tmp <= 90) $toa[$k] = $tmp %10;
    }
    $toa = array_reverse($toa);
    $sum1 = $sum2 = 0;
    foreach($toa as $k => $ch) {
        if ($k % 2 == 0) $sum1 += $ch;
        else $sum2 += $ch;
    }
    $sum = $sum1*3+$sum2;
    $ret = 10 - $sum % 10;
    return $ret == 10?0:$ret;
}

PDF manifest generation for the eParcel integration

The eParcel PDF manifest is the doc, which should be printed and enclosed to the goods. The requirements to this doc is described here:

6.1 eParcel Manifest Requirements
    6.1.1 It is mandatory to provide both an electronic and a hard-copy paper manifest with every physical pick up
           or lodgement of eParcels. The contents of the manifest should match what is being physically lodged.
    6.2.2 The paper manifest contains identical data to the electronic manifest, and is needed to allow Australia
           Post to check that the manifest data that has been provided matches the physical articles that are
           lodged. It is vitally important that the timing and method of the manifest production ensures that there is
           a direct match with the physical lodgement of parcels.
           The specification for the paper manifest is detailed in Section 6.2 of this document.
    6.3.3 The format of the electronic manifest is described in Appendix 1 of this document. The electronic
           manifest must be formatted as an .XML file and sent via the Australia Post SOAP interface. This replaces
           the previous FTP interface. Previous files are backwards compatible with the new system although they
           do not provide all of the functionality afforded by the new system.
           Electronic manifests will be validated against your eParcel Agreement and will be rejected if, for example,
           they have:
           ·    articles with a chargeable weight more than the maximum allowed in your contract (for a contract
                where cubing is required, this is typically 62.5kg ­
                 ie. The maximum size of 0.25 cu m x the typical cubing rate of 250kg per cu m)
           ·    more than 20 articles in a consignment
    6.4.4 Prior to implementing an eParcel manifest off your own system, it is essential that you secure the written
           approval of Australia Post, for both manifests and barcoded labels, through your State eParcel Controller.
    6.4.5 Manifest numbers must be sequential and only 10 characters in length. If you are an existing Australia
           Post Parcel customer, the manifest numbers should continue from the last manifest lodged under the
           previous system to avoid duplication.
    6.4.6 You must ensure that electronic manifests can be able to be re-transmitted on request by Australia Post in
           case of transmission problems.
    6.4.7 There is currently a restriction on the manifest size of 500 articles. If you lodge more than 500 articles
           each day you will need to break down your lodgement into manifests of 500 articles or less. This
           restriction will be lifted in a future release of the eParcel system but customers progressing integration at
           present will need to develop their system with the current limitation in mind.

For the pdf doc generation in the X-Cart, it's better to use the tcpdf php lib. In this case the pdf will be generated pretty fast and it's possible to make it very closed to the requirements.

The below you are able to see the example of the manifest generation function.

function func_eparcel_gen_manifest($orders) {
    global $config, $xcart_dir, $sql_tbl;

    $orders = array_keys($orders);

    func_eparcel_xml($orders);

    x_load('order');

    $font_size = 10;
    $font = 'times';
    $width = 85;

    $pdf = new TCPDF('L', 'mm', 'A4', true);

    $pdf->setJPEGQuality(100);
    $pdf->SetCreator(PDF_CREATOR);
    $pdf->SetAuthor($config['Company']['company_name']);

    $pdf->setPrintHeader(false);
    $pdf->setPrintFooter(false);
    $pdf->setFooterFont(Array($font, '', $font_size));
    $pdf->SetMargins('10', '10', '10');

    $pdf->setImageScale(1);

    $pdf->AddPage();
    $pdf->SetAutoPageBreak(true);

    $pdf->SetFillColor(0, 0, 0, 0);

    $pdf->SetFont($font, '', $font_size);

    $company = $config['Company'];
    $pdf->writeHTMLCell(0, 0, 10, 10, "<b>Australia Post manifest for $company[company_name]</b>", 0, 1, 0, true, 'C');
    $pdf->writeHTMLCell(0, 0, 10, 16, "<b>Customer's address:</b> $customer[s_address] $customer[s_address_2] $customer[s_city] $customer[s_state] $customer[s_zipcode]", 0, 1, 0, true, 'C');
    $pdf->writeHTMLCell(0, 0, 10, 22, "<b>Manifest created date:</b> ".date("l, j F, Y")." <b>Manifest Number:</b> ".$config['eparcel_transaction_id']."", 0, 1, 0, true, 'C');
    $pdf->writeHTMLCell(0, 0, 10, 28, "<b>Merchant ID:</b> ".$config['EParcel']['eparcel_username']." <b>Merchant Location ID:</b>".$config['EParcel']['merchant_location_id'], 0, 1, 0, true, 'C');
    $pdf->writeHTMLCell(0, 0, 10, 34, "<b>Australia post account number:</b>".$config['EParcel']['eparcel_account'], 0, 1, 0, true, 'C');
    $pdf->writeHTMLCell(0, 0, 10, 40, "<b>Lodgement facility: Web XML Upload", 'B', 1, 0, true, 'C');

    $pdf->writeHTMLCell(0, 0, 10, 46, "<br/><br/><br/>Cnsgmnt Nbr", 'B');
    $pdf->writeHTMLCell(0, 0, 45, 46, "<br/><br/><br/>Article Nbr", 'B');
    $pdf->writeHTMLCell(0, 0, 70, 46, "<br/><br/><br/>Deliver To", 'B');
    $pdf->writeHTMLCell(0, 0, 95, 46, "<br/><br/><br/>Postcode", 'B');
    $pdf->writeHTMLCell(0, 0, 110, 46, "<br/><br/><br/>Country", 'B');
    $pdf->writeHTMLCell(0, 0, 125, 46, "<br/><br/>Charge Code<br/>Description", 'B');
    $pdf->writeHTMLCell(0, 0, 190, 46, "<br/><br/>Chargin<br/>zone", 'B');
    $pdf->writeHTMLCell(0, 0, 204, 46, "<br/><br/>Dngrous<br/>Goods", 'B');
    $pdf->writeHTMLCell(0, 0, 218, 46, "Total<br/>articles<br/>in cnsgmnt", 'B');
    $pdf->writeHTMLCell(0, 0, 237, 46, "<br/><br/>Cubic<br/>weight", 'B');
    $pdf->writeHTMLCell(0, 0, 251, 46, "<br/><br/>Actual<br/>weight", 'B');
    $pdf->writeHTMLCell(0, 0, 265, 46, "<br/><br/>Chargeable<br/>weight", 'B');

    $pdf->SetFont($font, '', $font_size-1);

    $service_labels = array(
        'S1' => 'Standard eParcel',
        'S5' => 'Flat rate eParcel',
        'X1' => 'Express Post eParcel',
        'X2' => 'Flat rate Express Post eParcel',
    );

    $counter = 0;
    $total_amount = $total_weight = 0;
    foreach($orders as $orderid) {
        $order_data = func_order_data($orderid);
        $order = $order_data["order"];
        $products = $order_data['products'];
        $customer = $order_data["userinfo"];
        $labels = unserialize($order['labels']);

        $amount = $weight = 0;
        foreach($labels['labels'] as $index=>$data) {
            $current = 64+$counter*6;
            $i = $index+1;
            $pdf->writeHTMLCell(0, 0, 10, $current, sprintf('%07s', $orderid));
            $pdf->writeHTMLCell(0, 0, 45, $current, sprintf('%02s', $i));
            $pdf->writeHTMLCell(0, 0, 70, $current, "$customer[s_firstname] $customer[s_lastname]");
            $pdf->writeHTMLCell(0, 0, 95, $current, "$customer[s_zipcode]");
            $pdf->writeHTMLCell(0, 0, 110, $current, "$customer[s_countryname]");
            
            $pdf->writeHTMLCell(0, 0, 125, $current, $service_labels[$labels['service']]);
            $pdf->writeHTMLCell(0, 0, 190, $current, $labels['service']);
            $pdf->writeHTMLCell(0, 0, 204, $current, "N");
            $pdf->writeHTMLCell(0, 0, 218, $current, 1);
            $pdf->writeHTMLCell(0, 0, 237, $current, $data['weight']);
            $pdf->writeHTMLCell(0, 0, 251, $current, $data['weight']);
            $pdf->writeHTMLCell(0, 0, 265, $current, $data['weight']);
            $total_amount += 1;
            $total_weight += $data['weight'];
            $amount += 1;
            $weight += $data['weight'];
            $counter += 1;
        }     
        $current = 64+$counter*6;
        $pdf->writeHTMLCell(0, 0, 10, $current, 'subtotal (for 1 consignement)', 'TB');
        $pdf->writeHTMLCell(0, 0, 218, $current, $amount);
        $pdf->writeHTMLCell(0, 0, 237, $current, $weight);
        $pdf->writeHTMLCell(0, 0, 251, $current, $weight);
        $pdf->writeHTMLCell(0, 0, 265, $current, $weight);
        $counter += 1;
    }
    $pdf->writeHTMLCell(0, 0, 10, $current+6, "Total", 'T');
    $pdf->writeHTMLCell(0, 0, 218, $current+6, $total_amount);
    $pdf->writeHTMLCell(0, 0, 237, $current+6, $total_weight);
    $pdf->writeHTMLCell(0, 0, 251, $current+6, $total_weight);
    $pdf->writeHTMLCell(0, 0, 265, $current+6, $total_weight);


    $pdf->writeHTMLCell(0, 0, 200, $current+15, "Sender signature", 'B');

    $pdf->writeHTMLCell(50, 0, 10, $current+20, "For Australis Post Use", 'B');

    $pdf->writeHTMLCell(40, 8, 10, $current+28, "Checked by:", 1);
    $pdf->writeHTMLCell(90, 8, 50, $current+28, "", 1);
    $pdf->writeHTMLCell(40, 8, 10, $current+36, "Time received:", 1);
    $pdf->writeHTMLCell(90, 8, 50, $current+36, "", 1);
    $pdf->writeHTMLCell(40, 8, 10, $current+44, "Date Received:", 1);
    $pdf->writeHTMLCell(90, 8, 50, $current+44, "", 1);
    $pdf->writeHTMLCell(40, 8, 10, $current+52, "Number of ULDs:", 1);
    $pdf->writeHTMLCell(90, 8, 50, $current+52, "", 1);

    $pdf->writeHTMLCell(40, 8, 160, $current+28, "Approx no. of articles:", 1);
    $pdf->writeHTMLCell(90, 8, 200, $current+28, "", 1);
    $pdf->writeHTMLCell(40, 8, 160, $current+36, "Type of revenue check:", 1);
    $pdf->writeHTMLCell(90, 8, 200, $current+36, "", 1);
    $pdf->writeHTMLCell(40, 8, 160, $current+44, "Acceptance scan perfomed", 1);
    $pdf->writeHTMLCell(40, 8, 160, $current+47, "(date/time/initials)");
    $pdf->writeHTMLCell(90, 8, 200, $current+44, "", 1);
    $pdf->writeHTMLCell(40, 8, 160, $current+52, "Accepted in eParcel system", 1);
    $pdf->writeHTMLCell(40, 8, 160, $current+55, "(date/time/initials)");
    $pdf->writeHTMLCell(90, 8, 200, $current+52, "", 1);
	
	$manifest_file = "manifest_ID".$config['eparcel_transaction_id'].".pdf";
    $save_to_file = $xcart_dir.'/images/manifests/'.$manifest_file;
    db_query("update $sql_tbl[orders] set pdf_manifest='$manifest_file' where orderid in ('".implode("', '", $orders)."')");

    $pdf->Output($save_to_file, 'FD');
    die;
}

PDF labels generation for the eParcel integration

In additional to the mifest the eParcel labels should be generated. Generally there are the similar requirements for the labels.

5.1 eParcel label requirements
    Australia Post's eParcel system does away with the need for paper consignment notes. Every eParcel should
    have a label attached to the top face bearing basic parcel delivery information and an eParcel barcode (or
    approved alternative) that represents the Article ID. A full barcode specification is contained in section 4 of this
    document.
    There is a strong preference for this label to be branded with the Australia Post logo and the red Australia Post
    house colours as this maximises the opportunity for the parcel to be suitably handled and scanned within the
    network. Similarity to the standard eParcel label design is also highly recommended for similar reasons.
    However, it is recognised that this is not practical in all instances and Australia Post will also accept plain
    white labels with black print and no colour coding logo. The labels must bear the clear Australia Post eParcel
    identity and contain all specified information fields.
    There is also a major advantage if all labels bear a peel-off portion of the barcode for use in circumstances
    where scanners are unavailable and scanning has to be performed later off paper based records. Without the
    "peel-off" there will be a slight degradation in the level and quality of the scanning data provided. However,
    again, Australia Post recognise that provision of label stationery with a peel off is not always possible and
    labels without "peel offs" will be accepted.
    All labels and manifests produced off customers' own systems must be fully tested and approved before use.
    Please access this testing service through your State eParcel Controller.

These labels should be printed and attached to each package of goods. It's possible to generate it in different ways, but it's better to use the pdf format, similar to the pdf manifest. It's better to use it, because the pdf format can be printed without the same way as you can see it on your screen.

Below you can find the example of the pdf label generation:

function func_eparcel_gen_labels($orderid, $epi) {
    global $config, $xcart_dir;

    x_load('order');
    $order_data = func_order_data($orderid);
    $order = $order_data["order"];
    $customer = $order_data["userinfo"];

    $font_size = 11;
    $font = 'times';
    $width = 85;

    $pdf = new TCPDF('P', 'mm', 'A4', true);

    $pdf->setJPEGQuality(100);
    $pdf->SetCreator(PDF_CREATOR);
    $pdf->SetAuthor($config['Company']['company_name']);

    $pdf->setPrintHeader(false);
    $pdf->setPrintFooter(false);
    $pdf->setFooterFont(Array($font, '', $font_size));
    $pdf->SetMargins('10', '10', '10');

    $pdf->setImageScale(1);

    $pdf->AddPage();
    $pdf->SetAutoPageBreak(false);

    $pdf->SetFillColor(0, 0, 0, 0);


    $left_margin = 10;
    $top_margin = 10;
    foreach($epi['labels'] as $index=>$data) {
        $i = $index+1;

        $pdf->Image($xcart_dir.'/modules/EParcel/images/epi_header-red.jpg', $left_margin, $top_margin, $width);

        $pdf->SetFont($font, '', $font_size);
        $pdf->setCellHeightRatio(1);

        $pdf->writeHTMLCell($width, 0, $left_margin, $top_margin+13, "<b>DELIVER TO</b><br/>$customer[firstname] $customer[lastname]<br/>$customer[company]<br/>$customer[s_address]<br/>$customer[s_address_2]<br/><br/>$customer[s_city] $customer[s_state] $customer[s_zipcode]", 'B');
        $pdf->writeHTMLCell($width, 0, $left_margin+60, $top_margin+13, "Order #$orderid");


        $pdf->writeHTMLCell($width, 11, $left_margin, $top_margin+45, "<b>DELIVERY INSTRUCTIONS</b><br/>$epi[note]");

        $cons = sprintf('%07s', $orderid);
        $as = sprintf('%02s', $i);

        $pdf->SetFont($font, '', $font_size-3);
        $pdf->writeHTMLCell(40, 11, $left_margin, $top_margin+57, $epi['sign'] == 'Y'?"<b>SIGNATURE ON DELIVERY REQUIRED</b>":'', 'BT');
        $pdf->SetFont($font, '', $font_size);
        $pdf->writeHTMLCell(45, 11, $left_margin+40, $top_margin+57, "CON NO ".$config['EParcel']['merchant_location_id']."$cons<br/><b>PARCEL $i of ".count($epi['labels'])."</b>", 'BTL');

//        $barcode = 'C997'.'001'.'Product Code (2)'.'A'.$config['EParcel']['merchant_location_id'].'C'.'Consignment Suffix (7)'.'Article Suffix (2)'.'Service code(2)'.($number == 1?'2':($number == $i?'1':'0')).'0'.$customer['s_zipcode'];
        $product_codes = array(
            'S1' => '60',
            'S5' => '60',
            'X1' => '61',
            'X2' => '61',
        );
        $service_codes = array(
            'S1' => '14',
            'S5' => '14',
            'X1' => '14',
            'X2' => '14',
        );

        $pc = $product_codes[$epi['service']];
        $sc = $service_codes[$epi['service']];

        $hrd = $config['EParcel']['merchant_location_id'].$cons.$as.$sc.(count($epi['labels']) == 1?'2':(count($epi['labels']) == $i?'2':'1'));
        $hrdc = func_eparcel_hrd_get($hrd);
//        $barcode = 'C997'.'001'.$pc.'A'.$config['EParcel']['merchant_location_id'].'C'.$cons.$as.$sc.(count($epi['labels']) == 1?'2':(count($epi['labels']) == $i?'1':'0')).'0'.$customer['s_zipcode'];
        $barcode = '997'.'001'.$pc.$hrd.$hrdc.'0'.$customer['s_zipcode'];
        $article = $hrd.$hrdc;
		
		$pdf->SetFont($font, '', $font_size+2);
        $pdf->writeHTMLCell($width, 0, $left_margin, $top_margin+68, '<center>AP Article Id: '.$article.'</center>', 0);
// kornev, 0 - it's because the amount of the chars should be even in barcode128
        $pdf->write1DBarcode('0'.$barcode, 'C128C', $left_margin, $top_margin+76, 79, 26, 0.43, array('text' => 0));
        $pdf->writeHTMLCell($width, 0, $left_margin, $top_margin+103, '<center>AP Article Id: '.$article.'</center>');

        $pdf->SetFont($font, '', $font_size-3);
        $company = $config['Company'];
        $pdf->writeHTMLCell(35, 0, $left_margin, $top_margin+110, "<b>SENDER</b><br/>$company[company_name]<br/>$company[location_address]<br/><br/>$company[location_city] $company[location_state] $company[location_zipcode]<br/>$company[company_phone]", 'T');
        $pdf->SetFont($font, '', $font_size-4);
        $pdf->writeHTMLCell(50, 0, $left_margin+35, $top_margin+110, "<b>Aviation security and Dangerous Goods Declaration</b><br/>The sender acknowledges that this article may be carrier by air and will be subject for aviation security and clearing procedures; and the sender declares that the articles does not contain any dangerous or prohibited goods, explosive or incendiary devices. A false declaration is a criminal offense.", 'TL');

        if (($i+2)%4 == 0) {
            $top_margin += 140;
            $left_margin = 10;
        }
        if (($i+1)%2 == 0) {
            $left_margin += $width+10;
        }
        if ($i % 4 == 0 && $i != count($epi['labels'])) {
            $pdf->AddPage();
            $top_margin = 10;
            $left_margin = 10;
        }
    }

    $pdf->Output("labels-$orderid.pdf");//$save_to_file, 'F');
    die;
}

Generation of the XML manifest

The XML version of the manifest is generally contains teh same data as the PDF version, but it's organized differently of course and there is the special format. You can use the function below as the template for the XML manifest generation:

function func_eparcel_xml($orders) {
    global $config;

    if (!$config['eparcel_transaction_id']) {
        func_array2insert('config', array('name' => 'eparcel_transaction_id', 'value' => 1));
        $config['eparcel_transaction_id'] = 1;
    }  else {
    	$eparcel_transaction_id = $config['eparcel_transaction_id'] + 1;
    }

    x_load('order', 'http');

    $company = $config['Company'];

//    $time = date('Y-m-d', $order['date']+86400*3).'T'.date('h:i:s', $order['date']).'.0Z';
    $current_time = date('Y-m-d', time()+86400*3).'T'.date('h:i:s').'.0Z';

    $epconfig = $config['EParcel'];

    $IsInternationalDelivery = $customer['s_country'] == 'AU'?'false':'true';

$query = <<<EOT
<?xml version="1.0" encoding="UTF-8"?>
<PCMS xmlns="http://www.auspost.com.au/xml/pcms">
    <SendPCMSManifest>
        <header>
            <TransactionDateTime>$current_time</TransactionDateTime>
            <TransactionId>$eparcel_transaction_id</TransactionId>
            <TransactionSequence>0</TransactionSequence>
            <ApplicationId>MERCHANT</ApplicationId>
        </header>
        <body>
                            <PCMSManifest>
                                <MerchantLocationId>$epconfig[merchant_location_id]</MerchantLocationId>
                                <ManifestNumber>$eparcel_transaction_id</ManifestNumber>
                                <DateSubmitted>$current_time</DateSubmitted>
                                <DateLodged>$current_time</DateLodged>
EOT;

    foreach($orders as $orderid) {
        $order_data = func_order_data($orderid);
        $order = $order_data["order"];
        $products = $order_data['products'];
        $customer = $order_data["userinfo"];
        $labels = unserialize($order['labels']);

        $cons = sprintf('%07s', $orderid);
        $cc = $labels['service'];

        $is_signature_required = $labels['sign'] == 'Y'?'Y':'N';
        
        
        $consignment_num = $config['EParcel']['merchant_location_id'].$cons;

$query .= <<<EOT
                                <PCMSConsignment>
                                    <ConsignmentNumber>$consignment_num</ConsignmentNumber>
                                    <ChargeCode>$cc</ChargeCode>
                                    <InternalChargebackAccount>Finance</InternalChargebackAccount>
                                    <ReferenceNo1>$orderid</ReferenceNo1>
                                    <ReferenceNo2></ReferenceNo2>
                                    <DeliveryName>$customer[s_firstname] $customer[s_lastname]</DeliveryName>
                                    <DeliveryCompanyName>$customer[company]</DeliveryCompanyName>
                                    <DeliveryAddressLine1>$customer[s_address]</DeliveryAddressLine1>
                                    <DeliveryAddressLine2>$customer[s_address_2]</DeliveryAddressLine2>
                                    <DeliveryAddressLine3></DeliveryAddressLine3>
                                    <DeliveryAddressLine4></DeliveryAddressLine4>
                                    <DeliveryPhoneNumber>$customer[phone]</DeliveryPhoneNumber>
                                    <DeliveryEmailAddress>$customer[email]</DeliveryEmailAddress>
                                    <DeliverySuburb>$customer[s_city]</DeliverySuburb>
                                    <DeliveryStateCode>$customer[s_state]</DeliveryStateCode>
                                    <DeliveryPostcode>$customer[s_zipcode]</DeliveryPostcode>
                                    <DeliveryCountryCode>$customer[s_country]</DeliveryCountryCode>
                                    <DeliveryInstructions>$labels[note]</DeliveryInstructions>
                                    <IsInternationalDelivery>$IsInternationalDelivery</IsInternationalDelivery>
                                    <ReturnName>$company[company_name]</ReturnName>
                                    <ReturnAddressLine1>$company[location_address]</ReturnAddressLine1>
                                    <ReturnAddressLine2></ReturnAddressLine2>
                                    <ReturnAddressLine3></ReturnAddressLine3>
                                    <ReturnAddressLine4></ReturnAddressLine4>
                                    <ReturnSuburb>$company[location_city]</ReturnSuburb>
                                    <ReturnStateCode>$company[location_state]</ReturnStateCode>
                                    <ReturnPostcode>$company[location_zipcode]</ReturnPostcode>
                                    <ReturnCountryCode>$company[location_country]</ReturnCountryCode>
                                    <CreatedDateTime>$current_time</CreatedDateTime>
                                    <PostChargeToAccount>$epconfig[eparcel_account]</PostChargeToAccount>
                                    <IsSignatureRequired>$is_signature_required</IsSignatureRequired>
                                    <CTCAmount>0.00</CTCAmount>
                                    <DeliverPartConsignment>N</DeliverPartConsignment>
                                    <ContainsDangerousGoods>false</ContainsDangerousGoods>
EOT;

        $product_codes = array(
            'S1' => '60',
            'S5' => '60',
            'X1' => '61',
            'X2' => '61',
        );
        $service_codes = array(
            'S1' => '14',
            'S5' => '14',
            'X1' => '14',
            'X2' => '14',
        );
        if ($labels['labels'])
        foreach($labels['labels'] as $index=>$label) {
            $i = $index+1;
            $pc = $product_codes[$labels['service']];
            $sc = $service_codes[$labels['service']];

            $as = sprintf('%02s', $i);
            
            //$barcode = 'C997'.'001'.$pc.'A'.$config['EParcel']['merchant_location_id'].'C'.$cons.$as.$sc.(count($labels['labels']) == 1?'2':(count($labels['labels']) == $i?'1':'0')).'0'.$customer['s_zipcode'];

            $article_num = $config['EParcel']['merchant_location_id'].$cons.$as.$sc.(count($labels['labels']) == 1?'2':(count($labels['labels']) == $i?'1':'0')).'0'.$customer['s_zipcode'];
            
            $hrd = $config['EParcel']['merchant_location_id'].$cons.$as.$sc.(count($labels['labels']) == 1?'2':(count($labels['labels']) == $i?'1':'0'));
            $hrdc = func_eparcel_hrd_get($hrd);
            
            $barcode = '997'.'001'.$pc.$hrd.$hrdc.'0'.$customer['s_zipcode'];
            

$query .= <<<EOT
                                    <PCMSDomesticArticle>
                                        <ArticleNumber>$article_num</ArticleNumber>
                                        <BarcodeArticleNumber>$barcode</BarcodeArticleNumber>
                                        <ActualWeight>$label[weight]</ActualWeight>
                                        <IsTransitCoverRequired>N</IsTransitCoverRequired>
                                        <ContentsItem/>
                                    </PCMSDomesticArticle>
EOT;
        }
$query .= <<<EOT
                                </PCMSConsignment>
EOT;

    }
$query .= <<<EOT
                            </PCMSManifest>
        </body>
    </SendPCMSManifest>
</PCMS>
EOT;

return $query;
}

Sending of the xml manifest to the eParcel server

Since the SOAP interface is not able by some of the reason, we ahve to use the sftp to send the xml files to the eParcel server. It's not so good as SOAP, but it's posible to automatize it also.

The sftp hasn't got any ability to send the files with the command line, so we have to use the lftp (it have to be installed firstly) to cover it.

Here the solution for Linux:

    $filename = $config['EParcel']['merchant_location_id'].'_'.sprintf('%06s', $eparcel_transaction_id).'_'.$config['EParcel']['eparcel_username'].'.xml';
    global $var_dirs;
    $lp = $var_dirs['tmp'].'/'.$filename;
    $sf = $var_dirs['tmp'].'/'.$filename.'.scr';
    file_put_contents($sf, "open sftp://".($config['EParcel']['is_test_mode'] == 'Y'?"stdev.auspost.com.au":'st.auspost.com.au')."
user  ".$config['EParcel']['eparcel_username']." ".$config['EParcel']['eparcel_password']."
put $lp
quit");
    file_put_contents($lp, $src);
    exec($sql="lftp -f $sf");

Conclusion

There are a few problems with the AusPost interface implementation, but it's just a technical problems. The interace is pretty fine for the postage automatization in the admin area and pretty flexy for the any organization of work.