Provisionner un client

Ce tutoriel vous explique comment provisionner un client à l'aide du l'API Reseller.

Le provisionnement correct d'un client implique plusieurs étapes interdépendantes qui s'étendent dans plusieurs API de la plate-forme Google Workspace.

Flux des API utilisées pour créer un client Google Workspace.
Image 1. Principales étapes de provisionnement d'un client Google Workspace

Le schéma précédent montre quelles API sont utilisées à chaque étape pour provisionner un client:

  • Utilisez l'API Site Verification pour placer le jeton de validation du domaine.
  • Utilisez l'API Reseller pour créer un client.
  • Utilisez l'API Directory pour créer le premier utilisateur et le désigner comme administrateur.
  • Utilisez l'API Reseller pour créer un abonnement.
  • Utilisez l'API Site Verification pour valider le domaine.

Prérequis

  • Une instance de domaine de revendeur Google.
  • un contrat partenaire Google Workspace signé ;

Configurer votre environnement

Pour suivre ce tutoriel, configurez votre environnement.

Activer l'API

Avant d'utiliser les API Google, vous devez les activer dans un projet Google Cloud. Vous pouvez activer une ou plusieurs API dans un même projet Google Cloud.
  • Dans la console Google Cloud, activez l'API Reseller, l'API Site Verification et l'API SDK Admin .

    Activer les API

Créer un compte de service

Un compte de service est un type particulier de compte utilisé par une application, qu'une personne. Vous pouvez utiliser un compte de service pour accéder aux données ou effectuer des actions par le compte robot, ou d'accéder aux données pour le compte de Google Workspace ou Cloud Identity. Pour en savoir plus, consultez la page Comprendre les comptes de service.

console Google Cloud

  1. Dans la console Google Cloud, accédez au menu . > IAM et Administrateur > Comptes de service.

    Accéder à la page "Comptes de service"

  2. Cliquez sur Créer un compte de service.
  3. Renseignez les détails du compte de service, puis cliquez sur Créer et continuer.
  4. Facultatif: attribuez des rôles à votre compte de service pour accorder l'accès aux ressources de votre projet Google Cloud. Pour en savoir plus, consultez Accorder, modifier et révoquer les accès à des ressources.
  5. Cliquez sur Continuer.
  6. Facultatif: indiquez les utilisateurs ou les groupes autorisés à gérer ce compte de service et à y effectuer des actions. Pour en savoir plus, consultez Gérer l'emprunt d'identité d'un compte de service.
  7. Cliquez sur OK. Notez l'adresse e-mail du compte de service.

CLI gcloud

  1. Créez le compte de service :
    gcloud iam service-accounts create SERVICE_ACCOUNT_NAME \
      --display-name="SERVICE_ACCOUNT_NAME"
  2. Facultatif: attribuez des rôles à votre compte de service pour accorder l'accès aux ressources de votre projet Google Cloud. Pour en savoir plus, consultez Accorder, modifier et révoquer les accès à des ressources.

Créer des identifiants pour un compte de service

Vous devez obtenir ces identifiants sous la forme d'une paire de clés publique/privée. Ces identifiants sont utilisés par votre code pour autoriser les actions du compte de service dans votre application. <ph type="x-smartling-placeholder">
    </ph>
  1. Dans la console Google Cloud, accédez au menu . &gt; IAM et Administrateur &gt; Comptes de service.

    Accéder à la page "Comptes de service"

  2. Sélectionnez votre compte de service.
  3. Cliquez sur Clés &gt; Ajouter une clé &gt; Créer une clé.
  4. Sélectionnez JSON, puis cliquez sur Créer.

    Votre nouvelle paire de clés publique/privée est générée et téléchargée sur votre machine comme un nouveau fichier. Enregistrez le fichier JSON téléchargé sous le nom credentials.json dans votre dans le répertoire de travail actuel. Ce fichier est la seule copie de cette clé. Pour savoir comment stocker votre clé en toute sécurité, consultez Gérer des clés de compte de service

  5. Cliquez sur Fermer.

Configurer la délégation au niveau du domaine pour un compte de service

Pour appeler des API au nom des utilisateurs d'une organisation Google Workspace, votre compte de service doit disposer d'une délégation d'autorité au niveau du domaine la console d'administration Google Workspace par un compte super-administrateur. Pour plus pour en savoir plus, consultez Déléguer une autorité au niveau du domaine à un compte de service
  1. Dans la console Google Cloud, accédez au menu . &gt; IAM et Administrateur &gt; Comptes de service.

    Accéder à la page "Comptes de service"

  2. Sélectionnez votre compte de service.
  3. Cliquez sur Afficher les paramètres avancés.
  4. Sous "Délégation au niveau du domaine", recherchez l'ID client de votre compte de service. Cliquez sur Copier pour copier la valeur de l'ID client dans le presse-papiers.
  5. Si vous disposez d'un accès super-administrateur au compte Google Workspace approprié, cliquez sur Accédez à la console d'administration Google Workspace, puis connectez-vous à l'aide d'un super-administrateur. et suivez la procédure ci-dessous.

    Si vous ne disposez pas d'un accès super-administrateur au compte Google Workspace concerné, contactez un super-administrateur de ce compte et envoyez-lui l'ID client de votre compte de service et la liste des champs d'application OAuth pour qu'ils puissent effectuer les étapes suivantes dans la console d'administration.

    1. Dans la console d'administration Google, accédez au menu . &gt; Sécurité &gt; Contrôle des accès et des données &gt; Commandes des API.

      Accéder aux commandes des API

    2. Cliquez sur Gérer la délégation au niveau du domaine.
    3. Cliquez sur Ajouter.
    4. Dans "Numéro client", , collez l'ID client que vous avez copié précédemment.
    5. Dans "Champs d'application OAuth" , saisissez une liste des champs d'application requis par votre application, séparés par une virgule. Il s'agit du même ensemble de champs d'application que vous avez définis lors de la configuration de l'écran de consentement OAuth.
    6. Cliquez sur Autoriser.

Créer des objets de service avec des identifiants authentifiés

Pour commencer à utiliser une API Google, vous devez d'abord configurer l'authentification et des identifiants depuis votre application. Les bibliothèques clientes Google gérer cela pour vous. Toutes les bibliothèques ont des modèles pour créer d'identifiants, auquel vous pouvez accorder l'accès à toutes les API et les transmettre dans chaque service. Une application doit généralement comporter un seul ensemble et d'utiliser un seul projet Cloud pour toutes les interactions avec les API Google.

Utilisez le fichier de clé JSON que vous avez généré lors de la création d'un compte de service.

Python
import sys
from apiclient.discovery import build
from apiclient.http import HttpError
from oauth2client.service_account import ServiceAccountCredentials

############## REPLACE WITH YOUR OWN VALUES ####################
JSON_PRIVATE_KEY_FILE = 'path/to/json_key_file.json'
RESELLER_ADMIN_USER = 'admin@yourresellerdomain.com'
CUSTOMER_DOMAIN = 'example.com'
CUSTOMER_SITE = 'https://www.example.com'
################################################################

# Full List of scopes:
# https://developers.google.com/identity/protocols/googlescopes
OAUTH2_SCOPES = [
    'https://reseller.googleapis.com/auth/apps.order',
    'https://reseller.googleapis.com/auth/siteverification',
    'https://reseller.googleapis.com/auth/admin.directory.user',
]

credentials = ServiceAccountCredentials.from_json_keyfile_name(
    JSON_PRIVATE_KEY_FILE, OAUTH2_SCOPES).create_delegated(RESELLER_ADMIN_USER)

reseller_service = build(
    serviceName='reseller', version='v1', credentials=credentials)

directory_service = build(
    serviceName='admin', version='directory_v1', credentials=credentials)

verification_service = build(
    serviceName='siteVerification', version='v1', credentials=credentials)
Java
// OAuth2 and HTTP
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.HttpResponseException;
import com.google.api.client.json.jackson2.JacksonFactory;
// Directory API
import com.google.api.services.admin.directory.Directory;
import com.google.api.services.admin.directory.DirectoryScopes;
import com.google.api.services.admin.directory.model.User;
import com.google.api.services.admin.directory.model.UserMakeAdmin;
import com.google.api.services.admin.directory.model.UserName;
// Reseller API
import com.google.api.services.reseller.Reseller;
import com.google.api.services.reseller.ResellerScopes;
import com.google.api.services.reseller.model.Address;
import com.google.api.services.reseller.model.Customer;
import com.google.api.services.reseller.model.RenewalSettings;
import com.google.api.services.reseller.model.Seats;
import com.google.api.services.reseller.model.Subscription;
// Site Verification API
import com.google.api.services.siteVerification.SiteVerification;
import com.google.api.services.siteVerification.SiteVerificationScopes;
import com.google.api.services.siteVerification.model.SiteVerificationWebResourceGettokenRequest;
import com.google.api.services.siteVerification.model.SiteVerificationWebResourceGettokenResponse;
import com.google.api.services.siteVerification.model.SiteVerificationWebResourceResource;
// Java library imports
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.Arrays;
import java.util.List;

/**
 * This is a basic example of provisioning a Google Workspace customer.
 */
public class CodelabExample {
  // Full List of scopes:
  // https://developers.google.com/identity/protocols/googlescopes
  private static final List<String> OAUTH2_SCOPES = Arrays.asList(
    ResellerScopes.APPS_ORDER,
    SiteVerificationScopes.SITEVERIFICATION,
    DirectoryScopes.ADMIN_DIRECTORY_USER
  );

