Pub/Sub Notifications

Partners can receive notifications of the state changes on subscriptions and purchase orders during their life cycles and should be treated as the source of truth. Partners need to subscribe to the corresponding Cloud Pubsub topic provisioned by Payments Reseller Subscription backend.

Subscription and Purchase Order notifications can be useful to detect and process events such as:

  • Google cancels a subscription:
  • user deleting their Google Account, or
  • a subscription failing to be extended by the partner during the grace period.
  • Google refunds a purchase order, prorated or in full.

Partner could use appropriate processing in their application for such changes.

Currently, we don't provide notifications on other resources such as products and promotions.

Subscription Lifecycle

state transitions

Subscribing to Cloud Pubsub

During the onboarding process, each partner entity will be assigned with unique Cloud Pubsub Topic IDs for subscriptions and/or purchase orders. The partner will provide the service accounts they wish to be allow-listed to subscribe to the topics. We recommend using the default service accounts provided by Compute Engine, or App Engine.

Subscription Types

Pub/Sub offers different subscription types to cater to various use cases:

Pull subscriptions

With pull subscriptions, your application periodically makes requests to the Pub/Sub service to retrieve messages. This approach gives you more control over when and how many messages are consumed.

  • Batch processing where messages can be processed in bulk at specific intervals.
  • Applications that need fine-grained control over message flow and processing rate.
  • Scenarios where the subscriber cannot be exposed to a public endpoint (e.g., behind a firewall).

Push subscriptions

For push subscriptions, the Pub/Sub server initiates requests to your application to deliver messages. This is suitable for applications that need real-time message delivery.

  • Real-time applications that need to process messages immediately upon arrival.
  • Serverless architectures where your application can be triggered by Pub/Sub events.

BigQuery Subscriptions

With BigQuery subscriptions, Pub/Sub writes messages directly to a BigQuery table. This is useful for analytical workloads that need to persist messages for long-term storage and analysis.

  • Archiving messages for long-term data warehousing.
  • Performing SQL-based analysis on message data.
  • Joining message data with other datasets in BigQuery.

Cloud Storage Subscriptions

With Cloud Storage subscriptions, Pub/Sub writes messages directly to Cloud Storage files in a specified bucket. This type of subscription is useful for storing large numbers of messages in a cost-effective and scalable way.

  • Data lakes: storing large volumes of raw message data for later processing.
  • Archiving: long-term storage of messages for compliance or historical analysis.
  • Batch processing: using other Google Cloud services like Dataflow or Dataproc to process messages in Cloud Storage files.

For more in-depth analysis please see how to choose section.

Key Considerations

Message Ordering

  • Pub/Sub, by default, does not guarantee message ordering. If your application requires strict ordering please refer to pub/sub ordering.

At-Least-Once Delivery

  • Pub/Sub guarantees at-least-once delivery of messages. This means that a message may be delivered multiple times in rare cases.
  • Your application should be designed to be idempotent.

Please refer to subscriber best practices guide for more details.

Notification Specification

The notification is encoded in the pubsub message using the following specification:

  • data: subscription resource, or purchase order resource in json format. It is base64-encoded in Pubsub RESTful API. Pubsub SDK may return decoded value directly, see java example.

  • attributes: A map containing additional information related to the subscription in the message. Can be accessed via attributes field in the PubsubMessage, see java example. Currently has the following keys that are returned in the Map

Subscription Pubsub message attributes:

Key Description
state Value corresponds to the String value of the enum

State

cancellationReason This entry will be populated only when CancellationReason is present in the message.
Value corresponds to String value of enum

CancellationReason

endUserEntitled If an end user has linked their Google Account to the subscription. Possible values are true and false.
sequenceNumber The sequence number is a unique number within a subscription (not globally unique) that can be used to handle idempotency and out-of-order notifications. Recipients of notifications may want to persist this number and process a request only if the current sequence number is greater than the previous sequence number for a subscription.

Purchase order Pubsub message attributes:

Key Description
sequenceNumber The sequence number is a unique number within a purchase order (not globally unique) that can be used to handle idempotency and out-of-order notifications. Recipients of notifications may want to persist this number and process a request only if the current sequence number is greater than the previous sequence number for a purchase order.

Partners can use attributes to create topic subscription with a filter in order to receive only messages that matches the filter. For instance, use filter such as attributes.state = "STATE_CANCELLED" AND attributes.cancellationReason = "CANCELLATION_REASON_ACCOUNT_CLOSED" to receive messages for cancelled subscriptions due to account closure. See docs for more information.

Following fields are not used:

  • orderingKey

