diff --git a/api/auth/authproviders.py b/api/auth/authproviders.py
index da571255968e69cc341befa7feb9d35b7941f2c5..37b69052616a83ecfd0d8cff5479f6a5de582be2 100644
--- a/api/auth/authproviders.py
+++ b/api/auth/authproviders.py
@@ -196,10 +196,11 @@ class WechatOAuthProvider(AuthProvider):
         }
 
     def ensure_user_exists(self, openid, registration_code=None):
+        config.log.debug('openid is {} and reg code is {}'.format(openid, registration_code))
         if registration_code:
             user = config.db.users.find_one({'wechat.registration_code': registration_code})
             if user is None:
-                raise APIUnknownUserException('Invalid registration code.')
+                raise APIUnknownUserException('Invalid or expired registration code.')
             update = {
                 '$set': {
                     'wechat.openid': openid
diff --git a/api/handlers/userhandler.py b/api/handlers/userhandler.py
index cce32ac2063c59678bee9fd828fc869fe736183f..018f777b9d1f002bd651a279febe2433eb775566 100644
--- a/api/handlers/userhandler.py
+++ b/api/handlers/userhandler.py
@@ -23,7 +23,12 @@ class UserHandler(base.RequestHandler):
     def get(self, _id):
         user = self._get_user(_id)
         permchecker = userauth.default(self, user)
-        result = permchecker(self.storage.exec_op)('GET', _id, projection={'api_key': 0, 'wechat': 0} or None)
+        projection = {'api_key': 0}
+        if self.superuser_request:
+            projection['wechat.openid'] = 0
+        else:
+            projection['wechat'] = 0
+        result = permchecker(self.storage.exec_op)('GET', _id, projection=projection or None)
         if result is None:
             self.abort(404, 'User does not exist')
         return result
@@ -39,7 +44,12 @@ class UserHandler(base.RequestHandler):
 
     def get_all(self):
         permchecker = userauth.list_permission_checker(self)
-        result = permchecker(self.storage.exec_op)('GET', projection={'preferences': 0, 'api_key': 0, 'wechat': 0})
+        projection = {'preferences': 0, 'api_key': 0}
+        if self.superuser_request:
+            projection['wechat.openid'] = 0
+        else:
+            projection['wechat'] = 0
+        result = permchecker(self.storage.exec_op)('GET', projection=projection)
         if result is None:
             self.abort(404, 'Not found')
         return result
@@ -63,8 +73,6 @@ class UserHandler(base.RequestHandler):
         user = self._get_user(_id)
         permchecker = userauth.default(self, user)
         payload = self.request.json_body
-        if self.is_true('wechat'):
-            payload['wechat'] = {'registration_code': base64.urlsafe_b64encode(os.urandom(42))}
         mongo_schema_uri = validators.schema_uri('mongo', 'user.json')
         mongo_validator = validators.decorator_from_schema_path(mongo_schema_uri)
         payload_schema_uri = validators.schema_uri('input', 'user-update.json')
@@ -81,6 +89,8 @@ class UserHandler(base.RequestHandler):
         """Add user"""
         permchecker = userauth.default(self)
         payload = self.request.json_body
+        if self.is_true('wechat'):
+            payload['wechat'] = {'registration_code': base64.urlsafe_b64encode(os.urandom(42))}
         mongo_schema_uri = validators.schema_uri('mongo', 'user.json')
         mongo_validator = validators.decorator_from_schema_path(mongo_schema_uri)
         payload_schema_uri = validators.schema_uri('input', 'user-new.json')
diff --git a/api/web/base.py b/api/web/base.py
index 9ddb6ab968c0d105ac205e1e8e1929a120f492f5..11795108449d8744202763287b6359e2238832f6 100644
--- a/api/web/base.py
+++ b/api/web/base.py
@@ -173,6 +173,7 @@ class RequestHandler(webapp2.RequestHandler):
         """
 
         payload = self.request.json_body
+        config.log.debug(payload)
         if 'code' not in payload or 'auth_type' not in payload:
             self.abort(400, 'Auth code and type required for login')
 
@@ -182,7 +183,8 @@ class RequestHandler(webapp2.RequestHandler):
         except NotImplementedError as e:
             self.abort(400, str(e))
 
-        token_entry = auth_provider.validate_code(payload['code'])
+        registration_code = payload.get('registration_code')
+        token_entry = auth_provider.validate_code(payload['code'], registration_code=registration_code)
         timestamp = datetime.datetime.utcnow()
 
         # If this is the first time they've logged in, record that
diff --git a/raml/schemas/definitions/user.json b/raml/schemas/definitions/user.json
index 1df7df810826af0d67b21a0757a4d383ef746649..f92c8615509c7867b2ac5e5d1d7c199e22326511 100644
--- a/raml/schemas/definitions/user.json
+++ b/raml/schemas/definitions/user.json
@@ -35,6 +35,7 @@
                           "title": "Preferences",
                           "type": "object"
                         },
+    "wechat": {},
     "api_key":{
       "type":"object",
       "properties":{
@@ -55,7 +56,8 @@
         "avatars":{"$ref":"#/definitions/avatars"},
         "root":{"$ref":"#/definitions/root"},
         "disabled":{"$ref":"#/definitions/disabled"},
-        "preferences":{"$ref":"#/definitions/preferences"}
+        "preferences":{"$ref":"#/definitions/preferences"},
+        "wechat":{"$ref":"#/definitions/wechat"}
       },
       "additionalProperties":false
     },
@@ -71,6 +73,7 @@
         "root":{"$ref":"#/definitions/root"},
         "disabled":{"$ref":"#/definitions/disabled"},
         "preferences":{"$ref":"#/definitions/preferences"},
+        "wechat":{"$ref":"#/definitions/wechat"},
         "created":{"$ref":"../definitions/created-modified.json#/definitions/created"},
         "modified":{"$ref":"../definitions/created-modified.json#/definitions/modified"}
       },
diff --git a/raml/schemas/output/user-self.json b/raml/schemas/output/user-self.json
index 6bfa3cd3536075937e17efb03e327681e83e86c4..cf834066fa10ba93a7cf9d1f6500d2c76d624a4e 100644
--- a/raml/schemas/output/user-self.json
+++ b/raml/schemas/output/user-self.json
@@ -13,7 +13,8 @@
     "preferences":{"$ref":"../definitions/user.json#/definitions/preferences"},
     "created":{"$ref":"../definitions/created-modified.json#/definitions/created"},
     "modified":{"$ref":"../definitions/created-modified.json#/definitions/modified"},
-    "api_key":{"$ref":"../definitions/user.json#/definitions/api_key"}
+    "api_key":{"$ref":"../definitions/user.json#/definitions/api_key"},
+    "wechat":{"$ref":"../definitions/user.json#/definitions/wechat"}
   },
   "additionalProperties":false,
   "required":[