1

I've got basic proficiency in PHP, JavaScript, html, and SQL. I also use Postman little a bit. I hope a solution to my problem can be found within those skills, but I'm willing to learn a new language if necessary.

Using PHP, I've written myself a page of admin tools to be able to run my business. One feature I'd like, is an ability to prefill a customs declaration form (found here).

My first idea was to download the html page and run it, because if that works, all I need to do is fill out the form with PHP.

That failed. Even after changing all the relative paths to absolute paths, I still ran into the cors policy no 'access-control-allow-origin' header is present on the requested resource. issue.

Ideally, I'd like to bypass the page entirely and skip straight to where-ever the form submits to, but if that cannot be done, I'd happily settle for a button that navigates to a prefilled version of the page.

I respect that answering this question fully could take all day, but I'll happily award the green tick to anyone who can just give me a starting point to solve this problem from.

Maybe I just need the right header. Maybe there's a way to get my browser to treat the site as if it's at the same origin.

I've spent ages searching everywhere for a solution to this problem, but most people with this problem were trying to access their own resources, not someone else's.

Note: I received a very useful comment off this page which I will credit to its author

Investigating the network request when submitting a test shows the request is POSTed to auspost.com.au/bin/form/stopact with an escaped JSON string containing all the data. The response contains a customer reference code, QR code and other information. You could start by submitting data to that endpoint, with as many of the same headers as possible

jla

  • 1
    You can fill out this form programatically using `CURL POST`. You will need to HTML form on your server/app and use curl. – Cyborg Dec 21 '20 at 01:30
  • 1
    If the service provides an API that would much easier to maintain. Otherwise the next step is to run through the flow in a browser with a debugger so you can see what is being where. You can also inspect the page and see that the form's action is # (i.e. same url). You might be able to just post the data, or there may be anti-bot feature that would require you to emulate a browser (I have used (perl) Mechanize and Sellium) but there are many others. The first result I found was Mink for php. – Allan Wind Dec 21 '20 at 01:30
  • @AllanWind, the service does not. I had to do some serious digging though documents just to find the complete table of price-by-weight. A complete guide to the API is probably asking way too much of Australia Post, but maybe it does exist and I just haven't found it yet. – Jonathon Philip Chambers Dec 21 '20 at 01:32
  • 1
    Did you see https://developers.auspost.com.au/projects ? I didn't see an obvious answer though. – Allan Wind Dec 21 '20 at 01:34
  • @Cyborg that was my plan, but when I couldn't even get a duplicate form to submit I knew it was well beyond my `CURL POST` abilities. – Jonathon Philip Chambers Dec 21 '20 at 01:35
  • @AllanWind Nice find! No, I did not! Not sure if you're amazing at finding stuff, or if I'm dreadful. Maybe a combination of the two. – Jonathon Philip Chambers Dec 21 '20 at 01:37
  • @AllanWind on closer inspection, no sign of "customs declaration form" anywhere. But still a good find. I might find a use for it. – Jonathon Philip Chambers Dec 21 '20 at 01:52

1 Answers1

1

Try this CURL:

