diff --git a/nixos/modules/issuer.nix b/nixos/modules/issuer.nix
new file mode 100644
index 0000000000000000000000000000000000000000..8f98a6e7163f52f4344e453a5498efab498566b0
--- /dev/null
+++ b/nixos/modules/issuer.nix
@@ -0,0 +1,36 @@
+# A NixOS module which can run a Ristretto-based issuer for PrivacyStorage
+# ZKAPs.
+{ lib, pkgs, config, ... }: let
+  pspkgs = pkgs.callPackage ./pspkgs.nix { };
+  zkapissuer = pspkgs.callPackage ../pkgs/zkapissuer.nix { };
+in {
+  options = {
+    services.private-storage-issuer.enable = lib.mkEnableOption "PrivateStorage ZKAP Issuer Service";
+    services.private-storage-issuer.package = lib.mkOption {
+      default = zkapissuer.components.exes."PaymentServer-exe";
+      type = lib.types.package;
+      example = lib.literalExample "pkgs.zkapissuer";
+      description = ''
+        The package to use for the ZKAP issuer.
+      '';
+    };
+  };
+
+  config = let
+    cfg = config.services.private-storage-issuer;
+  in
+    lib.mkIf cfg.enable {
+      systemd.services.zkapissuer = {
+        enable = true;
+        description = "ZKAP Issuer";
+        wantedBy = [ "multi-user.target" ];
+        after = [ "network.target" ];
+
+        serviceConfig = {
+          ExecStart = "${cfg.package}/bin/PaymentServer-exe";
+          Type = "simple";
+          Restart = "always";
+        };
+      };
+    };
+}
diff --git a/nixos/modules/private-storage.nix b/nixos/modules/private-storage.nix
index d2db7dd661a8a923c04e245e45cad30305ebfe68..58f4ba36bedac2b7b2de626132b831d8cdbdc142 100644
--- a/nixos/modules/private-storage.nix
+++ b/nixos/modules/private-storage.nix
@@ -2,16 +2,7 @@
 # preferred configuration for the Private Storage grid.
 { pkgs, lib, config, ... }:
 let
-  # Derive a brand new version of pkgs which has our overlay applied.  The
-  # overlay defines a new version of Tahoe-LAFS and some of its dependencies
-  # and maybe other useful Private Storage customizations.
-  pspkgs = import pkgs.path
-  { overlays = [
-      # needs fetchFromGitHub to check out zkapauthorizer
-      (pkgs.callPackage ./zkap-overlay.nix { })
-      (import ./overlays.nix)
-    ];
-  };
+  pspkgs = pkgs.callPackage ./pspkgs.nix { };
   # Grab the configuration for this module for convenient access below.
   cfg = config.services.private-storage;
 in
diff --git a/nixos/modules/pspkgs.nix b/nixos/modules/pspkgs.nix
new file mode 100644
index 0000000000000000000000000000000000000000..189778e02e47dede02139fdcd8f3f3be4fa273cd
--- /dev/null
+++ b/nixos/modules/pspkgs.nix
@@ -0,0 +1,11 @@
+# Derive a brand new version of pkgs which has our overlay applied.  The
+# overlay defines a new version of Tahoe-LAFS and some of its dependencies
+# and maybe other useful Private Storage customizations.
+{ pkgs }:
+import pkgs.path {
+  overlays = [
+    # needs fetchFromGitHub to check out zkapauthorizer
+    (pkgs.callPackage ./zkap-overlay.nix { })
+    (import ./overlays.nix)
+  ];
+}
diff --git a/nixos/modules/tests/private-storage.nix b/nixos/modules/tests/private-storage.nix
index 30818b3301fc46c1d7f307ef48e11e9ddcdabd27..b2f2f1f0af63d47257b701bcca655b1d2d4d2289 100644
--- a/nixos/modules/tests/private-storage.nix
+++ b/nixos/modules/tests/private-storage.nix
@@ -47,6 +47,15 @@ import <nixpkgs/nixos/tests/make-test.nix> {
         services.private-storage.publicIPv4 = "storage";
         services.private-storage.introducerFURL = introducerFURL;
       } // networkConfig;
+
+    # Operate an issuer as well.
+    issuer =
+    { config, pkgs, ... }:
+    { imports =
+      [ ../issuer.nix
+      ];
+      services.private-storage-issuer.enable = true;
+    };
   };
 
   # Test the machines with a Perl program (sobbing).
@@ -135,6 +144,18 @@ import <nixpkgs/nixos/tests/make-test.nix> {
       );
       $client->waitForOpenPort(3456);
 
+      #
+      # Get some ZKAPs from the issuer.
+      #
+
+      # Simulate a payment for a voucher.
+      $voucher = "0123456789";
+      $client->succeed("${simulate-payment} $voucher");
+
+      # Tell the client to redeem the voucher.
+      $client->succeed("${redeem-voucher} $voucher");
+
+      # The client should be prepped now.  Make it try to use some storage.
       my ($code, $out) = $client->execute(
           'tahoe -d /tmp/client ' .
           'put /etc/issue'
diff --git a/nixos/pkgs/zkapissuer.nix b/nixos/pkgs/zkapissuer.nix
new file mode 100644
index 0000000000000000000000000000000000000000..823a9f91577b86c05592e60ceb866d71e7b9e0d0
--- /dev/null
+++ b/nixos/pkgs/zkapissuer.nix
@@ -0,0 +1,10 @@
+{ fetchFromGitHub, callPackage }:
+let
+  paymentServer = fetchFromGitHub {
+    owner = "PrivateStorage";
+    repo = "PaymentServer";
+    rev = "6fbaac7a14d2a03b74e10a4a82b1147ee1dd7d49";
+    sha256 = "0z8mqmns3fqbjy765830s5q6lhz3lxmslxahjc155jsv5b46gjip";
+  };
+in
+  (callPackage "${paymentServer}/nix" { }).PaymentServer