diff --git a/src/_secureaccesstokenauthorizer/resource.py b/src/_secureaccesstokenauthorizer/resource.py
index bab22f4eb0f39a28321b18ce13017296e10346c8..d8b3626e862d35dbb034345344af368ebbb947cf 100644
--- a/src/_secureaccesstokenauthorizer/resource.py
+++ b/src/_secureaccesstokenauthorizer/resource.py
@@ -92,6 +92,9 @@ class _PaymentReferenceNumberCollection(Resource):
 
 
     def render_PUT(self, request):
+        """
+        Record a PRN and begin attempting to redeem it.
+        """
         try:
             payload = loads(request.content.read())
         except Exception:
@@ -99,15 +102,7 @@ class _PaymentReferenceNumberCollection(Resource):
         if payload.keys() != [u"payment-reference-number"]:
             return bad_request().render(request)
         prn = payload[u"payment-reference-number"]
-        if not isinstance(prn, unicode):
-            return bad_request().render(request)
-        if len(prn) != 44:
-            # TODO.  44 is the length of 32 bytes base64 encoded.  This model
-            # information presumably belongs somewhere else.
-            return bad_request().render(request)
-        try:
-            urlsafe_b64decode(prn.encode("ascii"))
-        except Exception:
+        if not is_syntactic_prn(prn):
             return bad_request().render(request)
 
         self._controller.redeem(prn)
@@ -126,10 +121,8 @@ class _PaymentReferenceNumberCollection(Resource):
 
 
     def getChild(self, segment, request):
-        prn = segment
-        try:
-            urlsafe_b64decode(prn)
-        except Exception:
+        prn = segment.decode("utf-8")
+        if not is_syntactic_prn(prn):
             return bad_request()
         try:
             payment_reference = self._store.get(prn)
@@ -138,9 +131,38 @@ class _PaymentReferenceNumberCollection(Resource):
         return PaymentReferenceView(payment_reference)
 
 
+def is_syntactic_prn(prn):
+    """
+    :param prn: A candidate object to inspect.
+
+    :return bool: ``True`` if and only if ``prn`` is a unicode string
+        containing a syntactically valid payment reference number.  This says
+        **nothing** about the validity of the represented PRN itself.  A
+        ``True`` result only means the unicode string can be **interpreted**
+        as a PRN.
+    """
+    if not isinstance(prn, unicode):
+        return False
+    if len(prn) != 44:
+        # TODO.  44 is the length of 32 bytes base64 encoded.  This model
+        # information presumably belongs somewhere else.
+        return False
+    try:
+        urlsafe_b64decode(prn.encode("ascii"))
+    except Exception:
+        return False
+    return True
+
 
 class PaymentReferenceView(Resource):
+    """
+    This class implements a view for a ``PaymentReference`` instance.
+    """
     def __init__(self, reference):
+        """
+        :param PaymentReference reference: The model object for which to provide a
+            view.
+        """
         self._reference = reference
         Resource.__init__(self)
 
@@ -151,6 +173,10 @@ class PaymentReferenceView(Resource):
 
 
 def bad_request():
+    """
+    :return IResource: A resource which can be rendered to produce a **BAD
+        REQUEST** response.
+    """
     return ErrorPage(
         BAD_REQUEST, b"Bad Request", b"Bad Request",
     )
diff --git a/src/_secureaccesstokenauthorizer/tests/test_client_resource.py b/src/_secureaccesstokenauthorizer/tests/test_client_resource.py
index 3c1216b6f48fc13a55bf50c0d9c345b3999c36e9..be45313d683e21db316ab7013a42e552db9670d4 100644
--- a/src/_secureaccesstokenauthorizer/tests/test_client_resource.py
+++ b/src/_secureaccesstokenauthorizer/tests/test_client_resource.py
@@ -30,6 +30,9 @@ from json import (
 from io import (
     BytesIO,
 )
+from urllib import (
+    quote,
+)
 
 from testtools import (
     TestCase,
@@ -122,6 +125,11 @@ tahoe_configs_with_client_config = tahoe_configs(storage_client_plugins={
 })
 
 def is_not_json(bytestring):
+    """
+    :param bytes bytestring: A candidate byte string to inspect.
+
+    :return bool: ``False`` if and only if ``bytestring`` is JSON encoded.
+    """
     try:
         loads(bytestring)
     except:
@@ -129,16 +137,29 @@ def is_not_json(bytestring):
     return False
 
 def not_payment_reference_numbers():
-    return text().filter(
-        lambda t: (
-            # exclude / because it changes url dispatch and makes tests fail
-            # differently.
-            u"/" not in t and not is_urlsafe_base64(t)
+    """
+    Builds unicode strings which are not legal payment reference numbers.
+    """
+    return one_of(
+        text().filter(
+            lambda t: (
+                not is_urlsafe_base64(t)
+            ),
+        ),
+        payment_reference_numbers().map(
+            # Turn a valid PRN into a PRN that is invalid only by containing a
+            # character from the base64 alphabet in place of one from the
+            # urlsafe-base64 alphabet.
+            lambda prn: u"/" + prn[1:],
         ),
     )
 
-
 def is_urlsafe_base64(text):
+    """
+    :param unicode text: A candidate unicode string to inspect.
+
+    :return bool: ``True`` if and only if ``text`` is urlsafe-base64 encoded
+    """
     try:
         urlsafe_b64decode(text)
     except:
@@ -172,6 +193,13 @@ def invalid_bodies():
 
 
 def root_from_config(config):
+    """
+    Create a client root resource from a Tahoe-LAFS configuration.
+
+    :param _Config config: The Tahoe-LAFS configuration.
+
+    :return IResource: The root client resource.
+    """
     return from_configuration(
         config,
         PaymentReferenceStore.from_node_config(
@@ -269,20 +297,25 @@ class PaymentReferenceNumberTests(TestCase):
             ),
         )
 
-    @given(tahoe_configs_with_client_config, payment_reference_numbers())
-    def test_get_invalid_prn(self, get_config, prn):
+    @given(tahoe_configs_with_client_config, not_payment_reference_numbers())
+    def test_get_invalid_prn(self, get_config, not_prn):
         """
         When a syntactically invalid PRN is requested with a ``GET`` to a child of
         ``PaymentReferenceNumberCollection`` the response is **BAD REQUEST**.
         """
         tempdir = self.useFixture(TempDir())
-        not_prn = prn[1:]
         config = get_config(tempdir.join(b"tahoe.ini"), b"tub.port")
         root = root_from_config(config)
         agent = RequestTraversalAgent(root)
+        url = u"http://127.0.0.1/payment-reference-number/{}".format(
+            quote(
+                not_prn.encode("utf-8"),
+                safe=b"",
+            ).decode("utf-8"),
+        ).encode("ascii")
         requesting = agent.request(
             b"GET",
-            u"http://127.0.0.1/payment-reference-number/{}".format(not_prn).encode("utf-8"),
+            url,
         )
         self.assertThat(
             requesting,
@@ -345,7 +378,12 @@ class PaymentReferenceNumberTests(TestCase):
 
         getting = agent.request(
             b"GET",
-            u"http://127.0.0.1/payment-reference-number/{}".format(prn).encode("ascii"),
+            u"http://127.0.0.1/payment-reference-number/{}".format(
+                quote(
+                    prn.encode("utf-8"),
+                    safe=b"",
+                ).decode("utf-8"),
+            ).encode("ascii"),
         )
 
         self.assertThat(