Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 894 lines (692 sloc) 31.193 kb
44b123e @nuex initial
authored
1 <?php
2
3 //
4 // Implementation of UPS Rating Package XML
5 //
6 // Copyright 2011 Chase Allen James <chaseajames@gmail.com>
7 //
8 // Ported from ups_xml_gateway Ruby UPS Shipping Library
9 // written by Todd Willey
10 //
11 class ups_rating {
12
13 const DIMENSIONAL_VOLUME = 5184;
14 const DIMENSIONAL_DIVISOR = 194;
15 const ITEM_WEIGHT_LIMIT = 150;
16
17 const URL = "https://onlinetools.ups.com/ups.app/xml/Rate";
18 const TESTING_URL = "https://wwwcie.ups.com/ups.app/xml/Rate";
19
20 const XPCI_VERSION = "1.0";
21
22 public static $PICKUP_TYPES = array(
23 'daily_pickup' => '01',
24 'customer_counter' => '03',
25 'one_time_pickup' => '06',
26 'on_call_air' => '07',
27 'suggested_retail_rates' => '11',
28 'letter_center' => '19',
29 'air_service_center' => '20'
30 );
31
32 public static $CUSTOMER_CLASSIFICATIONS = array(
33 'wholesale' => '01',
34 'occasional' => '03',
35 'retail' => '04'
36 );
37
38 public static $WEIGHT_UNITS = array(
39 'lbs' => 'LBS',
40 'kgs' => 'KGS'
41 );
42
43 public static $LENGTH_UNITS = array(
44 'in' => 'IN',
45 'cm' => 'CM'
46 );
47
48 public static $SERVICE_TYPES = array(
49 'next_day_air' => '01',
50 'second_day_air' => '02',
51 'ground' => '03',
52 'worldwide_express' => '07',
53 'worldwide_expedited' => '08',
54 'standard' => '11',
55 'three_day_select' => '12',
56 'next_day_air_saver' => '13', // not in docs, but exists!
57 'next_day_air_early' => '14',
58 'worldwide_express_plus' => '54',
59 'second_day_air_am' => '59',
60 'saver' => '65'
61 );
62
63 public static $PACKAGE_TYPES = array(
64 'unknown' => '00',
65 'letter' => '01',
66 'package' => '02',
67 'tube' => '03',
68 'pak' => '04',
69 'small_express' => '2a',
70 'medium_express' => '2b',
71 'large_express' => '2c',
72 'twofive_kg_box' => '24',
73 'onezero_kg_box' => '25',
74 'pallet' => '30'
75 );
76
77 public static $FUND_CODES = array(
78 'cash' => '0',
79 'check' => '8' // Cashier's check or money order
80 );
81
82 public static $DELIVERY_CONFIRMATION_CODES = array(
83 'confirmation' => '1',
84 'signature' => '2',
85 'adult_signature' => '3'
86 );
87
88 public static $PICKUP_DAYS = array(
89 'same_day' => '01',
90 'future' => '02'
91 );
92
93 public static $ONCALL_METHODS =array(
94 'internet' => '01',
95 'phone' => '02'
96 );
97
98 public static $REQUIRED_OPTIONS = array(
99 'ups_access_license_number',
100 'ups_userid',
101 'ups_password',
102 'country',
103 'to_country'
104 );
105
106 //
107 // API FUNCTIONS
108 //
109
110 // Execute RateServiceSelectionRequest
111 //
112 // Usage:
113 //
114 // $opts = array(
115 // 'ups_access_license_number' => MY_LICENSE_NUMBER,
116 // 'ups_userid' => MY_USERID,
117 // 'ups_password' => MY_PASSWORD,
118 // 'country' => 'US',
119 // 'to_country' => 'US',
120 // 'weight' => 20
121 // );
122 //
123 // Packages are also supported:
124 //
125 // $opts['packages'] = array(
126 // array(
127 // 'type' => 'medium_express',
128 // 'weight' => 20
129 // ),
130 // array(
131 // 'type' => 'medium_express',
132 // 'weight' => 18
133 // )
134 // );
135 //
136 // $response = ups_rating::rates($opts);
137 //
138 function rates($opts) {
139 self::validate_options($opts, self::$REQUIRED_OPTIONS);
140 $xml = self::access_request($opts) . self::rating_service_selection_request($opts);
141 $raw_response = self::http_client_post_xml($xml, $opts);
142 $response = self::parse_response($raw_response, $opts);
143 return $response;
144 }
145
146
147
148 //
149 // INTERNAL FUNCTIONS
150 //
151
152 function validate_options($opts, $required) {
153 $matching_keys = array_intersect(array_keys($opts), $required);
154 if (count($matching_keys) != count($required)) {
155 throw new Exception("Error: missing required options");
156 }
157 }
158
159 function access_request($opts) {
160 $doc = new DOMDocument('1.0');
161 $access_request = $doc->appendChild(
162 new DOMElement('AccessRequest'));
163 $access_request->setAttributeNode(
164 new DOMAttr('xml:lang', 'en-US'));
165 $access_request->appendChild(
166 new DOMElement('AccessLicenseNumber', $opts['ups_access_license_number']));
167 $access_request->appendChild(
168 new DOMElement('UserId', $opts['ups_userid']));
169 $access_request->appendChild(
170 new DOMElement('Password', $opts['ups_password']));
171 return $doc->saveXML();
172 }
173
174 function rating_service_selection_request($opts) {
175 $doc = new DOMDocument('1.0');
176
177 $method = (isset($opts['shop']) && $opts['shop']) ? 'Shop' : 'Rate';
178
179 $rssr = $doc->appendChild(
180 new DOMElement('RatingServiceSelectionRequest'));
181 $rssr->setAttributeNode(
182 new DOMAttr('xml:lang', 'en-US'));
183 $request = $rssr->appendChild(
184 new DOMElement('Request'));
185 $request->appendChild(
186 new DOMElement('RequestAction', 'Rate'));
187
188 $request->appendChild(
189 new DOMElement('RequestOption', $method));
190
191 $transaction_reference = $request->appendChild(
192 new DOMElement('TransactionReference'));
193
194 if (isset($opts['customer_context'])) {
195 $transaction_reference->appendChild(
196 new DOMElement('CustomerContext', substr($opts['customer_context'], 0, 512)));
197 }
198
199 $transaction_reference->appendChild(
200 new DOMElement('XpciVersion', self::XPCI_VERSION));
201 if (isset($opts['tool_version'])) {
202 $transaction_reference->appendChild(
203 new DOMElement('ToolVersion', $opts['tool_version']));
204 }
205
206 if (isset($opts['pickup_type'])) {
207 $pickup_type = $request->appendChild(
208 new DOMElement('PickupType'));
209 $pickup_type->appendChild(
210 new DOMElement('Code', self::$PICKUP_TYPES[$opts['pickup_type']]));
211 }
212
213 if (isset($opts['customer_classification'])) {
214 $customer_classification = $request->appendChild(
215 new DOMElement('CustomerClassification'));
216 $customer_classification->appendChild(
217 new DOMElement('Code', self::$CUSTOMER_CLASSIFICATIONS[$opts['customer_classification']]));
218 }
219
220 $shipment = $rssr->appendChild(
221 new DOMElement('Shipment'));
222
223 if (isset($opts['description'])) {
224 $shipment->appendChild(
225 new DOMElement('Description', substr($opts['description'], 0, 35)));
226 }
227
228 $shipper = $shipment->appendChild(
229 new DOMElement('Shipper'));
230
231 if (isset($opts['ups_account_number'])) {
232 $shipper->appendChild(
233 new DOMElement('ShipperNumber', $opts['ups_account_number']));
234 }
235
236 $address = $shipper->appendChild(
237 new DOMElement('Address'));
238
239 if (isset($opts['street_address1'])) {
240 $address->appendChild(
241 new DOMElement('AddressLine1', substr($opts['street_address1'], 0, 35)));
242 }
243
244 if (isset($opts['street_address2'])) {
245 $address->appendChild(
246 new DOMElement('AddressLine2', substr($opts['street_address2'], 0, 35)));
247 }
248
249 if (isset($opts['street_address3'])) {
250 $address->appendChild(
251 new DOMElement('AddressLine3', substr($opts['street_address3'], 0, 35)));
252 }
253
254 if (isset($opts['city'])) {
255 $address->appendChild(
256 new DOMElement('City', substr($opts['city'], 0, 30)));
257 }
258
259 if (isset($opts['state'])) {
260 $address->appendChild(
261 new DOMElement('StateProvinceCode', substr($opts['state'], 0, 5)));
262 }
263
264 if (isset($opts['postal_code'])) {
265 $address->appendChild(
266 new DOMElement('PostalCode', substr($opts['postal_code'], 0, 9)));
267 }
268
269 $address->appendChild(
270 new DOMElement('CountryCode', strtoupper(substr($opts['country'], 0, 2))));
271
272 $ship_to = $shipment->appendChild(
273 new DOMElement('ShipTo'));
274
275 if (isset($opts['recipient_number'])) {
276 $ship_to->appendChild(
277 new DOMElement('ShipperAssignedIdentificationNumber', $opts['recipient_number']));
278 }
279
280 if (isset($opts['company_name'])) {
281 $ship_to->appendChild(
282 new DOMElement('CompanyName', $opts['company_name']));
283 }
284
285 if (isset($opts['attention_name'])) {
286 $ship_to->appendChild(
287 new DOMElement('CompanyName', $opts['attention_name']));
288 }
289
290 if (isset($opts['phone'])) {
291 $ship_to->appendChild(
292 new DOMElement('PhoneNumber', $opts['phone']));
293 } elseif (isset($opts['structured_phone'])) {
294 $phone_number = $ship_to->appendChild(
295 new DOMElement('PhoneNumber'));
296
297 if (isset($opts['structured_phone']['country_code'])) {
298 $phone_number->appendChild(
299 new DOMElement('PhoneCountryCode', substr($opts['structured_phone']['country_code'], 0, 3)));
300 }
301
302 $phone_number->appendChild(
303 new DOMElement('PhoneDialPlanNumber', substr($opts['structured_phone']['plan'], 0, 15)));
304
305 $phone_number->appendChild(
306 new DOMElement('PhoneLineNumber', substr($opts['structured_phone']['line'], 0, 15)));
307
308 if (isset($opts['structured_phone']['extension'])) {
309 $phone_number->appendChild(
310 new DOMElement('PhoneExtension', substr($opts['structured_phone']['extension'], 0, 4)));
311 }
312 } // end PhoneNumber
313
314 if (isset($opts['tax_id'])) {
315 $ship_to->appendChild(
316 new DOMElement('TaxIdentificationNumber', substr($opts['tax_id'], 0, 15)));
317 }
318
319 if (isset($opts['fax'])) {
320 $ship_to->appendChild(
321 new DOMElement('FaxNumber', substr($opts['fax'], 0, 15)));
322 }
323
324 $address = $ship_to->appendChild(
325 new DOMElement('Address'));
326
327 if (isset($opts['to_street_address1'])) {
328 $address->appendChild(
329 new DOMElement('AddressLine1', substr($opts['to_street_address1'], 0, 35)));
330 }
331
332 if (isset($opts['to_street_address2'])) {
333 $address->appendChild(
334 new DOMElement('AddressLine2', substr($opts['to_street_address2'], 0, 35)));
335 }
336
337 if (isset($opts['to_street_address3'])) {
338 $address->appendChild(
339 new DOMElement('AddressLine3', substr($opts['to_street_address3'], 0, 35)));
340 }
341
342 if (isset($opts['to_city'])) {
343 $address->appendChild(
344 new DOMElement('City', substr($opts['to_city'], 0, 30)));
345 }
346
347 if (isset($opts['to_state'])) {
348 $address->appendChild(
349 new DOMElement('StateProvinceCode', $opts['to_state']));
350 }
351
352 if (isset($opts['to_postal_code'])) {
353 $address->appendChild(
354 new DOMElement('PostalCode', $opts['to_postal_code']));
355 }
356
357 $address->appendChild(
358 new DOMElement('CountryCode', substr($opts['to_country'], 0, 2)));
359
360 if (isset($opts['to_residence'])) {
361 $address->appendChild(
362 new DOMElement('ResidentialAddressIndicator'));
363 }
364
365 // end Address
366
367 // end ShipTo
368
369 if (isset($opts['ship_from_country'])) {
370 $ship_from = $shipment->appendChild(
371 new DOMElement('ShipFrom'));
372
373 if (isset($opts['recipient_number'])) {
374 $ship_from->appendChild(
375 new DOMElement('ShipperAssignedIdentificationNumber', $opts['recipient_number']));
376 }
377
378 if (isset($opts['company_name'])) {
379 $ship_from->appendChild(
380 new DOMElement('CompanyName', $opts['company_name']));
381 }
382
383 if (isset($opts['attention_name'])) {
384 $ship_from->appendChild(
385 new DOMElement('CompanyName', $opts['attention_name']));
386 }
387
388 if (isset($opts['phone'])) {
389 $ship_from->appendChild(
390 new DOMElement('PhoneNumber', $opts['phone']));
391 } elseif (isset($opts['structured_phone'])) {
392 $phone_number = $ship_from->appendChild(
393 new DOMElement('PhoneNumber'));
394
395 if (isset($opts['structured_phone']['country_code'])) {
396 $phone_number->appendChild(
397 new DOMElement('PhoneCountryCode', substr($opts['structured_phone']['country_code'], 0, 3)));
398 }
399
400 $phone_number->appendChild(
401 new DOMElement('PhoneDialPlanNumber', substr($opts['structured_phone']['plan'], 0, 15)));
402
403 $phone_number->appendChild(
404 new DOMElement('PhoneLineNumber', substr($opts['structured_phone']['line'], 0, 15)));
405
406 if (isset($opts['structured_phone']['extension'])) {
407 $phone_number->appendChild(
408 new DOMElement('PhoneExtension', substr($opts['structured_phone']['extension'], 0, 4)));
409 }
410 } // end PhoneNumber
411
412 if (isset($opts['tax_id'])) {
413 $ship_from->appendChild(
414 new DOMElement('TaxIdentificationNumber', substr($opts['tax_id'], 0, 15)));
415 }
416
417 if (isset($opts['fax'])) {
418 $ship_from->appendChild(
419 new DOMElement('FaxNumber', substr($opts['fax'], 0, 15)));
420 }
421
422 $address = $ship_from->appendChild(
423 new DOMElement('Address'));
424
425 if (isset($opts['street_address1'])) {
426 $address->appendChild(
427 new DOMElement('AddressLine1', substr($opts['street_address1'], 0, 35)));
428 }
429
430 if (isset($opts['street_address2'])) {
431 $address->appendChild(
432 new DOMElement('AddressLine2', substr($opts['street_address2'], 0, 35)));
433 }
434
435 if (isset($opts['street_address3'])) {
436 $address->appendChild(
437 new DOMElement('AddressLine3', substr($opts['street_address3'], 0, 35)));
438 }
439
440 if (isset($opts['city'])) {
441 $address->appendChild(
442 new DOMElement('City', substr($opts['city'], 0, 30)));
443 }
444
445 if (isset($opts['state'])) {
446 $address->appendChild(
447 new DOMElement('StateProvinceCode', $opts['state']));
448 }
449
450 if (isset($opts['postal_code'])) {
451 $address->appendChild(
452 new DOMElement('PostalCode', $opts['postal_code']));
453 }
454
455 $address->appendChild(
456 new DOMElement('CountryCode', substr($opts['country'], 0, 2)));
457
458 if (isset($opts['from_residence'])) {
459 $address->appendChild(
460 new DOMElement('ResidentialAddressIndicator'));
461 }
462
463 // end Address
464
465 // end ShipFrom
466
467 } // end if ship_from_country
468
469 if ($method == 'Rate') {
470 $service = $shipment->appendChild(
471 new DOMElement('Service'));
472
473 $service_type = (isset($opts['service_type']) ? $opts['service_type'] : 'ground');
474
475 $service->appendChild(
476 new DOMElement('Code', self::$SERVICE_TYPES[$service_type]));
477 }
478
479 if (isset($opts['documents_only'])) {
480 $shipment->appendChild(
481 new DOMElement('DocumentsOnly'));
482 }
483
484 if (isset($opts['packages'])) {
485 foreach ($opts['packages'] as $pkg) {
486 $package = $shipment->appendChild(
487 new DOMElement('Package'));
488
489 $packaging_type = $package->appendChild(
490 new DOMElement('PackagingType'));
491
492 $type = (isset($pkg['type']) ? $pkg['type'] : 'package');
493
494 $packaging_type->appendChild(
495 new DOMElement('Code', self::$PACKAGE_TYPES[$type]));
496
497 if (isset($pkg['packaging_description'])) {
498 $packaging_type->appendChild(
499 new DOMElement('Description', substr($pkg['packaging_description'], 0, 35)));
500 }
501
502 if (isset($pkg['description'])) {
503 $package->appendChild(
504 new DOMElement('Description', substr($pkg['description'], 0, 35)));
505 }
506
507 if (!in_array($type, array('letter', 'tube', 'small_express', 'medium_express', 'large_express'))) {
508 $dimensions = $package->appendChild(
509 new DOMElement('Dimensions'));
510
511 $unit_of_measurement = $dimensions->appendChild(
512 new DOMElement('UnitOfMeasurement'));
513
514 $length_unit = (isset($pkg['length_unit']) ? $pkg['length_unit'] : 'in');
515
516 $unit_of_measurement->appendChild(
517 new DOMElement('Code', self::$LENGTH_UNITS[$length_unit]));
518
519 if (isset($pkg['dimension_description'])) {
520 $unit_of_measurement->appendChild(
521 new DOMElement('Description', substr($pkg['dimension_description'], 0, 35)));
522 }
523
524 $dimensions->appendChild(
525 new DOMElement('Length', trim(sprintf("%6.2f", floatval($pkg['length'])))));
526
527 $dimensions->appendChild(
528 new DOMElement('Width', trim(sprintf("%6.2f", floatval($pkg['width'])))));
529
530 $dimensions->appendChild(
531 new DOMElement('Height', trim(sprintf("%6.2f", floatval($pkg['height'])))));
532
533 } // Dimensions
534
535 if (isset($pkg['dimensional_weight'])) {
536 $dimensional_weight = $package->appendChild(
537 new DOMElement('DimensionalWeight'));
538
539 $unit_of_measurement = $dimensional_weight->appendChild(
540 new DOMElement('UnitOfMeasurement'));
541
542 $dimensional_weight_unit = (isset($pkg['dimensional_weight_unit']) ? $pkg['dimensional_weight_unit'] : 'lbs');
543
544 $unit_of_measurement->appendChild(
545 new DOMElement('Code', self::$WEIGHT_UNITS[$dimensional_weight_unit]));
546
547 if (isset($pkg['dimensional_weight_description'])) {
548 $unit_of_measurement->appendChild(
549 new DOMElement('Description', substr($pkg['dimensional_weight_description'], 0, 35)));
550 }
551
552 $unit_of_measurement->appendChild(
553 new DOMElement('Weight', trim(sprintf("%6.1f", floatval($pkg['dimensional_weight'])))));
554 } // DimensionalWeight
555
556 if (isset($pkg['weight'])) {
557 $package_weight = $package->appendChild(
558 new DOMElement('PackageWeight'));
559
560 $weight_unit = (isset($pkg['weight_unit']) ? $pkg['weight_unit'] : 'lbs');
561
562 $package_weight->appendChild(
563 new DOMElement('Code', self::$WEIGHT_UNITS[$weight_unit]));
564
565 if (isset($pkg['weight_description'])) {
566 $package_weight->appendChild(
567 new DOMElement('Description', substr($pkg['weight_description'], 0, 35)));
568 }
569
570 $package_weight->appendChild(
571 new DOMElement('Weight', trim(sprintf("%6.1f", floatval($pkg['weight'])))));
572 } // Weight
573
574 if (isset($pkg['large_package'])) {
575 $package->appendChild(
576 new DOMElement('LargePackageIndicator'));
577 }
578
579 if (isset($pkg['cod_value']) ||
580 isset($pkg['delivery_confirmation']) ||
581 isset($pkg['phone']) ||
582 isset($pkg['structured_phone']) ||
583 isset($pkg['additional_handling'])) {
584
585 $package_service_options = $package->appendChild(
586 new DOMElement('PackageServiceOptions'));
587
588 if (isset($pkg['cod_value'])) {
589 $cod = $package_service_options->appendChild(
590 new DOMElement('COD'));
591
592 if (isset($pkg['cod_fund_code'])) {
593 $cod->appendChild(
594 new DOMElement('CODFundsCode', self::$FUND_CODES[$pkg['cod_fund_code']]));
595 }
596
597 $cod->appendChild(
598 new DOMElement('CODCode', '3'));
599
600 $cod_amount = $cod->appendChild(
601 new DOMElement('CODAmount'));
602
603 $cod_currency_code = (isset($pkg['cod_currency_code']) ? $pkg['cod_currency_code'] : 'USD');
604
605 $cod_amount->appendChild(
606 new DOMElement('CurrencyCode', $cod_currency_code));
607
608 $cod_amount->appendChild(
609 new DOMElement('MonetaryValue', trim(sprintf("%8.2f", floatval($pkg['cod_value'])))));
610
611 $insured_value = $cod->appendChild(
612 new DOMElement('InsuredValue'));
613
614 $insured_value->appendChild(
615 new DOMElement('CurrencyCode', $cod_currency_code));
616
617 $insured_value->appendChild(
618 new DOMElement('MonetaryValue', trim(sprintf("%8.2f", floatval($pkg['cod_insurance'])))));
619
620 if (isset($pkg['cod_control_number'])) {
621 $cod->appendChild(
622 new DOMElement('ControlNumber', substr($pkg['cod_control_number'], 0, 11)));
623 }
624
625 } // COD
626
627 if (isset($pkg['delivery_confirmation'])) {
628 $delivery_confirmation = $package_service_options->appendChild(
629 new DOMElement('DeliveryConfirmation'));
630
631 $delivery_confirmation->appendChild(
632 new DOMElement('DCISType', self::$DELIVERY_CONFIRMATION_CODES[$pkg['delivery_confirmation']]));
633 } // DeliveryConfirmation
634
635 if (isset($pkg['phone']) || isset($pkg['structured_phone'])) {
636 $verbal_confirmation = $package_service_options->appendChild(
637 new DOMElement('VerbalConfirmation'));
638
639 if (isset($pkg['verbal_confirmation_name'])) {
640 $verbal_confirmation->appendChild(
641 new DOMElement('Name', substr($pkg['verbal_confirmation_name'], 0, 35)));
642 }
643
644 if (isset($pkg['phone'])) {
645 $verbal_confirmation->appendChild(
646 new DOMElement('PhoneNumber', $pkg['phone']));
647 } elseif (isset($pkg['structured_phone'])) {
648 $phone_number = $verbal_confirmation->appendChild(
649 new DOMElement('PhoneNumber'));
650
651 if (isset($pkg['structured_phone']['country_code'])) {
652 $phone_number->appendChild(
653 new DOMElement('PhoneCountryCode', substr($opts['structured_phone']['country_code'], 0, 3)));
654 }
655
656 $phone_number->appendChild(
657 new DOMElement('PhoneDialPlanNumber', substr($opts['structured_phone']['plan'], 0, 15)));
658
659 $phone_number->appendChild(
660 new DOMElement('PhoneLineNumber', substr($opts['structured_phone']['line'], 0, 15)));
661
662 if (isset($opts['structured_phone']['extension'])) {
663 $phone_number->appendChild(
664 new DOMElement('PhoneExtension', substr($opts['structured_phone']['extension'], 0, 4)));
665 }
666
667 } // PhoneNumber
668 } // VerbalConfirmation
669
670 if (isset($pkg['additional_handling'])) {
671 $package_service_options->appendChild(
672 new DOMElement('AdditionalHandling'));
673 }
674
675 } // if pkg services specified
676
677 } // foreach $opts['packages']
678
679 } else { // A list of packages was not passed in, fake one out here
680
681 $package = $shipment->appendChild(
682 new DOMElement('Package'));
683
684 $packaging_type = $package->appendChild(
685 new DOMElement('PackagingType'));
686
687 $package_type = (isset($opts['package_type']) ? $opts['package_type'] : 'package');
688
689 $packaging_type->appendChild(
690 new DOMElement('Code', self::$PACKAGE_TYPES[$package_type]));
691
692 $packaging_type->appendChild(
693 new DOMElement('Description', '(Default) Medium Express Box'));
694
695 $package->appendChild(
696 new DOMElement('Description', 'Default Generated Package'));
697
698 $package_weight = $package->appendChild(
699 new DOMElement('PackageWeight'));
700
701 $unit_of_measurement = $package_weight->appendChild(
702 new DOMElement('UnitOfMeasurement'));
703
704 $weight_unit = (isset($opts['weight_unit']) ? $opts['weight_unit'] : 'lbs');
705
706 $unit_of_measurement->appendChild(
707 new DOMElement('Code', self::$WEIGHT_UNITS[$weight_unit]));
708
709 $package_weight->appendChild(
710 new DOMElement('Weight', trim(sprintf('%6.1f', floatval($opts['weight'])))));
711
712 } // Package
713
714 if (isset($opts['saturday_pickup']) ||
715 isset($opts['cod_value']) ||
716 isset($opts['on_call_day']) ||
717 isset($opts['insured_value'])) {
718
719 $package_service_options = $shipment->appendChild(
720 new DOMElement('ShipmentServiceOptions'));
721
722 if (isset($opts['saturday_pickup'])) {
723 $package_service_options->appendChild(
724 new DOMElement('SaturdayPickupIndicator'));
725 }
726
727 if (isset($opts['on_call_day']) || isset($opts['on_call_method'])) {
728 $on_call_air = $package_service_options->appendChild(
729 new DOMElement('OnCallAir'));
730
731 $schedule = $on_call_air->appendChild(
732 new DOMElement('Schedule'));
733
734 $on_call_day = (isset($opts['on_call_day']) ? $opts['on_call_day'] : 'future');
735
736 $schedule->appendChild(
737 new DOMElement('PickupDay', self::$PICKUP_DAYS[$on_call_day]));
738
739 $on_call_method = (isset($opts['on_call_method']) ? $opts['on_call_method'] : 'internet');
740
741 $schedule->appendChild(
742 new DOMElement('Method', self::$ONCALL_METHODS[$on_call_method]));
743 }
744
745 if (isset($opts['insured_value'])) {
746 $insured_value = $package_service_options->appendChild(
747 new DOMElement('InsuredValue'));
748
749 $code = (isset($opts['cod_currency_code']) ? $opts['cod_currency_code'] : 'USD');
750
751 $insured_value->appendChild(
752 new DOMElement('CurrencyCode', $code));
753
754 $insured_value->appendChild(
755 new DOMElement('MonetaryValue', $opts['insured_value']));
756 }
757
758 if (isset($opts['cod_value'])) {
759 $cod = $package_service_options->appendChild(
760 new DOMElement('COD'));
761
762 if (isset($opts['cod_fund_code'])) {
763 $cod->appendChild(
764 new DOMElement('CODFundsCode', self::$FUND_CODES[$opts['cod_fund_code']]));
765 }
766
767 $cod->appendChild(
768 new DOMElement('CODCode', '3'));
769
770 $cod_amount = $cod->appendChild(
771 new DOMElement('CODAmount'));
772
773 $code = (isset($opts['cod_currency_code']) ? $opts['cod_currency_code'] : 'USD');
774
775 $cod_amount->appendChild(
776 new DOMElement('CurrencyCode', $code));
777
778 $cod_amount->appendChild(
779 new DOMElement('MonetaryValue', $opts['cod_value']));
780
781 $insured_value = $cod->appendChild(
782 new DOMElement('InsuredValue'));
783
784 $code = (isset($opts['cod_currency_code']) ? $opts['cod_currency_code'] : 'USD');
785
786 $insured_value->appendChild(
787 new DOMElement('CurrencyCode', $code));
788
789 $insured_value->appendChild(
790 new DOMElement('MonetaryValue', $opts['insured_value']));
791
792 if (isset($opts['cod_control_number'])) {
793 $cod->appendChild(
794 new DOMElement('ControlNumber', substr($opts['cod_control_number'], 0, 11)));
795 }
796
797 } // COD
798
799 } // if any shipping services
800
801 if (isset($opts['negotiated_rates'])) {
802 $rate_information = $shipment->appendChild(
803 new DOMElement('RateInformation'));
804
805 $rate_information->appendChild(
806 new DOMElement('NegotiatedRatesIndicator'));
807 }
808
809 return $doc->saveXML();
810 }
811
812 function http_client_post_xml($xml, $opts) {
813
814 $url = ((isset($opts['test']) && $opts['test']) ? self::TESTING_URL : self::URL);
815
816 $client = curl_init($url);
817 curl_setopt_array($client, array(
818 CURLOPT_VERBOSE => true,
819 CURLOPT_RETURNTRANSFER => true,
820 CURLOPT_POST => true,
821 CURLOPT_POSTFIELDS => $xml,
822 CURLOPT_TIMEOUT => 60,
823 CURLOPT_SSL_VERIFYPEER => false,
824 CURLOPT_SSL_VERIFYHOST => false,
825 CURLOPT_HEADER => false,
826 CURLOPT_HTTPHEADER => array(
827 'Content-Type: text/xml; charset=utf-8',
828 'Content-Length: ' . strlen($xml)
829 )
830 ));
831
832 $resp = curl_exec($client);
833 curl_close($client);
834
835 return $resp;
836 }
837
838 function parse_response($resp, $opts) {
839 $xml = simplexml_load_string($resp);
840 $response = array();
841 if (empty($resp)) {
842 $response['success'] = false;
843 $response['error_message'] = 'Communication with UPS failed.';
844 } elseif (self::is_error_response($xml)) {
845 $response['success'] = false;
846 $response['error_response'] = array(
847 'status_code' => (string) $xml->Response->ResponseStatusCode,
848 'status_description' => (string) $xml->Response->ResponseStatusDescription,
849 'error' => array(
850 'severity' => (string) $xml->Response->Error->ErrorSeverity,
851 'code' => (string) $xml->Response->Error->ErrorCode,
852 'description' => (string) $xml->Response->Error->ErrorDescription,
853 'location' => (string) $xml->Response->Error->ErrorLocation->ErrorLocationElementName
854 )
855 );
856 $response['error_message'] = $response['error_response']['status_description'];
857 } else {
858 $rated_shipments = $xml->xpath('//RatingServiceSelectionResponse/RatedShipment');
859 $response['rates'] = array();
860 foreach ($rated_shipments as $shipment) {
861 $service_code = self::service_code($shipment);
862 $charge = self::total_charge($shipment);
863 $response['rates'][$service_code] = $charge;
864 }
865 $response['success'] = true;
866 }
867 return $response;
868 }
869
870 // If there is no status code or if the status code is 0, this response is an error
871 function is_error_response($xml) {
872 $status_code = (string) $xml->Response->ResponseStatusCode;
873 return (!$status_code || (intval($status_code) == 0));
874 }
875
876 // Get the service code from the given shipment XML
877 function service_code($shipment) {
878 $service_code_raw = (string) $shipment->Service->Code;
879 $service_code = array_search($service_code_raw, self::$SERVICE_TYPES);
880 return $service_code;
881 }
882
883 // Get the total charges from the given shipment XML
884 function total_charge($shipment) {
885 $total_charges_raw = (string) $shipment->TotalCharges->MonetaryValue;
886 $total_charges = floatval($total_charges_raw);
887 return $total_charges;
888 }
889
890
891 } // ups_rating class
892
893 ?>
Something went wrong with that request. Please try again.