diff --git a/Mobile Buy SDK/Mobile Buy SDK.xcodeproj/project.pbxproj b/Mobile Buy SDK/Mobile Buy SDK.xcodeproj/project.pbxproj
index f8213c4..720a207 100644
--- a/Mobile Buy SDK/Mobile Buy SDK.xcodeproj/project.pbxproj
+++ b/Mobile Buy SDK/Mobile Buy SDK.xcodeproj/project.pbxproj
@@ -248,6 +248,20 @@
 		9A3B2DCA1CD27D5B00BFF49C /* BUYCustomer.h in Headers */ = {isa = PBXBuildFile; fileRef = 9A3B2DC71CD27D5B00BFF49C /* BUYCustomer.h */; settings = {ATTRIBUTES = (Public, ); }; };
 		9A3B2DCB1CD27D5B00BFF49C /* BUYCustomer.m in Sources */ = {isa = PBXBuildFile; fileRef = 9A3B2DC81CD27D5B00BFF49C /* BUYCustomer.m */; };
 		9A3B2DCC1CD27D5B00BFF49C /* BUYCustomer.m in Sources */ = {isa = PBXBuildFile; fileRef = 9A3B2DC81CD27D5B00BFF49C /* BUYCustomer.m */; };
+		9A3B2DCF1CD2822F00BFF49C /* BUYClient+Customers.h in Headers */ = {isa = PBXBuildFile; fileRef = 9A3B2DCD1CD2822F00BFF49C /* BUYClient+Customers.h */; };
+		9A3B2DD01CD2822F00BFF49C /* BUYClient+Customers.h in Headers */ = {isa = PBXBuildFile; fileRef = 9A3B2DCD1CD2822F00BFF49C /* BUYClient+Customers.h */; };
+		9A3B2DD11CD2822F00BFF49C /* BUYClient+Customers.m in Sources */ = {isa = PBXBuildFile; fileRef = 9A3B2DCE1CD2822F00BFF49C /* BUYClient+Customers.m */; };
+		9A3B2DD21CD2822F00BFF49C /* BUYClient+Customers.m in Sources */ = {isa = PBXBuildFile; fileRef = 9A3B2DCE1CD2822F00BFF49C /* BUYClient+Customers.m */; };
+		9A3B2DD51CD2829900BFF49C /* BUYAccountCredentials.h in Headers */ = {isa = PBXBuildFile; fileRef = 9A3B2DD31CD2829900BFF49C /* BUYAccountCredentials.h */; };
+		9A3B2DD61CD2829900BFF49C /* BUYAccountCredentials.h in Headers */ = {isa = PBXBuildFile; fileRef = 9A3B2DD31CD2829900BFF49C /* BUYAccountCredentials.h */; };
+		9A3B2DD71CD2829900BFF49C /* BUYAccountCredentials.m in Sources */ = {isa = PBXBuildFile; fileRef = 9A3B2DD41CD2829900BFF49C /* BUYAccountCredentials.m */; };
+		9A3B2DD81CD2829900BFF49C /* BUYAccountCredentials.m in Sources */ = {isa = PBXBuildFile; fileRef = 9A3B2DD41CD2829900BFF49C /* BUYAccountCredentials.m */; };
+		9A3B2DDA1CD282DA00BFF49C /* BUYClient_Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 9A3B2DD91CD282DA00BFF49C /* BUYClient_Internal.h */; };
+		9A3B2DDB1CD282DA00BFF49C /* BUYClient_Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 9A3B2DD91CD282DA00BFF49C /* BUYClient_Internal.h */; };
+		9A3B2DDD1CD28D7300BFF49C /* BUYSerializable.m in Sources */ = {isa = PBXBuildFile; fileRef = 9A3B2DDC1CD28D6F00BFF49C /* BUYSerializable.m */; };
+		9A3B2DDE1CD28D7300BFF49C /* BUYSerializable.m in Sources */ = {isa = PBXBuildFile; fileRef = 9A3B2DDC1CD28D6F00BFF49C /* BUYSerializable.m */; };
+		9A3B2DE01CD28E9900BFF49C /* BUYShopifyErrorCodes.h in Headers */ = {isa = PBXBuildFile; fileRef = 9A3B2DDF1CD28E9900BFF49C /* BUYShopifyErrorCodes.h */; };
+		9A3B2DE11CD28E9900BFF49C /* BUYShopifyErrorCodes.h in Headers */ = {isa = PBXBuildFile; fileRef = 9A3B2DDF1CD28E9900BFF49C /* BUYShopifyErrorCodes.h */; };
 		BE1007951B6038150031CEE7 /* BUYProductVariant+Options.h in Headers */ = {isa = PBXBuildFile; fileRef = BE1007931B6038150031CEE7 /* BUYProductVariant+Options.h */; };
 		BE1007961B6038150031CEE7 /* BUYProductVariant+Options.m in Sources */ = {isa = PBXBuildFile; fileRef = BE1007941B6038150031CEE7 /* BUYProductVariant+Options.m */; };
 		BE10079B1B6165EC0031CEE7 /* BUYOptionValueCell.h in Headers */ = {isa = PBXBuildFile; fileRef = BE1007991B6165EC0031CEE7 /* BUYOptionValueCell.h */; };
