Fovea.Billing

is now IAPTIC, please go to the new and better version of our system.

Validate API

This page is archived Fovea.Billing documentation. It is kept online for reference and is no longer updated. For current documentation, see the current /v1/validate page.
POST /v1/validate
Validate and retrieve information from a raw receipt.

Requirements

Request body

The /v1/validate request returns a JSON object containing…

{
  "id": "com.example.app",
  "type": "application",
  "transaction": {
    "id": "com.example.app",
    "type": "ios-appstore",
    "appStoreReceipt": "MIIabcdefgh...xyz=="
  },
  "additionalData": {
    "applicationUsername": "james_bond_007"
  }
}
Property name Type Description
id string Identifier of the product you want to validate. On iOS, can be set to your application identifier.
type string Type of product being validated. Possible values:

  • application – Validate the application download (Apple only).
  • paid subscription – An auto-renewing subscription.
  • non renewing subscription – A non renewing subscription.
  • consumable – A consumable product.
  • non consumable – A non-consumable product.
additionalData.applicationUsername string Attach the purchases to the given application user.

Apple validation request

Fields specific to Apple receipt validation.

Property name Type Description
transaction.type string “ios-appstore”
transaction.id string Identifier of the transaction to evaluate, or set it to your application identifier if id has been set so.
transaction.appStoreReceipt string Base64 encoded appStoreReceipt.

Google validation request

Fields specific to Google receipt validation.

Property name Type Description
transaction.type string “android-playstore”
transaction.id string Identifier of the transaction to evaluate, corresponds to the orderId in the receipt from Google
transaction.purchaseToken string The purchase token.
transaction.receipt string JSON-encoded receipt.
transaction.signature string Signature for the attached receipt.

Microsoft validation request

Fields specific to Microsoft Store receipt validation.

Notice: validation for microsoft can respond with specific fields set:

  • data.serviceTicketType – “purchase” or “collections”
  • data.serviceTicket – an authentication ticket

The value of this ticket is used to retrieve the storeId required in the validation request. Contact us if you need assistance with that.

Property name Type Description
transaction.type string “windows-store-transaction”
transaction.storeId string (Microsoft only) Identifier of the product to validate.
license.storeIdKey_collections string Microsoft b2bKey for collections
license.storeIdKey_purchase string Microsoft b2bKey for purchases

Success response body

The /v1/validate request data should be a JSON object containing…

{
  "ok": true,
  "data": {
    "ineligible_for_intro_price": [
      "my_subscription"
    ],
    "transaction": {
      "platform-specific transaction data": "can be ignored"
    },
    "collection": [
      {
        "id": "my_subscription",
        "isBillingRetryPeriod": false,
        "isTrialPeriod": false,
        "isIntroPeriod": false,
        "renewalIntent": "Lapse",
        "purchaseDate": 1569766544000,
        "expiryDate": 1583749446000,
        "cancelationReason": "Customer",
        "lastRenewalDate": 1583749266000,
        "isExpired": true
      },
      {
        "id": "my_subscription",
        "isTrialPeriod": false,
        "isIntroPeriod": true,
        "purchaseDate": 1569766544000,
        "expiryDate": 1569769054000,
        "lastRenewalDate": 1569768754000,
        "isExpired": true
      }
    ]
  }
}
Property name Type Description
ok boolean True if the validation request was successful.
data.collection array An array of Purchase object. See below.
data.ineligible_for_intro_price array An array of product IDs for which the user cannot use introductory prices

Purchase

A purchase object.

Property name Type Description
id string The unique identifier of the product.
purchaseDate number Time at which the product was granted, in milliseconds since epoch
expiryDate number Time at which the current (or last active) subscription is set to expire, in milliseconds since epoch
isExpired boolean Whether a subscription has expired. Check the cancelationReason field to know the reason why the subscription has expired.
renewalIntent string Whether the customer intents to let a subscription be renewed when it reaches its current expiry time. Possible values:

  • Renew – The subscription will renew at the end of the current subscription period.
  • Lapse – The customer has turned off automatic renewal for the subscription. Check the cancelationReason field for details.