curl 'https://auspost.com.au/bin/form/stopact' \
  -H 'Connection: keep-alive' \
  -H 'Pragma: no-cache' \
  -H 'Cache-Control: no-cache' \
  -H 'Accept: */*' \
  -H 'X-Requested-With: XMLHttpRequest' \
  -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36' \
  -H 'Content-Type: application/x-www-form-urlencoded; charset=UTF-8' \
  -H 'Origin: https://auspost.com.au' \
  -H 'Sec-Fetch-Site: same-origin' \
  -H 'Sec-Fetch-Mode: cors' \
  -H 'Sec-Fetch-Dest: empty' \
  -H 'Referer: https://auspost.com.au/declaration-form-fields-page' \
  -H 'Accept-Language: en-US,en;q=0.9,nb;q=0.8,no;q=0.7,mt;q=0.6' \
  -H 'Cookie: at_check=true; AMCVS_0A2D38B352782F1E0A490D4C%40AdobeOrg=1; _gcl_au=1.1.881765264.1608514094; s_ecid=MCMID%7C76693753864336349821406673003588424534; AMCV_0A2D38B352782F1E0A490D4C%40AdobeOrg=1585540135%7CMCIDTS%7C18618%7CMCMID%7C76693753864336349821406673003588424534%7CMCAAMLH-1609118894%7C6%7CMCAAMB-1609118894%7CRKhpRz8krg2tLO6pguXWp5olkAcUniQYPHaMWWgdJ3xzPWQmdj0y%7CMCOPTOUT-1608521294s%7CNONE%7CMCAID%7CNONE%7CvVersion%7C4.4.0; mbox=session#abb194d9ddc9409e82fa625b0006f1ed#1608515955|PC#abb194d9ddc9409e82fa625b0006f1ed.37_0#1671758895; sat_track=true; _uetsid=ccd99990432b11eb9b9307315b7acaa7; _uetvid=ccda0b90432b11eb9f64f7c0bb2931b9; _fbp=fb.2.1608514096500.1515985073; s_auth=false; s_cc=true; s_sq=%5B%5BB%5D%5D; prevUrl=https%3A%2F%2Fauspost.com.au%2Fdeclaration-form-fields-page%23summary; s_ppn=auspost%3Astopact%3Acustoms%20declaration%3Aform%3Areview; s_nr=1608515010527' \
  --data-raw 'jsonFormData=%7B%22customDeclaration%22%3A%7B%22label%22%3A%7B%22source%22%3A%22AEM%22%2C%22postagePaidIndicator%22%3Afalse%2C%22eadIndicator%22%3Anull%7D%2C%22parcelCharacteristics%22%3A%7B%22productClassification%22%3A31%2C%22dangerousGoodsIndicator%22%3Afalse%2C%22returnInstructions%22%3A%22Return+By+Most+Economical+Route%22%2C%22importerReferenceNumber%22%3A%22ImportREF%22%2C%22content%22%3A%5B%7B%22content%22%3A%22testItem%22%2C%22contentQuantity%22%3A1%2C%22contentUnitValue%22%3A10%2C%22totalContentValue%22%3A10%2C%22contentWeight%22%3A1%2C%22contentCountryOfOrigin%22%3A%22AU%22%7D%5D%2C%22totalConsignmentValue%22%3A10%7D%2C%22senderAddress%22%3A%7B%22firstName%22%3A%22sFirstname%22%2C%22lastName%22%3A%22sLastname%22%2C%22companyName%22%3A%22sBiz%22%2C%22addressLine%22%3A%5B%22sBaddr%22%5D%2C%22suburb%22%3A%22SbCity%22%2C%22state%22%3A%22ACT%22%2C%22postcode%22%3A%220100%22%2C%22email%22%3A%22saddr%40test.com%22%2C%22phone%22%3A%229876543210%22%2C%22smsConfirmation%22%3Afalse%2C%22countryCode%22%3A%22AU%22%7D%2C%22receiverAddress%22%3A%7B%22firstName%22%3A%22FirstName%22%2C%22lastName%22%3A%22LastName%22%2C%22companyName%22%3A%22TestBiz%22%2C%22countryCode%22%3A%22null%22%2C%22addressLine%22%3A%5B%22Addr1%22%2C%22Addr2%22%5D%2C%22suburb%22%3A%22CITY%22%2C%22state%22%3A%22State%22%2C%22postcode%22%3A%22PO%22%2C%22email%22%3A%22test%40form.com%22%2C%22phone%22%3A%22123456%22%7D%7D%7D' \
  --compressed

Here in sample the Data to submit is URLENCODED from JSON:

{"customDeclaration":{"label":{"source":"AEM","postagePaidIndicator":false,"eadIndicator":null},"parcelCharacteristics":{"productClassification":31,"dangerousGoodsIndicator":false,"returnInstructions":"Return+By+Most+Economical+Route","importerReferenceNumber":"ImportREF","content":[{"content":"testItem","contentQuantity":1,"contentUnitValue":10,"totalContentValue":10,"contentWeight":1,"contentCountryOfOrigin":"AU"}],"totalConsignmentValue":10},"senderAddress":{"firstName":"sFirstname","lastName":"sLastname","companyName":"sBiz","addressLine":["sBaddr"],"suburb":"SbCity","state":"ACT","postcode":"0100","email":"saddr@test.com","phone":"9876543210","smsConfirmation":false,"countryCode":"AU"},"receiverAddress":{"firstName":"FirstName","lastName":"LastName","companyName":"TestBiz","countryCode":"null","addressLine":["Addr1","Addr2"],"suburb":"CITY","state":"State","postcode":"PO","email":"test@form.com","phone":"123456"}}}