@@ -504,6 +518,13 @@
 		90FC31A71B50371600AFAB51 /* BUYProductViewHeaderBackgroundImageView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BUYProductViewHeaderBackgroundImageView.m; path = "Product View/BUYProductViewHeaderBackgroundImageView.m"; sourceTree = "<group>"; };
 		9A3B2DC71CD27D5B00BFF49C /* BUYCustomer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BUYCustomer.h; sourceTree = "<group>"; };
 		9A3B2DC81CD27D5B00BFF49C /* BUYCustomer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BUYCustomer.m; sourceTree = "<group>"; };
+		9A3B2DCD1CD2822F00BFF49C /* BUYClient+Customers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "BUYClient+Customers.h"; sourceTree = "<group>"; };
+		9A3B2DCE1CD2822F00BFF49C /* BUYClient+Customers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "BUYClient+Customers.m"; sourceTree = "<group>"; };
+		9A3B2DD31CD2829900BFF49C /* BUYAccountCredentials.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BUYAccountCredentials.h; sourceTree = "<group>"; };
+		9A3B2DD41CD2829900BFF49C /* BUYAccountCredentials.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BUYAccountCredentials.m; sourceTree = "<group>"; };
+		9A3B2DD91CD282DA00BFF49C /* BUYClient_Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BUYClient_Internal.h; sourceTree = "<group>"; };
+		9A3B2DDC1CD28D6F00BFF49C /* BUYSerializable.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BUYSerializable.m; sourceTree = "<group>"; };
+		9A3B2DDF1CD28E9900BFF49C /* BUYShopifyErrorCodes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BUYShopifyErrorCodes.h; sourceTree = "<group>"; };
 		BE1007931B6038150031CEE7 /* BUYProductVariant+Options.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "BUYProductVariant+Options.h"; sourceTree = "<group>"; };
 		BE1007941B6038150031CEE7 /* BUYProductVariant+Options.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "BUYProductVariant+Options.m"; sourceTree = "<group>"; };
 		BE1007991B6165EC0031CEE7 /* BUYOptionValueCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BUYOptionValueCell.h; sourceTree = "<group>"; };
@@ -877,6 +898,23 @@
 			children = (
 				841ADE2B1CB6F320000004B0 /* Persistent */,
 				841ADE2A1CB6F31C000004B0 /* Transient */,
+				9A3B2DD31CD2829900BFF49C /* BUYAccountCredentials.h */,
+				9A3B2DD41CD2829900BFF49C /* BUYAccountCredentials.m */,
+				90AFAA601B01390F00F21C23 /* BUYAddress.h */,
+				90AFAA611B01390F00F21C23 /* BUYAddress.m */,
+				F773744719C77A210039681C /* BUYCart.h */,
+				F773744819C77A210039681C /* BUYCart.m */,
+				900396991B601DF400226B73 /* BUYCartLineItem.h */,
+				9003969A1B601DF400226B73 /* BUYCartLineItem.m */,
+				BEB74A1B1B5490140005A300 /* BUYCheckout_Private.h */,
+				F773749419C77C260039681C /* BUYCheckout.h */,
+				F773749519C77C260039681C /* BUYCheckout.m */,
+				9032F2D81BE9457A00BB9EEF /* BUYCheckoutAttribute.h */,
+				9032F2D91BE9457A00BB9EEF /* BUYCheckoutAttribute.m */,
+				BEB74A8E1B55A3D00005A300 /* BUYCollection.h */,
+				9089CC5D1BB48D06009726D6 /* BUYCollection.m */,
+				900396F41B69563400226B73 /* BUYCollection+Additions.h */,
+				900396F51B69563400226B73 /* BUYCollection+Additions.m */,
 				F77374AA19C796BD0039681C /* BUYCreditCard.h */,
 				F77374AB19C796BD0039681C /* BUYCreditCard.m */,
 				9A3B2DC71CD27D5B00BFF49C /* BUYCustomer.h */,
@@ -888,6 +926,15 @@
 				2AF52A931A7010B20087DB2C /* BUYObject.h */,
 				2AF52A941A7010B20087DB2C /* BUYObject.mm */,
 				F76CFF1E19CB7C500079C703 /* BUYSerializable.h */,
+				9A3B2DDC1CD28D6F00BFF49C /* BUYSerializable.m */,
+				90AFAA641B01398A00F21C23 /* BUYShippingRate.h */,
+				90AFAA651B01398A00F21C23 /* BUYShippingRate.m */,
+				2AF52A831A700B0A0087DB2C /* BUYShop.h */,
+				2AF52A841A700B0A0087DB2C /* BUYShop.m */,
+				90AFAA5C1B011EA600F21C23 /* BUYTaxLine.h */,
+				90AFAA5D1B011EA600F21C23 /* BUYTaxLine.m */,
+				BEB74A861B5589C80005A300 /* BUYCollection.h */,
+				BEB74A871B5589C80005A300 /* BUYCollection.m */,
 			);
 			path = Models;
 			sourceTree = "<group>";