renewalIntentChangeDate number Last time the customer or system changed the renewalIntent status.
cancelationReason string The reason why a transaction was canceled, a subscription is not auto-renewing or expired. Possible values are:

  • Developer – Subscription canceled by the developer.
  • System – Subscription canceled by the system for an unspecified reason.
  • System.Replaced – Subscription upgraded or downgraded to a new subscription.
  • System.ProductUnavailable – Product not available for purchase at the time of renewal.
  • System.BillingError – Billing error; for example customer’s payment information is no longer valid.
  • System.Deleted – Subscription is gone; generally when the user account has been deleted.
  • Customer – Subscription canceled by the user for an unspecified reason.
  • Customer.TechnicalIssues – Customer canceled their transaction due to an actual or perceived issue within your app.
  • Customer.PriceIncrease – Customer did not agree to a recent price increase. See also priceConsentStatus.
  • Customer.Cost – Customer canceled for cost-related reasons.
  • Customer.FoundBetterApp – Customer claimed to have found a better app.
  • Customer.NotUsefulEnough – Customer did not find the product useful enough.
  • Customer.OtherReason – Subscription canceled for another reason; for example, if the customer made the purchase accidentally.
  • Unknown – Subscription canceled for unknown reasons.

You can use this value to display an alternative subscription product in your app, to win back the customer, such as a lower-level subscription plan to which the user can downgrade from their current plan. Consider presenting an attractive upgrade or downgrade offer.

isBillingRetryPeriod boolean Whether an auto-renewable subscription is in the billing retry period.

  • true – The platform is attempting to renew the subscription.
  • false – The platform has stopped attempting to renew the subscription.

This field indicates whether the platform is attempting to renew an expired subscription automatically. If the customer’s subscription failed to renew because the platform was unable to complete the transaction, this value reflects whether the platform is still trying to renew the subscription. You can use this field to:

  • Inform the user that there may be an issue with their billing information. For example, an expired credit card or insufficient balance could prevent this customer’s account from being billed.
  • Implement a grace period to improve recovery, if the value is true and the isExpired field is set. A grace period is free or limited subscription access while a subscriber is in a billing retry state.
isTrialPeriod boolean Whether a subscription is in the free trial period. Possible values are:

  • true – The subscription is in the free trial period
  • false – The subscription is not in the free trial period
isIntroPeriod boolean Whether an auto-renewable subscription is in the introductory price period.
discountId string Identifier of the subscription offer redeemed by the user. (iOS only)
You provide this value in the Promotional Offer Product Code field when you create the subscription offer in App Store Connect. You can use this value to:

  • Confirm that the sale of the subscription was from a subscription offer.
  • Confirm which subscription offer was redeemed.
  • Keep track of the subscription offers that a user has redeemed to limit discounts you offer, according to your business model.
priceConsentStatus string Price consent status for a subscription price increase. Possible values:

  • Notified – Customer has been notified of the price increase but did not agree to it.
  • Agreed – Customer agreed to the price increase.

Error response

When the validation was not successful or the validated product is not owned, /v1/validate answers HTTP 200 with a JSON object containing the fields below. Errors raised by the validation handler also repeat a deprecated data.code / data.error.message pair and add a diagnostic source object; neither is part of this contract, so the example below leaves them out.

{
  "ok": false,
  "route": "/validate",
  "status": 419,
  "code": 6778003,
  "message": "Transaction has expired 2020-03-09T10:24:06.000Z",
  "data": {
    "latest_receipt": true
  }
}
Property name Type Description
ok boolean False if the validation request was unsuccessful or the requested product is not owned.
route string The route that failed, without the /v1 prefix: /validate.
status number The error status, repeated in the body. The HTTP status stays 200.
code number or string The error code: the 6778xxx family is returned as a number, the application-level family as the code’s name. Possible values:

  • 6778001 – Invalid payload – something is wrong about the request.
  • 6778002 – Connection failed – Apple, Google or Microsoft servers are not reachable.
  • 6778003 – Subscription expired – The subscription product is expired and has not been renewed.
  • 6778004 – Purchase consumed – The consumable product has been consumed already.
  • 6778005 – Internal error – Something prevented the server from processing your request.
  • 6778006 – Need more data – Requesting more data to complete the request.
  • 6778007 – Unknown
  • “AppNotFound” – Wrong app name.
  • “Forbidden” – The provided credentials do not allow this request.
  • “DatabaseError” – An error occurred at the database level.
  • “ResourceNotFound” – A named thing the request refers to, or a configuration key the app needs, is missing.
message string Plain english description of the error.
data object Kept for backward compatibility with older client versions: latest_receipt is true when the latest receipt was used. Its code and error.message members are deprecated duplicates – read the top-level code and message.