# Greenfield API examples with PHP

The Greenfield API (opens new window) (also available on your instance on /docs) allows you to operate BTCPay Server via an easy-to-use REST API.

For PHP we have a client library available which can be found here (opens new window) and is also available for installation via Composer composer require btcpayserver/btcpayserver-greenfield-php

In this guide, we will give some examples how to use the Greenfield API with our PHP library. Additional examples can be found here (opens new window).

You can generate your API key in the BTCPay Server UI under "Account" -> "Manage Account" -> "API Keys" (path /account/apikeys). Make sure that the API key you are using has the permissions to execute the needed requests.

# Create a new user

Creating a new user can be done by using this endpoint (opens new window).

require __DIR__ . './vendor/autoload.php';

$host = 'https://mainnet.demo.btcpayserver.org';
$apiKey = 'pQc2FYhYwNzhf4DF7Foo6YpQc2FYhYwNzhf4DF7Foo6Y';
$email = 'test@test.com';
$password = 'Testing##123';
$isAdministrator = false;

try {
    $client = new \BTCPayServer\Client\User($host, $apiKey);
    var_dump($client->createUser($email, $password, $isAdministrator));
} catch (\Throwable $e) {
    echo "Error: " . $e->getMessage();
}

# Create a new API key

While we can use basic authentication to access the greenfield API, it is recommended to use API Keys to limit the scope of the credentials.

For example: If we want to create a new store (opens new window) we need the btcpay.store.canmodifystoresettings permission for the API key. Warning: If you do not pass any permission then the API key will have unrestricted access.

As mentioned above, you can do this through the BTCPay Server UI of your instance, but let's do it through the API using this endpoint (opens new window).

require __DIR__ . './vendor/autoload.php';

$host = 'https://mainnet.demo.btcpayserver.org';
$apiKey = 'API_KEY';

try {
    $client = new \BTCPayServer\Client\Apikey($host, $apiKey);
    var_dump($client->createApiKey('api generated', ['btcpay.store.canmodifystoresettings']));
} catch (\Throwable $e) {
    echo "Error: " . $e->getMessage();
}

# Create a new store

Now, we can use the api key to create a new store (opens new window).

require __DIR__ . './vendor/autoload.php';

$host = 'https://mainnet.demo.btcpayserver.org';
$apiKey = 'API_KEY';

// Create a new store.
try {
  $client = new \BTCPayServer\Client\Store($host, $apiKey);
  var_dump($client->createStore('my new store'));
} catch (\Throwable $e) {
  echo "Error: " . $e->getMessage();
}

# Create a simple invoice

require __DIR__ . './vendor/autoload.php';

$host = 'https://mainnet.demo.btcpayserver.org';
$apiKey = 'API_KEY';
$storeId = 'STORE_ID';
$amount = 5.15 + mt_rand(0, 20);
$currency = 'USD';
$orderId = 'Test39939' . mt_rand(0, 1000);
$buyerEmail = 'john@example.com';

// Create a basic invoice.
try {
    $client = new \BTCPayServer\Client\Invoice($host, $apiKey);
    var_dump(
        $client->createInvoice(
            $storeId,
            $currency,
            PreciseNumber::parseString($amount),
            $orderId,
            $buyerEmail
        )
    );
} catch (\Throwable $e) {
    echo "Error: " . $e->getMessage();
}

You can find a more advanced example with metadata and checkout options here (opens new window)

# Webhook implementation and validation with PHP

You can register a webhook for invoice events (opens new window) through your Store settings UI ("Settings" -> "Webhooks") or via this endpoint (opens new window).

The webhook payloads of BTCPay Server are signed, and therefore you can trust its content - but only after proper request validation. The validation of the provided BTCPay-Sig HTTP-header and payload, is done by the library.

On webhook creation, you provide an url that points to an endpoint route on your PHP site. e.g. https://example.com/mywebhookcallback. If you did not provide the secret yourself it will be autogenerated for you.

On that endpoint you can read and validate the webhook payload of your BTCPay Server instance like this:

require __DIR__ . './vendor/autoload.php';

$host = 'https://mainnet.demo.btcpayserver.org';
$apiKey = 'API_KEY';
$storeId = 'STORE_ID';
$webhookSecret = 'WEBHOOK_SECRET'

$raw_post_data = file_get_contents('php://input');
$payload = json_decode($raw_post_data, false, 512, JSON_THROW_ON_ERROR);

// Get the BTCPay signature header.
$headers = getallheaders();
foreach ($headers as $key => $value) {
    if (strtolower($key) === 'btcpay-sig') {
        $sig = $value;
    }
}

$webhookClient = new \BTCPayServer\Client\Webhook($host, $apiKey);

// Validate the webhook request.
if (!$webhookClient->isIncomingWebhookRequestValid($raw_post_data, $sig, $secret)) {
    throw new \RuntimeException(
        'Invalid BTCPayServer payment notification message received - signature did not match.'
    );
}

// Your own processing code goes here.

echo 'OK';

You can find many more examples here (opens new window)