More easy to read JSON:

{
  "customDeclaration": {
    "label": {
      "source": "AEM",
      "postagePaidIndicator": false,
      "eadIndicator": null
    },
    "parcelCharacteristics": {
      "productClassification": 31,
      "dangerousGoodsIndicator": false,
      "returnInstructions": "Return+By+Most+Economical+Route",
      "importerReferenceNumber": "ImportREF",
      "content": [
        {
          "content": "testItem",
          "contentQuantity": 1,
          "contentUnitValue": 10,
          "totalContentValue": 10,
          "contentWeight": 1,
          "contentCountryOfOrigin": "AU"
        }
      ],
      "totalConsignmentValue": 10
    },
    "senderAddress": {
      "firstName": "sFirstname",
      "lastName": "sLastname",
      "companyName": "sBiz",
      "addressLine": [
        "sBaddr"
      ],
      "suburb": "SbCity",
      "state": "ACT",
      "postcode": "0100",
      "email": "saddr@test.com",
      "phone": "9876543210",
      "smsConfirmation": false,
      "countryCode": "AU"
    },
    "receiverAddress": {
      "firstName": "FirstName",
      "lastName": "LastName",
      "companyName": "TestBiz",
      "countryCode": "null",
      "addressLine": [
        "Addr1",
        "Addr2"
      ],
      "suburb": "CITY",
      "state": "State",
      "postcode": "PO",
      "email": "test@form.com",
      "phone": "123456"
    }
  }
}

PHP CURL:

<?php

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://auspost.com.au/bin/form/stopact');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "jsonFormData=%7B%22customDeclaration%22%3A%7B%22label%22%3A%7B%22source%22%3A%22AEM%22%2C%22postagePaidIndicator%22%3Afalse%2C%22eadIndicator%22%3Anull%7D%2C%22parcelCharacteristics%22%3A%7B%22productClassification%22%3A31%2C%22dangerousGoodsIndicator%22%3Afalse%2C%22returnInstructions%22%3A%22Return+By+Most+Economical+Route%22%2C%22importerReferenceNumber%22%3A%22ImportREF%22%2C%22content%22%3A%5B%7B%22content%22%3A%22testItem%22%2C%22contentQuantity%22%3A1%2C%22contentUnitValue%22%3A10%2C%22totalContentValue%22%3A10%2C%22contentWeight%22%3A1%2C%22contentCountryOfOrigin%22%3A%22AU%22%7D%5D%2C%22totalConsignmentValue%22%3A10%7D%2C%22senderAddress%22%3A%7B%22firstName%22%3A%22sFirstname%22%2C%22lastName%22%3A%22sLastname%22%2C%22companyName%22%3A%22sBiz%22%2C%22addressLine%22%3A%5B%22sBaddr%22%5D%2C%22suburb%22%3A%22SbCity%22%2C%22state%22%3A%22ACT%22%2C%22postcode%22%3A%220100%22%2C%22email%22%3A%22saddr%40test.com%22%2C%22phone%22%3A%229876543210%22%2C%22smsConfirmation%22%3Afalse%2C%22countryCode%22%3A%22AU%22%7D%2C%22receiverAddress%22%3A%7B%22firstName%22%3A%22FirstName%22%2C%22lastName%22%3A%22LastName%22%2C%22companyName%22%3A%22TestBiz%22%2C%22countryCode%22%3A%22null%22%2C%22addressLine%22%3A%5B%22Addr1%22%2C%22Addr2%22%5D%2C%22suburb%22%3A%22CITY%22%2C%22state%22%3A%22State%22%2C%22postcode%22%3A%22PO%22%2C%22email%22%3A%22test%40form.com%22%2C%22phone%22%3A%22123456%22%7D%7D%7D");
curl_setopt($ch, CURLOPT_ENCODING, 'gzip, deflate');