@@ -895,6 +942,7 @@
 		F773744519C779C20039681C /* Utils */ = {
 			isa = PBXGroup;
 			children = (
+				9A3B2DDF1CD28E9900BFF49C /* BUYShopifyErrorCodes.h */,
 				BE33B4F91B177EC80067982B /* BUYAddress+Additions.h */,
 				BE33B4FA1B177EC80067982B /* BUYAddress+Additions.m */,
 				F70CE40D1A8BF1D90055BEB8 /* BUYApplePayAdditions.h */,
@@ -949,6 +997,11 @@
 			children = (
 				F7FDA17019C93F6F00AF4E93 /* BUYClient.h */,
 				F7FDA17119C93F6F00AF4E93 /* BUYClient.m */,
+				9A3B2DD91CD282DA00BFF49C /* BUYClient_Internal.h */,
+				9A3B2DCD1CD2822F00BFF49C /* BUYClient+Customers.h */,
+				9A3B2DCE1CD2822F00BFF49C /* BUYClient+Customers.m */,
+				BE2E1D381B5E8663009610DA /* BUYClient+Test.h */,
+				BE2E1D391B5E8663009610DA /* BUYClient+Test.m */,
 			);
 			path = Data;
 			sourceTree = "<group>";
@@ -966,6 +1019,7 @@
 				901931271BC5B9BC00D1134E /* BUYAddress.h in Headers */,
 				901931281BC5B9BC00D1134E /* BUYApplePayHelpers.h in Headers */,
 				901931291BC5B9BC00D1134E /* BUYStoreViewController.h in Headers */,
+				9A3B2DDB1CD282DA00BFF49C /* BUYClient_Internal.h in Headers */,
 				9019312A1BC5B9BC00D1134E /* BUYCreditCard.h in Headers */,
 				9019312B1BC5B9BC00D1134E /* BUYOption.h in Headers */,
 				9019312C1BC5B9BC00D1134E /* BUYProductVariantCell.h in Headers */,
@@ -984,6 +1038,7 @@
 				9019313B1BC5B9BC00D1134E /* BUYOptionValue.h in Headers */,
 				9019313C1BC5B9BC00D1134E /* BUYShop.h in Headers */,
 				9019313D1BC5B9BC00D1134E /* BUYShippingRate.h in Headers */,
+				9A3B2DE11CD28E9900BFF49C /* BUYShopifyErrorCodes.h in Headers */,
 				9019313E1BC5B9BC00D1134E /* BUYApplePayAdditions.h in Headers */,
 				901931401BC5B9BC00D1134E /* BUYTheme+Additions.h in Headers */,
 				901931411BC5B9BC00D1134E /* BUYVariantOptionView.h in Headers */,
@@ -1005,6 +1060,9 @@
 				841ADE181CB6C942000004B0 /* NSRegularExpression+BUYAdditions.h in Headers */,
 				841ADE0C1CB6C942000004B0 /* NSDecimalNumber+BUYAdditions.h in Headers */,
 				901931491BC5B9BC00D1134E /* BUYGiftCard.h in Headers */,
+				BE6D059A1BD6BA6700772EBB /* NSDictionary+Additions.h in Headers */,
+				9A3B2DD61CD2829900BFF49C /* BUYAccountCredentials.h in Headers */,
+				9019314A1BC5B9BC00D1134E /* BUYClient+Test.h in Headers */,
 				9019314B1BC5B9BC00D1134E /* BUYNavigationController.h in Headers */,
 				9019314D1BC5B9BC00D1134E /* BUYVariantOptionBreadCrumbsView.h in Headers */,
 				9019314E1BC5B9BC00D1134E /* BUYProductViewFooter.h in Headers */,
@@ -1029,6 +1087,7 @@
 				901931651BC5B9BC00D1134E /* NSDecimalNumber+BUYAdditions.h in Headers */,
 				9A3B2DCA1CD27D5B00BFF49C /* BUYCustomer.h in Headers */,
 				901931661BC5B9BC00D1134E /* BUYCheckout.h in Headers */,
+				9A3B2DD01CD2822F00BFF49C /* BUYClient+Customers.h in Headers */,
 				901931671BC5B9BC00D1134E /* BUYCart.h in Headers */,
 				901931681BC5B9BC00D1134E /* BUYProductViewController.h in Headers */,
 				901931691BC5B9BC00D1134E /* BUYProduct.h in Headers */,
@@ -1047,6 +1106,7 @@
 				BE9A64531B503CBE0033E558 /* BUYAddress.h in Headers */,
 				BE9A64741B503D2E0033E558 /* BUYApplePayHelpers.h in Headers */,
 				BE9A647E1B503D930033E558 /* BUYStoreViewController.h in Headers */,
+				9A3B2DDA1CD282DA00BFF49C /* BUYClient_Internal.h in Headers */,
 				BE9A64551B503CC50033E558 /* BUYCreditCard.h in Headers */,
 				BE9A645F1B503CE90033E558 /* BUYOption.h in Headers */,
 				BEB74A6F1B5564260005A300 /* BUYProductVariantCell.h in Headers */,
@@ -1065,6 +1125,8 @@
 				BE9A64661B503D010033E558 /* BUYShop.h in Headers */,
 				BE9A644D1B503CA20033E558 /* BUYShippingRate.h in Headers */,
 				BE9A646C1B503D180033E558 /* BUYApplePayAdditions.h in Headers */,
+				9A3B2DE01CD28E9900BFF49C /* BUYShopifyErrorCodes.h in Headers */,
+				BE9A646A1B503D100033E558 /* BUYProduct+Options.h in Headers */,
 				906EAE431B836DE000976165 /* BUYTheme+Additions.h in Headers */,
 				BEB74A7B1B5564810005A300 /* BUYVariantOptionView.h in Headers */,
 				BE5DC3631B71022D00B2BC1E /* BUYMaskedCreditCard.h in Headers */,
@@ -1086,6 +1148,9 @@
 				841ADE171CB6C942000004B0 /* NSRegularExpression+BUYAdditions.h in Headers */,
 				841ADE0B1CB6C942000004B0 /* NSDecimalNumber+BUYAdditions.h in Headers */,
 				BE9A64571B503CCC0033E558 /* BUYGiftCard.h in Headers */,
+				BE6D05991BD6BA6700772EBB /* NSDictionary+Additions.h in Headers */,
+				9A3B2DD51CD2829900BFF49C /* BUYAccountCredentials.h in Headers */,
+				BE2E1D3A1B5E8663009610DA /* BUYClient+Test.h in Headers */,
 				BEB74A671B55640C0005A300 /* BUYNavigationController.h in Headers */,
 				90DE92701B9897B6002EF4DA /* BUYVariantOptionBreadCrumbsView.h in Headers */,
 				BEB74A711B5564300005A300 /* BUYProductViewFooter.h in Headers */,
@@ -1110,6 +1175,7 @@
 				BE9A64701B503D230033E558 /* NSDecimalNumber+BUYAdditions.h in Headers */,
 				9A3B2DC91CD27D5B00BFF49C /* BUYCustomer.h in Headers */,
 				BE9A644B1B503C9B0033E558 /* BUYCheckout.h in Headers */,
+				9A3B2DCF1CD2822F00BFF49C /* BUYClient+Customers.h in Headers */,
 				BE9A64491B503C940033E558 /* BUYCart.h in Headers */,
 				BEB74A2D1B554E870005A300 /* BUYProductViewController.h in Headers */,
 				BE9A64611B503CEF0033E558 /* BUYProduct.h in Headers */,
@@ -1315,6 +1381,7 @@
 				901931011BC5B9BC00D1134E /* BUYTheme+Additions.m in Sources */,
 				901931021BC5B9BC00D1134E /* BUYStoreViewController.m in Sources */,
 				901931031BC5B9BC00D1134E /* BUYOptionValue.m in Sources */,
+				9A3B2DDE1CD28D7300BFF49C /* BUYSerializable.m in Sources */,
 				901931041BC5B9BC00D1134E /* BUYApplePayAdditions.m in Sources */,
 				901931051BC5B9BC00D1134E /* BUYOptionSelectionNavigationController.m in Sources */,
 				901931061BC5B9BC00D1134E /* BUYDiscount.m in Sources */,
@@ -1342,12 +1409,14 @@
 				901931161BC5B9BC00D1134E /* BUYShippingRate.m in Sources */,
 				841ADE061CB6C942000004B0 /* NSDate+BUYAdditions.m in Sources */,
 				901931181BC5B9BC00D1134E /* BUYGradientView.m in Sources */,
+				9A3B2DD21CD2822F00BFF49C /* BUYClient+Customers.m in Sources */,
 				901931191BC5B9BC00D1134E /* BUYViewController.m in Sources */,
 				9019311A1BC5B9BC00D1134E /* BUYImageKit.m in Sources */,
 				9019311B1BC5B9BC00D1134E /* BUYAddress.m in Sources */,
 				9019311C1BC5B9BC00D1134E /* BUYOption.m in Sources */,
 				9019311D1BC5B9BC00D1134E /* BUYClient.m in Sources */,
 				9019311E1BC5B9BC00D1134E /* UIFont+BUYAdditions.m in Sources */,
+				9A3B2DD81CD2829900BFF49C /* BUYAccountCredentials.m in Sources */,
 				9019311F1BC5B9BC00D1134E /* BUYProductView.m in Sources */,
 				901931201BC5B9BC00D1134E /* BUYCreditCard.m in Sources */,
 				901931211BC5B9BC00D1134E /* BUYProductImageCollectionViewCell.m in Sources */,
@@ -1422,6 +1491,7 @@
 				906EAE441B836DE000976165 /* BUYTheme+Additions.m in Sources */,
 				BE9A647F1B503D960033E558 /* BUYStoreViewController.m in Sources */,
 				BE9A64691B503D0C0033E558 /* BUYOptionValue.m in Sources */,
+				9A3B2DDD1CD28D7300BFF49C /* BUYSerializable.m in Sources */,
 				BE9A646D1B503D1C0033E558 /* BUYApplePayAdditions.m in Sources */,
 				BEB74A2A1B554BFB0005A300 /* BUYOptionSelectionNavigationController.m in Sources */,
 				BE9A64501B503CAD0033E558 /* BUYDiscount.m in Sources */,
@@ -1449,12 +1519,14 @@
 				BE9A644E1B503CA60033E558 /* BUYShippingRate.m in Sources */,
 				841ADE051CB6C942000004B0 /* NSDate+BUYAdditions.m in Sources */,
 				BEB74A661B5564030005A300 /* BUYGradientView.m in Sources */,
+				9A3B2DD11CD2822F00BFF49C /* BUYClient+Customers.m in Sources */,
 				BE9A64811B503D9E0033E558 /* BUYViewController.m in Sources */,
 				900E7C851B5DA559006F3C81 /* BUYImageKit.m in Sources */,
 				BE9A64541B503CC30033E558 /* BUYAddress.m in Sources */,
 				BE9A64601B503CEC0033E558 /* BUYOption.m in Sources */,
 				BE9A64481B503C900033E558 /* BUYClient.m in Sources */,
 				9099444A1B71B76800C40A33 /* UIFont+BUYAdditions.m in Sources */,
+				9A3B2DD71CD2829900BFF49C /* BUYAccountCredentials.m in Sources */,
 				900396AD1B627CB900226B73 /* BUYProductView.m in Sources */,
 				BE9A64561B503CC90033E558 /* BUYCreditCard.m in Sources */,
 				904606B01B6BC8D700754173 /* BUYProductImageCollectionViewCell.m in Sources */,
diff --git a/Mobile Buy SDK/Mobile Buy SDK/Data/BUYClient+Customers.h b/Mobile Buy SDK/Mobile Buy SDK/Data/BUYClient+Customers.h
new file mode 100644
index 0000000..9968d5d
--- /dev/null
+++ b/Mobile Buy SDK/Mobile Buy SDK/Data/BUYClient+Customers.h
@@ -0,0 +1,149 @@
+//
+//  BUYClient+Customers.h
+//  Mobile Buy SDK
+//
+//  Created by Gabriel O'Flaherty-Chan on 2016-04-04.
+//  Copyright © 2016 Shopify Inc. All rights reserved.
+//
+
+#import "BUYClient.h"
+
+@class BUYCustomer;
+@class BUYOrder;
+@class BUYAccountCredentials;
+
+NSString *const BUYClientCustomerAccessToken = @"X-Shopify-Customer-Access-Token";
+
+/**
+ *  Return block containing a BUYCustomer object for an existing customer of the shop
+ *
+ *  @param customer A BUYCustomer
+ *  @param error    An optional NSError
+ */
+typedef void (^BUYDataCustomerBlock)(BUYCustomer *customer, NSError *error);
+
+/**
+ *  Return block containing a customer auth token
+ *
+ *  @param customer A BUYCustomer
+ *  @param token    An authentication token to retrieve the customer later.  Store this token securely on the device.
+ *  @param error    An optional NSError
+ */
+typedef void (^BUYDataCustomerTokenBlock)(BUYCustomer *customer, NSString *token, NSError *error);
+
+/**
+ *  Return block containing a customer auth token
+ *
+ *  @param token    An authentication token to retrieve the customer later.  Store this token securely on the device.
+ *  @param error    An optional NSError
+ */
+typedef void (^BUYDataTokenBlock)(NSString *token, NSError *error);
+
+/**
+ *  Return block containing an array of BUYOrders
+ *
+ *  @param orders An array of BUYOrders
+ *  @param error  An optional NSError
+ */
+typedef void (^BUYDataOrdersBlock)(NSArray <BUYOrder*> *orders, NSError *error);
+
+
+@interface BUYClient (Customers)
+
+/**
+ *  GET /api/customers/:customer_id
+ *  Gets an existing customer
+ *
+ *  @param customerID A customer ID retrieved from either customer creation or login
+ *  @param block      (BUYCustomer *customer, NSError *error)
+ *
+ *  @return The associated NSURLSessionDataTask
+ */
+- (NSURLSessionDataTask *)getCustomerWithID:(NSString *)customerID callback:(BUYDataCustomerBlock)block;
+
+/**
+ *  POST /api/customers
+ *  Creates a new customer
+ *  Expects first name, last name, email, password, and password confirmation
+ *
+ *  @param credentials Credentials object containing items for required fields
+ *  @param block       (BUYCustomer *customer, NSString *token, NSError *error)
+ *
+ *  @return The associated NSURLSessionDataTask
+ *
+ *  @discussion The customer is automatically logged in using -loginCustomerWithCredentials:callback:
+ */
+- (NSURLSessionDataTask *)createCustomerWithCredentials:(BUYAccountCredentials *)credentials callback:(BUYDataCustomerTokenBlock)block;
+
+/**
+ *  POST /api/customers/customer_token
+ *  Logs in an existing customer
+ *  Expects email and password
+ *
+ *  @param credentials Credentials object containing items for required fields
+ *  @param block    (BUYCustomer *customer, NSString *token, NSError *error)
+ *
+ *  @return The associated NSURLSessionDataTask
+ */
+- (NSURLSessionDataTask *)loginCustomerWithCredentials:(BUYAccountCredentials *)credentials callback:(BUYDataCustomerTokenBlock)block;
+
+/**
+ *  POST /api/customers/recover
+ *  Sends email for password recovery to an existing customer
+ *
+ *  @param email Email to send the password reset to
+ *  @param block (BUYStatus status, NSError *error)
+ *
+ *  @return the associated NSURLSessionDataTask
+ */
+- (NSURLSessionDataTask *)recoverPasswordForCustomer:(NSString *)email callback:(BUYDataCheckoutStatusBlock)block;
+
+/**
+ *  PUT /api/customers/:customer_id/customer_token/renew
+ *  Renews an existing customer's token
+ *
+ *  @param customerID ID of customer renewing token
+ *  @param block      (NSString *token, NSError *error)
+ *
+ *  @return the associated NSURLSessionDataTask
+ */
+- (NSURLSessionDataTask *)renewCustomerTokenWithID:(NSString *)customerID callback:(BUYDataTokenBlock)block;
+
+/**
+ *  PUT /api/customers/:customer_id/activate
+ *  Activates an unactivated customer
+ *
+ *  @param credentials   Credentials containing a password and password confirmation
+ *  @param customerID    ID of customer being activated
+ *  @param customerToken Token contained in activation URL
+ *  @param block         (BUYCustomer *customer, NSString *token, NSError *error)
+ *
+ *  @return The associated NSURLSessionDataTask
+ */
+- (NSURLSessionDataTask *)activateCustomerWithCredentials:(BUYAccountCredentials *)credentials customerID:(NSString *)customerID customerToken:(NSString *)customerToken callback:(BUYDataCustomerTokenBlock)block;
+
+/**
+ *  PUT /api/customers/:customer_id/reset
+ *  Resets an existing customer's password
+ *
+ *  @param credentials   Credentials containing a password and password confirmation
+ *  @param customerID    ID of customer resetting password
+ *  @param customerToken Token contained in reset URL
+ *  @param block         (BUYCustomer *customer, NSString *token, NSError *error)
+ *
+ *  @return The associated NSURLSessionDataTask
+ */
+- (NSURLSessionDataTask *)resetPasswordWithCredentials:(BUYAccountCredentials *)credentials customerID:(NSString *)customerID customerToken:(NSString *)customerToken callback:(BUYDataCustomerTokenBlock)block;
+
+/**
+ *  GET /api/customers/:customer_id/orders
+ *  Gets orders for a given customer
+ *
+ *  @param token An auth token retrieved from customer creation or customer login API
+ *  @param block    (NSArray <BUYOrder*> *orders, NSError *error)
+ *
+ *  @return The associated NSURLSessionDataTask
+ */
+- (NSURLSessionDataTask *)getOrdersForCustomerWithCallback:(BUYDataOrdersBlock)block;
+
+@end
diff --git a/Mobile Buy SDK/Mobile Buy SDK/Data/BUYClient+Customers.m b/Mobile Buy SDK/Mobile Buy SDK/Data/BUYClient+Customers.m
new file mode 100644
index 0000000..535a3fc
--- /dev/null
+++ b/Mobile Buy SDK/Mobile Buy SDK/Data/BUYClient+Customers.m
@@ -0,0 +1,251 @@
+//
+//  BUYClient+Customers.m
+//  Mobile Buy SDK
+//
+//  Created by Gabriel O'Flaherty-Chan on 2016-04-04.
+//  Copyright © 2016 Shopify Inc. All rights reserved.
+//
+
+#import "BUYClient+Customers.h"
+#import "BUYClient_Internal.h"
+#import "NSDateFormatter+BUYAdditions.h"
+#import "BUYCustomer.h"
+#import "BUYAccountCredentials.h"
+#import "BUYOrder.h"
+#import "BUYShopifyErrorCodes.h"
+
+@interface BUYAuthenticatedResponse : NSObject
++ (BUYAuthenticatedResponse *)responseFromJSON:(NSDictionary *)json;
+@property (nonatomic, copy) NSString *accessToken;
+@property (nonatomic, copy) NSDate *expiry;
+@property (nonatomic, copy) NSString *customerID;
+@end
+
+@implementation BUYAuthenticatedResponse
+
++ (BUYAuthenticatedResponse *)responseFromJSON:(NSDictionary *)json
+{
+	BUYAuthenticatedResponse *response = [BUYAuthenticatedResponse new];
+	NSDictionary *access = json[@"customer_access_token"];
+	response.accessToken = access[@"access_token"];
+	NSDateFormatter *formatter = [NSDateFormatter dateFormatterForPublications];
+	response.expiry = [formatter dateFromString:access[@"expires_at"]];
+	response.customerID = [NSString stringWithFormat:@"%@", access[@"customer_id"]];
+	return response;
+}
+
+@end
+
+@implementation BUYClient (Customers)
+
+#pragma mark - Customer
+
+- (NSURLSessionDataTask *)getCustomerWithID:(NSString *)customerID callback:(BUYDataCustomerBlock)block
+{
+	NSURLComponents *components = [self URLComponentsForCustomerWithID:customerID];
+	return [self getRequestForURL:components.URL completionHandler:^(NSDictionary *json, NSURLResponse *response, NSError *error) {
+		block((json && !error ? [[BUYCustomer alloc] initWithDictionary:json] : nil), error);
+	}];
+}
+
+- (NSURLSessionDataTask *)createCustomerWithCredentials:(BUYAccountCredentials *)credentials callback:(BUYDataCustomerTokenBlock)block
+{
+	NSURLComponents *components = [self URLComponentsForCustomers];
+	return [self postRequestForURL:components.URL object:credentials.JSONRepresentation completionHandler:^(NSDictionary *json, NSURLResponse *response, NSError *error) {
+		if (json && error == nil) {
+			[self createTokenForCustomerWithCredentials:credentials customerJSON:json callback:block];
+		}
+		else {
+			block(nil, nil, error);
+		}
+	}];
+}
+
+- (NSURLSessionDataTask *)createTokenForCustomerWithCredentials:(BUYAccountCredentials *)credentials customerJSON:(NSDictionary *)customerJSON callback:(BUYDataCustomerTokenBlock)block
+{
+	NSURLComponents *components = [self URLComponentsForCustomerLogin];
+	return [self postRequestForURL:components.URL object:credentials.JSONRepresentation completionHandler:^(NSDictionary *json, NSURLResponse *response, NSError *error) {
+		if (json && error == nil) {
+			BUYAuthenticatedResponse *authenticatedResponse = [BUYAuthenticatedResponse responseFromJSON:json];
+			self.customerToken = authenticatedResponse.accessToken;
+			
+			if (customerJSON == nil) {
+				[self getCustomerWithID:authenticatedResponse.customerID callback:^(BUYCustomer *customer, NSError *error) {
+					block(customer, self.customerToken, error);
+				}];
+			}
+			else {
+				block([[BUYCustomer alloc] initWithDictionary:json], self.customerToken, error);
+			}
+		}
+		else {
+			block(nil, nil, error);
+		}
+	}];
+}
+
+- (NSURLSessionDataTask *)loginCustomerWithCredentials:(BUYAccountCredentials *)credentials callback:(BUYDataCustomerTokenBlock)block
+{
+	return [self createTokenForCustomerWithCredentials:credentials customerJSON:nil callback:block];
+}
+
+- (NSURLSessionDataTask *)recoverPasswordForCustomer:(NSString *)email callback:(BUYDataCheckoutStatusBlock)block
+{
+	NSURLComponents *components = [self URLComponentsForPasswordReset];
+	
+	return [self postRequestForURL:components.URL object:@{@"email": email} completionHandler:^(NSDictionary *json, NSURLResponse *response, NSError *error) {
+		
+		NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode];
+		error = error ?: [self extractErrorFromResponse:response json:json];
+		
+		block(statusCode, error);
+	}];
+}
+
+- (NSURLSessionDataTask *)renewCustomerTokenWithID:(NSString *)customerID callback:(BUYDataTokenBlock)block
+{
+	if (self.customerToken) {
+		NSURLComponents *components = [self URLComponentsForTokenRenewalWithID:customerID];
+		
+		return [self putRequestForURL:components.URL body:nil completionHandler:^(NSDictionary *json, NSURLResponse *response, NSError *error) {
+			
+			NSString *accessToken = nil;
+			if (json && error == nil) {
+				BUYAuthenticatedResponse *authenticatedResponse = [BUYAuthenticatedResponse responseFromJSON:json];
+				accessToken = authenticatedResponse.accessToken;
+			}
+			
+			error = error ?: [self extractErrorFromResponse:response json:json];
+			
+			block(accessToken, error);
+		}];
+	}
+	else {
+		block(nil, [NSError errorWithDomain:kShopifyError code:BUYShopifyError_InvalidCustomerToken userInfo:nil]);
+		return nil;
+	}
+}
+
+- (NSURLSessionDataTask *)activateCustomerWithCredentials:(BUYAccountCredentials *)credentials customerID:(NSString *)customerID customerToken:(NSString *)customerToken callback:(BUYDataCustomerTokenBlock)block
+{
+	NSURLComponents *components = [self URLComponentsForCustomerActivationWithID:customerID customerToken:customerToken];
+	NSData *data = [NSJSONSerialization dataWithJSONObject:credentials.JSONRepresentation options:0 error:nil];
+	
+	return [self putRequestForURL:components.URL body:data completionHandler:^(NSDictionary *json, NSURLResponse *response, NSError *error) {
+		if (json && error == nil) {
+			BUYAccountCredentialItem *emailItem = [BUYAccountCredentialItem itemWithKey:@"email" value:json[@"customer"][@"email"]];
+			credentials[@"email"] = emailItem;
+			[self loginCustomerWithCredentials:credentials callback:block];
+		}
+		else {
+			block(nil, nil, error);
+		}
+	}];
+}
+
+- (NSURLSessionDataTask *)resetPasswordWithCredentials:(BUYAccountCredentials *)credentials customerID:(NSString *)customerID customerToken:(NSString *)customerToken callback:(BUYDataCustomerTokenBlock)block
+{
+	NSURLComponents *components = [self URLComponentsForCustomerPasswordResetWithCustomerID:customerID customerToken:customerToken];
+	NSData *data = [NSJSONSerialization dataWithJSONObject:credentials.JSONRepresentation options:0 error:nil];
+	
+	return [self putRequestForURL:components.URL body:data completionHandler:^(NSDictionary *json, NSURLResponse *response, NSError *error) {
+		if (json && error == nil) {
+			BUYAccountCredentialItem *emailItem = [BUYAccountCredentialItem itemWithKey:@"email" value:json[@"customer"][@"email"]];
+			credentials[@"email"] = emailItem;
+			[self loginCustomerWithCredentials:credentials callback:block];
+		}
+		else {
+			block(nil, nil, error);
+		}
+	}];
+}
+
+- (NSURLSessionDataTask *)getOrdersForCustomerWithCallback:(BUYDataOrdersBlock)block
+{
+	NSURLComponents *components = [self URLComponentsForCustomerOrders];
+	return [self getRequestForURL:components.URL completionHandler:^(NSDictionary *json, NSURLResponse *response, NSError *error) {
+		NSArray *ordersJSON = json[@"orders"];
+		if (!error && ordersJSON) {
+			
+			NSMutableArray *container = [NSMutableArray new];
+			for (NSDictionary *orderJSON in ordersJSON) {
+				[container addObject:[[BUYOrder alloc] initWithDictionary:orderJSON]];
+			}
+			block([container copy], error);
+			
+		} else {
+			block(nil, error);
+		}
+	}];
+}
+
+#pragma mark - URL Formatting
+
+- (NSURLComponents *)URLComponentsForCustomers
+{
+	return [self customerURLComponents];
+}
+
+- (NSURLComponents *)URLComponentsForCustomerWithID:(NSString *)customerID
+{
+	return [self customerURLComponentsAppendingPath:customerID];
+}
+
+- (NSURLComponents *)URLComponentsForCustomerLogin
+{
+	return [self customerURLComponentsAppendingPath:@"customer_token"];
+}
+
+- (NSURLComponents *)URLComponentsForCustomerActivationWithID:(NSString *)customerID customerToken:(NSString *)customerToken
+{
+	NSDictionary *queryItems = @{ @"token": customerToken };
+	NSString *path = [NSString stringWithFormat:@"%@/activate", customerID];
+	return [self customerURLComponentsAppendingPath:path queryItems:queryItems];
+}
+
+- (NSURLComponents *)URLComponentsForCustomerPasswordResetWithCustomerID:(NSString *)customerID customerToken:(NSString *)customerToken
+{
+	NSDictionary *queryItems = @{ @"token": customerToken };
+	NSString *path = [NSString stringWithFormat:@"%@/reset", customerID];
+	return [self customerURLComponentsAppendingPath:path queryItems:queryItems];
+}
+
+- (NSURLComponents *)URLComponentsForPasswordReset
+{
+	return [self customerURLComponentsAppendingPath:@"recover" queryItems:nil];
+}
+
+- (NSURLComponents *)URLComponentsForTokenRenewalWithID:(NSString *)customerID
+{
+	NSString *path = [NSString stringWithFormat:@"%@/customer_token/renew", customerID];
+	return [self customerURLComponentsAppendingPath:path queryItems:nil];
+}
+
+- (NSURLComponents *)URLComponentsForCustomerOrders
+{
+	return [self customerURLComponentsAppendingPath:@"orders" queryItems:nil];
+}
+
+#pragma mark - Convenience methods
+
+- (NSURLComponents *)customerURLComponents
+{
+	return [self customerURLComponentsAppendingPath:nil];
+}
+
+- (NSURLComponents *)customerURLComponentsAppendingPath:(NSString *)path
+{
+	return [self customerURLComponentsAppendingPath:path queryItems:nil];
+}
+
+- (NSURLComponents *)customerURLComponentsAppendingPath:(NSString *)path queryItems:(NSDictionary *)queryItems
+{
+	return [self URLComponentsForAPIPath:@"customers" appendingPath:path queryItems:queryItems];
+}
+
+- (NSString *)accessTokenFromHeaders:(NSDictionary *)headers
+{
+	return [headers valueForKey:BUYClientCustomerAccessToken];
+}
+
+@end
diff --git a/Mobile Buy SDK/Mobile Buy SDK/Data/BUYClient.h b/Mobile Buy SDK/Mobile Buy SDK/Data/BUYClient.h
index 1bdaa6e..311fea2 100644
--- a/Mobile Buy SDK/Mobile Buy SDK/Data/BUYClient.h
+++ b/Mobile Buy SDK/Mobile Buy SDK/Data/BUYClient.h
@@ -272,6 +272,12 @@ typedef void (^BUYDataGiftCardBlock)(BUYGiftCard *giftCard, NSError *error);
  */
 @property (nonatomic, strong) NSString *urlScheme;
 
+/**
+ *  Allows the client to hold onto the customer token
+ *
+ *  @param token The token received from the create and login callbacks
+ */
+@property (strong, nonatomic) NSString *customerToken;
 
 #pragma mark - Storefront
 
diff --git a/Mobile Buy SDK/Mobile Buy SDK/Data/BUYClient_Internal.h b/Mobile Buy SDK/Mobile Buy SDK/Data/BUYClient_Internal.h
new file mode 100644
index 0000000..a365849
--- /dev/null
+++ b/Mobile Buy SDK/Mobile Buy SDK/Data/BUYClient_Internal.h
@@ -0,0 +1,24 @@
+//
+//  BUYClient_Internal.h
+//  Mobile Buy SDK
+//
+//  Created by Gabriel O'Flaherty-Chan on 2016-04-04.
+//  Copyright © 2016 Shopify Inc. All rights reserved.
+//
+
+#import "BUYClient.h"
+#import "BUYSerializable.h"
+
+static NSString *const kShopifyError = @"shopify";
+
+@interface BUYClient (Internal)
+
+- (NSURLSessionDataTask *)postRequestForURL:(NSURL *)url object:(id <BUYSerializable>)object completionHandler:(void (^)(NSDictionary *json, NSURLResponse *response, NSError *error))completionHandler;
+- (NSURLSessionDataTask *)putRequestForURL:(NSURL *)url body:(NSData *)body completionHandler:(void (^)(NSDictionary *json, NSURLResponse *response, NSError *error))completionHandler;
+- (NSURLSessionDataTask *)getRequestForURL:(NSURL *)url completionHandler:(void (^)(NSDictionary *json, NSURLResponse *response, NSError *error))completionHandler;
+
+- (NSURLSessionDataTask *)requestForURL:(NSURL *)url method:(NSString *)method body:(NSData *)body additionalHeaders:(NSDictionary *)headers completionHandler:(void (^)(NSDictionary *json, NSURLResponse *response, NSError *error))completionHandler;
+- (NSURLComponents *)URLComponentsForAPIPath:(NSString *)apiPath appendingPath:(NSString *)appendingPath queryItems:(NSDictionary*)queryItems;
+- (NSError *)extractErrorFromResponse:(NSURLResponse *)response json:(NSDictionary *)json;
+
+@end
diff --git a/Mobile Buy SDK/Mobile Buy SDK/Models/BUYSerializable.h b/Mobile Buy SDK/Mobile Buy SDK/Models/BUYSerializable.h
index a113bb0..0ff7ff3 100644
--- a/Mobile Buy SDK/Mobile Buy SDK/Models/BUYSerializable.h
+++ b/Mobile Buy SDK/Mobile Buy SDK/Models/BUYSerializable.h
@@ -31,3 +31,7 @@
 - (NSDictionary *)jsonDictionaryForCheckout;
 
 @end
+
+@interface NSDictionary (BUYSerializable) <BUYSerializable>
+
+@end
\ No newline at end of file
diff --git a/Mobile Buy SDK/Mobile Buy SDK/Models/BUYSerializable.m b/Mobile Buy SDK/Mobile Buy SDK/Models/BUYSerializable.m
new file mode 100644
index 0000000..8331d0f
--- /dev/null
+++ b/Mobile Buy SDK/Mobile Buy SDK/Models/BUYSerializable.m
@@ -0,0 +1,35 @@
+//
+//  BUYSerializable.m
+//  Mobile Buy SDK
+//
+//  Created by Shopify.
+//  Copyright (c) 2015 Shopify Inc. All rights reserved.
+//
+//  Permission is hereby granted, free of charge, to any person obtaining a copy
+//  of this software and associated documentation files (the "Software"), to deal
+//  in the Software without restriction, including without limitation the rights
+//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+//  copies of the Software, and to permit persons to whom the Software is
+//  furnished to do so, subject to the following conditions:
+//
+//  The above copyright notice and this permission notice shall be included in
+//  all copies or substantial portions of the Software.
+//
+//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+//  THE SOFTWARE.
+//
+
+#import "BUYSerializable.h"
+
+@implementation NSDictionary (BUYSerializable)
+
+- (NSDictionary *)jsonDictionaryForCheckout {
+	return self;
+}
+
+@end
diff --git a/Mobile Buy SDK/Mobile Buy SDK/Utils/BUYShopifyErrorCodes.h b/Mobile Buy SDK/Mobile Buy SDK/Utils/BUYShopifyErrorCodes.h
new file mode 100644
index 0000000..2eef8b8
--- /dev/null
+++ b/Mobile Buy SDK/Mobile Buy SDK/Utils/BUYShopifyErrorCodes.h
@@ -0,0 +1,64 @@
+//
+//  BUYShopifyErrorCodes.h
+//  Mobile Buy SDK
+//
+//  Created by Gabriel O'Flaherty-Chan on 2016-03-14.
+//  Copyright © 2016 Shopify Inc. All rights reserved.
+//
+
+#ifndef BUYShopifyErrorCodes_h
+#define BUYShopifyErrorCodes_h
+
+static NSString * const BUYShopifyError = @"BUYShopifyError";
+
+/**
+ *  A collection of enums for error codes specific to the SDK
+ */
+typedef NS_ENUM(NSUInteger, BUYCheckoutError){
+	/**
+	 *  An error occurred retrieving the cart for an existing web checkout with StoreViewController
+	 */
+	BUYShopifyError_CartFetchError,
+	/**
+	 *  No shipping rates are available for the selected address
+	 */
+	BUYShopifyError_NoShippingMethodsToAddress,
+	/**
+	 *  No product or product ID was provided when loading a product in BUYProductViewController
+	 */
+	BUYShopifyError_NoProductSpecified,
+	/**
+	 *  The product ID or IDs provided were invalid for the shop. Check that the product are made visible on the Mobile App channel on /admin.
+	 */
+	BUYShopifyError_InvalidProductID,
+	/**
+	 *  No collection ID was provided when loading a collection
+	 */
+	BUYShopifyError_NoCollectionIdSpecified,
+	/**
+	 *  No gift card code was provided when applying a gift card to a checkout
+	 */
+	BUYShopifyError_NoGiftCardSpecified,
+	/**
+	 *  No credit card was provided when calling `storeCreditCard:completion:`
+	 */
+	BUYShopifyError_NoCreditCardSpecified,
+	/**
+	 *  No Apple Pay token was provided when attempting to complete a checkout using Apple Pay
+	 */
+	BUYShopifyError_NoApplePayTokenSpecified,
+	/**
+	 *  The checkout is invalid and does not have a checkout token. This generally means the BUYCheckout object
+	 *  has not been synced with Shopify via `createCheckout:completion:` before making subsequent calls to update
+	 *  or complete the checkout
+	 */
+	BUYShopifyError_InvalidCheckoutObject,
+	
+	/**
+	 *  A customer token has not been configured on the client
+	 */
+	BUYShopifyError_InvalidCustomerToken
+};
+
+
+#endif /* BUYShopifyErrorCodes_h */