//Creating the shipment object. In this example, the objects are directly passed to the
//Shipment.create method, Alternatively, the Address and Parcel objects could be created
//using Address.create(..) and Parcel.create(..) functions respectively.
$shipment = Shippo_Shipment::create(array('object_purpose' => 'PURCHASE', 'address_from' => $fromAddress, 'address_to' => $toAddress, 'parcel' => $parcel, 'submission_type' => 'PICKUP', 'insurance_amount' => '30', 'insurance_currency' => 'USD', 'extra' => '{signature_confirmation: true}', 'customs_declaration' => $customs_declaration["object_id"]));
//Wait for rates to be generated
$attempts = 0;
while (($shipment["object_status"] == "QUEUED" || $shipment["object_status"] == "WAITING") && $attempts < 10) {
    $shipment = Shippo_Shipment::retrieve($shipment["object_id"]);
    $attempts += 1;
}
//Get all rates for shipment.
$rates = Shippo_Shipment::get_shipping_rates(array('id' => $shipment["object_id"]));
//Get the first rate in the rates results.
$rate = $rates["results"][0];
//Purchase the desired rate. sync=True indicates that the function will wait until the
//carrier returns a shipping label before it returns
$transaction = Shippo_Transaction::create(array('rate' => $rate["object_id"]));
//Wait for transaction to be proccessed
$attempts = 0;
while (($transaction["object_status"] == "QUEUED" || $transaction["object_status"] == "WAITING") && $attempts < 10) {
    $transaction = Shippo_Transaction::retrieve($transaction["object_id"]);
    $attempts += 1;
}
//label_url and tracking_number
if ($transaction["object_status"] == "SUCCESS") {
    echo $transaction["label_url"];
    echo "\n";
    echo $transaction["tracking_number"];
} else {
    echo $transaction["messages"];
}
 public function testInvalidRetrieve()
 {
     $transaction = self::getDefaultTransaction();
     $retrieve_transaction = Shippo_Transaction::retrieve($transaction->object_id);
     $this->assertNotEqual($retrieve_transaction->object_id, 'Invalid Value');
 }