$headers = array();
$headers[] = 'Connection: keep-alive';
$headers[] = 'Pragma: no-cache';
$headers[] = 'Cache-Control: no-cache';
$headers[] = 'Accept: */*';
$headers[] = 'X-Requested-With: XMLHttpRequest';
$headers[] = 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36';
$headers[] = 'Content-Type: application/x-www-form-urlencoded; charset=UTF-8';
$headers[] = 'Origin: https://auspost.com.au';
$headers[] = 'Sec-Fetch-Site: same-origin';
$headers[] = 'Sec-Fetch-Mode: cors';
$headers[] = 'Sec-Fetch-Dest: empty';
$headers[] = 'Referer: https://auspost.com.au/declaration-form-fields-page';
$headers[] = 'Accept-Language: en-US,en;q=0.9,nb;q=0.8,no;q=0.7,mt;q=0.6';
$headers[] = 'Cookie: at_check=true; AMCVS_0A2D38B352782F1E0A490D4C%40AdobeOrg=1; _gcl_au=1.1.881765264.1608514094; s_ecid=MCMID%7C76693753864336349821406673003588424534; AMCV_0A2D38B352782F1E0A490D4C%40AdobeOrg=1585540135%7CMCIDTS%7C18618%7CMCMID%7C76693753864336349821406673003588424534%7CMCAAMLH-1609118894%7C6%7CMCAAMB-1609118894%7CRKhpRz8krg2tLO6pguXWp5olkAcUniQYPHaMWWgdJ3xzPWQmdj0y%7CMCOPTOUT-1608521294s%7CNONE%7CMCAID%7CNONE%7CvVersion%7C4.4.0; mbox=session#abb194d9ddc9409e82fa625b0006f1ed#1608515955|PC#abb194d9ddc9409e82fa625b0006f1ed.37_0#1671758895; sat_track=true; _uetsid=ccd99990432b11eb9b9307315b7acaa7; _uetvid=ccda0b90432b11eb9f64f7c0bb2931b9; _fbp=fb.2.1608514096500.1515985073; s_auth=false; s_cc=true; s_sq=%5B%5BB%5D%5D; prevUrl=https%3A%2F%2Fauspost.com.au%2Fdeclaration-form-fields-page%23summary; s_ppn=auspost%3Astopact%3Acustoms%20declaration%3Aform%3Areview; s_nr=1608515010527';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
curl_close($ch);

$data = json_decode($result, 1);
$statusCode = $data['statusCode'];

if ($statusCode === 200) {
    $customerReferenceId = $data['customerReferenceId'];
    $qrCode = $data['qrCode'];
    $label = $data['label'];

    echo "customerReferenceId: $customerReferenceId\n";
    echo '<div>
    <p>qrCode:</p>
    <img src="data:image/png;base64, '.$qrCode.'" alt="qrCode" />
    </div>';

    echo '<div>
    <p>label:</p>
    <iframe src="data:application/pdf;base64,'.$label.'">
    </div>';

} else {
    echo "ERROR, form not sent";
}

The code above shows the customerReferenceId, qrCode image and labels.

To save qrCode and PDF on file you can use:

Convert Base64 string to an image file? and: PHP get pdf file from base64 encoded data string

Cyborg
  • 1,437
  • 19
  • 40
  • I'll probably award this the green tick when I get the opportunity to test that it works. Good job. – Jonathon Philip Chambers Dec 21 '20 at 01:56
  • Sure, please try. Let me know if there is any issue. – Cyborg Dec 21 '20 at 02:06
  • It's still untested, but I'll give you the tick because this reference makes the whole answer obsolete anyway https://developers.auspost.com.au/apis/shipping-and-tracking/info/api-resources/labels (However, if the API proves difficult, I'll come back to this method.) – Jonathon Philip Chambers Dec 21 '20 at 08:02
  • Its working as expected, I get JSON results with: `customerReferenceId`, `qrCode` image and `label` in PDF. Anyway if they have API then I guess its better to use API. – Cyborg Dec 21 '20 at 10:36
  • update: the solution above is only for customers willing to commit to a minimum of 40 parcels sent per week. I'm around half that. There is also a CSV upload feature, which my volume does make me eligible for in MyPost business. Definitely a time saver, but I still need to drag and drop the CSV file manually, which is annoying. So I'll probably be giving your solution a try very soon. – Jonathon Philip Chambers Dec 22 '20 at 06:05
  • I'm probably missing something obvious here, but when I run that code, I only get text. No image, no PDF. However the text is very long, so the information must be in there. How do I decode it? – Jonathon Philip Chambers Dec 22 '20 at 06:20
  • The text you get is in JSON, I will update answer. – Cyborg Dec 22 '20 at 06:30
  • I wish I could give you two green ticks. Thanks for your help. This goes beyond a normal question/answer. You've literally been doing development work on this snippet. – Jonathon Philip Chambers Dec 22 '20 at 06:32