Bir müşterinin temel hazırlığını yapın

Bu eğiticide, Bayi API'sini kullanarak bir müşterinin temel hazırlığını nasıl yapacağınız gösterilmektedir.

Müşterinin temel hazırlığı, Google Workspace platformundaki birden fazla API'ye yayılan, birbirine bağlı birkaç adımdan oluşur.

Google Workspace müşterisi oluşturmak için kullanılan API'lerin akışı.
Şekil 1. Google Workspace müşterilerinin temel hazırlığını yapmayla ilgili üst düzey adımlar

Yukarıdaki şemada, müşteriye temel hazırlığın her adımda hangi API'lerin kullanıldığı gösterilmektedir:

  • Alan doğrulama jetonunu yerleştirmek için Site Verification API'yi kullanın.
  • Müşteri oluşturmak için Bayi API'sini kullanın.
  • İlk kullanıcıyı oluşturmak ve yönetici yapmak için Directory API'yi kullanın.
  • Abonelik oluşturmak için Bayi API'sini kullanın.
  • Alanı doğrulamak için Site Verification API'yi kullanma.

Ön koşullar

  • Bir Google Bayisi alanı örneği.
  • Eksiksiz şekilde akdedilmiş bir Google Workspace iş ortağı sözleşmesi.

Ortamınızı ayarlama

Bu eğiticiyi tamamlamak için ortamınızı ayarlayın.

API'yi etkinleştirme

Google API'lerini kullanmadan önce bunları bir Google Cloud projesinde etkinleştirmeniz gerekir. Tek bir Google Cloud projesinde bir veya daha fazla API etkinleştirebilirsiniz.
  • Google Cloud konsolunda Reseller API, Site Verification API ve Admin SDK API'yi etkinleştirin .

    APIS'yi etkinleştirme

Hizmet hesabı oluşturma

Hizmet hesabı, bir kişi yerine uygulama tarafından kullanılan özel bir hesap türüdür. Verilere erişmek veya robot hesabı tarafından işlem gerçekleştirmek ya da Google Workspace veya Cloud Identity kullanıcıları adına verilere erişmek için bir hizmet hesabı kullanabilirsiniz. Daha fazla bilgi için Hizmet hesaplarını anlama bölümüne bakın.

Google Cloud Console

  1. Google Cloud konsolunda Menü > IAM ve Yönetici > Hizmet Hesapları'na gidin.

    Hizmet Hesapları'na git

  2. Hizmet hesabı oluştur'u tıklayın.
  3. Hizmet hesabı ayrıntılarını girip Oluştur ve devam et'i tıklayın.
  4. İsteğe bağlı: Google Cloud projenizin kaynaklarına erişim izni vermek için hizmet hesabınıza roller atayın. Daha fazla bilgi için Kaynaklara erişim izni verme, erişimi değiştirme ve iptal etme başlıklı makaleyi inceleyin.
  5. Devam'ı tıklayın.
  6. İsteğe bağlı: Bu hizmet hesabını yönetebilen ve işlem gerçekleştirebilecek kullanıcıları veya grupları girin. Daha fazla bilgi için Hizmet hesabı kimliğine bürünmeyi yönetme başlıklı makaleye bakın.
  7. Done'ı (Bitti) tıklayın. Hizmet hesabının e-posta adresini not edin.

gcloud CLI

  1. Hizmet hesabını oluşturun:
    gcloud iam service-accounts create SERVICE_ACCOUNT_NAME \
      --display-name="SERVICE_ACCOUNT_NAME"
  2. İsteğe bağlı: Google Cloud projenizin kaynaklarına erişim izni vermek için hizmet hesabınıza roller atayın. Daha fazla bilgi için Kaynaklara erişim izni verme, erişimi değiştirme ve iptal etme başlıklı makaleyi inceleyin.

Bir hizmet hesabı için kimlik bilgileri oluşturma

Kimlik bilgilerini herkese açık/özel anahtar çifti şeklinde almanız gerekir. Bu kimlik bilgileri, kodunuz tarafından uygulamanızdaki hizmet hesabı işlemlerini yetkilendirmek için kullanılır.
  1. Google Cloud konsolunda Menü > IAM ve Yönetici > Hizmet Hesapları'na gidin.

    Hizmet Hesapları'na git

  2. Hizmet hesabınızı seçin.
  3. Anahtarlar > Anahtar ekle > Yeni anahtar oluştur'u tıklayın.
  4. JSON'u seçip Oluştur'u tıklayın.

    Yeni herkese açık/özel anahtar çiftiniz oluşturulur ve yeni bir dosya olarak makinenize indirilir. İndirilen JSON dosyasını çalışma dizininize credentials.json olarak kaydedin. Dosya, bu anahtarın tek kopyasıdır. Anahtarınızı güvenli bir şekilde nasıl saklayacağınız hakkında bilgi edinmek için Hizmet hesabı anahtarlarını yönetme konusuna bakın.

  5. Close'u (Kapat) tıklayın.