  /***************** REPLACE WITH YOUR OWN VALUES ********************************/
  public static final String JSON_PRIVATE_KEY_FILE = "path/to/json_key_file.json";
  public static final String RESELLER_ADMIN_USER = "admin@yourresellerdomain.com";
  public static final String CUSTOMER_DOMAIN = "example.com";
  public static final String CUSTOMER_SITE = "https://www.example.com/";
  /*******************************************************************************/

  public static void main(String[] args)
      throws IOException, GeneralSecurityException, FileNotFoundException {
    // Instantiate services with authenticated credentials
    GoogleCredential jsonCredentials = GoogleCredential
      .fromStream(new FileInputStream(JSON_PRIVATE_KEY_FILE));
    GoogleCredential credentials = new GoogleCredential.Builder()
      .setTransport(GoogleNetHttpTransport.newTrustedTransport())
      .setJsonFactory(JacksonFactory.getDefaultInstance())
      .setServiceAccountScopes(OAUTH2_SCOPES)
      .setServiceAccountUser(RESELLER_ADMIN_USER)
      .setServiceAccountPrivateKey(jsonCredentials.getServiceAccountPrivateKey())
      .setServiceAccountId(jsonCredentials.getServiceAccountId())
      .build();

    Reseller resellerService = new Reseller.Builder(
        credentials.getTransport(),
        credentials.getJsonFactory(),
        credentials).setApplicationName("Google Workspace Creator").build();

    Directory directoryService = new Directory.Builder(
        credentials.getTransport(),
        credentials.getJsonFactory(),
        credentials).setApplicationName("Google Workspace Creator").build();

    SiteVerification verificationService = new SiteVerification.Builder(
        credentials.getTransport(),
        credentials.getJsonFactory(),
        credentials).setApplicationName("Google Workspace Creator").build();
C#
// OAuth2 and HTTP
using Google.Apis.Auth.OAuth2;
using Google.Apis.Services;
// Reseller API
using Google.Apis.Reseller.v1;
using Google.Apis.Reseller.v1.Data;
// Directory API
using Google.Apis.Admin.Directory.directory_v1;
using User = Google.Apis.Admin.Directory.directory_v1.Data.User;
using UserName = Google.Apis.Admin.Directory.directory_v1.Data.UserName;
using UserMakeAdmin = Google.Apis.Admin.Directory.directory_v1.Data.UserMakeAdmin;
//Site Verification API
using Google.Apis.SiteVerification.v1;
using Google.Apis.SiteVerification.v1.Data;
// System imports
using System;
using System.IO;

class CodelabExample
{
    // Full List of scopes:
    // https://developers.google.com/identity/protocols/googlescopes
    static string[] OAUTH2_SCOPES = {
        ResellerService.Scope.AppsOrder,
        DirectoryService.Scope.AdminDirectoryUser,
        SiteVerificationService.Scope.Siteverification
    };

    /***************** REPLACE WITH YOUR OWN VALUES ********************************/
    public static String JSON_PRIVATE_KEY_FILE = "path/to/json_key_file.json";
    public static String RESELLER_ADMIN_USER = "admin@yourresellerdomain.com";
    public static String CUSTOMER_DOMAIN = "example.com";
    public static String CUSTOMER_SITE = "https://www.example.com/";
    /*******************************************************************************/

    static void Main(string[] args)
    {
        GoogleCredential credential;

        using (var stream = new FileStream(JSON_PRIVATE_KEY_FILE, FileMode.Open, FileAccess.Read))
        {
            credential = GoogleCredential
                .FromStream(stream)
                .CreateScoped(OAUTH2_SCOPES)
                .CreateWithUser(RESELLER_ADMIN_USER);
        }

        var resellerService = new ResellerService(new BaseClientService.Initializer()
        {
            HttpClientInitializer = credential,
        });

        var directoryService = new DirectoryService(new BaseClientService.Initializer()
        {
            HttpClientInitializer = credential,
        });

        var verificationService = new SiteVerificationService(new BaseClientService.Initializer()
        {
            HttpClientInitializer = credential,
        });
PHP
// https://developers.google.com/api-client-library/php/
require_once 'vendor/autoload.php';

// Full List of scopes:
// https://developers.google.com/identity/protocols/googlescopes
$OAUTH2_SCOPES = [
  Google_Service_Reseller::APPS_ORDER,
  Google_Service_SiteVerification::SITEVERIFICATION,
  Google_Service_Directory::ADMIN_DIRECTORY_USER,
];

######### REPLACE WITH YOUR OWN VALUES ###############
$JSON_PRIVATE_KEY_FILE = 'path/to/json_key_file.json';
$RESELLER_ADMIN_USER = 'admin@yourresellerdomain.com';
$CUSTOMER_DOMAIN = 'example.com';
$CUSTOMER_SITE = 'https://www.example.com/';
######################################################

$client = new Google_Client();
$client->setAuthConfig($JSON_PRIVATE_KEY_FILE);
$client->setSubject($RESELLER_ADMIN_USER);
$client->setScopes($OAUTH2_SCOPES);

$resellerService = new Google_Service_Reseller($client);
$directoryService = new Google_Service_Directory($client);
$verificationService = new Google_Service_SiteVerification($client);
Ruby
require 'googleauth'
require 'google/apis/reseller_v1'
require 'google/apis/site_verification_v1'
require 'google/apis/admin_directory_v1'

# Full List of scopes:
# https://developers.google.com/identity/protocols/googlescopes
OAUTH2_SCOPES = [
  'https://reseller.googleapis.com/auth/apps.order',
  'https://reseller.googleapis.com/auth/admin.directory.user',
  'https://reseller.googleapis.com/auth/siteverification',
]

####### REPLACE WITH YOUR OWN VALUES ###############
JSON_PRIVATE_KEY_FILE = 'path/to/json_key_file.json'
RESELLER_ADMIN_USER = 'admin@yourresellerdomain.com'
CUSTOMER_DOMAIN = 'example.com'
CUSTOMER_SITE = 'https://www.example.com/'
####################################################

credentials = Google::Auth::ServiceAccountCredentials.make_creds(
  json_key_io: File.open(JSON_PRIVATE_KEY_FILE),
  scope: OAUTH2_SCOPES)
credentials.sub = RESELLER_ADMIN_USER

Google::Apis::RequestOptions.default.authorization = credentials

reseller_service = Google::Apis::ResellerV1::ResellerService.new
directory_service = Google::Apis::AdminDirectoryV1::DirectoryService.new
verification_service = Google::Apis::SiteVerificationV1::SiteVerificationService.new
Node.js
// NOTE: This script needs googleapis 28.0.0 or later as it uses promises
const {google} = require('googleapis');

// ############## REPLACE WITH YOUR OWN VALUES ####################
const JSON_PRIVATE_KEY_FILE = 'path/to/json_key_file.json';
const RESELLER_ADMIN_USER = 'admin@yourresellerdomain.com';
const CUSTOMER_DOMAIN = 'example.com';
const CUSTOMER_SITE = 'https://www.example.com/';
// ################################################################

// Full List of scopes: https://developers.google.com/identity/protocols/googlescopes
const OAUTH2_SCOPES = [
  'https://reseller.googleapis.com/auth/apps.order',
  'https://reseller.googleapis.com/auth/siteverification',
  'https://reseller.googleapis.com/auth/admin.directory.user',
];

const authJWT = new google.auth.JWT({
  keyFile: JSON_PRIVATE_KEY_FILE,
  scopes: OAUTH2_SCOPES,
  subject: RESELLER_ADMIN_USER,
});

const resellerService = google.reseller({version: 'v1', auth: authJWT});
const directoryService = google.admin({version: 'directory_v1', auth: authJWT});
const verificationService = google.siteVerification({version: 'v1', auth: authJWT});

Commencer la procédure de validation du domaine

Cette étape est facultative, mais nous vous conseillons de la suivre si vous avez la possibilité de vérifier domaine du client. Cette étape se termine à la fin du tutoriel, lorsque vous valider le domaine.

Si vous ne validez pas le domaine du client, il disposera des éléments suivants : restrictions:

Pour récupérer un jeton de validation de site, procédez comme suit:

  1. Pour récupérer un jeton de validation de site, utilisez la méthode API Site Verification : Vous ne pouvez pas vérifier si un domaine a déjà été validé, mais vous pouvez valider les sites plusieurs fois sans aucun problème. Selon que vous validez un type INET_DOMAIN ou SITE, Les paramètres verificationMethod varient. Choisissez l'une des options suivantes :

    • Pour le type INET_DOMAIN, utilisez l'un des éléments verificationMethod suivants. paramètres:

      • DNS_TXT
      • DNS_CNAME

      L'exemple de récupération de jetons suivant utilise un type INET_DOMAIN:

      Python
      # Retrieve the site verification token and place it according to:
      # https://developers.google.com/site-verification/v1/getting_started#tokens
      response = verification_service.webResource().getToken(
          body={
              'site': {
                  'type': 'INET_DOMAIN',
                  'identifier': CUSTOMER_DOMAIN
              },
              'verificationMethod': 'DNS_TXT'
          }).execute()
      print(response)
      Java
      // Retrieve the site verification token and place it according to:
      // https://developers.google.com/site-verification/v1/getting_started#tokens
      SiteVerificationWebResourceGettokenRequest.Site getTokenSite =
          new SiteVerificationWebResourceGettokenRequest.Site()
              .setType("INET_DOMAIN")
              .setIdentifier(CUSTOMER_DOMAIN);
      
      SiteVerificationWebResourceGettokenRequest request =
          new SiteVerificationWebResourceGettokenRequest()
              .setVerificationMethod("DNS_TXT")
              .setSite(getTokenSite);
      
      SiteVerificationWebResourceGettokenResponse getTokenResponse =
          verificationService.webResource().getToken(request).execute();
      System.out.println("Site Verification Token: " + getTokenResponse.getToken());
      C#
      // Retrieve the site verification token and place it according to:
      // https://developers.google.com/site-verification/v1/getting_started#tokens
      SiteVerificationWebResourceGettokenRequest.SiteData getTokenSite =
          new SiteVerificationWebResourceGettokenRequest.SiteData()
          {
              Type = "INET_DOMAIN",
              Identifier = CUSTOMER_DOMAIN
          };
      
      SiteVerificationWebResourceGettokenRequest request =
          new SiteVerificationWebResourceGettokenRequest()
          {
              VerificationMethod = "DNS_TXT",
              Site = getTokenSite
          };
      
      SiteVerificationWebResourceGettokenResponse getTokenResponse =
          verificationService.WebResource.GetToken(request).Execute();
      Console.WriteLine("Site Verification Token: {0}", getTokenResponse.Token);
      PHP
      // Retrieve the site verification token and place it according to:
      // https://developers.google.com/site-verification/v1/getting_started#tokens
      $body =
      new Google_Service_SiteVerification_SiteVerificationWebResourceGettokenRequest([
        'verificationMethod' => 'DNS_TXT',
        'site' => [
          'type' => 'INET_DOMAIN',
          'identifier' => $CUSTOMER_DOMAIN
        ]
      ]);
      $response = $verificationService->webResource->getToken($body);
      print_r ($response);
      Ruby
      # Retrieve the site verification token and place it according to:
      # https://developers.google.com/site-verification/v1/getting_started#tokens
      request = Google::Apis::SiteVerificationV1::GetWebResourceTokenRequest.new(
        site: {
          type: 'INET_DOMAIN',
          identifier: CUSTOMER_DOMAIN
        },
        verification_method: 'DNS_TXT'
      )
      
      response = verification_service.get_web_resource_token(request)
      puts response.inspect
      Node.js
      /**
       * Retrieve the site verification token and place it according to:
       * https://developers.google.com/site-verification/v1/getting_started#tokens
       */
      const getTokenPromise = verificationService.webResource.getToken({
        requestBody: {
          site: {
            type: 'INET_DOMAIN',
            identifier: CUSTOMER_DOMAIN,
          },
          verificationMethod: 'DNS_TXT',
        }
      }).then(({data}) => {
        console.log(data);
        return data;
      });
    • Pour le type SITE, utilisez l'un des éléments verificationMethod suivants. paramètres:

      • FILE
      • META

      L'exemple de récupération de jetons suivant utilise un type SITE avec le FILE méthode de validation. Lorsque vous utilisez le type de validation SITE, vous devez ajoutez le préfixe http:// ou https:// à l'identifiant.

      Python
      # Retrieve the site verification token and place it according to:
      # https://developers.google.com/site-verification/v1/getting_started#tokens
      response = verification_service.webResource().getToken(
          body={
              'site': {
                  'type': 'SITE',
                  'identifier': CUSTOMER_SITE
              },
              'verificationMethod': 'FILE'
          }).execute()
      print(response)
      Java
      // Retrieve the site verification token and place it according to:
      // https://developers.google.com/site-verification/v1/getting_started#tokens
      SiteVerificationWebResourceGettokenRequest.Site getTokenSite =
          new SiteVerificationWebResourceGettokenRequest.Site()
              .setType("SITE")
              .setIdentifier(CUSTOMER_SITE);
      
      SiteVerificationWebResourceGettokenRequest request =
          new SiteVerificationWebResourceGettokenRequest()
              .setVerificationMethod("FILE")
              .setSite(getTokenSite);
      
      SiteVerificationWebResourceGettokenResponse getTokenResponse =
          verificationService.webResource().getToken(request).execute();
      System.out.println("Site Verification Token: " + getTokenResponse.getToken());
      C#
      // Retrieve the site verification token and place it according to:
      // https://developers.google.com/site-verification/v1/getting_started#tokens
      SiteVerificationWebResourceGettokenRequest.SiteData getTokenSite =
          new SiteVerificationWebResourceGettokenRequest.SiteData()
          {
              Type = "SITE",
              Identifier = CUSTOMER_SITE
          };
      
      SiteVerificationWebResourceGettokenRequest request =
          new SiteVerificationWebResourceGettokenRequest()
          {
              VerificationMethod = "FILE",
              Site = getTokenSite
          };
      
      SiteVerificationWebResourceGettokenResponse getTokenResponse =
          verificationService.WebResource.GetToken(request).Execute();
      Console.WriteLine("Site Verification Token: {0}", getTokenResponse.Token);
      PHP
      // Retrieve the site verification token and place it according to:
      // https://developers.google.com/site-verification/v1/getting_started#tokens
      $body =
      new Google_Service_SiteVerification_SiteVerificationWebResourceGettokenRequest([
        'verificationMethod' => 'FILE',
        'site' => [
          'type' => 'SITE',
          'identifier' => $CUSTOMER_DOMAIN
        ]
      ]);
      $response = $verificationService->webResource->getToken($body);
      print_r($response);
      Ruby
      # Retrieve the site verification token and place it according to:
      # https://developers.google.com/site-verification/v1/getting_started#tokens
      request = Google::Apis::SiteVerificationV1::GetWebResourceTokenRequest.new(
        site: {
          type: 'SITE',
          identifier: CUSTOMER_SITE
        },
        verification_method: 'FILE'
      )
      
      response = verification_service.get_web_resource_token(request)
      puts response.inspect
      Node.js
      /**
       * Retrieve the site verification token and place it according to:
       * https://developers.google.com/site-verification/v1/getting_started#tokens
       */
      const getTokenPromise = verificationService.webResource.getToken({
        requestBody: {
          site: {
            type: 'SITE',
            identifier: CUSTOMER_SITE,
          },
          verificationMethod: 'FILE',
        }
      }).then(({data}) => {
        console.log(data);
        return data;
      });
  2. Placez le jeton de validation de site dans l'enregistrement DNS ou le site.

Créer un client avec l'API Reseller

  1. Utilisez les Customers.Get pour déterminer si un client existe déjà dans Google Workspace:

    Python
    # Determine if customer domain already has Google Workspace
    try:
      response = reseller_service.customers().get(
          customerId=CUSTOMER_DOMAIN).execute()
      print('Customer already exists if call succeeds')
      sys.exit()
    except HttpError as error:
      if int(error.resp['status']) == 404:
        print('Domain available for Google Workspace creation')
      else:
        raise
    Java
    // Determine if customer domain already has Google Workspace
    try {
      resellerService.customers().get(CUSTOMER_DOMAIN).execute();
      System.out.println("Customer already exists if call succeeds");
      System.exit(0);
    } catch (HttpResponseException e) {
        if (e.getStatusCode() == 404) {
          System.out.println("Domain available for Google Workspace creation");
        } else { 
          throw e; 
        }
    }
    C#
    // Determine if customer domain already has Google Workspace
    try
    {
        resellerService.Customers.Get(CUSTOMER_DOMAIN).Execute();
        Console.WriteLine("Customer already exists if call succeeds");
        Environment.Exit(0);
    }
    catch (Google.GoogleApiException e) {
        if (e.Error.Code == 404)
        {
            Console.WriteLine("Domain available for Google Workspace creation");
        } else throw e;
    }
    PHP
    // Determine if customer domain already has Google Workspace
    try {
      $response = $resellerService->customers->get($CUSTOMER_DOMAIN);
      exit('Customer already exists if call succeeds');
    } catch(Google_Service_Exception $e) {
      if ($e->getErrors()[0]['reason'] == 'notFound'){
        print ("Domain available for Google Workspace creation\n");
      } else {
        throw $e;
      }
    }
    Ruby
    # Determine if customer domain already has Google Workspace
    begin
      reseller_service.get_customer(CUSTOMER_DOMAIN)
      abort('Customer already exists if call succeeds')
    rescue Google::Apis::ClientError => ex
      if ex.status_code == 404
        puts 'Domain available for Google Workspace creation'
      else
        raise ex
      end
    end
    Node.js
    // Determine if customer domain already has Google Workspace
    const getCustomerPromise = resellerService.customers.get({
      customerId: CUSTOMER_DOMAIN
    }).then(() => {
      throw new Error('Customer already exists');
    }, resErr => {
      if (resErr.code === 404) {
        console.log('Domain available for Google Workspace creation');
      } else {
        throw resErr;
      }
    });
  2. En fonction de la réponse, procédez comme suit:

    • Si le client n'existe pas, la méthode customers.get renvoie une Code d'erreur HTTP 404. Passez à l'étape suivante, où vous allez créer un que les clients enregistrent dans Google Workspace.

    • Si la méthode customers.get renvoie un résultat sans erreur, déterminez si le client vous appartient en vérifiant le corps de la réponse pour alternateEmail. Si la propriété alternateEmail est manquante, vous devez transférer le client et ses abonnements.

  3. Créez un enregistrement client dans Google Workspace. Vous devez créer un client avant de pouvoir créer des abonnements pour ce client à l'aide de la consignes suivantes:

    • alternateEmail ne peut pas se trouver sur le même domaine que customerDomain.
    • postalAddress.countryCode doit être un pays ISO à deux caractères du code source.

    L'exemple suivant illustre la création d'un enregistrement client:

    Python
    # Create customer resource
    response = reseller_service.customers().insert(
        body={
            'customerDomain': CUSTOMER_DOMAIN,
            'alternateEmail': 'marty.mcfly@gmail.com',
            'postalAddress': {
                'contactName': 'Marty McFly',
                'organizationName': 'Acme Corp',
                'postalCode': '10009',
                'countryCode': 'US',
            }
        }).execute()
    print(response)
    Java
    // Create customer resource
    Address address = new Address()
      .setContactName("Marty McFly")
      .setOrganizationName("Acme Corp")
      .setCountryCode("US")
      .setPostalCode("10009");
    
    Customer customer = new Customer()
      .setCustomerDomain(CUSTOMER_DOMAIN)
      .setAlternateEmail("marty.mcfly@gmail.com")
      .setPostalAddress(address);
    
    Customer customerResponse = resellerService.customers()
      .insert(customer).execute();
    System.out.println("Created Customer:\n" + customerResponse);
    C#
    // Create customer resource
    Address address = new Address()
    {
        ContactName = "Marty McFly",
        OrganizationName = "Acme Corp",
        CountryCode = "US",
        PostalCode = "10009"
    };
    
    Customer customer = new Customer()
    {
        CustomerDomain = CUSTOMER_DOMAIN,
        AlternateEmail = "marty.mcfly@gmail.com",
        PostalAddress = address
    };
    
    Customer customerResponse = resellerService.Customers.Insert(customer).Execute();
    Console.WriteLine("Created Customer:\n{0}", customerResponse);
    PHP
    // Create customer resource
    $customer = new Google_Service_Reseller_Customer([
      'customerDomain' => $CUSTOMER_DOMAIN,
      'alternateEmail' => 'marty.mcfly@gmail.com',
      'postalAddress' => [
        'contactName' => 'Marty McFly',
        'organizationName' => 'Acme Corp',
        'countryCode' => 'US',
        'postalCode' => '10009'
      ]
    ]);
    $response = $resellerService->customers->insert($customer);
    print_r ($response);
    Ruby
    # Create customer resource
    customer = Google::Apis::ResellerV1::Customer.new(
      customer_domain: CUSTOMER_DOMAIN,
      alternate_email: 'marty.mcfly@gmail.com',
      postal_address: {
        contact_name: 'Marty McFly',
        organization_name: 'Acme Corp',
        country_code: 'US',
        postal_code: '10009'})
    
    response = reseller_service.insert_customer(customer)
    puts response.inspect
    Node.js
    // Create customer resource
    const insertCustomerPromise = resellerService.customers.insert({
      requestBody: {
        customerDomain: CUSTOMER_DOMAIN,
        alternateEmail: 'marty.mcfly@gmail.com',
        postalAddress: {
          contactName: 'Marty McFly',
          organizationName: 'Acme Corp',
          postalCode: '10009',
          countryCode: 'US',
        }
      }
    }).then(({data}) => {
      console.log(data);
      return data;
    });

Créer le premier compte administrateur avec l'API SDK Admin

Après avoir provisionné un client, vous devez créer le premier compte utilisateur. attribuer à l'utilisateur le rôle de super-administrateur du domaine pour que le client puisse accéder à leurs nouveaux services et accepter les conditions d'utilisation applicables.

  1. Créez le premier utilisateur et définissez son mot de passe. Les mots de passe doivent être de complexité et doit contenir au moins huit caractères. Pour plus d'informations, consultez les Ressource user.

    Python
    # Create first admin user
    response = directory_service.users().insert(
        body={
            'primaryEmail': 'marty.mcfly@' + CUSTOMER_DOMAIN,
            'name': {
                'givenName': 'Marty',
                'familyName': 'McFly',
            },
            'password': 'Timecircuit88'
        }).execute()
    print(response)
    Java
    // Create first admin user
    String userEmail = "marty.mcfly@" + CUSTOMER_DOMAIN;
    
    UserName name = new UserName();
    name.setGivenName("Marty");
    name.setFamilyName("McFly");
    
    User user = new User();
    user.setPrimaryEmail(userEmail);
    user.setPassword("TimeCircuit88");
    user.setName(name);
    
    User userResponse = directoryService.users().insert(user).execute();
    System.out.println("Created User:\n" + userResponse);
    C#
    // Create first admin user
    String userEmail = "marty.mcfly@" + CUSTOMER_DOMAIN;
    
    UserName name = new UserName()
    {
        GivenName = "Marty",
        FamilyName = "McFly"
    };
    
    User user = new User()
    {
        PrimaryEmail = userEmail,
        Password = "TimeCircuit88",
        Name = name
    };
    
    User userResponse = directoryService.Users.Insert(user).Execute();
    Console.WriteLine("Created User:\n{0}", userResponse);
    PHP
    // Create first admin user
    $user = new Google_Service_Directory_User([
      'primaryEmail' => 'marty.mcfly@' . $CUSTOMER_DOMAIN,
      'password' => 'Timecircuit88',
      'name' => [
        'givenName' => 'Marty',
        'familyName' => 'McFly',
        'fullName' => 'Marty McFly'
      ]
    ]);
    $response = $directoryService->users->insert($user);
    print_r ($response);
    Ruby
    # Create first admin user
    user = Google::Apis::AdminDirectoryV1::User.new(
      name: {
        given_name: 'Marty',
        family_name: 'McFly',
        full_name: 'Marty McFly'
      },
      password: 'Timecircuit88',
      primary_email: 'marty.mcfly@' + CUSTOMER_DOMAIN,
    )
    
    response = directory_service.insert_user(user)
    puts response.inspect
    Node.js
    // Create first admin user
    const insertUserPromise = directoryService.users.insert({
      requestBody: {
        primaryEmail: `marty.mcfly@${CUSTOMER_DOMAIN}`,
        name: {
          givenName: 'Marty',
          familyName: 'McFly',
        },
        password: 'Timecircuit88',
      }
    }).then(({data}) => {
      console.log(data);
      return data;
    });

    Si l'appel pour créer l'utilisateur renvoie un HTTP 409, le nom d'utilisateur peut existent déjà en tant que compte Google personnel.

  2. Attribuez le rôle de super-administrateur à l'utilisateur:

    Python
    # Promote user to admin status
    response = directory_service.users().makeAdmin(
        userKey='marty.mcfly@' + CUSTOMER_DOMAIN, body={
            'status': True
        }).execute()
    Java
    // Promote user to admin status
    UserMakeAdmin admin = new UserMakeAdmin();
    admin.setStatus(true);
    
    directoryService.users().makeAdmin(userEmail, admin).execute();
    System.out.println("User promoted to Admin");
    C#
    // Promote user to admin status
    UserMakeAdmin admin = new UserMakeAdmin()
    {
        Status = true
    };
    directoryService.Users.MakeAdmin(admin, userEmail).Execute();
    Console.WriteLine("User promoted to Admin");
    PHP
    // Promote user to admin status
    $makeAdmin = new Google_Service_Directory_UserMakeAdmin([
      'status' => true
    ]);
    $directoryService->users->makeAdmin(
      'marty.mcfly@' . $CUSTOMER_DOMAIN,
      $makeAdmin
    );
    Ruby
    # Promote user to admin status
    admin_status = Google::Apis::AdminDirectoryV1::UserMakeAdmin.new(
      status: true
    )
    
    response = directory_service.make_user_admin('marty.mcfly@' + CUSTOMER_DOMAIN, admin_status)
    Node.js
    // Promote user to admin status
    const makeAdminPromise = directoryService.users.makeAdmin({
      userKey: `marty.mcfly@${CUSTOMER_DOMAIN}`,
      requestBody: {
        status: true
      }
    });

Créer un abonnement Google Workspace pour un client

Lorsque vous créez un abonnement pour un client, vous devez placer un l'ID de transaction ou l'identifiant de ce client dans le champ purchaseOrderId. Pour en savoir plus sur des arguments et des valeurs spécifiques, consultez Gérer les abonnements

  1. Pour créer un abonnement, utilisez la Subscriptions.Insert . L'exemple suivant utilise un abonnement ANNUAL_YEARLY_PAY:

    Python
    # Create subscription resource
    response = reseller_service.subscriptions().insert(
        customerId=CUSTOMER_DOMAIN,
        body={
            'customerId': CUSTOMER_DOMAIN,
            'skuId': '1010020027',
            'plan': {
                'planName': 'ANNUAL_MONTHLY_PAY',
            },
            'seats': {
                'numberOfSeats': 5,
            },
            'renewalSettings': {  # only relevant for annual plans
                'renewalType': 'RENEW_CURRENT_USERS_MONTHLY_PAY'
            }
        }).execute()
    print(response)
    Java
    // Create subscription resource
    Seats seats = new Seats()
      .setNumberOfSeats(5);
    
    Subscription.Plan plan = new Subscription.Plan()
      .setPlanName("ANNUAL_YEARLY_PAY");
    
    RenewalSettings renewalSettings = new RenewalSettings()
      .setRenewalType("RENEW_CURRENT_USERS_MONTHLY_PAY");
    
    Subscription subscription = new Subscription()
      .setCustomerId(CUSTOMER_DOMAIN)
      .setSeats(seats)
      .setPlan(plan)
      .setSkuId("1010020027")
      .setRenewalSettings(renewalSettings);
    
    Subscription subscriptionResponse = resellerService.subscriptions()
      .insert(CUSTOMER_DOMAIN, subscription).execute();
    System.out.println("Created Subscription:\n" + subscriptionResponse);
    C#
    // Create subscription resource
    Seats seats = new Seats()
    {
        NumberOfSeats = 5
    };
    
    Subscription.PlanData plan = new Subscription.PlanData()
    {
        PlanName = "ANNUAL_YEARLY_PAY"
    };
    
    RenewalSettings renewalSettings = new RenewalSettings()
    {
        RenewalType = "RENEW_CURRENT_USERS_MONTHLY_PAY"
    };
    
    Subscription subscription = new Subscription()
    {
        CustomerId = CUSTOMER_DOMAIN,
        Seats = seats,
        Plan = plan,
        SkuId = "1010020027",
        RenewalSettings = renewalSettings
    };
    
    Subscription subscriptionResponse = resellerService.Subscriptions
        .Insert(subscription, CUSTOMER_DOMAIN).Execute();
    Console.WriteLine("Created Subscription:\n" + subscriptionResponse);
    PHP
    // Create subscription resource
    $subscription = new Google_Service_Reseller_Subscription([
      'customerId' => $CUSTOMER_DOMAIN,
      'skuId' => '1010020027',
      'plan' => [
        'planName' => 'ANNUAL_MONTHLY_PAY'
      ],
      'seats' => [
        'numberOfSeats' => '5'
      ],
      'renewalSettings' => [
        'renewalType' => 'RENEW_CURRENT_USERS_MONTHLY_PAY'
      ]
    ]);
    $response = $resellerService->subscriptions->insert(
      $CUSTOMER_DOMAIN,
      $subscription
    );
    print_r ($response);
    Ruby
    # Create subscription resource
    subscription = Google::Apis::ResellerV1::Subscription.new(
      customer_id: CUSTOMER_DOMAIN,
      sku_id: '1010020027',
      plan: {
        plan_name: 'ANNUAL_MONTHLY_PAY'
      },
      seats: {
        number_of_seats: 5,
      },
      renewal_settings: {
        renewal_type: 'RENEW_CURRENT_USERS_MONTHLY_PAY'
      }
    )
    
    response = reseller_service.insert_subscription(CUSTOMER_DOMAIN, subscription)
    puts response.inspect
    Node.js
    // Create subscription resource
    const insertSubscriptionPromise = resellerService.subscriptions.insert({
      customerId: CUSTOMER_DOMAIN,
      requestBody: {
        customerId: CUSTOMER_DOMAIN,
        skuId: '1010020027',
        plan: {
          planName: 'ANNUAL_MONTHLY_PAY',
        },
        seats: {
          numberOfSeats: 5,
        },
        renewalSettings: { // only relevant for annual plans
          renewalType: 'RENEW_CURRENT_USERS_MONTHLY_PAY',
        }
      }
    }).then(({data}) => {
      console.log(data);
      return data;
    });
  2. Les abonnements sont à l'état SUSPENDED jusqu'à ce qu'un administrateur du client soit administrateur se connecte et accepte les conditions d'utilisation. Les administrateurs du client sont redirigé vers les conditions d'utilisation lors de sa première connexion lorsqu'il accède à propriété Google (par exemple, Gmail ou Google Drive).

Valider le domaine et désigner ses propriétaires

Cette étape est facultative, mais recommandée si vous avez la possibilité de vérifier domaine du client. L'API Site Verification webResource.insert() appelle les deux valide un domaine et lui attribue les propriétaires que vous spécifiez dans le Paramètre owners[] du corps de la requête.

L'exemple suivant montre comment vérifier un INET_DOMAIN:

Python
# Verify domain and designate domain owners
response = verification_service.webResource().insert(
    verificationMethod='DNS_TXT',
    body={
        'site': {
            'type': 'INET_DOMAIN',
            'identifier': CUSTOMER_DOMAIN
        },
        'owners': ['marty.mcfly@' + CUSTOMER_DOMAIN]
    }).execute()
print(response)
Java
// Verify domain and designate domain owners
SiteVerificationWebResourceResource.Site verifySite =
      new SiteVerificationWebResourceResource.Site()
            .setIdentifier(CUSTOMER_DOMAIN)
            .setType("INET_DOMAIN");

List<String> owners = Arrays.asList(userEmail);

SiteVerificationWebResourceResource resource =
  new SiteVerificationWebResourceResource()
        .setSite(verifySite)
        .setOwners(owners);

SiteVerificationWebResourceResource verifyResponse = 
  verificationService.webResource().insert("DNS_TXT", resource).execute();
System.out.println("Site Verification Web Resource:\n" + verifyResponse);
C#
// Verify domain and designate domain owners
SiteVerificationWebResourceResource.SiteData verifySite =
      new SiteVerificationWebResourceResource.SiteData()
      {
          Identifier = CUSTOMER_DOMAIN,
          Type = "INET_DOMAIN"
      };

string[] owners = { userEmail };

SiteVerificationWebResourceResource resource =
  new SiteVerificationWebResourceResource()
  {
      Site = verifySite,
      Owners = owners
  };

SiteVerificationWebResourceResource verifyResponse =
    verificationService.WebResource.Insert(resource, "DNS_TXT").Execute();
Console.WriteLine("Site Verification Web Resource:\n" + verifyResponse);
PHP
// Verify domain and designate domain owners
$body =
new Google_Service_SiteVerification_SiteVerificationWebResourceResource([
  'site' => [
    'type' => 'INET_DOMAIN',
    'identifier' => $CUSTOMER_DOMAIN,
  ],
  'owners' => ['marty.mcfly@' . $CUSTOMER_DOMAIN]
]);

$response = $verificationService->webResource->insert('DNS_TXT', $body);
print_r ($response);
Ruby
# Verify domain and designate domain owners
webResource = Google::Apis::SiteVerificationV1::SiteVerificationWebResourceResource.new(
  site: {
    type: 'INET_DOMAIN',
    identifier: CUSTOMER_DOMAIN
  },
  owners: ['marty.mcfly@' + CUSTOMER_DOMAIN]
)

response = verification_service.insert_web_resource('DNS_TXT', webResource)
puts response.inspect
Node.js
// Verify domain and designate domain owners
const verifyDomainPromise = verificationService.webResource.insert({
  verificationMethod: 'DNS_TXT',
  requestBody: {
    site: {
      type: 'INET_DOMAIN',
      identifier: CUSTOMER_DOMAIN,
    },
    owners: [`marty.mcfly@${CUSTOMER_DOMAIN}`],
  }
}).then(({data}) => {
  console.log(data);
  return data;
});

Si l'appel aboutit, il renvoie un code HTTP 200. Si webResource.insert() ne peut pas valider le domaine, un code d'erreur de niveau HTTP 400 s'affiche. Réessayez la webResource.insert() appel avec un intervalle entre les tentatives, jusqu'à ce que le domaine soit validé.

Regrouper tous les éléments

L'exemple suivant présente le code complet permettant de provisionner Client Google Workspace:

Python
"""This is a basic example of provisioning a Google Workspace customer.
"""
import sys
from apiclient.discovery import build
from apiclient.http import HttpError
from oauth2client.service_account import ServiceAccountCredentials

############## REPLACE WITH YOUR OWN VALUES ####################
JSON_PRIVATE_KEY_FILE = 'path/to/json_key_file.json'
RESELLER_ADMIN_USER = 'admin@yourresellerdomain.com'
CUSTOMER_DOMAIN = 'example.com'
CUSTOMER_SITE = 'https://www.example.com'
################################################################

# Full List of scopes:
# https://developers.google.com/identity/protocols/googlescopes
OAUTH2_SCOPES = [
    'https://reseller.googleapis.com/auth/apps.order',
    'https://reseller.googleapis.com/auth/siteverification',
    'https://reseller.googleapis.com/auth/admin.directory.user',
]

credentials = ServiceAccountCredentials.from_json_keyfile_name(
    JSON_PRIVATE_KEY_FILE, OAUTH2_SCOPES).create_delegated(RESELLER_ADMIN_USER)

reseller_service = build(
    serviceName='reseller', version='v1', credentials=credentials)

directory_service = build(
    serviceName='admin', version='directory_v1', credentials=credentials)

verification_service = build(
    serviceName='siteVerification', version='v1', credentials=credentials)

# Retrieve the site verification token and place it according to:
# https://developers.google.com/site-verification/v1/getting_started#tokens
response = verification_service.webResource().getToken(
    body={
        'site': {
            'type': 'INET_DOMAIN',
            'identifier': CUSTOMER_DOMAIN
        },
        'verificationMethod': 'DNS_TXT'
    }).execute()
print(response)

# Determine if customer domain already has Google Workspace
try:
  response = reseller_service.customers().get(
      customerId=CUSTOMER_DOMAIN).execute()
  print('Customer already exists if call succeeds')
  sys.exit()
except HttpError as error:
  if int(error.resp['status']) == 404:
    print('Domain available for Google Workspace creation')
  else:
    raise

# Create customer resource
response = reseller_service.customers().insert(
    body={
        'customerDomain': CUSTOMER_DOMAIN,
        'alternateEmail': 'marty.mcfly@gmail.com',
        'postalAddress': {
            'contactName': 'Marty McFly',
            'organizationName': 'Acme Corp',
            'postalCode': '10009',
            'countryCode': 'US',
        }
    }).execute()
print(response)

# Create first admin user
response = directory_service.users().insert(
    body={
        'primaryEmail': 'marty.mcfly@' + CUSTOMER_DOMAIN,
        'name': {
            'givenName': 'Marty',
            'familyName': 'McFly',
        },
        'password': 'Timecircuit88'
    }).execute()
print(response)

# Promote user to admin status
response = directory_service.users().makeAdmin(
    userKey='marty.mcfly@' + CUSTOMER_DOMAIN, body={
        'status': True
    }).execute()

# Create subscription resource
response = reseller_service.subscriptions().insert(
    customerId=CUSTOMER_DOMAIN,
    body={
        'customerId': CUSTOMER_DOMAIN,
        'skuId': '1010020027',
        'plan': {
            'planName': 'ANNUAL_MONTHLY_PAY',
        },
        'seats': {
            'numberOfSeats': 5,
        },
        'renewalSettings': {  # only relevant for annual plans
            'renewalType': 'RENEW_CURRENT_USERS_MONTHLY_PAY'
        }
    }).execute()
print(response)

# Verify domain and designate domain owners
response = verification_service.webResource().insert(
    verificationMethod='DNS_TXT',
    body={
        'site': {
            'type': 'INET_DOMAIN',
            'identifier': CUSTOMER_DOMAIN
        },
        'owners': ['marty.mcfly@' + CUSTOMER_DOMAIN]
    }).execute()
print(response)
Java
// OAuth2 and HTTP
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.HttpResponseException;
import com.google.api.client.json.jackson2.JacksonFactory;
// Directory API
import com.google.api.services.admin.directory.Directory;
import com.google.api.services.admin.directory.DirectoryScopes;
import com.google.api.services.admin.directory.model.User;
import com.google.api.services.admin.directory.model.UserMakeAdmin;
import com.google.api.services.admin.directory.model.UserName;
// Reseller API
import com.google.api.services.reseller.Reseller;
import com.google.api.services.reseller.ResellerScopes;
import com.google.api.services.reseller.model.Address;
import com.google.api.services.reseller.model.Customer;
import com.google.api.services.reseller.model.RenewalSettings;
import com.google.api.services.reseller.model.Seats;
import com.google.api.services.reseller.model.Subscription;
// Site Verification API
import com.google.api.services.siteVerification.SiteVerification;
import com.google.api.services.siteVerification.SiteVerificationScopes;
import com.google.api.services.siteVerification.model.SiteVerificationWebResourceGettokenRequest;
import com.google.api.services.siteVerification.model.SiteVerificationWebResourceGettokenResponse;
import com.google.api.services.siteVerification.model.SiteVerificationWebResourceResource;
// Java library imports
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.Arrays;
import java.util.List;

/**
 * This is a basic example of provisioning a Google Workspace customer.
 */
public class CodelabExample {
  // Full List of scopes:
  // https://developers.google.com/identity/protocols/googlescopes
  private static final List<String> OAUTH2_SCOPES = Arrays.asList(
    ResellerScopes.APPS_ORDER,
    SiteVerificationScopes.SITEVERIFICATION,
    DirectoryScopes.ADMIN_DIRECTORY_USER
  );

  /***************** REPLACE WITH YOUR OWN VALUES ********************************/
  public static final String JSON_PRIVATE_KEY_FILE = "path/to/json_key_file.json";
  public static final String RESELLER_ADMIN_USER = "admin@yourresellerdomain.com";
  public static final String CUSTOMER_DOMAIN = "example.com";
  public static final String CUSTOMER_SITE = "https://www.example.com/";
  /*******************************************************************************/

  public static void main(String[] args)
      throws IOException, GeneralSecurityException, FileNotFoundException {
    // Instantiate services with authenticated credentials
    GoogleCredential jsonCredentials = GoogleCredential
      .fromStream(new FileInputStream(JSON_PRIVATE_KEY_FILE));
    GoogleCredential credentials = new GoogleCredential.Builder()
      .setTransport(GoogleNetHttpTransport.newTrustedTransport())
      .setJsonFactory(JacksonFactory.getDefaultInstance())
      .setServiceAccountScopes(OAUTH2_SCOPES)
      .setServiceAccountUser(RESELLER_ADMIN_USER)
      .setServiceAccountPrivateKey(jsonCredentials.getServiceAccountPrivateKey())
      .setServiceAccountId(jsonCredentials.getServiceAccountId())
      .build();

    Reseller resellerService = new Reseller.Builder(
        credentials.getTransport(),
        credentials.getJsonFactory(),
        credentials).setApplicationName("Google Workspace Creator").build();

    Directory directoryService = new Directory.Builder(
        credentials.getTransport(),
        credentials.getJsonFactory(),
        credentials).setApplicationName("Google Workspace Creator").build();

    SiteVerification verificationService = new SiteVerification.Builder(
        credentials.getTransport(),
        credentials.getJsonFactory(),
        credentials).setApplicationName("Google Workspace Creator").build();

    // Retrieve the site verification token and place it according to:
    // https://developers.google.com/site-verification/v1/getting_started#tokens
    SiteVerificationWebResourceGettokenRequest.Site getTokenSite =
        new SiteVerificationWebResourceGettokenRequest.Site()
            .setType("INET_DOMAIN")
            .setIdentifier(CUSTOMER_DOMAIN);

    SiteVerificationWebResourceGettokenRequest request =
        new SiteVerificationWebResourceGettokenRequest()
            .setVerificationMethod("DNS_TXT")
            .setSite(getTokenSite);

    SiteVerificationWebResourceGettokenResponse getTokenResponse =
        verificationService.webResource().getToken(request).execute();
    System.out.println("Site Verification Token: " + getTokenResponse.getToken());

    // Determine if customer domain already has Google Workspace
    try {
      resellerService.customers().get(CUSTOMER_DOMAIN).execute();
      System.out.println("Customer already exists if call succeeds");
      System.exit(0);
    } catch (HttpResponseException e) {
        if (e.getStatusCode() == 404) {
          System.out.println("Domain available for Google Workspace creation");
        } else { 
          throw e; 
        }
    }

    // Create customer resource
    Address address = new Address()
      .setContactName("Marty McFly")
      .setOrganizationName("Acme Corp")
      .setCountryCode("US")
      .setPostalCode("10009");

    Customer customer = new Customer()
      .setCustomerDomain(CUSTOMER_DOMAIN)
      .setAlternateEmail("marty.mcfly@gmail.com")
      .setPostalAddress(address);

    Customer customerResponse = resellerService.customers()
      .insert(customer).execute();
    System.out.println("Created Customer:\n" + customerResponse);

    // Create first admin user
    String userEmail = "marty.mcfly@" + CUSTOMER_DOMAIN;

    UserName name = new UserName();
    name.setGivenName("Marty");
    name.setFamilyName("McFly");

    User user = new User();
    user.setPrimaryEmail(userEmail);
    user.setPassword("TimeCircuit88");
    user.setName(name);

    User userResponse = directoryService.users().insert(user).execute();
    System.out.println("Created User:\n" + userResponse);

    // Promote user to admin status
    UserMakeAdmin admin = new UserMakeAdmin();
    admin.setStatus(true);

    directoryService.users().makeAdmin(userEmail, admin).execute();
    System.out.println("User promoted to Admin");

    // Create subscription resource
    Seats seats = new Seats()
      .setNumberOfSeats(5);

    Subscription.Plan plan = new Subscription.Plan()
      .setPlanName("ANNUAL_YEARLY_PAY");

    RenewalSettings renewalSettings = new RenewalSettings()
      .setRenewalType("RENEW_CURRENT_USERS_MONTHLY_PAY");

    Subscription subscription = new Subscription()
      .setCustomerId(CUSTOMER_DOMAIN)
      .setSeats(seats)
      .setPlan(plan)
      .setSkuId("1010020027")
      .setRenewalSettings(renewalSettings);

    Subscription subscriptionResponse = resellerService.subscriptions()
      .insert(CUSTOMER_DOMAIN, subscription).execute();
    System.out.println("Created Subscription:\n" + subscriptionResponse);

    // Verify domain and designate domain owners
    SiteVerificationWebResourceResource.Site verifySite =
          new SiteVerificationWebResourceResource.Site()
                .setIdentifier(CUSTOMER_DOMAIN)
                .setType("INET_DOMAIN");

    List<String> owners = Arrays.asList(userEmail);

    SiteVerificationWebResourceResource resource =
      new SiteVerificationWebResourceResource()
            .setSite(verifySite)
            .setOwners(owners);

    SiteVerificationWebResourceResource verifyResponse = 
      verificationService.webResource().insert("DNS_TXT", resource).execute();
    System.out.println("Site Verification Web Resource:\n" + verifyResponse);
  }
}
C#
// OAuth2 and HTTP
using Google.Apis.Auth.OAuth2;
using Google.Apis.Services;
// Reseller API
using Google.Apis.Reseller.v1;
using Google.Apis.Reseller.v1.Data;
// Directory API
using Google.Apis.Admin.Directory.directory_v1;
using User = Google.Apis.Admin.Directory.directory_v1.Data.User;
using UserName = Google.Apis.Admin.Directory.directory_v1.Data.UserName;
using UserMakeAdmin = Google.Apis.Admin.Directory.directory_v1.Data.UserMakeAdmin;
//Site Verification API
using Google.Apis.SiteVerification.v1;
using Google.Apis.SiteVerification.v1.Data;
// System imports
using System;
using System.IO;

class CodelabExample
{
    // Full List of scopes:
    // https://developers.google.com/identity/protocols/googlescopes
    static string[] OAUTH2_SCOPES = {
        ResellerService.Scope.AppsOrder,
        DirectoryService.Scope.AdminDirectoryUser,
        SiteVerificationService.Scope.Siteverification
    };

    /***************** REPLACE WITH YOUR OWN VALUES ********************************/
    public static String JSON_PRIVATE_KEY_FILE = "path/to/json_key_file.json";
    public static String RESELLER_ADMIN_USER = "admin@yourresellerdomain.com";
    public static String CUSTOMER_DOMAIN = "example.com";
    public static String CUSTOMER_SITE = "https://www.example.com/";
    /*******************************************************************************/

    static void Main(string[] args)
    {
        GoogleCredential credential;

        using (var stream = new FileStream(JSON_PRIVATE_KEY_FILE, FileMode.Open, FileAccess.Read))
        {
            credential = GoogleCredential
                .FromStream(stream)
                .CreateScoped(OAUTH2_SCOPES)
                .CreateWithUser(RESELLER_ADMIN_USER);
        }

        var resellerService = new ResellerService(new BaseClientService.Initializer()
        {
            HttpClientInitializer = credential,
        });

        var directoryService = new DirectoryService(new BaseClientService.Initializer()
        {
            HttpClientInitializer = credential,
        });

        var verificationService = new SiteVerificationService(new BaseClientService.Initializer()
        {
            HttpClientInitializer = credential,
        });

        // Retrieve the site verification token and place it according to:
        // https://developers.google.com/site-verification/v1/getting_started#tokens
        SiteVerificationWebResourceGettokenRequest.SiteData getTokenSite =
            new SiteVerificationWebResourceGettokenRequest.SiteData()
            {
                Type = "INET_DOMAIN",
                Identifier = CUSTOMER_DOMAIN
            };

        SiteVerificationWebResourceGettokenRequest request =
            new SiteVerificationWebResourceGettokenRequest()
            {
                VerificationMethod = "DNS_TXT",
                Site = getTokenSite
            };

        SiteVerificationWebResourceGettokenResponse getTokenResponse =
            verificationService.WebResource.GetToken(request).Execute();
        Console.WriteLine("Site Verification Token: {0}", getTokenResponse.Token);

        // Determine if customer domain already has Google Workspace
        try
        {
            resellerService.Customers.Get(CUSTOMER_DOMAIN).Execute();
            Console.WriteLine("Customer already exists if call succeeds");
            Environment.Exit(0);
        }
        catch (Google.GoogleApiException e) {
            if (e.Error.Code == 404)
            {
                Console.WriteLine("Domain available for Google Workspace creation");
            } else throw e;
        }

        // Create customer resource
        Address address = new Address()
        {
            ContactName = "Marty McFly",
            OrganizationName = "Acme Corp",
            CountryCode = "US",
            PostalCode = "10009"
        };

        Customer customer = new Customer()
        {
            CustomerDomain = CUSTOMER_DOMAIN,
            AlternateEmail = "marty.mcfly@gmail.com",
            PostalAddress = address
        };

        Customer customerResponse = resellerService.Customers.Insert(customer).Execute();
        Console.WriteLine("Created Customer:\n{0}", customerResponse);

        // Create first admin user
        String userEmail = "marty.mcfly@" + CUSTOMER_DOMAIN;

        UserName name = new UserName()
        {
            GivenName = "Marty",
            FamilyName = "McFly"
        };

        User user = new User()
        {
            PrimaryEmail = userEmail,
            Password = "TimeCircuit88",
            Name = name
        };

        User userResponse = directoryService.Users.Insert(user).Execute();
        Console.WriteLine("Created User:\n{0}", userResponse);

        // Promote user to admin status
        UserMakeAdmin admin = new UserMakeAdmin()
        {
            Status = true
        };
        directoryService.Users.MakeAdmin(admin, userEmail).Execute();
        Console.WriteLine("User promoted to Admin");

        // Create subscription resource
        Seats seats = new Seats()
        {
            NumberOfSeats = 5
        };

        Subscription.PlanData plan = new Subscription.PlanData()
        {
            PlanName = "ANNUAL_YEARLY_PAY"
        };

        RenewalSettings renewalSettings = new RenewalSettings()
        {
            RenewalType = "RENEW_CURRENT_USERS_MONTHLY_PAY"
        };

        Subscription subscription = new Subscription()
        {
            CustomerId = CUSTOMER_DOMAIN,
            Seats = seats,
            Plan = plan,
            SkuId = "1010020027",
            RenewalSettings = renewalSettings
        };

        Subscription subscriptionResponse = resellerService.Subscriptions
            .Insert(subscription, CUSTOMER_DOMAIN).Execute();
        Console.WriteLine("Created Subscription:\n" + subscriptionResponse);

        // Verify domain and designate domain owners
        SiteVerificationWebResourceResource.SiteData verifySite =
              new SiteVerificationWebResourceResource.SiteData()
              {
                  Identifier = CUSTOMER_DOMAIN,
                  Type = "INET_DOMAIN"
              };

        string[] owners = { userEmail };

        SiteVerificationWebResourceResource resource =
          new SiteVerificationWebResourceResource()
          {
              Site = verifySite,
              Owners = owners
          };

        SiteVerificationWebResourceResource verifyResponse =
            verificationService.WebResource.Insert(resource, "DNS_TXT").Execute();
        Console.WriteLine("Site Verification Web Resource:\n" + verifyResponse);
    }
}
PHP
// https://developers.google.com/api-client-library/php/
require_once 'vendor/autoload.php';

// Full List of scopes:
// https://developers.google.com/identity/protocols/googlescopes
$OAUTH2_SCOPES = [
  Google_Service_Reseller::APPS_ORDER,
  Google_Service_SiteVerification::SITEVERIFICATION,
  Google_Service_Directory::ADMIN_DIRECTORY_USER,
];

######### REPLACE WITH YOUR OWN VALUES ###############
$JSON_PRIVATE_KEY_FILE = 'path/to/json_key_file.json';
$RESELLER_ADMIN_USER = 'admin@yourresellerdomain.com';
$CUSTOMER_DOMAIN = 'example.com';
$CUSTOMER_SITE = 'https://www.example.com/';
######################################################

$client = new Google_Client();
$client->setAuthConfig($JSON_PRIVATE_KEY_FILE);
$client->setSubject($RESELLER_ADMIN_USER);
$client->setScopes($OAUTH2_SCOPES);

$resellerService = new Google_Service_Reseller($client);
$directoryService = new Google_Service_Directory($client);
$verificationService = new Google_Service_SiteVerification($client);

// Retrieve the site verification token and place it according to:
// https://developers.google.com/site-verification/v1/getting_started#tokens
$body =
new Google_Service_SiteVerification_SiteVerificationWebResourceGettokenRequest([
  'verificationMethod' => 'DNS_TXT',
  'site' => [
    'type' => 'INET_DOMAIN',
    'identifier' => $CUSTOMER_DOMAIN
  ]
]);
$response = $verificationService->webResource->getToken($body);
print_r ($response);

// Determine if customer domain already has Google Workspace
try {
  $response = $resellerService->customers->get($CUSTOMER_DOMAIN);
  exit('Customer already exists if call succeeds');
} catch(Google_Service_Exception $e) {
  if ($e->getErrors()[0]['reason'] == 'notFound'){
    print ("Domain available for Google Workspace creation\n");
  } else {
    throw $e;
  }
}

// Create customer resource
$customer = new Google_Service_Reseller_Customer([
  'customerDomain' => $CUSTOMER_DOMAIN,
  'alternateEmail' => 'marty.mcfly@gmail.com',
  'postalAddress' => [
    'contactName' => 'Marty McFly',
    'organizationName' => 'Acme Corp',
    'countryCode' => 'US',
    'postalCode' => '10009'
  ]
]);
$response = $resellerService->customers->insert($customer);
print_r ($response);

// Create first admin user
$user = new Google_Service_Directory_User([
  'primaryEmail' => 'marty.mcfly@' . $CUSTOMER_DOMAIN,
  'password' => 'Timecircuit88',
  'name' => [
    'givenName' => 'Marty',
    'familyName' => 'McFly',
    'fullName' => 'Marty McFly'
  ]
]);
$response = $directoryService->users->insert($user);
print_r ($response);

// Promote user to admin status
$makeAdmin = new Google_Service_Directory_UserMakeAdmin([
  'status' => true
]);
$directoryService->users->makeAdmin(
  'marty.mcfly@' . $CUSTOMER_DOMAIN,
  $makeAdmin
);

// Create subscription resource
$subscription = new Google_Service_Reseller_Subscription([
  'customerId' => $CUSTOMER_DOMAIN,
  'skuId' => '1010020027',
  'plan' => [
    'planName' => 'ANNUAL_MONTHLY_PAY'
  ],
  'seats' => [
    'numberOfSeats' => '5'
  ],
  'renewalSettings' => [
    'renewalType' => 'RENEW_CURRENT_USERS_MONTHLY_PAY'
  ]
]);
$response = $resellerService->subscriptions->insert(
  $CUSTOMER_DOMAIN,
  $subscription
);
print_r ($response);

// Verify domain and designate domain owners
$body =
new Google_Service_SiteVerification_SiteVerificationWebResourceResource([
  'site' => [
    'type' => 'INET_DOMAIN',
    'identifier' => $CUSTOMER_DOMAIN,
  ],
  'owners' => ['marty.mcfly@' . $CUSTOMER_DOMAIN]
]);

$response = $verificationService->webResource->insert('DNS_TXT', $body);
print_r ($response);
Ruby
require 'googleauth'
require 'google/apis/reseller_v1'
require 'google/apis/site_verification_v1'
require 'google/apis/admin_directory_v1'

# Full List of scopes:
# https://developers.google.com/identity/protocols/googlescopes
OAUTH2_SCOPES = [
  'https://reseller.googleapis.com/auth/apps.order',
  'https://reseller.googleapis.com/auth/admin.directory.user',
  'https://reseller.googleapis.com/auth/siteverification',
]

####### REPLACE WITH YOUR OWN VALUES ###############
JSON_PRIVATE_KEY_FILE = 'path/to/json_key_file.json'
RESELLER_ADMIN_USER = 'admin@yourresellerdomain.com'
CUSTOMER_DOMAIN = 'example.com'
CUSTOMER_SITE = 'https://www.example.com/'
####################################################

credentials = Google::Auth::ServiceAccountCredentials.make_creds(
  json_key_io: File.open(JSON_PRIVATE_KEY_FILE),
  scope: OAUTH2_SCOPES)
credentials.sub = RESELLER_ADMIN_USER

Google::Apis::RequestOptions.default.authorization = credentials

reseller_service = Google::Apis::ResellerV1::ResellerService.new
directory_service = Google::Apis::AdminDirectoryV1::DirectoryService.new
verification_service = Google::Apis::SiteVerificationV1::SiteVerificationService.new

# Retrieve the site verification token and place it according to:
# https://developers.google.com/site-verification/v1/getting_started#tokens
request = Google::Apis::SiteVerificationV1::GetWebResourceTokenRequest.new(
  site: {
    type: 'INET_DOMAIN',
    identifier: CUSTOMER_DOMAIN
  },
  verification_method: 'DNS_TXT'
)

response = verification_service.get_web_resource_token(request)
puts response.inspect

# Determine if customer domain already has Google Workspace
begin
  reseller_service.get_customer(CUSTOMER_DOMAIN)
  abort('Customer already exists if call succeeds')
rescue Google::Apis::ClientError => ex
  if ex.status_code == 404
    puts 'Domain available for Google Workspace creation'
  else
    raise ex
  end
end

# Create customer resource
customer = Google::Apis::ResellerV1::Customer.new(
  customer_domain: CUSTOMER_DOMAIN,
  alternate_email: 'marty.mcfly@gmail.com',
  postal_address: {
    contact_name: 'Marty McFly',
    organization_name: 'Acme Corp',
    country_code: 'US',
    postal_code: '10009'})

response = reseller_service.insert_customer(customer)
puts response.inspect

# Create first admin user
user = Google::Apis::AdminDirectoryV1::User.new(
  name: {
    given_name: 'Marty',
    family_name: 'McFly',
    full_name: 'Marty McFly'
  },
  password: 'Timecircuit88',
  primary_email: 'marty.mcfly@' + CUSTOMER_DOMAIN,
)

response = directory_service.insert_user(user)
puts response.inspect

# Promote user to admin status
admin_status = Google::Apis::AdminDirectoryV1::UserMakeAdmin.new(
  status: true
)

response = directory_service.make_user_admin('marty.mcfly@' + CUSTOMER_DOMAIN, admin_status)

# Create subscription resource
subscription = Google::Apis::ResellerV1::Subscription.new(
  customer_id: CUSTOMER_DOMAIN,
  sku_id: '1010020027',
  plan: {
    plan_name: 'ANNUAL_MONTHLY_PAY'
  },
  seats: {
    number_of_seats: 5,
  },
  renewal_settings: {
    renewal_type: 'RENEW_CURRENT_USERS_MONTHLY_PAY'
  }
)

response = reseller_service.insert_subscription(CUSTOMER_DOMAIN, subscription)
puts response.inspect

# Verify domain and designate domain owners
webResource = Google::Apis::SiteVerificationV1::SiteVerificationWebResourceResource.new(
  site: {
    type: 'INET_DOMAIN',
    identifier: CUSTOMER_DOMAIN
  },
  owners: ['marty.mcfly@' + CUSTOMER_DOMAIN]
)

response = verification_service.insert_web_resource('DNS_TXT', webResource)
puts response.inspect
Node.js
// NOTE: This script needs googleapis 28.0.0 or later as it uses promises
const {google} = require('googleapis');

// ############## REPLACE WITH YOUR OWN VALUES ####################
const JSON_PRIVATE_KEY_FILE = 'path/to/json_key_file.json';
const RESELLER_ADMIN_USER = 'admin@yourresellerdomain.com';
const CUSTOMER_DOMAIN = 'example.com';
const CUSTOMER_SITE = 'https://www.example.com/';
// ################################################################

// Full List of scopes: https://developers.google.com/identity/protocols/googlescopes
const OAUTH2_SCOPES = [
  'https://reseller.googleapis.com/auth/apps.order',
  'https://reseller.googleapis.com/auth/siteverification',
  'https://reseller.googleapis.com/auth/admin.directory.user',
];

const authJWT = new google.auth.JWT({
  keyFile: JSON_PRIVATE_KEY_FILE,
  scopes: OAUTH2_SCOPES,
  subject: RESELLER_ADMIN_USER,
});

const resellerService = google.reseller({version: 'v1', auth: authJWT});
const directoryService = google.admin({version: 'directory_v1', auth: authJWT});
const verificationService = google.siteVerification({version: 'v1', auth: authJWT});

// Run all the steps one after each other, and exit as soon as one of them fail
Promise.resolve()
  .then(() => {
    /**
     * Retrieve the site verification token and place it according to:
     * https://developers.google.com/site-verification/v1/getting_started#tokens
     */
    const getTokenPromise = verificationService.webResource.getToken({
      requestBody: {
        site: {
          type: 'INET_DOMAIN',
          identifier: CUSTOMER_DOMAIN,
        },
        verificationMethod: 'DNS_TXT',
      }
    }).then(({data}) => {
      console.log(data);
      return data;
    });


    return getTokenPromise;
  })
  .then(() => {
    // Determine if customer domain already has Google Workspace
    const getCustomerPromise = resellerService.customers.get({
      customerId: CUSTOMER_DOMAIN
    }).then(() => {
      throw new Error('Customer already exists');
    }, resErr => {
      if (resErr.code === 404) {
        console.log('Domain available for Google Workspace creation');
      } else {
        throw resErr;
      }
    });

    return getCustomerPromise;
  })
  .then(() => {
    // Create customer resource
    const insertCustomerPromise = resellerService.customers.insert({
      requestBody: {
        customerDomain: CUSTOMER_DOMAIN,
        alternateEmail: 'marty.mcfly@gmail.com',
        postalAddress: {
          contactName: 'Marty McFly',
          organizationName: 'Acme Corp',
          postalCode: '10009',
          countryCode: 'US',
        }
      }
    }).then(({data}) => {
      console.log(data);
      return data;
    });

    return insertCustomerPromise;
  })
  .then(() => {
    // Create first admin user
    const insertUserPromise = directoryService.users.insert({
      requestBody: {
        primaryEmail: `marty.mcfly@${CUSTOMER_DOMAIN}`,
        name: {
          givenName: 'Marty',
          familyName: 'McFly',
        },
        password: 'Timecircuit88',
      }
    }).then(({data}) => {
      console.log(data);
      return data;
    });

    return insertUserPromise;
  }).then(() => {
    // Promote user to admin status
    const makeAdminPromise = directoryService.users.makeAdmin({
      userKey: `marty.mcfly@${CUSTOMER_DOMAIN}`,
      requestBody: {
        status: true
      }
    });

    return makeAdminPromise;
  })
  .then(() => {
    // Create subscription resource
    const insertSubscriptionPromise = resellerService.subscriptions.insert({
      customerId: CUSTOMER_DOMAIN,
      requestBody: {
        customerId: CUSTOMER_DOMAIN,
        skuId: '1010020027',
        plan: {
          planName: 'ANNUAL_MONTHLY_PAY',
        },
        seats: {
          numberOfSeats: 5,
        },
        renewalSettings: { // only relevant for annual plans
          renewalType: 'RENEW_CURRENT_USERS_MONTHLY_PAY',
        }
      }
    }).then(({data}) => {
      console.log(data);
      return data;
    });

    return insertSubscriptionPromise;
  })
  .then(() => {
    // Verify domain and designate domain owners
    const verifyDomainPromise = verificationService.webResource.insert({
      verificationMethod: 'DNS_TXT',
      requestBody: {
        site: {
          type: 'INET_DOMAIN',
          identifier: CUSTOMER_DOMAIN,
        },
        owners: [`marty.mcfly@${CUSTOMER_DOMAIN}`],
      }
    }).then(({data}) => {
      console.log(data);
      return data;
    });

    return verifyDomainPromise;
  })
  .catch(err => {
    console.error('Error:', err.message);
    if (err.code) {
      console.log('Error code:', err.code);
    }
    if (err.errors) {
      console.log('Details:', err.errors);
    }
  });