The[Google Play Developer API](https://developers.google.com/android-publisher)now includes additional functionality to report transactions from an[alternative billing](https://developer.android.com/google/play/billing/alternative)or[external offers](https://developer.android.com/google/play/billing/external)system. This guide describes how to report alternative billing or external offers transactions.

There are a few components that might be necessary to handle your in-app purchases from your backend. To build them, you need to set up your backend integration as indicated in[Configure the Google Play Developer API](https://developer.android.com/google/play/billing/getting-ready#dev-api). For all developer backend functionality that is not specific to alternative billing or external offers APIs, the instructions from the[Google Play billing system documentation](https://developer.android.com/google/play/billing)applies.

## Report new external transactions to Google Play

Integrate with[`Externaltransactions APIs`](https://developers.google.com/android-publisher/api-ref/rest/v3/externaltransactions)to**report transactions happening outside Google Play's billing system in supported countries, including $0 transactions** resulting from free trial purchases. Transactions on alternative billing or external offers systems should only be started and reported for eligible user countries as permitted under the[alternative billing](https://support.google.com/googleplay/android-developer/answer/13821247)or[external offers](https://support.google.com/googleplay/android-developer/answer/14372887)programs, otherwise the API call will be rejected. This applies to all transactions, including new purchases, renewals, top-ups, upgrades, downgrades, and others.

### External transaction reporting

You should call the`Externaltransactions API`to report an external transaction after the payment has been authorized through the alternative billing or external offer system. This applies to all transactions, including initial charges, renewals, refunds, and others. All transactions are required to be reported within 24 hours of the transaction occurring.

Each external transaction is reported with an external transaction ID. For recurring purchases (such as auto-renewable subscriptions), you need to send the external transaction ID associated with the first transaction in the recurring purchase as a parameter for any subsequent transactions, including refunds. This records the series of transactions for that purchase. You send a new external transaction ID for purchases when the product changes (such as an upgrade or a downgrade), or if the recurring transaction is canceled or expired and the same product is bought again later. You must not include any personally identifiable information, proprietary or confidential information as part of this external transaction ID.

### Report a new purchase

Every time a new purchase is successful in the alternative billing or external offers system, a call to the`Externaltransactions`API is required. For these new purchases, you need to provide a**unique** `externalTransactionId`associated with the purchase in your backend as a query parameter. This`externalTransactionId`cannot be reused within the same app's package ID.

The`externalTransactionToken`received by the app through the`UserChoiceBillingListener`,`AlternativeBillingOnlyReportingDetailsListener`, or`ExternalOfferReportingDetailsListener`callbacks is also required as part of the request body for one-time purchases and first-time transactions in a recurring purchase (such as a subscription). In either case, this is called an*initial transaction* . After the initial transaction, the`externalTransactionToken`is no longer necessary, and you report subsequent transactions (such as subscription renewals) by providing a new unique`externalTransactionId`. See[Report subsequent transactions for a purchase](https://developer.android.com/google/play/billing/outside-gpb-backend#report-subsequent)for more details on how to report subsequent transactions.

**Example**:

1. A developer configures and enables alternative billing in their app.
2. User 1 is in South Korea, a supported country, and is attempting to buy`product1`, for 12634.10KRW/month, with a one month free trial offer.
3. The app launches the purchase flow with the`ProductDetails`for`product1`and the offer that the user selected.
4. User 1 selects the developer's alternative billing system.
5. The`UserChoiceBillingListener`receives the value`my_token`as the`externalTransactionToken`.
6. The developer then sends the pertinent information to their backend (`externalTransactionToken`value and products being purchased). Then, they launch the purchase flow for`product1`in the alternative billing system. This transaction is assigned a unique transaction ID on the developer side that is used to report it to Google Play:*123-456-789*. The transaction ID is required, even though the user is receiving a free trial.
7. After the transaction for the purchase occurs in the alternative billing system, the developer reports the transaction to Google Play with the following request. It is reported as a zero-dollar transaction initially because the user gets a free month.

    POST /androidpublisher/v3/applications/com.myapp.android/externalTransactions?externalTransactionId=123-456-789

    Body
     {
    "originalPreTaxAmount" : {
       "priceMicros": "0",
       "currency": "KRW"
     },
     "originalTaxAmount" : {
       "priceMicros": "0",
       "currency": "KRW"
     },
    "transactionTime" : "2022-02-22T12:45:00Z",
     "recurringTransaction" : {
       "externalTransactionToken": "my_token",
       "externalSubscription" {
         "subscriptionType": "RECURRING"
       }
     },
     "userTaxAddress" : {
       "regionCode": "KR"
     }
    }

| **Note:** `subscriptionType`can be`RECURRING`(for auto-renewing subscriptions) or`PREPAID`(for prepaid subscriptions).
| **Note:** `OtherRecurringProduct`may be used to represent one-time purchases that require multiple payments or a delayed payment. For example, a pre-order may have an initial $0 transaction followed by a second transaction at a later date for the price of the SKU when the pre-order is fulfilled. See[Report subsequent transactions for a purchase](https://developer.android.com/google/play/billing/outside-gpb-backend#report-subsequent)for more details on reporting subsequent transactions.
| **Note:** Reporting a transaction for a purchase using alternative billing only or external offers is the same as above except the`externalTransactionToken`is obtained using the steps described in alternative billing only or external offers guide.

If transacting with a user residing in India where tax varies depends on their administrative area (such as state or province), then be sure to include that area under[userTaxAddress](https://developers.google.com/android-publisher/api-ref/rest/v3/externaltransactions#ExternalTransactionAddress). Refer to the predefined list of strings in the API reference guide for applicable administrative areas.  

    POST /androidpublisher/v3/applications/com.myapp.android/externalTransactions?externalTransactionId=123-456-789

    Body
     {
    "originalPreTaxAmount" : {
       "priceMicros": "0",
       "currency": "INR"
     },
     "originalTaxAmount" : {
       "priceMicros": "0",
       "currency": "INR"
     },
    "transactionTime" : "2023-11-01T12:45:00Z",
     "recurringTransaction" : {
       "externalTransactionToken": "my_token",
       "externalSubscription" {
         "subscriptionType": "RECURRING"
       }
     },
     "userTaxAddress" : {
       # Tax varies in India based on state, so include that information in
       # administrativeArea
       "regionCode": "IN"
       "administrativeArea": "KERALA"
     }
    }

### Report subsequent transactions for a purchase

In some cases, there is more than one user payment associated with the same external purchase (for example, subscription renewals or prepaid plan top-ups). You can report these subsequent transactions by using the same API in`Externaltransactions`. As described in[Report a new purchase](https://developer.android.com/google/play/billing/outside-gpb-backend#report-new), the`externalTransactionToken`isn't necessary for subsequent transactions. Instead, a new unique`externalTransactionId`is sent as the query parameter for each renewal or top-up transaction, with the ID of the initial transaction included in the`initialExternalTransactionId`field.

Following the previous example:

1. User 1's first renewal occurs on the alternative billing system. The initial transaction ID was*123-456-789*.
2. The developer reports the transaction recurrence in the URL query parameter as the external transaction ID for this new transaction, while referencing the external transaction ID of the initial transaction in the`initialExternalTransactionId`field.

**Example request**:  

    POST /androidpublisher/v3/applications/com.myapp.android/externalTransactions?externalTransactionId=abc-def-ghi

    Body
     {
    "originalPreTaxAmount" : {
       "priceMicros": "12634000000",
       "currency": "KRW"
     },
     "originalTaxAmount" : {
       "priceMicros": "1263000000",
       "currency": "KRW"
     },
    "transactionTime" : "2022-02-22T12:45:00Z",
     "recurringTransaction" : {
       "initialExternalTransactionId": "123-456-789",

       "externalSubscription" {
         "subscriptionType": "RECURRING"
       }
     },
     "userTaxAddress" : {
       "regionCode": "KR"
     }
    }

### Report an upgrade or downgrade

To report an upgrade or a downgrade when the user owns a subscription in the alternative billing system you use the same endpoint and function in the`Externaltransactions`API, sending the`externalTransactionToken`that was provided to the app for the upgrade or downgrade transaction. This works similarly to[reporting a new purchase](https://developer.android.com/google/play/billing/outside-gpb-backend#report-new).

### Migrate from manual reporting of alternative billing transactions

| **Note:** Manual reporting of alternative billing only and user choice billing is being sunset. For more details about migration deadlines, see[Understanding user choice billing on Google Play](https://support.google.com/googleplay/android-developer/answer/13821247). Be sure to migrate all active subscriptions that started while you were offering alternative billing without automated reporting through the Externaltransactions API before manual reporting is disabled.

To migrate active subscriptions that started while you were offering alternative billing without automated reporting, create a new zero-cost transaction using the`migratedTransactionProgram`field instead of specifying an`initialExternalTransactionId`or`externalTransactionToken`. Set the`transactionTime`to the time when the user initially signed up for each active subscription. Afterwards, report each subsequent transaction for these subscriptions as normal through the APIs, providing the`initialExternalTransactionId`used above to create the renewal transactions. Once the subscription is migrated, you will no longer need to manually report the subsequent transactions for the subscription, provided they are being reported through the automated methods described in this page.

While migrating subscriptions, be mindful of the[quota limits](https://developer.android.com/google/play/billing/alternative/backend#api-quotas)in place to ensure the migration does not cause a quota outage. If many subscriptions need to be migrated, spread them out across multiple days or[request for an increase in quota](https://support.google.com/googleplay/android-developer/contact/apiqr).
| **Note:** Only developers who have offered alternative billing without automated reporting will be able to set the migratedTransactionProgram field. If you previously offered alternative billing without automation and are getting an error when attempting to make a request to migrate the subscription, you can[contact our support team](https://support.google.com/googleplay/android-developer/contact/additional_billing_system_q)for help.

The`migratedTransactionProgram`field may only be used when migrating from manual reporting. It will be deprecated when manual reporting is no longer supported.

**Example request**:  

    # Note that the externalTransactionId specified here will used to report subsequent
    # transactions.

    POST /androidpublisher/v3/applications/com.myapp.android/externalTransactions?externalTransactionId=abc-def-ghi

    Body
     {
     # Be sure to set the price to 0 for this transaction since it does not reflect
     # an actual subscription renewal.
     "originalPreTaxAmount" : {
       "priceMicros": "0",
       "currency": "KRW"
     },
     "originalTaxAmount" : {
       "priceMicros": "0",
       "currency": "KRW"
     },

     # The transaction time should be set to when the user signed up for this
     # subscription.
     "transactionTime" : "2022-02-22T12:45:00Z",
      "recurringTransaction" : {
        "migratedTransactionProgram": "USER_CHOICE_BILLING",

        "externalSubscription" {
          "subscriptionType": "RECURRING"
        }
      },
     "userTaxAddress" : {
       "regionCode": "KR"
     }
    }

### Report Play partner programs

Developers participating in partner programs such as the[Play Media Experience Program](https://play.google.com/console/about/programs/mediaprogram/)must provide the[`transaction_program_code`](https://developers.google.com/android-publisher/api-ref/rest/v3/externaltransactions)when reporting external transactions. If you are an eligible developer, contact your Business Development Manager for more information on how to set this field.

## Report purchase refunds to Google Play

Integrate with the`Externaltransactions`API to report transactions refunded to users outside Google Play's billing system. For Play to correctly identify which transaction has been refunded, you should include the corresponding`externalTransactionId`for the previously reported transaction as part of the URL parameters.

When reporting refunds of subscription purchases, reference the`externalTransactionId`of the specific recurrence of the subscription that is being refunded.

**Example**: Suppose a subscription has the following transactions:

- An initial transaction with external transaction ID*ABC.1234-5678-9012-34567*
- The first recurring transaction with external transaction ID*ABC.1234-5678-9012-34567..0*
- The second recurring transaction with external transaction ID*ABC.1234-5678-9012-34567..1*

To report a refund of all transactions for the subscription, you need to make three separate refund requests: one for the initial transaction and two for the subsequent transactions.

This method accepts both[full refunds](https://developers.google.com/android-publisher/api-ref/rest/v3/externaltransactions/refundexternaltransaction#fullrefund)(where the amount is the same amount that the user paid in the original external transaction) and[partial refunds](https://developers.google.com/android-publisher/api-ref/rest/v3/externaltransactions/refundexternaltransaction#partialrefund)(where the amount is smaller than what the user paid in the original external transaction). For partial refunds, you need to specify the pre-tax amount that was refunded.

## API quotas

The`Externaltransactions`API is subject to[daily API quotas](https://developers.google.com/android-publisher/quotas)for all calls, just like any other endpoint in the Google Play Developer API.

Additionally, the`Externaltransactions`API has a 1,200 Queries Per Minute (QPM) limit on calls to`Externaltransactions.createexternaltransaction`or`Externaltransactions.refundexternaltransaction`. Calls to`Externaltransactions.getexternaltransaction`don't count toward this 1,200 QPM limit.