Subscription notification examples:

  • User activating the service:
{
  "data": "ewogICJuYW1lIjogInBhcnRuZXJzL2RlbW8vc3Vic2NyaXB0aW9ucy82NWEzMGRmOS04NjY1LTQyYTgtOGM3Yi0wM2RjZTkxMzVlOWEiLAogICJwcm9kdWN0IjogInBhcnRuZXJzL2RlbW8vcHJvZHVjdHMvUFRQRC0xMjM0NTY3OCIsCiAgInBhcnRuZXJVc2VyVG9rZW4iOiAiMjE1NDkzNDI1MTY2IiwKICAicmVkaXJlY3RVcmkiOiAiaHR0cHM6Ly93d3cuZXhhbXBsZS5jb20iLAogICJzZXJ2aWNlTG9jYXRpb24iOiB7CiAgICAicmVnaW9uQ29kZSI6ICJVUyIKICB9LAogICJjeWNsZUVuZFRpbWUiOiAiMjAyMS0wMi0wMlQxNTowMToyM1oiLAogICJmcmVlVHJpYWxFbmRUaW1lIjogIjIwMjEtMDEtMDJUMTU6MDE6MjNaIiwKICAiZW5kVXNlckVudGl0bGVkIjogdHJ1ZSwKICAic3RhdGUiOiAiU1RBVEVfQUNUSVZFIiwKICAicHJvdmlzaW9uVGltZSI6ICIyMDIwLTEwLTAyVDE1OjAxOjIwWiIsCiAgImNyZWF0ZVRpbWUiOiAiMjAyMC0xMC0wMlQxNTowMToyM1oiLAogICJ1cGRhdGVUaW1lIjogIjIwMjAtMTAtMDhUMTU6MDE6MjNaIiwKfQ==",
  "attributes": {
    "state": "STATE_ACTIVE"
  },
  "messageId": "967147fc-6b2e-11eb-b3ac-a1d6ba962d73",
  "publishTime": "2021-02-02T15:01:23Z"
}

// The `data` field encodes the following subscription resource:
{
  "name": "partners/demo/subscriptions/65a30df9-8665-42a8-8c7b-03dce9135e9a",
  "products": ["partners/demo/products/PTPD-12345678"],
  "partnerUserToken": "215493425166",
  "redirectUri": "https://www.example.com",
  "serviceLocation": {
    "regionCode": "US"
  },
  "cycleEndTime": "2021-02-02T15:01:23Z",
  "freeTrialEndTime": "2021-01-02T15:01:23Z",
  "endUserEntitled": true,
  "state": "STATE_ACTIVE",
  "provisionTime": "2020-10-02T15:01:20Z",
  "createTime": "2020-10-02T15:01:23Z",
  "updateTime": "2020-10-08T15:01:23Z",
  "renewalTime": "2021-02-02T15:01:23Z",
  "lineItems": [{
    "product": "partners/demo/products/PTPD-12345678",
    "state": "LINE_ITEM_STATE_ACTIVE",
    "description": "Base Plan",
    "recurrenceType": "LINE_ITEM_RECURRENCE_TYPE_PERIODIC",
    "amount": {
      "currencyCode": "USD",
      "amountMicros": "12990000"
    },
    "lineItemIndex": 0
  }]
}
  • Subscription cancellation. It can be initiated by the partner or Google.
{
  "data": "ewogICJuYW1lIjogInBhcnRuZXJzL2RlbW8vc3Vic2NyaXB0aW9ucy82NWEzMGRmOS04NjY1LTQyYTgtOGM3Yi0wM2RjZTkxMzVlOWEiLAogICJwcm9kdWN0IjogInBhcnRuZXJzL2RlbW8vcHJvZHVjdHMvUFRQRC0xMjM0NTY3OCIsCiAgInBhcnRuZXJVc2VyVG9rZW4iOiAiMjE1NDkzNDI1MTY2IiwKICAicmVkaXJlY3RVcmkiOiAiaHR0cHM6Ly93d3cuZXhhbXBsZS5jb20iLAogICJzZXJ2aWNlTG9jYXRpb24iOiB7CiAgICAicmVnaW9uQ29kZSI6ICJVUyIKICB9LAogICJjeWNsZUVuZFRpbWUiOiAiMjAyMS0wMi0wMlQxNTowMToyM1oiLAogICJmcmVlVHJpYWxFbmRUaW1lIjogIjIwMjEtMDEtMDJUMTU6MDE6MjNaIiwKICAiZW5kVXNlckVudGl0bGVkIjogdHJ1ZSwKICAic3RhdGUiOiAiU1RBVEVfQ0FOQ0VMTEVEIiwKICAiY2FuY2VsbGF0aW9uRGV0YWlscyI6IHsKICAgICJyZWFzb24iOiAiQUNDT1VOVF9DTE9TRUQiCiAgfSwKICAicHJvdmlzaW9uVGltZSI6ICIyMDIwLTEwLTAyVDE1OjAxOjIwWiIsCiAgImNyZWF0ZVRpbWUiOiAiMjAyMC0xMC0wMlQxNTowMToyM1oiLAogICJ1cGRhdGVUaW1lIjogIjIwMjAtMTAtMDhUMTU6MDE6MjNaIiwKfQ==",
  "attributes": {
    "state": "STATE_CANCELLED",
    "cancellationReason": "CANCELLATION_REASON_ACCOUNT_CLOSED"
  },
  "messageId": "967147fc-6b2e-11eb-b3ac-a1d6ba962d73",
  "publishTime": "2021-02-02T15:01:23Z"
}

