This section describes the steps to integrate your app's backend with Cloud Marketplace. With this integration, you can manage users' accounts and entitlements, which indicate that users have bought your product from Cloud Marketplace. If you chose a usage-based pricing model, you also integrate your backend to report usage to Google.
For an example of integrating a basic app with Cloud Marketplace and a walkthrough of the sample code, see the codelab to integrate a managed service.
For the sample code used in the codelab, see the GitHub repository.
Before you begin
- Set up access to the Cloud Commerce Partner Procurement API, as described in Integrating your app: setting up.
- If you chose a usage-based pricing scheme, verify that your Partner Engineer has created a service that you can report usage against. This service displays in the Service domain field of the Billing Integration section of Producer Portal.
Create a service account
To integrate your product with Google Cloud, you must create a service account in the project that you are using for your product. Your app uses this service account to interact with the Cloud Marketplace Partner APIs and get information about users' purchases.
Use Producer Portal to create and link your service accounts. For detailed steps to create a service account, see Creating and managing service accounts.
Use Producer Portal to integrate your app's backend
To access all of the information you need to integrate your app's backend with Cloud Marketplace from one location, such as your service accounts and plan level identifiers, you can use the Billing integration section of Producer Portal.
The direct link to Producer Portal is:
https://console.cloud.google.com/producer-portal?project=YOUR_PROJECT_ID
To access the Billing integration section:
In the list of products, click the name of your product.
On the Overview page of your product, go to the Technical integration section and click on Billing integration.
Creating and linking service accounts in Producer Portal
You can use the Billing integration section of Producer Portal to create and link the service accounts that you use to interact with the Partner APIs and to get information about users' purchases.
The direct link to Producer Portal is:
https://console.cloud.google.com/producer-portal?project=YOUR_PROJECT_ID
In the following steps, you can use existing service accounts, or create new service accounts. If you create a new service account, specify the service account's name in the Service account name field and the service account's ID in the Service account ID field, and then click Create and link.
To link your service accounts:
In the list of products, click the name of your product.
On the Overview page of your product, go to the Technical integration section and click on Billing integration.
To integrate with the Partner Procurement API, under Link a service account to call Procurement API, click Add service account. You can enter an existing service account into the field, or create a new service account.
To integrate with Pub/Sub, under Link a service account to subscribe to Pub/Sub topic, click Add service account. You can enter an existing service account into the field, or create a new service account.
To integrate with the Service Control API, under Add
roles/servicemanagement.serviceController
to a service account, click Add service account. You can enter an existing service account into the field, or create a new service account.
User account tasks
At a high level, your app must handle the following scenario:
A user makes a request or change in Cloud Marketplace, such as signing up for your product.
Cloud Marketplace sends your app a notification through Pub/Sub, containing information about the request in the
eventType
field. For example, if a user changes their entitlement, theeventType
isENTITLEMENT_PLAN_CHANGED
.See the full list of possible
eventType
s.To approve the request, your app sends an
HTTP POST
request to the Partner Procurement API.
The following sections describe the types of requests that users can make, and what your app must do to handle the requests.
For the API calls described in this section, use this endpoint:
https://cloudcommerceprocurement.googleapis.com/
Create an account for a new user
When a user first purchases your product, Cloud Marketplace creates an account resource that tracks the user's relationship with you. When the account resource is created, you get notified through the Pub/Sub topic that was created for you. The Pub/Sub message is in the following format:
{ "eventId": "...", "providerId": "YOUR_PARTNER_ID", "account": { "id": "USER_ACCOUNT_ID", "updateTime": "..." } }
where USER_ACCOUNT_ID is the account ID created by Cloud Marketplace and YOUR_PARTNER_ID is an ID assigned to you when your Partner Engineer enables access to the Partner Procurement API.
Simultaneously, the user is directed to your sign-up page, where they create an account in your system. For information on creating the sign-up page, see Integrating your app's frontend.
Approve a user's account
After the user has successfully signed up, your app must call the
Partner Procurement API and indicate that the account has been approved.
Accounts are created in the ACCOUNT_ACTIVE
state, but they have a PENDING
entry in the approvals
field called signup
, which indicates that the user
has not yet signed up. To approve the account after the user has signed up, use
the following HTTP POST
request:
POST v1/providers/YOUR_PARTNER_ID/accounts/USER_ACCOUNT_ID:approve {'approvalName': 'signup'}
Check the status of a user's account
To check the status of a linked account, use the following HTTP GET
request:
GET v1/providers/YOUR_PARTNER_ID/accounts/USER_ACCOUNT_ID
The response is in the following format:
{ "name": "providers/YOUR_PARTNER_ID/accounts/USER_ACCOUNT_ID", "provider": "acme-services", "state": "ACCOUNT_ACTIVE", "approvals": [{ "name": "signup", "state": "APPROVED", "updateTime": "...", }], "updateTime": "...", "createTime": "..." }
For a list of possible account states, see the
providers.accounts
API reference.
Manage entitlements
When customers choose a pricing plan for your software, Google creates an entitlement, which indicates that the customer has bought your product from Cloud Marketplace. This section reviews how to create and manage entitlements for your customers using the Partner Procurement API.
For more details on managing entitlements, visit the reference documentation.
If you have enabled multiple orders of the same product, then the Partner Procurement API can send multiple events with the ENTITLEMENT_ACTIVE
event type for the same ACCOUNT_ID
, each with a unique ENTITLEMENT_ID
for different offers. In this case, make sure that you modify the event handling logic for your application such that it responds to the ENTITLEMENT_ID
instead of the ACCOUNT_ID
or the PRODUCT_ID
.
You also need to make changes to your frontend integration to handle the new orders
object sent in the JWT payload. For more information, see
Integrating your app's frontend.
For more information about opting in for multiple orders of the same product, see Turn on multiple orders of the same product.
Approve or reject an entitlement
When a customer chooses a pricing plan, Cloud Marketplace creates an entitlement and sends the following Pub/Sub message to your app:
{ "eventId": "...", "eventType": "ENTITLEMENT_CREATION_REQUESTED", "providerId": "YOUR_PARTNER_ID", "entitlement": { "id": "ENTITLEMENT_ID", "updateTime": "...", "newOfferDuration": "P2Y3M", // Contract duration for offer-based entitlements }, }
where ENTITLEMENT_ID is an ID created by Cloud Marketplace. If the offer has a specified duration, that duration is provided in years and months. If the offer has a specified end date, instead of a duration, the field indicating the duration is empty.
In your system, update the user's account to reflect that they have purchased
a plan. Then, to approve the entitlement, make an HTTP POST
request to the
Partner Procurement API, and send the ENTITLEMENT_ID that you are
approving:
POST v1/providers/YOUR_PARTNER_ID/entitlements/ENTITLEMENT_ID:approve
To reject an entitlement, instead use the reject
method in your HTTP POST
request:
POST v1/providers/YOUR_PARTNER_ID/entitlements/ENTITLEMENT_ID:reject
To give a reason for rejecting the entitlement in the request body, use the following format:
{ "reason": "..." }
Change an entitlement plan
Depending on how you set up your pricing plans, your customers might be able to change their plan. If a customer selects a new pricing plan, you receive a Pub/Sub message, in the following format:
{ "eventId": "...", "eventType": "ENTITLEMENT_PLAN_CHANGE_REQUESTED", "providerId": "YOUR_PARTNER_ID", "entitlement": { "id": "ENTITLEMENT_ID", "newPlan": "ultimate", // New plan "updateTime": "...", "newOfferDuration": "P2Y3M", // Contract duration for the new offer, for offer-based entitlements }, }
If the offer has a specified duration, that duration is provided in years and months. If the offer has a specified end date, instead of a duration, the field indicating the duration is empty.
To approve the plan change, make the following HTTP POST
request to the
Partner Procurement API:
POST v1/providers/YOUR_PARTNER_ID/entitlements/ENTITLEMENT_ID:approvePlanChange
The request body must have the plan that is being approved:
{
"pendingPlanName": PLAN_NAME
}
After the change is approved, you receive another Pub/Sub message
when the change takes effect. In the message, the eventType
field changes to
ENTITLEMENT_PLAN_CHANGED
. To check the status of a plan, make the following
HTTP GET
request to the Partner Procurement API.
GET v1/providers/YOUR_PARTNER_ID/entitlements/ENTITLEMENT_ID
The response is similar to the following, with the state
field indicating
whether the new plan is active, or whether the plan change is still pending:
{ "name": "providers/YOUR_PARTNER_ID/entitlements/ENTITLEMENT_ID", "provider": "YOUR_PARTNER_ID", "account": "USER_ACCOUNT_ID", "product": "example-server", "plan": "pro", "state": "ENTITLEMENT_PENDING_PLAN_CHANGE", "newPendingPlan": "ultimate", ... }
Cancel an entitlement
If a user decides to cancel their entitlement, you receive a Pub/Sub notification. Similar to changing a plan, the actual cancellation might take effect at the end of the current billing cycle.
The notification is in the following format:
{ "eventId": "...", // If the entitlement is canceled at the end of the month, // eventType is ENTITLEMENT_PENDING_CANCELLATION "eventType": "ENTITLEMENT_CANCELLED", "providerId": "YOUR_PARTNER_ID", "entitlement": { "id": "ENTITLEMENT_ID", "updateTime": "..." }, }
Deleting an entitlement
If a user makes a direct request to Google support, or if they leave the Google platform, their entitlements are immediately canceled, and their entitlement and accounts are deleted after a 60 day grace period. To protect the user's privacy, you must delete their data from your servers when you are notified.
When the entitlements are canceled and the account is deleted, you receive notifications similar to the following:
{ "eventId": "...", "eventType": "ENTITLEMENT_DELETED", "providerId": "YOUR_PARTNER_ID", "entitlement": { "id": "ENTITLEMENT_ID", "updateTime": "...", }, }
{ "eventId": "...", "eventType": "ACCOUNT_DELETED", "providerId": "YOUR_PARTNER_ID", "account": { "id": "USER_ACCOUNT_ID", "updateTime": "...", }, }
List of event types for account tasks
The following is a list of the eventType
s that your app might receive in
Pub/Sub messages:
eventType | Description |
---|---|
ACCOUNT_CREATION_REQUESTED | Deprecated |
ACCOUNT_ACTIVE | Indicates that the customer's account has been created. |
ACCOUNT_DELETED | Indicates that the customer's account was deleted from Google Cloud systems. |
ENTITLEMENT_CREATION_REQUESTED | Indicates that a customer selected one of your pricing plans. |
ENTITLEMENT_OFFER_ACCEPTED | Indicates that an offer was accepted by a customer. Includes the scheduled start time of the offer, if there is one. This event is sent for both private offers and standard offers (public purchases). |
ENTITLEMENT_ACTIVE | Indicates that a customer's chosen plan is now active. |
ENTITLEMENT_PLAN_CHANGE_REQUESTED | Indicates that a customer chose a new plan. |
ENTITLEMENT_PLAN_CHANGED | Indicates that a customer's plan change is approved and the changes have taken effect. |
ENTITLEMENT_PLAN_CHANGE_CANCELLED | Indicates that a customer's plan change was canceled, either because it wasn't approved, or because they switched back to their old plan. |
ENTITLEMENT_PENDING_CANCELLATION | Indicates that a customer canceled their plan, and the cancellation is pending until the end of the billing cycle. |
ENTITLEMENT_CANCELLATION_REVERTED | Indicates that a customer's pending cancellation was reverted. Note that cancellations cannot be reverted after they are final. |
ENTITLEMENT_CANCELLED | Indicates that a customer's plan was canceled. |
ENTITLEMENT_CANCELLING | Indicates that a customer's plan is in the process of being canceled. |
ENTITLEMENT_RENEWED | Indicates that a customer's entitlement was renewed for another term. You don't need to take any action to complete the renewal. |
ENTITLEMENT_OFFER_ENDED | Indicates that a customer's private offer has ended. If the customer's entitlement was canceled, a separate ENTITLEMENT_CANCELLED event is triggered. If the customer's entitlement is still active, their plan reverts to non-discounted pricing. |
ENTITLEMENT_DELETED | Indicates that information about a customer's plan was deleted from Cloud Marketplace. |
(For usage-based pricing) Reporting usage to Google
If you choose usage-based pricing for your product, you must report your app's usage to the Service Control API.
For an introduction to Service Control, see the Getting Started Guide.
We recommend that you use Producer Portal to create a service account in Producer Portal for use with Service Control.
When an entitlement is created, you must call the Partner Procurement API
to retrieve a usageReportingId
, using the following HTTP GET
request:
GET v1/providers/YOUR_PARTNER_ID/entitlements/ENTITLEMENT_ID
The response contains information about the entitlement, in the following format:
{ "name": "providers/YOUR_PARTNER_ID/entitlements/ENTITLEMENT_ID", "provider": "YOUR_PARTNER_ID", "account": "USER_ACCOUNT_ID", "product": "example-messaging-service", "plan": "pro", "usageReportingId": "USAGE_REPORTING_ID", "state": "ENTITLEMENT_ACTIVATION_REQUESTED", "updateTime": "...", "createTime": "..." }
To report usage, you must first make a
services.check
API call, to check the service's configuration. In the response, if the
checkErrors[]
object is empty, make a
services.report
API call to send the usage report.
The usage report is a Service Control API
Operation
.
The following is an example of a usage report for example-messaging-service
that sends information about the storage being used by the customer:
POST https://servicecontrol.googleapis.com/v1/services/example-messaging-service.gcpmarketplace.example.com:report
{ "operations": [{ "operationId": "1234-example-operation-id-4567", "operationName": "Hourly Usage Report", "consumerId": "USAGE_REPORTING_ID", "startTime": "2019-02-06T12:00:00Z", "endTime": "2019-02-06T13:00:00Z", "metricValueSets": [{ "metricName": "example-messaging-service/UsageInGiB", "metricValues": [{ "int64Value": "150" }] }], "userLabels": { "cloudmarketplace.googleapis.com/resource_name": "order_history_cache", "cloudmarketplace.googleapis.com/container_name": "storefront_prod", "environment": "prod", "region": "us-west2" } }] }
where:
operationId
is a unique string that your service instance generates. You should use the sameoperationId
for yourcheck
andreport
operations.consumerId
is the same as theusageReportingId
from the entitlement.startTime
andendTime
represent the start and end times of the total interval for thereport
Operation. In most cases, thestartTime
of areport
Operation should have the same value as theendTime
of the previousreport
Operation.If a customer's service is disabled before the
startTime
of areport
Operation, theservices.check
API call sends an error in thecheckErrors[]
object, and the customer is not charged for the corresponding interval.MetricValueSet
contains one or intermediate time intervals and corresponding updated metric values. You define your service's metrics when you choose and submit your pricing model.You view and reference the identifiers for your metrics in the Technical integration section of Producer Portal.
userLabels
are user-created labels, defined as key-value strings that follow specific syntax requirements. These labels are forwarded to Cloud Billing cost management tools for attribution. For recommended labeling conventions, see Best practices for usage labeling.
If the services.check
API returns one or more of the following errors, we
recommend that you stop providing your service to the customer until the error
is resolved:
SERVICE_NOT_ACTIVATED
BILLING_DISABLED
PROJECT_DELETED
Best practices for usage reporting
When reporting usage, for example user operation or resource utilization, keep in mind the following information to ensure that your customers are billed correctly.
Reporting usage at time of occurrence
Delays in usage reporting degrade your customers' cost management experience and might not be reflected in partner reports. Service providers must report usage within one hour of the usage being generated.
If you need more time to report usage, contact your partner engineer.
Reporting usage after an entitlement is canceled
If you have unreported usage after an entitlement is canceled, you can still report it with a timestamp that reflects the actual time when the usage was generated. The timestamp must be before the entitlement was canceled. Report this usage within one hour. You must not report any usage as new usage after the entitlement ends.
Reporting usage at the end of the month
The one hour reporting window applies to the month-end cutoff deadline. To ensure that usage is reported on the current month's invoice, report the usage by 1 AM, US and Canadian Pacific Time (UTC-7 or UTC-8) the following day.
For example, for a September invoice, report the usage by October 1st, 1 AM, US and Canadian Pacific Time (UTC-7 or UTC-8).
If the usage is reported later in the day, it might not be included in the current month invoice.
Remediation for customer actions that prevent reporting usage at the time of occurrence
If you cannot report usage, or if the service or billing is disabled for an extended time, we recommend that you provide the customer a grace period to restore the service. We recommend not exceeding 30 days. During this grace period, consider doing the following:
Degrade the provided service. For example, switch the customer to a free tier or start to reject calls.
Continue collecting the usage log while the service is disabled. We recommend collecting the usage with the charge breakdown by, at most, a one hour window so it can be replayed after the service is enabled.
When the service is enabled, you must report the usage collected while the service was disabled as actual usage with the time the data was collected. You must also resume your normal usage reporting.
For Kubernetes apps, if usage reports fail during the app's startup, we recommend that your app stop itself, so that your customers get immediate feedback and can resolve the issue.
Best practices for usage labeling
For usage-based SaaS products, usage is attributed to a single project
specified by the usageReportingId
field.
In some scenarios, a SaaS product might be shared broadly
within a customer's organization and used across many customer projects. To
enable support for more specific cost attribution, we recommend that usage-based
SaaS products include the optional userLabels
field on their usage report
operation.
If your service natively supports a concept of resource labels, we recommend that you forward those labels in your usage reports. Labels must conform to the syntax requirements.
Cloud Marketplace reserves the following labels. You can use these labels to identify additional context for usage within your native service platform. We recommend that you include these labels in your usage reports by default.
Label Key | Label Value | Description> |
---|---|---|
cloudmarketplace.googleapis.com/resource_name | USER_SUPPLIED | The name of the resource associated with a usage metric. |
cloudmarketplace.googleapis.com/container_name | USER_SUPPLIED | The name of a resource container. |
Labels are forwarded to Cloud Billing cost management tools, including cost reports and billing exports.
Usage labeling example
For this example, imagine your organization offers a storage product called SaaS Storage Solutions.
A customer, Carl, has purchased your storage offering for their
Google Cloud project e-commerce-website
, to host the user_profiles_db
and products_db
databases for their e-commerce website:
user_profiles_db
contains information about users that visit Carl's site.products_db
contains information about products that Carl sells on their site.
If you want to provide Carl a detailed cost breakdown of their usage, you can
use the userLabels
key-value pair to report the cost of usage for each
database separately.
For example, to report the cost attributed to Carl's products_db
storage
usage, you could send the following report, which indicates that Carl's
products_db
storage is costing them 100 units:
operation = {
'operationId': '<UUID>',
'operationName': 'db-total-storage',
'consumerId': 'project:carl_website',
'startTime': '<Timestamp>',
'endTime': '<Timestamp>',
'metricValues': [{
'int64Value': 100,
}],
'userLabels': {
'cloudmarketplace.googleapis.com/container_name': 'e-commerce-website',
'cloudmarketplace.googleapis.com/resource_name': 'products_db'
}
}
service.services().report(
serviceName=service_name, body={
'operations': [operation]
}).execute()
In this example, service_name
is the Project ID of Carl's Google Cloud
project.
For a more detailed example of using userLabels
, you can refer to the
SaaS codelab.
(Optional) Integrate your reporting with Virtual Private Cloud (VPC)
If you want to use Virtual Private Cloud (VPC) in the environment in which your product's service runs, you must complete the following steps to integrate Google Cloud Marketplace reporting with VPC. By default, the Compute Engine VMs in your VPC can only communicate internally. You must configure one of the VMs to communicate externally, so that the rest of the VMs in your VPC can use it for reporting.
Before you begin
Set up your preferred implementation of VPC in your service environment. For steps to set up VPC, visit Create and modify Virtual Private Cloud (VPC) networks.
Ensure that you have the Compute Network Admin (
roles/compute.NetworkAdmin
) Identity and Access Management (IAM) role for your Google Cloud project.
Set up Private Google Access
To enable your product's Compute Engine virtual machines (VMs) to communicate externally for reporting purposes, you must set up Private Google Access. For more information about configuring Private Google Access, refer to Configuring Private Google Access.
Enable Private Google Access for your service environment.
Configure DNS to resolve requests to
private.googleapis.com
.Create a custom route for Google APIs:
For the Name, specify
route-google-apis-services
.For Network, select your VPC.
For Destination IP range, specify
199.36.153.8/30
.For Priority, specify
0
.For Instance tags, specify
google-apis-services
.For Next hop, select Default internet gateway.
Create a VPC firewall rule to enable your product to communicate with Google APIs:
For the Name, specify
google-apis-services
.For the Description, specify
Allow egress traffic to Google APIs and services
.Enable firewall rules logging.
For Network, select your VPC.
For Direction of traffic, select Egress.
For the Action on match, select Allow.
For the Name, specify
google-apis-services
.For Targets, select
Specified target tags
, and then for Target tags, specifygoogle-apis-services
.For the Destination filter, select
IPv4 ranges
, and for the Destination IPv4 ranges, specify199.36.153.8/30
.For Protocols and ports, select
Allow all
.
In Google Cloud console, select the VM you want to use to report your product's usage. Under Network tags, add
google-apis-services
, and click SAVE.Under Network interfaces, locate your VPC's network interface.
In the Subnetwork column, click on the subnet link. From the Subnet details page, click EDIT, and set Private Google Access to On.
Click SAVE.
(Optional) Integrate your reporting with VPC Service Controls
If you want to use VPC Service Controls in the environment in which your product's service runs, you must complete the following steps to integrate Google Cloud Marketplace reporting with VPC Service Controls:
Set up your preferred implementation of VPC Service Controls in your service environment. For more information about setting up VPC Service Controls, visit Set up a service perimeter by using VPC Service Controls.
Ensure that the
servicecontrol.googleapis.com
service in your implementation of VPC Service Controls isn't restricted.