Skip to content

Commit 9db7996

Browse files
committed
added open and distribute and international shipping labels
1 parent 9133104 commit 9db7996

8 files changed

+598
-22
lines changed

README.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ This wrapper allows you to perform some basic calls to the USPS api. Some of the
77
- Zip code lookup by address
88
- City/State lookup by zip code
99
- Verify address
10-
- Print Shipping Labels
10+
- Create Priority Shipping Labels
11+
- Create Open & Distribute Shipping Labels
12+
- Create International Shipping Labels (Express, Priority, First Class)
1113
- Service Delivery Calculator
1214
- Confirm Tracking
1315

@@ -30,9 +32,6 @@ Authors
3032
=======
3133
Vincent Gabriel <http://vadimg.com>
3234

33-
Thanks
34-
======
35-
3635
License
3736
=======
3837

USPSBase.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,11 @@ class USPSBase {
7070
'FirstClassMail' => 'FirstClassMailRequest',
7171
'SDCGetLocations' => 'SDCGetLocationsRequest',
7272
'ExpressMailLabel' => 'ExpressMailLabelRequest',
73+
'OpenDistributePriorityV2' => 'OpenDistributePriorityV2.0Request',
74+
'OpenDistributePriorityV2Certify' => 'OpenDistributePriorityV2.0CertifyRequest',
75+
'ExpressMailIntl' => 'ExpressMailIntlRequest',
76+
'PriorityMailIntl' => 'PriorityMailIntlRequest',
77+
'FirstClassMailIntl' => 'FirstClassMailIntlRequest',
7378
);
7479
/**
7580
* Default options for curl.
@@ -122,6 +127,13 @@ public function setApiVersion($version) {
122127
public function setTestMode($value) {
123128
self::$testMode = (bool) $value;
124129
}
130+
/**
131+
* Response api name
132+
* @return string
133+
*/
134+
public function getResponseApiName() {
135+
return str_replace('Request', 'Response', $this->apiCodes[$this->apiVersion]);
136+
}
125137
/**
126138
* Makes an HTTP request. This method can be overriden by subclasses if
127139
* developers want to do fancier things or use something other than curl to

USPSInternationalLabel.php

Lines changed: 260 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,260 @@
1+
<?php
2+
/**
3+
* Load required classes
4+
*/
5+
require_once('USPSBase.php');
6+
7+
/**
8+
*/
9+
class USPSInternationalLabel extends USPSBase {
10+
/**
11+
* @var string - the api version used for this type of call
12+
*/
13+
protected $apiVersion = 'ExpressMailIntl';
14+
/**
15+
* @var array - route added so far.
16+
*/
17+
protected $fields = array();
18+
19+
protected $contents = array();
20+
/**
21+
* Perform the API call.
22+
* @return string
23+
*/
24+
public function createLabel() {
25+
// Add contents
26+
if($this->contents && count($this->contents)) {
27+
$this->setField(31, 'ShippingContents', $this->contents);
28+
}
29+
30+
// Add missing required
31+
$this->addMissingRequired();
32+
33+
// Sort them
34+
// Hack by the only way this will work properly
35+
// since usps wants the tags to be in
36+
// a certain order
37+
ksort($this->fields, SORT_NUMERIC);
38+
39+
// remove the \d. from the key
40+
foreach($this->fields as $key => $value) {
41+
$newKey = str_replace('.', '', $key);
42+
$newKey = preg_replace('/\d+\:/', '', $newKey);
43+
unset($this->fields[$key]);
44+
$this->fields[$newKey] = $value;
45+
}
46+
47+
return $this->doRequest();
48+
}
49+
50+
/**
51+
* Return the USPS confirmation/tracking number if we have one
52+
* @return string|bool
53+
*/
54+
public function getConfirmationNumber() {
55+
$response = $this->getArrayResponse();
56+
// Check to make sure we have it
57+
if(isset($response[$this->getResponseApiName()])) {
58+
if(isset($response[$this->getResponseApiName()]['BarcodeNumber'])) {
59+
return $response[$this->getResponseApiName()]['BarcodeNumber'];
60+
}
61+
}
62+
63+
return false;
64+
}
65+
66+
/**
67+
* Return the USPS label as a base64 encoded string
68+
* @return string|bool
69+
*/
70+
public function getLabelContents() {
71+
$response = $this->getArrayResponse();
72+
// Check to make sure we have it
73+
if(isset($response[$this->getResponseApiName()])) {
74+
if(isset($response[$this->getResponseApiName()]['LabelImage'])) {
75+
return $response[$this->getResponseApiName()]['LabelImage'];
76+
}
77+
}
78+
79+
return false;
80+
}
81+
82+
/**
83+
* returns array of all fields added
84+
* @return array
85+
*/
86+
public function getPostFields() {
87+
return $this->fields;
88+
}
89+
90+
/**
91+
* Add shipping contents
92+
*
93+
* @return object
94+
*/
95+
public function addContent($description, $value, $pounds, $ounces, $quantity=1, $tarrifNumber=null, $countryOfOrigin=null) {
96+
$this->contents['ItemDetail'][] = array(
97+
'Description' => $description,
98+
'Quantity' => $quantity,
99+
'Value' => $value,
100+
'NetPounds' => $pounds,
101+
'NetOunces' => $ounces,
102+
'HSTariffNumber' => $tarrifNumber,
103+
'CountryOfOrigin' => $countryOfOrigin,
104+
);
105+
106+
return $this;
107+
}
108+
109+
/**
110+
* Set the from address
111+
* @param string $firstName
112+
* @param string $lastName
113+
* @param string $company
114+
* @param string $address
115+
* @param string $city
116+
* @param string $state
117+
* @param string $zip
118+
* @param string $address2
119+
* @param string $zip4
120+
* @param string $phone
121+
* @return object
122+
*/
123+
public function setFromAddress($firstName, $lastName, $company, $address, $city, $state, $zip, $address2=null, $zip4=null, $phone=null, $middleName=null) {
124+
$this->setField(5, 'FromFirstName', $firstName);
125+
$this->setField(6, 'FromMiddleInitial', $middleName);
126+
$this->setField(7, 'FromLastName', $lastName);
127+
$this->setField(8, 'FromFirm', $company);
128+
$this->setField(9, 'FromAddress1', $address2);
129+
$this->setField(10, 'FromAddress2', $address);
130+
$this->setField(11, 'FromCity', $city);
131+
$this->setField(12, 'FromState', $state);
132+
$this->setField(13, 'FromZip5', $zip);
133+
$this->setField(14, 'FromZip4', $zip4);
134+
$this->setField(15, 'FromPhone', $phone);
135+
136+
return $this;
137+
}
138+
139+
/**
140+
* Set the to address
141+
* @param string $firstName
142+
* @param string $lastName
143+
* @param string $company
144+
* @param string $address
145+
* @param string $city
146+
* @param string $state
147+
* @param string $zip
148+
* @param string $address2
149+
* @param string $zip4
150+
* @param string $phone
151+
* @return object
152+
*/
153+
public function setToAddress($firstName, $lastName, $company, $address, $city, $province, $country, $zip, $address2=null, $poBoxFlag='N', $phone=null, $fax=null, $email=null) {
154+
$this->setField(16, 'ToFirstName', $firstName);
155+
$this->setField(17, 'ToLastName', $lastName);
156+
$this->setField(18, 'ToFirm', $company);
157+
$this->setField(19, 'ToAddress1', $address2);
158+
$this->setField(20, 'ToAddress2', $address);
159+
$this->setField(21, 'ToCity', $city);
160+
$this->setField(22, 'ToProvince', $province);
161+
$this->setField(23, 'ToCountry', $country);
162+
$this->setField(24, 'ToPostalCode', $zip);
163+
$this->setField(25, 'ToPOBoxFlag', $poBoxFlag);
164+
$this->setField(26, 'ToPhone', $phone);
165+
$this->setField(27, 'ToFax', $fax);
166+
$this->setField(28, 'ToEmail', $email);
167+
168+
return $this;
169+
}
170+
171+
/**
172+
* Set any other requried string make sure you set the correct position as well
173+
* as the position of the items matters
174+
* @param int $position
175+
* @param string $key
176+
* @param string $value
177+
* @return object
178+
*/
179+
public function setField($position, $key, $value) {
180+
$this->fields[$position . ':' . $key] = $value;
181+
return $this;
182+
}
183+
184+
/**
185+
* Set package weight in ounces
186+
*
187+
*/
188+
public function setWeightOunces($weight) {
189+
$this->setField(33, 'GrossOunces', $weight);
190+
return $this;
191+
}
192+
193+
/**
194+
* Set package weight in ounces
195+
*
196+
*/
197+
public function setWeightPounds($weight) {
198+
$this->setField(32, 'GrossPounds', $weight);
199+
return $this;
200+
}
201+
202+
203+
/**
204+
* Add missing required elements
205+
* @return void
206+
*/
207+
protected function addMissingRequired() {
208+
$required = array(
209+
'1:Option' => '',
210+
'1.1:Revision' => '2',
211+
'4:ImageParameters' => '',
212+
213+
214+
'30:Container' => 'NONRECTANGULAR',
215+
'32:GrossPounds' => '',
216+
'33:GrossOunces' => '',
217+
'34:ContentType' => 'Documents',
218+
'35:Agreement' => 'Y',
219+
'36:ImageType' => 'PDF',
220+
'37:ImageLayout' => 'ALLINONEFILE',
221+
'38:POZipCode' => '',
222+
'39:LabelDate' => '',
223+
'40:HoldForManifest' => 'N',
224+
'41:Size' => 'LARGE',
225+
'42:Length' => '',
226+
'43:Width' => '',
227+
'44:Height' => 'false',
228+
'45:Girth' => '',
229+
);
230+
231+
232+
// We need to add additional fields based on api we are using
233+
if($this->apiVersion == 'ExpressMailIntl') {
234+
$required = array_merge($required, array(
235+
'29:NonDeliveryOption' => 'Return',
236+
));
237+
} elseif($this->apiVersion == 'PriorityMailIntl') {
238+
$required = array_merge($required, array(
239+
'29:NonDeliveryOption' => 'Return',
240+
'31.1:Insured' => 'N',
241+
'40.1:EELPFC' => '',
242+
));
243+
} elseif($this->apiVersion == 'FirstClassMailIntl') {
244+
$required = array_merge($required, array(
245+
'30.1:FirstClassMailType' => 'PARCEL',
246+
'31.1:Insured' => 'N',
247+
'33.1:Machinable' => 'false',
248+
'40.1:EELPFC' => '',
249+
));
250+
}
251+
252+
foreach($required as $item => $value) {
253+
$explode = explode(':', $item);
254+
if(!isset($this->fields[$item])) {
255+
$this->setField($explode[0], $explode[1], $value);
256+
}
257+
}
258+
}
259+
260+
}

0 commit comments

Comments
 (0)