diff --git a/go/svc/invoice/main.go b/go/svc/invoice/main.go
new file mode 100644
index 0000000..8a5ddbe
--- /dev/null
+++ b/go/svc/invoice/main.go
@@ -0,0 +1,211 @@
+package main
+
+import (
+	"context"
+	"flag"
+
+	"github.com/golang/glog"
+	"google.golang.org/grpc/codes"
+	"google.golang.org/grpc/status"
+
+	"code.hackerspace.pl/hscloud/go/mirko"
+	pb "code.hackerspace.pl/hscloud/proto/invoice"
+)
+
+var (
+	flagDatabasePath string
+	flagInit         bool
+	flagDisablePKI   bool
+)
+
+type service struct {
+	m *model
+}
+
+func (s *service) CreateInvoice(ctx context.Context, req *pb.CreateInvoiceRequest) (*pb.CreateInvoiceResponse, error) {
+	if req.Invoice == nil {
+		return nil, status.Error(codes.InvalidArgument, "invoice must be given")
+	}
+	if len(req.Invoice.Item) < 1 {
+		return nil, status.Error(codes.InvalidArgument, "invoice must contain at least one item")
+	}
+	for i, item := range req.Invoice.Item {
+		if item.Title == "" {
+			return nil, status.Errorf(codes.InvalidArgument, "invoice item %d must have title set", i)
+		}
+		if item.Count == 0 || item.Count > 1000000 {
+			return nil, status.Errorf(codes.InvalidArgument, "invoice item %d must have correct count", i)
+		}
+		if item.UnitPrice == 0 {
+			return nil, status.Errorf(codes.InvalidArgument, "invoice item %d must have correct unit price", i)
+		}
+		if item.Vat > 100000 {
+			return nil, status.Errorf(codes.InvalidArgument, "invoice item %d must have correct vat set", i)
+		}
+	}
+	if len(req.Invoice.CustomerBilling) < 1 {
+		return nil, status.Error(codes.InvalidArgument, "invoice must contain at least one line of the customer's billing address")
+	}
+	if len(req.Invoice.InvoicerBilling) < 1 {
+		return nil, status.Error(codes.InvalidArgument, "invoice must contain at least one line of the invoicer's billing address")
+	}
+	for i, c := range req.Invoice.InvoicerContact {
+		if c.Medium == "" {
+			return nil, status.Errorf(codes.InvalidArgument, "contact point %d must have medium set", i)
+		}
+		if c.Contact == "" {
+			return nil, status.Errorf(codes.InvalidArgument, "contact point %d must have contact set", i)
+		}
+	}
+	if req.Invoice.InvoicerVatId == "" {
+		return nil, status.Error(codes.InvalidArgument, "invoice must contain invoicer's vat id")
+	}
+
+	uid, err := s.m.createInvoice(ctx, req.Invoice)
+	if err != nil {
+		if _, ok := status.FromError(err); ok {
+			return nil, err
+		}
+		glog.Errorf("createInvoice(_, _): %v", err)
+		return nil, status.Error(codes.Unavailable, "could not create invoice")
+	}
+	return &pb.CreateInvoiceResponse{
+		Uid: uid,
+	}, nil
+}
+
+func (s *service) GetInvoice(ctx context.Context, req *pb.GetInvoiceRequest) (*pb.GetInvoiceResponse, error) {
+	invoice, err := s.m.getInvoice(ctx, req.Uid)
+	if err != nil {
+		if _, ok := status.FromError(err); ok {
+			return nil, err
+		}
+		glog.Errorf("getInvoice(_, %q): %v", req.Uid, err)
+		return nil, status.Error(codes.Unavailable, "internal server error")
+	}
+	sealedUid, err := s.m.getSealedUid(ctx, req.Uid)
+	if err != nil {
+		if _, ok := status.FromError(err); ok {
+			return nil, err
+		}
+		glog.Errorf("getSealedUid(_, %q): %v", req.Uid, err)
+		return nil, status.Error(codes.Unavailable, "internal server error")
+	}
+
+	res := &pb.GetInvoiceResponse{
+		Invoice: invoice,
+	}
+	if sealedUid == "" {
+		res.State = pb.GetInvoiceResponse_STATE_PROFORMA
+	} else {
+		res.State = pb.GetInvoiceResponse_STATE_SEALED
+		res.FinalUid = sealedUid
+	}
+
+	return res, nil
+}
+
+func newService(m *model) *service {
+	return &service{
+		m: m,
+	}
+}
+
+func (s *service) RenderInvoice(req *pb.RenderInvoiceRequest, srv pb.Invoicer_RenderInvoiceServer) error {
+	sealed, err := s.m.getSealedUid(srv.Context(), req.Uid)
+	if err != nil {
+		if _, ok := status.FromError(err); ok {
+			return err
+		}
+		glog.Errorf("getSealedUid(_, %q): %v", req.Uid, err)
+		return status.Error(codes.Unavailable, "internal server error")
+	}
+
+	var rendered []byte
+	if sealed != "" {
+		// Invoice is sealed, return stored PDF.
+		rendered, err = s.m.getRendered(srv.Context(), req.Uid)
+		if err != nil {
+			if _, ok := status.FromError(err); ok {
+				return err
+			}
+			glog.Errorf("getRendered(_, %q): %v", req.Uid, err)
+			return status.Error(codes.Unavailable, "internal server error")
+		}
+	} else {
+		// Invoice is proforma, render.
+		invoice, err := s.m.getInvoice(srv.Context(), req.Uid)
+		if err != nil {
+			if _, ok := status.FromError(err); ok {
+				return err
+			}
+			glog.Errorf("getInvoice(_, %q): %v", req.Uid, err)
+			return status.Error(codes.Unavailable, "internal server error")
+		}
+
+		glog.Infof("%+v", invoice)
+		rendered, err = renderInvoicePDF(invoice, "xxxx", true)
+		if err != nil {
+			glog.Errorf("renderProformaPDF(_): %v", err)
+			return status.Error(codes.Unavailable, "internal server error")
+		}
+	}
+
+	chunkSize := 16 * 1024
+	chunk := &pb.RenderInvoiceResponse{}
+	for i := 0; i < len(rendered); i += chunkSize {
+		if i+chunkSize > len(rendered) {
+			chunk.Data = rendered[i:len(rendered)]
+		} else {
+			chunk.Data = rendered[i : i+chunkSize]
+		}
+		if err := srv.Send(chunk); err != nil {
+			glog.Errorf("srv.Send: %v", err)
+			return status.Error(codes.Unavailable, "stream broken")
+		}
+	}
+	return nil
+}
+
+func (s *service) SealInvoice(ctx context.Context, req *pb.SealInvoiceRequest) (*pb.SealInvoiceResponse, error) {
+	if err := s.m.sealInvoice(ctx, req.Uid); err != nil {
+		if _, ok := status.FromError(err); ok {
+			return nil, err
+		}
+		glog.Errorf("sealInvoice(_, %q): %v", req.Uid, err)
+		return nil, status.Error(codes.Unavailable, "internal server error")
+	}
+	return &pb.SealInvoiceResponse{}, nil
+}
+
+func init() {
+	flag.Set("logtostderr", "true")
+}
+
+func main() {
+	flag.StringVar(&flagDatabasePath, "db_path", "./foo.db", "path to sqlite database")
+	flag.BoolVar(&flagInit, "init_db", false, "init database and exit")
+	flag.Parse()
+
+	m, err := newModel(flagDatabasePath)
+	if err != nil {
+		glog.Exitf("newModel: %v", err)
+	}
+	if flagInit {
+		glog.Exit(m.init())
+	}
+
+	mi := mirko.New()
+	if err := mi.Listen(); err != nil {
+		glog.Exitf("Listen failed: %v", err)
+	}
+
+	s := newService(m)
+	pb.RegisterInvoicerServer(mi.GRPC(), s)
+
+	if err := mi.Serve(); err != nil {
+		glog.Exitf("Serve failed: %v", err)
+	}
+
+	<-mi.Done()
+}
