> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stigg.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Customer management

> Provision, update, retrieve, and archive customers using Stigg backend SDKs.

## Customer management

### Provisioning customers

When a new customer is provisioned in your application (for example, during registration or onboarding), you should also provision them in Stigg.

You provide the customer's unique identifier, and optionally their name, billing email address, a coupon to apply, initial subscription parameters, billing and shipping addresses (including tax IDs and payment method), and arbitrary metadata.

<Note>
  To control the customer's initial access to a product according to the [product's Customer Journey settings](/documentation/modeling-your-pricing-in-stigg/products#defining-the-customer-journey), initial subscription parameters must be provided. To provision a customer without any default subscription, explicitly pass no subscription parameters.
</Note>

<Note>
  Passing billing information will cause the customer to be synced to the integrated billing solution even if they don't have any paid subscriptions. Billing information is not persisted on Stigg's servers.
</Note>

<CodeGroup>
  ```javascript Node.js theme={null}
  const customer = await stiggClient.provisionCustomer({
      customerId: 'customer-test-id',
      name: 'My very first customer', // optional
      email: 'john@example.com',      // optional - billing email address
      couponId: 'coupon-test-id',     // optional
      subscriptionParams: {           // optional - pass null to skip initial subscription
        planId: 'plan-basic',
        resourceId: 'resource-01',      // optional, required for multiple subscription for same product
        billableFeatures: [{ 						// optional, required for subscriptions with per unit pricing
          featureId:'feature-01-templates',
          quantity: 2
        }],
        billingPeriod: 'MONTHLY', 			// optional, relevant only for paid subscriptions
        addons: [{  										// optional
          addonId: 'addon-extra-stuff',
          quantity: 1,
        }],
        promotionCode: 'STIGG30', 			// optional
        billingCountryCode:'DK',     		// optional, required for price localization, must be in the ISO-3166-1 format
        metadata: { 									  // optional
          key: 'value',
        },
      },
      metadata: { 				// optional - metadata that will be stored in Stigg
          key: "value",
      }
  });
  ```

  ```python Python theme={null}
  data = await client.provision_customer(ProvisionCustomerInput(**{
    "refId": "customer-demo-123",
    "name": "Acme", 						# optional
    "email": "john@example.com", 	# optional - billing email address
    "couponRefId": "coupon-id", # optional
    "subscriptionParams": {
      "planId": "plan-revvenu-basic",
      "billingCountryCode": "DK"  # optional, required for price localization
    },
    "billingInformation": { 		# optional
      "language": "en",
      "timezone": "America/New_York",
      "billingAddress": {
        "country": "US",
        "city": "New York",
        "state": "NY",
        "addressLine1": "123 Main Street",
        "postalCode": "10164"
      },
    },
    "additionalMetaData": {			 # optional
      "key": "value"
    }
  }))
  ```

  ```go Go theme={null}
  result, err := client.ProvisionCustomer(context.Background(), stigg.ProvisionCustomerInput{
    CustomerID: Ptr("customer-id"),
    Name:  Ptr("Acme"), 						// optional
    Email: Ptr("john@example.com"), 	// optional - billing email address
    CouponRefID: Ptr("coupon-id"),	// optional
    SubscriptionParams: &stigg.ProvisionCustomerSubscriptionInput{ // optional
      PlanID: "plan-revvenu-basic",
      BillingCountryCode: Ptr("DK"), // optional, required for price localization
    },
    BillingInformation: &stigg.CustomerBillingInfo{ // optional
      Language: Ptr("en"),
      Timezone: Ptr("America/New_York"),
      BillingAddress: &stigg.Address{
        Country:      Ptr("US"),
        City:         Ptr("New York"),
        State:        Ptr("NY"),
        AddressLine1: Ptr("123 Main Street"),
        PostalCode:   Ptr("10164"),
      },
    },
    AdditionalMetaData: map[string]interface{}{ // optional
      "Key": "Value",
    },
  })
  ```

  ```ruby Ruby theme={null}
  resp = client.request(Stigg::Mutation::ProvisionCustomer, {
      "input": {
          "customerId": "CUSTOMER-ID-1",
          "name": "Acme",							# optional
          "email": "john@example.com",	# optional - billing email address
          "couponRefId": "coupon-id", # optional
        	"subscriptionParams": {
              "planId": "plan-revvenu-basic",
            	"billingCountryCode":"DK"   # optional, required for price localization
          },
          "billingInformation": {			# optional
              "language": "en",
              "timezone": "America/New_York",
              "billingAddress": {
                  "country": "US",
                  "city": "New York",
                  "state": "NY",
                  "addressLine1": "123 Main Street",
                  "postalCode": "10164"
              },
          },
          "additionalMetaData": {			# optional
              "key": "value"
          }
      },
  })
  ```

  ```java Java theme={null}
  var resp = stigg.mutation(
    ProvisionCustomerMutation.builder()
    .input(ProvisionCustomerInput.builder()
           .customerId("customer-81726628184")
           .name("Acme")                        // optional
           .email("john@example.com")           // optional
           .billingInformation(CustomerBillingInfo.builder()
                               .billingAddress(Address.builder()
                                               .country("US")
                                               .city("New York")
                                               .state("NY")
                                               .addressLine1("123 Main Street")
                                               .postalCode("10164")
                                               .build())
                               .build())
           .additionalMetaData(new HashMap<>() {{
             put("key", "value");
           }})
           .subscriptionParams(ProvisionCustomerSubscriptionInput.builder()
                               .planId("plan-revvenu-basic")
                               .build())
           .build())
    .build()
  );
  ```

  ```c# .NET theme={null}
  var resp = await stigg.ProvisionCustomer.ExecuteAsync(new ProvisionCustomerInput()
  {
    CustomerId= "customer-81726628184",
    Name = "Acme",                        // optional
    Email = "john@example.com",           // optional
    SubscriptionParams = new ProvisionCustomerSubscriptionInput()
    {
      PlanId = "plan-revvenu-basic"
    }
  });
  ```
</CodeGroup>

<Expandable title="Result (Node.js)">
  ```json theme={null}
  {
    "customer": {
      "id": "customer-test-id",
      "experimentInfo": {
        "name": "should we use freemium?",
        "id": "should-we-use-freemium",
        "groupName": "Variant group",
        "groupType": "VARIANT"
      }
    },
    "subscriptionDecisionStrategy": "REQUESTED_PLAN",
    "subscription": {
      "id": "subscription-plan-basic-ed5dac",
      "planId": "plan-basic",
      "status": "ACTIVE",
      "addons": [],
      "customerId": "customer-test-id",
      "pricingType": "FREE",
      "resource": {
        "id": "resource-01"
      }
    }
  }
  ```
</Expandable>

### Updating customers

Customer information can be updated at any time. Only the fields being updated need to be sent.

<Warning>
  Since billing information is not persisted on Stigg's servers, the entire billing information object must be passed each time it needs to be updated.
</Warning>

<CodeGroup>
  ```javascript Node.js theme={null}
  const customer = await stiggClient.updateCustomer({
      customerId: 'customer-test-id',
      email: 'john@example.com', // optional, use to update the customer's email address
      couponId: 'coupon-test-id',   // optional, use to apply a coupon to a customer
      billingInfo: {  							// optional, use to update the customer's billing information
          ...
      },
      metadata: {  									// optional, use to update the customer's metadata
        key: 'value',
      }
  });
  ```

  ```python Python theme={null}
  data = await client.update_customer(UpdateCustomerInput(
    **{
      "email": "john@example.com",
      "name": "Acme",
      "refId": "customer-id2",
      "billingInformation": {
        "payment_method_id": "pm_123123",
        "language": "en",
        "timezone": "America/New_York",
        "currency": "USD",
      },
      "additionalMetaData": {
        "key": "value"
      }
    }
  ))
  ```

  ```go Go theme={null}
  result, err := client.UpdateCustomer(context.Background(), stigg.UpdateCustomerInput{
    CustomerID:  Ptr("customer-id"),
    Name:  Ptr("Acme"),
    Email: Ptr("john@example.com"),
    BillingInformation: &stigg.CustomerBillingInfo{
      Language: Ptr("en"),
      Timezone: Ptr("America/New_York"),
    },
    AdditionalMetaData: map[string]interface{}{
      "Key": "Value",
    },
  })
  ```

  ```ruby Ruby theme={null}
  resp = client.request(Stigg::Mutation::UpdateCustomer, {
      "input": {
          "customerId": "CUSTOMER-ID-1",
          "email": "john@example.com",
          "name": "Acme",
          "billingInformation": {
              "language": "en",
              "timezone": "America/New_York",
              "currency": "USD",
          },
          "additionalMetaData": {
              "key": "value"
          }
      }
  })
  ```

  ```java Java theme={null}
  var resp = stigg.mutation(
    UpdateCustomerMutation.builder()
    .input(UpdateCustomerInput.builder()
           .customerId("customer-demo-01")
           .name("Acme")
           .email("john@example.com")
           .additionalMetaData(new HashMap<>() {{
             put("key", "value");
           }})
           .billingInformation(CustomerBillingInfo.builder()
                               .language("en")
                               .timezone("America/New_York")
                               .currency(Currency.USD)
                               .build())
           .build())
    .build()
  );
  ```

  ```c# .NET theme={null}
  var res = await stigg.UpdateCustomer.ExecuteAsync(new UpdateCustomerInput()
  {
    CustomerId = "customer-demo-01",
    Name = "Acme",
    Email = "john@example.com",
  });
  ```
</CodeGroup>

<Expandable title="Result (Node.js)">
  ```json theme={null}
  {
    "id": "customer-test-id"
  }
  ```
</Expandable>

### Getting customer data

Retrieve customer details by their customer ID, including metadata, promotional entitlements, and payment method status.

<CodeGroup>
  ```javascript Node.js theme={null}
  const customer = await stiggClient.getCustomer('customer-demo-01');
  ```

  ```python Python theme={null}
  data = await client.get_customer_by_id(GetCustomerByRefIdInput({
    "customerId": "customer-id2"
  }))
  ```

  ```go Go theme={null}
  result, err := client.GetCustomerByID(context.Background(), stigg.GetCustomerByRefIDInput{
    CustomerID: "customer-f9942a",
  })
  ```

  ```ruby Ruby theme={null}
  resp = client.request(Stigg::Query::GetCustomerById,{
      "customerId": "customer-id"
  })
  ```

  ```java Java theme={null}
  var resp = stigg.query(
    GetCustomerByIdQuery.builder()
    .input(GetCustomerByRefIdInput.builder().customerId("customer-demo-01").build())
    .build()
  );
  ```

  ```c# .NET theme={null}
  var res = await stigg.GetCustomerById.ExecuteAsync(new GetCustomerByRefIdInput()
  {
    CustomerId = "customer-demo-01",
  });
  ```
</CodeGroup>

<Expandable title="Result (Node.js)">
  ```json theme={null}
  {
    "id": "customer-demo-01",
    "name": "Test Name",
    "email": "john@example.com",
    "createdAt": "2022-09-20T09:59:22.324Z",
    "updatedAt": "2022-09-20T10:00:32.750Z",
    "hasPaymentMethod": false,
    "promotionalEntitlements": [],
    "metadata": {
      "lorem": "ipsum"
    }
  }
  ```
</Expandable>

### Archiving customers

When a customer is archived:

1. Their PII (name and email) will be nullified.
2. They will no longer appear in the Stigg app UI.
3. They will no longer be returned by the Stigg API and SDKs.

<Warning>
  New customers cannot reuse the customer ID of archived customers. When Stigg is integrated with a billing solution, archived customers will still exist in the billing solution to allow upcoming invoices to be finalized.
</Warning>
