PHPackages                             rogierw/letsencrypt-client - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [CLI &amp; Console](/categories/cli)
4. /
5. rogierw/letsencrypt-client

Abandoned → [https://github.com/RogierW/rw-acme-client](/?search=https%3A%2F%2Fgithub.com%2FRogierW%2Frw-acme-client)Library[CLI &amp; Console](/categories/cli)

rogierw/letsencrypt-client
==========================

LetsEncrypt client library for ACME v2 written in PHP.

6.0.1(5mo ago)59442↓100%14[1 issues](https://github.com/RogierW/rw-acme-client/issues)MITPHPPHP ^8.2

Since Nov 29Pushed 5mo ago2 watchersCompare

[ Source](https://github.com/RogierW/rw-acme-client)[ Packagist](https://packagist.org/packages/rogierw/letsencrypt-client)[ Docs](https://github.com/RogierW/rw-acme-client)[ RSS](/packages/rogierw-letsencrypt-client/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (10)Dependencies (4)Versions (36)Used By (0)

Let’s Encrypt ACME client written in PHP
========================================

[](#lets-encrypt-acme-client-written-in-php)

[![Latest Version on Packagist](https://camo.githubusercontent.com/d37f820da1d0b4f9a69bbfc5d8bd05b18c88c794f12220857914c846328054db/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f726f67696572772f72772d61636d652d636c69656e742e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/rogierw/rw-acme-client)[![Scrutinizer Code Quality](https://camo.githubusercontent.com/419550621140a698ca4cd72438e068530478dfce965be7bf64849000d5522f6b/68747470733a2f2f696d672e736869656c64732e696f2f7363727574696e697a65722f672f526f67696572572f72772d61636d652d636c69656e742e7376673f7374796c653d666c61742d737175617265)](https://scrutinizer-ci.com/g/RogierW/rw-acme-client/?branch=master)[![StyleCI](https://camo.githubusercontent.com/658df999d6a647e242c0f42c08cb36285820c047513b6688b205b4705c2dbb36/68747470733a2f2f6769746875622e7374796c6563692e696f2f7265706f732f3232343930323836322f736869656c643f7374796c653d666c61742d737175617265266272616e63683d6d6173746572)](https://github.styleci.io/repos/224902862)

This library allows you to request, renew and revoke SSL certificates provided by Let's Encrypt.

If you're looking for an easy-to-use CLI tool for managing your LE certificates, take a look at the [RW ACME CLI](https://github.com/RogierW/rw-acme-cli) project.

Requirements
------------

[](#requirements)

- PHP ^8.2
- OpenSSL &gt;= 1.0.1
- cURL extension
- JSON extension

**Notes:**

- It's recommended to have [dig](https://linux.die.net/man/1/dig) installed on your system, as it will be used to fetch DNS information.
- v4 of this package only supports `php:^8.2`. If you're looking for the older versions, check out [v1](https://github.com/RogierW/rw-acme-client/tree/v1) or [v3](https://github.com/RogierW/rw-acme-client/tree/v3).

Installation
------------

[](#installation)

You can install the package via composer:

`composer require rogierw/rw-acme-client`

Usage
-----

[](#usage)

Create an instance of `Rogierw\RwAcme\Api` client and provide it with a local account that will be used to store the account keys.

```
$localAccount = new \Rogierw\RwAcme\Support\LocalFileAccount(__DIR__.'/__account');
$client = new Api(localAccount: $localAccount);
```

You could also create a client and pass the local account data later:

```
$client = new Api();

// Do some stuff.

$localAccount = new \Rogierw\RwAcme\Support\LocalFileAccount(__DIR__.'/__account');
$client->setLocalAccount($localAccount);
```

> Please note that **setting a local account is required** before making any of the calls detailed below.

### Creating an account

[](#creating-an-account)

```
if (! $client->account()->exists()) {
    $account = $client->account()->create();
}

// Or get an existing account.
$account = $client->account()->get();
```

### Difference between `account` and `localAccount`

[](#difference-between-account-and-localaccount)

- `account` is the account created at the ACME (Let's Encrypt) server with data from the `localAccount`.
- `localAccount` handles the private/public key pair used to sign requests to the ACME server. Depending on the implementation, this data is stored locally or, for example, in a database.

### Creating an order

[](#creating-an-order)

```
$order = $client->order()->new($account, ['example.com']);
```

#### Renewal

[](#renewal)

Simply create a new order to renew an existing certificate as described above. Ensure that you use the same account as you did for the initial request.

#### Getting an order

[](#getting-an-order)

```
$order = $client->order()->get($order->id);
```

### Domain validation

[](#domain-validation)

#### Getting the DCV status

[](#getting-the-dcv-status)

```
$validationStatus = $client->domainValidation()->status($order);
```

#### http-01

[](#http-01)

Get the name and content for the validation file:

```
// Get the data for the HTTP challenge; filename and content.
$validationData = $client->domainValidation()->getValidationData($validationStatus, \Rogierw\RwAcme\Enums\AuthorizationChallengeEnum::HTTP);
```

This returns an array:

```
Array
(
    [0] => Array
        (
            [type] => http-01
            [identifier] => example.com
            [filename] => sqQnDYNNywpkwuHeU4b4FTPI2mwSrDF13ti08YFMm9M
            [content] => sqQnDYNNywpkwuHeU4b4FTPI2mwSrDF13ti08YFMm9M.kB7_eWSDdG3aWIaPSp6Uy4vLBbBI5M0COvM-AZOBcoQ
        )
)
```

The Let's Encrypt validation server will make a request to the following URL:

```
http://example.com/.well-known/acme-challenge/sqQnDYNNywpkwuHeU4b4FTPI2mwSrDF13ti08YFMm9M

```

#### dns-01

[](#dns-01)

Get the name and the value for the TXT record:

```
// Get the data for the DNS challenge.
$validationData = $client->domainValidation()->getValidationData($validationStatus, \Rogierw\RwAcme\Enums\AuthorizationChallengeEnum::DNS);
```

This returns an array:

```
Array
(
    [0] => Array
        (
            [type] => dns-01
            [identifier] => example.com
            [name] => _acme-challenge
            [value] => 8hSNdxGNkx4MI7ZN5F8uZj3cTSMX92SGMCMHQMh0cMA
        )
)
```

#### Start domain validation

[](#start-domain-validation)

##### http-01

[](#http-01-1)

```
try {
    $client->domainValidation()->start($account, $validationStatus[0], \Rogierw\RwAcme\Enums\AuthorizationChallengeEnum::HTTP);
} catch (DomainValidationException $exception) {
    // The local HTTP challenge test has been failed...
}
```

##### dns-01

[](#dns-01-1)

```
try {
    $client->domainValidation()->start($account, $validationStatus[0], \Rogierw\RwAcme\Enums\AuthorizationChallengeEnum::DNS);
} catch (DomainValidationException $exception) {
    // The local DNS challenge test has been failed...
}
```

#### Generating a CSR

[](#generating-a-csr)

```
$privateKey = \Rogierw\RwAcme\Support\OpenSsl::generatePrivateKey(key_type: OPENSSL_KEYTYPE_RSA);
// ^- you can switch "key_type: OPENSSL_KEYTYPE_EC" to generate a ECDSA key and certificate instead of RSA
$csr = \Rogierw\RwAcme\Support\OpenSsl::generateCsr(['example.com'], $privateKey);
```

#### Finalizing order

[](#finalizing-order)

```
if ($order->isReady() && $client->domainValidation()->allChallengesPassed($order)) {
    $client->order()->finalize($order, $csr);
}
```

#### Getting the actual certificate

[](#getting-the-actual-certificate)

```
if ($order->isFinalized()) {
    $certificateBundle = $client->certificate()->getBundle($order);
}
```

#### Revoke a certificate

[](#revoke-a-certificate)

```
if ($order->isValid()) {
    $client->certificate()->revoke($certificateBundle->fullchain);
}
```

###  Health Score

53

—

FairBetter than 97% of packages

Maintenance72

Regular maintenance activity

Popularity28

Limited adoption so far

Community18

Small or concentrated contributor base

Maturity81

Battle-tested with a long release history

 Bus Factor1

Top contributor holds 71.3% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~64 days

Recently: every ~161 days

Total

35

Last Release

153d ago

Major Versions

v1.x-dev → 2.0.02022-08-09

2.0.1 → 3.0.02023-03-09

3.0.5 → 4.0.02023-11-21

4.2.0 → 5.0.02024-12-09

5.0.0 → 6.0.02025-06-11

PHP version history (4 changes)0.0.1PHP ^7.1

1.1.0PHP ^7.1 || ^8.0

2.0.0PHP ^8.1

4.0.0PHP ^8.2

### Community

Maintainers

![](https://www.gravatar.com/avatar/26f03e5694c4f76245c1d3ec205ed4138ea594c0808d56f4f94186686d797237?d=identicon)[rogier](/maintainers/rogier)

---

Top Contributors

[![RogierW](https://avatars.githubusercontent.com/u/9381528?v=4)](https://github.com/RogierW "RogierW (112 commits)")[![trizz](https://avatars.githubusercontent.com/u/832056?v=4)](https://github.com/trizz "trizz (17 commits)")[![robbinjanssen](https://avatars.githubusercontent.com/u/120077?v=4)](https://github.com/robbinjanssen "robbinjanssen (14 commits)")[![StyleCIBot](https://avatars.githubusercontent.com/u/11048387?v=4)](https://github.com/StyleCIBot "StyleCIBot (7 commits)")[![bashgeek](https://avatars.githubusercontent.com/u/4669888?v=4)](https://github.com/bashgeek "bashgeek (6 commits)")[![divinity76](https://avatars.githubusercontent.com/u/1874996?v=4)](https://github.com/divinity76 "divinity76 (1 commits)")

---

Tags

certificatecliletsencryptphpssl

### Embed Badge

![Health badge](/badges/rogierw-letsencrypt-client/health.svg)

```
[![Health](https://phpackages.com/badges/rogierw-letsencrypt-client/health.svg)](https://phpackages.com/packages/rogierw-letsencrypt-client)
```

###  Alternatives

[league/climate

PHP's best friend for the terminal. CLImate allows you to easily output colored text, special formats, and more.

1.9k14.0M272](/packages/league-climate)[humbug/box

Fast, zero config application bundler with PHARs.

1.3k801.5k68](/packages/humbug-box)[crunzphp/crunz

Schedule your tasks right from the code.

2292.0M6](/packages/crunzphp-crunz)[vanilla/garden-cli

A full-featured, yet ridiculously simple commandline parser for your next php cli script. Stop fighting with getopt().

1171.2M42](/packages/vanilla-garden-cli)[rogierw/rw-acme-client

LetsEncrypt client library for ACME v2 written in PHP.

5923.5k1](/packages/rogierw-rw-acme-client)[graze/parallel-process

run a pool of processes simultaneously

103214.3k1](/packages/graze-parallel-process)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