// The `data` field encodes the following subscription resource with cancellation details:
{
  "name": "partners/demo/subscriptions/65a30df9-8665-42a8-8c7b-03dce9135e9a",
  "products": ["partners/demo/products/PTPD-12345678"],
  "partnerUserToken": "215493425166",
  "redirectUri": "https://www.example.com",
  "serviceLocation": {
    "regionCode": "US"
  },
  "cycleEndTime": "2021-02-02T15:01:23Z",
  "freeTrialEndTime": "2021-01-02T15:01:23Z",
  "renewalTime": "2021-02-02T15:01:23Z",
  "endUserEntitled": true,
  "state": "STATE_CANCELLED",
  "cancellationDetails": {
    "reason": "CANCELLATION_REASON_ACCOUNT_CLOSED"
  },
  "provisionTime": "2020-10-02T15:01:20Z",
  "createTime": "2020-10-02T15:01:23Z",
  "updateTime": "2020-10-08T15:01:23Z",
  "lineItems": [{
    "product": "partners/demo/products/PTPD-12345678",
    "state": "LINE_ITEM_STATE_ACTIVE",
    "description": "Base Plan",
    "recurrenceType": "LINE_ITEM_RECURRENCE_TYPE_PERIODIC",
    "amount": {
      "currencyCode": "USD",
      "amountMicros": "12990000"
    },
    "lineItemIndex": 0
  }]
}

Purchase Order notification examples:

  • Upon subscription renewal charge :
{
  "data": "ewogICJuYW1lIjogInBhcnRuZXJzL2RlbW8vc3Vic2NyaXB0aW9ucy82NWEzMGRmOS04NjY1LTQyYTgtOGM3Yi0wM2RjZTkxMzVlOWEiLAogICJwcm9kdWN0IjogInBhcnRuZXJzL2RlbW8vcHJvZHVjdHMvUFRQRC0xMjM0NTY3OCIsCiAgInBhcnRuZXJVc2VyVG9rZW4iOiAiMjE1NDkzNDI1MTY2IiwKICAicmVkaXJlY3RVcmkiOiAiaHR0cHM6Ly93d3cuZXhhbXBsZS5jb20iLAogICJzZXJ2aWNlTG9jYXRpb24iOiB7CiAgICAicmVnaW9uQ29kZSI6ICJVUyIKICB9LAogICJjeWNsZUVuZFRpbWUiOiAiMjAyMS0wMi0wMlQxNTowMToyM1oiLAogICJmcmVlVHJpYWxFbmRUaW1lIjogIjIwMjEtMDEtMDJUMTU6MDE6MjNaIiwKICAiZW5kVXNlckVudGl0bGVkIjogdHJ1ZSwKICAic3RhdGUiOiAiU1RBVEVfQUNUSVZFIiwKICAicHJvdmlzaW9uVGltZSI6ICIyMDIwLTEwLTAyVDE1OjAxOjIwWiIsCiAgImNyZWF0ZVRpbWUiOiAiMjAyMC0xMC0wMlQxNTowMToyM1oiLAogICJ1cGRhdGVUaW1lIjogIjIwMjAtMTAtMDhUMTU6MDE6MjNaIiwKfQ==",
  "attributes": {
    "sequenceNumber": "1680291396"
  },
  "messageId": "967147fc-6b2e-11eb-b3ac-a1d6ba962d73",
  "publishTime": "2021-02-02T15:01:23Z"
}


// The `data` field encodes the following purchase order resource with charged details:
{
  "name": "partners/demo_partner/purchaseorders/be587593-9b44-4e6d-90b2-08db29689362",
  "partnerUserToken": "09DDE00156E31A9A909E0004AC1EA1AD",
  "lineItems": [{
    "product": "partners/demo_partner/products/844b3390-fc0b-4cce-9881-2531aa9ac56d",
    "description": "Base Plan",
    "amount": {
      "currencyCode": "USD",
      "amountMicros": "62990000"
    },
    "servicePeriod": {
      "startTime": "2023-03-25T17:33:47.503Z",
      "endTime": "2023-04-25T17:33:47.503Z"
    },
    "chargedDetails": {
      "priceDetails": {
        "pretaxAmount": {
          "currencyCode": "USD",
          "amountMicros": "62990000"
        },
        "taxAmount": {
          "currencyCode": "USD",
          "amountMicros": "0"
        },
        "totalAmount": {
          "currencyCode": "USD",
          "amountMicros": "62990000"
        }
      }
    }
  }],
  "subscriptionDetails": {
    "subscription": "partners/demo_partner/subscriptions/be587593-9b44-4e6d-90b2-08db29689362",
    "purchaseOrderType": "PURCHASE_ORDER_TYPE_RENEWAL"
  }
}