Bir hizmet hesabı için alan genelinde yetki ayarlarını yapma

Bir Google Workspace kuruluşundaki kullanıcılar adına API'leri çağırmak için hizmet hesabınıza bir süper yönetici hesabı tarafından Google Workspace Yönetici Konsolu'nda alan genelinde yetki yetkisi verilmesi gerekir. Daha fazla bilgi için Bir hizmet hesabına alan genelinde yetki verme sayfasını inceleyin.
  1. Google Cloud konsolunda Menü > IAM ve Yönetici > Hizmet Hesapları'na gidin.

    Hizmet Hesapları'na git

  2. Hizmet hesabınızı seçin.
  3. Gelişmiş ayarları göster'i tıklayın.
  4. "Alan genelinde yetki" bölümünde hizmet hesabınızın "İstemci Kimliği"ni bulun. Kopyala'yı tıklayarak istemci kimliği değerini panonuza kopyalayın.
  5. İlgili Google Workspace hesabına süper yönetici erişiminiz varsa Google Workspace Yönetici Konsolu'nu Göster'i tıklayın, ardından süper yönetici kullanıcı hesabı kullanarak oturum açın ve bu adımları uygulamaya devam edin.

    İlgili Google Workspace hesabına süper yönetici erişiminiz yoksa hesabın süper yöneticilerinden biriyle iletişime geçip hizmet hesabınızın İstemci Kimliği'ni ve OAuth Kapsamları listesini kendisine göndererek Yönetici Konsolu'nda aşağıdaki adımları tamamlamasını isteyin.

    1. Google Yönetici Konsolu'nda Menü > Güvenlik > Erişim ve veri denetimi > API denetimleri'ne gidin.

      API denetimlerine git

    2. Alan Genelinde Yetkiyi Yönet'i tıklayın.
    3. Yeni ekle'yi tıklayın.
    4. Daha önce kopyaladığınız istemci kimliğini "İstemci Kimliği" alanına yapıştırın.
    5. "OAuth Kapsamları" alanına, uygulamanızın gerektirdiği kapsamların virgülle ayrılmış listesini girin. Bu, OAuth izin ekranını yapılandırırken tanımladığınız kapsam grubuyla aynıdır.
    6. Yetkilendir'i tıklayın.

Kimliği doğrulanmış kimlik bilgileriyle hizmet nesneleri oluşturma

Herhangi bir Google API'sini kullanmaya başlamak için öncelikle uygulamanızın içinden kimlik doğrulama ve kimlik bilgilerini ayarlamanız gerekir. Google İstemci Kitaplıkları bu işlemi sizin adınıza gerçekleştirir. Tüm kitaplıklarda kimlik bilgisi nesnesi oluşturmak için kalıplar bulunur. Bu kalıpları, tüm API'lere erişim izni verebilir ve her bir hizmete geçirebilirsiniz. Uygulamalar genellikle tek bir kimlik bilgisi grubuna sahip olmalı ve tüm Google API etkileşimleri için yalnızca bir bulut projesi kullanmalıdır.

Hizmet hesabı oluştururken oluşturduğunuz JSON anahtar dosyasını kullanın.

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});

Alan doğrulama işlemine başlama

Bu adım isteğe bağlıdır, ancak müşterinin alanını doğrulayabiliyorsanız önerilir. Bu adım, alanı doğrulamanızın ardından eğiticinin sonunda tamamlanır.

Müşterinin alanını doğrulamazsanız müşteri aşağıdaki kısıtlamalara tabi olur:

  • Kullanıcılar, yalnızca manuel alan doğrulaması süreci konusunda kendilerine yönlendirildikleri Yönetici Konsolu'na erişebilirler.
  • Oluşturulduktan 21 gün sonra askıya alınabilirler.

Site doğrulama jetonu almak için aşağıdakileri yapın:

  1. Site doğrulama jetonu almak için Site Verification API'yi kullanın. Bir alanın daha önce doğrulanıp doğrulanmadığını doğrulayamazsınız ancak siteleri herhangi bir sorun yaşamadan birden fazla kez doğrulayabilirsiniz. INET_DOMAIN veya SITE türünü doğruladığınıza bağlı olarak verificationMethod parametreleri değişiklik gösterir. Aşağıdakilerden birini seçin:

    • INET_DOMAIN türü için aşağıdaki verificationMethod parametrelerinden birini kullanın:

      • DNS_TXT
      • DNS_CNAME

      Aşağıdaki jeton alma örneği INET_DOMAIN türü kullanır:

      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;
      });
    • SITE türü için aşağıdaki verificationMethod parametrelerinden birini kullanın:

      • FILE
      • META

      Aşağıdaki jeton alma örneği, FILE doğrulama yöntemiyle bir SITE türü kullanır. SITE doğrulama türünü kullandığınızda tanımlayıcının önüne http:// veya https:// eklemeniz gerekir.

      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. Site doğrulama jetonunu DNS kaydına veya sitesine yerleştirin.

