diff --git a/acme.go b/acme.go
index 4cb17897872ee86b4e88c46a703b91bf7f61bc9c..85c0c1126a002f416b0750112ae263f04c2d99b9 100644
--- a/acme.go
+++ b/acme.go
@@ -133,7 +133,7 @@ func (a *ACME) acmeClient(ctx context.Context) (*acme.Client, error) {
 	// account is already registered we get a StatusConflict,
 	// which we can ignore.
 	_, err = client.Register(ctx, ac, func(_ string) bool { return true })
-	if ae, ok := err.(*acme.Error); err == nil || ok && ae.StatusCode == http.StatusConflict {
+	if ae, ok := err.(*acme.Error); err == nil || err == acme.ErrAccountAlreadyExists || (ok && ae.StatusCode == http.StatusConflict) {
 		a.client = client
 		err = nil
 	}
@@ -149,7 +149,8 @@ func (a *ACME) GetCertificate(ctx context.Context, key crypto.Signer, c *certCon
 		return nil, nil, err
 	}
 
-	if err = a.verifyAll(ctx, client, c); err != nil {
+	o, err := a.verifyAll(ctx, client, c)
+	if err != nil {
 		return nil, nil, err
 	}
 
@@ -157,7 +158,7 @@ func (a *ACME) GetCertificate(ctx context.Context, key crypto.Signer, c *certCon
 	if err != nil {
 		return nil, nil, err
 	}
-	der, _, err = client.CreateCert(ctx, csr, 0, true)
+	der, _, err = client.CreateOrderCert(ctx, o.FinalizeURL, csr, true)
 	if err != nil {
 		return nil, nil, err
 	}
@@ -168,56 +169,66 @@ func (a *ACME) GetCertificate(ctx context.Context, key crypto.Signer, c *certCon
 	return der, leaf, nil
 }
 
-func (a *ACME) verifyAll(ctx context.Context, client *acme.Client, c *certConfig) error {
-	for _, domain := range c.Names {
-		if err := a.verify(ctx, client, c, domain); err != nil {
-			return err
-		}
-	}
-	return nil
-}
-
-func (a *ACME) verify(ctx context.Context, client *acme.Client, c *certConfig, domain string) error {
+func (a *ACME) verifyAll(ctx context.Context, client *acme.Client, c *certConfig) (*acme.Order, error) {
 	// Make an authorization request to the ACME server, and
 	// verify that it returns a valid response with challenges.
-	authz, err := client.Authorize(ctx, domain)
+	o, err := client.AuthorizeOrder(ctx, acme.DomainIDs(c.Names...))
 	if err != nil {
-		return err
-	}
-	switch authz.Status {
-	case acme.StatusValid:
-		return nil // already authorized
-	case acme.StatusInvalid:
-		return fmt.Errorf("invalid authorization %q", authz.URI)
+		return nil, fmt.Errorf("AuthorizeOrder failed: %v", err)
 	}
 
-	// Pick a challenge that matches our preferences and the
-	// available validators. The validator fulfills the challenge,
-	// and returns a cleanup function that we're going to call
-	// before we return. All steps are sequential and idempotent.
-	chal := a.pickChallenge(authz.Challenges, c)
-	if chal == nil {
-		return fmt.Errorf("unable to authorize %q", domain)
-	}
-	v, ok := a.validators[chal.Type]
-	if !ok {
-		return fmt.Errorf("challenge type '%s' is not available", chal.Type)
+	switch o.Status {
+	case acme.StatusReady:
+		return o, nil // already authorized
+	case acme.StatusPending:
+	default:
+		return nil, fmt.Errorf("invalid new order status %q", o.Status)
 	}
-	cleanup, err := v.Fulfill(ctx, client, domain, chal)
-	if err != nil {
-		return err
+
+	for _, zurl := range o.AuthzURLs {
+		z, err := client.GetAuthorization(ctx, zurl)
+		if err != nil {
+			return nil, fmt.Errorf("GetAuthorization(%s) failed: %v", zurl, err)
+		}
+		if z.Status != acme.StatusPending {
+			continue
+		}
+		// Pick a challenge that matches our preferences and the
+		// available validators. The validator fulfills the challenge,
+		// and returns a cleanup function that we're going to call
+		// before we return. All steps are sequential and idempotent.
+		chal := a.pickChallenge(z.Challenges, c)
+		if chal == nil {
+			return nil, fmt.Errorf("unable to authorize %q", c.Names)
+		}
+
+		v, ok := a.validators[chal.Type]
+		if !ok {
+			return nil, fmt.Errorf("challenge type '%s' is not available", chal.Type)
+		}
+
+		for _, domain := range c.Names {
+			cleanup, err := v.Fulfill(ctx, client, domain, chal)
+			if err != nil {
+				return nil, fmt.Errorf("fulfillment failed: %v", err)
+			}
+			defer cleanup()
+		}
+
+		if _, err := client.Accept(ctx, chal); err != nil {
+			return nil, fmt.Errorf("challenge accept failed: %v", err)
+		}
+		if _, err := client.WaitAuthorization(ctx, z.URI); err != nil {
+			return nil, fmt.Errorf("WaitAuthorization(%s) failed: %v", z.URI, err)
+		}
 	}
-	defer cleanup()
 
-	// Tell the ACME server that we've accepted the challenge, and
-	// then wait, possibly for some time, until there is an
-	// authorization response (either successful or not) from the
-	// server.
-	if _, err = client.Accept(ctx, chal); err != nil {
-		return err
+	// Authorizations are satisfied, wait for the CA
+	// to update the order status.
+	if _, err = client.WaitOrder(ctx, o.URI); err != nil {
+		return nil, err
 	}
-	_, err = client.WaitAuthorization(ctx, authz.URI)
-	return err
+	return o, nil
 }
 
 // Pick a challenge with the right type from the Challenge response