Bayi API'si ile müşteri oluşturma

  1. Bir müşterinin zaten Google Workspace'te olup olmadığını belirlemek için Customers.Get yöntemini kullanın:

    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. Yanıta bağlı olarak aşağıdakileri yapın:

    • Müşteri mevcut değilse customers.get yöntemi, HTTP 404 hata kodu döndürür. Google Workspace'te müşteri kaydı oluşturduğunuz bir sonraki adıma geçin.

    • customers.get yöntemi hatasız döndürülürse alternateEmail özelliğinin yanıt gövdesini kontrol ederek müşterinin size ait olup olmadığını belirleyin. alternateEmail özelliği yoksa müşteriyi ve aboneliklerini aktarmanız gerekir.

  3. Google Workspace'te müşteri kaydı oluşturun. Aşağıdaki yönergeleri kullanarak söz konusu müşteri için abonelik oluşturmadan önce müşteri kaydı oluşturmanız gerekir:

    • alternateEmail, customerDomain ile aynı alanda olamaz.
    • postalAddress.countryCode, iki karakterli bir ISO ülke kodu olmalıdır.

    Aşağıdaki örnekte bir müşteri kaydı oluşturma işlemi gösterilmektedir:

    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;
    });

Admin SDK API ile ilk yönetici kullanıcıyı oluşturma

Bir müşterinin temel hazırlığını yaptıktan sonra ilk kullanıcıyı oluşturmanız ve müşterinin yeni hizmetlerine erişebilmesi ve geçerli tüm Hizmet Şartları'nı kabul edebilmesi için kullanıcıyı hemen alan süper yöneticisi düzeyine yükseltmeniz gerekir.

  1. İlk kullanıcıyı oluşturun ve şifresini belirleyin. Şifreler yeterli düzeyde karmaşıklık sağlamalı ve en az sekiz karakter içermelidir. Daha fazla bilgi için user kaynağını inceleyin.

    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;
    });

    Kullanıcıyı oluşturma çağrısı HTTP 409 döndürürse kullanıcı adı zaten bir tüketici Google Hesabı olarak var olabilir.

  2. Kullanıcıyı süper yönetici rolüne yükseltin:

    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
      }
    });

Müşteri için Google Workspace aboneliği oluşturma

Bir müşteri için abonelik oluşturduğunuzda, purchaseOrderId alanına bu müşteriyle ilgili bir dahili işlem kimliği veya tanımlayıcı yerleştirmeniz gerekir. Belirli bağımsız değişkenler ve değerler hakkında daha fazla bilgi için Abonelikleri yönetme bölümüne bakın.

  1. Abonelik oluşturmak için Subscriptions.Insert çağrısını kullanın. Aşağıdaki örnekte ANNUAL_YEARLY_PAY aboneliği kullanılmaktadır:

    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. Bir müşteri yöneticisi giriş yapıp Hizmet Şartları'nı kabul edene kadar abonelikler SUSPENDED durumunda kalır. Müşteri yöneticileri, herhangi bir Google mülküne (örneğin, Gmail veya Google Drive) eriştiklerinde ilk girişlerinde Hizmet Şartları'na yönlendirilir.

Alanı doğrulama ve alan sahiplerini belirleme

Bu adım isteğe bağlıdır, ancak müşterinin alanını doğrulayabiliyorsanız önerilir. Site Verification API webResource.insert() çağrısı, hem bir alanı doğrular hem de istek gövdesinin owners[] parametresinde belirttiğiniz sahipleri alan adına atar.

Aşağıdaki örnekte, bir INET_DOMAIN öğesinin nasıl doğrulanacağı gösterilmektedir:

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;
});

Başarılı olursa bu çağrı bir HTTP 200 kodu döndürür. webResource.insert(), alanı doğrulayamazsa HTTP 400 düzeyinde bir hata kodu döndürür. Alan başarıyla doğrulanana kadar, webResource.insert() aramasını geri yükleme gecikmesiyle yeniden deneyin.

Her şeyi bir araya getirin

Aşağıdaki örnekte, Google Workspace müşterilerinin temel hazırlığını yapmak için gereken kodun tamamı gösterilmektedir:

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);
    }
  });