API for Verifying the Purchase Token for the Order Service

Function

This API is used to verify the purchase token in the payment result sent from the Huawei IAP server to ensure payment accuracy.

Scenario

After a payment is complete, the IAP client returns a purchase order details JSON string InAppPurchaseData and a signature string inAppDataSignature. The app can verify the signature string to ensure the accuracy of order details.

If the app has high security requirements and needs to verify order information on the Huawei IAP server, the app can parse the purchaseToken parameter from InAppPurchaseData and call this API to send a verification request to the Huawei IAP server. The purchaseToken parameter uniquely identifies the mapping between a product and a user.

说明
  • This API applies only to non-subscription products, including consumables and non-consumables.
  • This API is optional and should be called only when the app requires server verification.
  • Only the latest token of a specified product can be verified. Otherwise, an error message is returned. For example, a user has purchased a consumable and token A is generated, and the user confirms the consumption. Token B is generated when the user purchases the consumable again. In this case, an error message will be returned if token A is verified.
  • Before delivery, use this API to verify the purchase token. After the delivery is successful, call the consumeOwnedPurchase API of the IAP client or the API for Confirming the Purchase for the Order Service of the IAP server to confirm the delivery. If this API is called to verify the purchase token after the delivery is confirmed, an error message will be displayed.

Restrictions

The response body must be verified using the public RSA payment key of the app. For details, please refer to Verifying the Signature in the Returned Result. For details about how to obtain the public payment key, please refer to Querying IAP Information.

Prototype

Protocol

HTTPS POST

Direction

Developer server -> Huawei IAP server

URL

{rootUrl}/applications/purchases/tokens/verify

说明

The value of rootUrl varies depending on the site. You must select the nearest site for access. For details, please refer to Site Information and Site Selection.

Data Format

Request: Content-Type: application/json

Response: Content-Type: application/json

Request Parameters

Request Header

Parameter

Mandatory (M)/Optional (O)

Type

Description

Content-Type

M

String

Value: application/json; charset=UTF-8

Authorization

M

String

Authentication information, which should contain data generated based on the access token for authentication by the Huawei IAP server. The access token is obtained through the Huawei public API for OAuth 2.0-based authentication. The authentication information format is described in Overview, and for details about how to obtain the access token, please refer to API for Obtaining an App-Level Access Token.

HW-IAP-APPINFO

O

String

Extended information, through which the signature algorithm can be passed. To learn more, please refer to Signature Algorithm.

Request Body

Parameter

Mandatory (M)/Optional (O)

Type

Description

purchaseToken

M

String

Purchase token of a product to be delivered. It is returned when a request is initiated to purchase a product or query information about the product to be consumed.

productId

M

String

ID of a product to be delivered. If a product is managed by the PMS, the product ID is the same as that set when you configure product information in AppGallery Connect. If the product is not managed by the PMS, you need to create an ID.

Request Example

POST /applications/purchases/tokens/verify
Content-Type: application/json; charset=UTF-8
Authorization: Basic QVQ6Q1YzQ1NPbVlBaGwrZUtRWExtMTBVV2pyWXZHTVF4MmYvcVMya1B0ZElLY3UwaFJrdFNTMmxwdk1FQkIyYldXWGt0REVaR3I4UjFUTTRLMVlmNXdwWU80RG04THdXQWxjaFhEYjBMUjBNTUJtWnFYcGFtazc3THN3UnFJbkhHK28xekdqRzNSMg==
Accept: application/json
Content-Length: 143
{
  "purchaseToken": "00000173741056a37eef310dff9c6a86fec57efafe318ae478e52d9c4261994d64c8f6fc8ea1abbdx5347.5.3089",
  "productId": "prd1"
}

Response Parameters

Response Header

Parameter

Mandatory (M)/Optional (O)

Type

Description

Content-Type

M

String

Value: application/json; charset=UTF-8

Response Body

Parameter

Mandatory (M)/Optional (O)

Type

Description

responseCode

M

String

Result code. The options are as follows:

  • 0: success
  • Other values: failure. For details about the result codes, please refer to Result Codes.

responseMessage

O

String

Response description.

purchaseTokenData

O

String

JSON string that contains purchase data. For details, please refer to InappPurchaseDetails.

This parameter should be used for signature without any changes.

dataSignature

O

String

Signature information of purchaseTokenData signed by the RSA private key of the app. Find the signature algorithm from the value of signatureAlgorithm. The app can perform signature verification on the JSON string of PurchaseTokenData using the public payment key. For details, please refer to Verifying the Signature in the Returned Result.

signatureAlgorithm

M

String

Signature algorithm.

Response Example

HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
Content-Length: 1020
{
  "responseCode": "0",
  "purchaseTokenData": "{\"autoRenewing\":false,\"orderId\":\"202008172303339595b1212421.123456\",\"packageName\":\"com.huawei.packagename\",\"applicationId\":123456,\"kind\":0,\"productId\":\"3\",\"productName\":\"Product name\",\"purchaseTime\":1597676623000,\"purchaseTimeMillis\":1597676623000,\"purchaseState\":0,\"developerPayload\":\"payload data\",\"purchaseToken\":\"00000173741056a37eef310dff9c6a86fec57efafe318ae478e52d9c4261994d64c8f6fc8ea1abbdx5347.5.3089\",\"consumptionState\":0,\"confirmed\":0,\"currency\":\"CNY\",\"price\":\"100\",\"country\":\"CN\",\"payOrderId\":\"WX123456789ce8e23ee927\",\"payType\":\"17\"}",
  "dataSignature": "FiJJZYRdVIFgEzDA4GbGrR/JbmExXgXJOnYLINc1besVPKakC01NuwfD54HFYKcm092iwoctqEbGleODbwjINRv047320p51dzeXozB8ozjqXQ2DlkaMgYUe0CLgB72ttkYG2EIrHyJullNpPuaMXNQ6R5DOrY0XRLDF4yOpiRoSHuQohTVk2wx5ugZ7537E2c5ZCc/AmiGLJT1Uxh4EDyTB8aGBZTWJgy2D/ogJLW86PKpVREhJEWxVco1IbVe5dvjutheh5oBfRcsJg+AgSLoNgbKvjn1dNlEGc4VoRsJSBP1M5ukYgh16r4y7DBqBA/QrRE7ocvzzPm/W/teeng==",
  "signatureAlgorithm":"SHA256WithRSA"
}

Call Example

说明

After a payment is complete, your app obtains the JSON string InAppPurchaseData, which contains the accountFlag field.

The following is a part of Java sample code in Server Sample Code, in which you also can find sample code of other languages. You can download the sample code to check the libraries and methods in detail.

Java
Python
Go
public class OrderService {    
    // Use the actual IP address and port number in ip:port. Process logic related to certificate authentication when HTTPS is used.
    public static final String TOC_SITE_URL = "https://ip:port";

    // Service address provided for telecom carriers.
    public static final String TOBTOC_SITE_URL = "https://orders-at-dre.iap.dbankcloud.com";

    // The value of accountFlag can be obtained from InAppPurchaseData.
    public static String getRootUrl(Integer accountFlag) {
        if (accountFlag != null && accountFlag == 1) {
            return TOBTOC_SITE_URL;
        }
        return TOC_SITE_URL;    
    }
    public static void verifyToken(String purchaseToken, String productId, Integer accountFlag) throws Exception {
        // Obtain the app-level access token.
        String appAt = AtDemo.getAppAT();
        // Construct an Authorization field in the request header.
        Map<String, String> headers = AtDemo.buildAuthorization(appAt);

        // Generate the request body.
        Map<String, String> bodyMap = new HashMap<>();
        bodyMap.put("purchaseToken", purchaseToken);
        bodyMap.put("productId", productId);

        String msgBody = JSONObject.toJSONString(bodyMap);
       // In the demo, 5000 is used as the timeout interval. You can adjust the value as required.
        String response = AtDemo.httpPost(getRootUrl(accountFlag) + "/applications/purchases/tokens/verify",
            "application/json; charset=UTF-8", msgBody, 5000, 5000, headers);
        // Display the response as a character string on the console. You can replace the processing method based on the service logic.
        System.out.println(response);
    }
}
class OrderService:
    def __init__(self):
        # TODO: Replace ip:port with the actual IP address and port number. Process logic related to certificate authentication when HTTPS is used.
        self.TOC_SITE_URL = "https://ip:port"
        self.TOBTOC_SITE_URL = "https://orders-at-dre.iap.dbankcloud.com"
        self.verifyTokenUrl = "%s/applications/purchases/tokens/verify"

    def getRootUrl(self, accountFlag):
        if accountFlag is not None and accountFlag == 1:
            return self.TOBTOC_SITE_URL
        return self.TOC_SITE_URL

    def verifyToken(self, purchaseToken, productId, accountFlag):
        # Obtain the app-level access token.
        appAt = AtDemo.getAppAT()
        if appAt is None or appAt == "":
            return
        # Add authorization information to the request header.
        headers = AtDemo.buildAuthorization(appAt)
        # Generate the request body.
        bodyDict = {"purchaseToken": purchaseToken, "productId": productId}
        data = json.dumps(bodyDict)
        response = AtDemo.httpPost(self.verifyTokenUrl % self.getRootUrl(accountFlag), str.encode(data), headers)
        # TODO: Show the response as a character string in the console. You can change the processing method based on the service logic.
        print(response)
type OrderClient struct {
}

var OrderDemo = &OrderClient{}

func getOrderUrl(accountFlag int) string {
  if accountFlag == 1 {
    // Service address provided for telecom carriers.
    return  "https://orders-at-dre.iap.dbankcloud.com"
  } else {
    // Replace ip:port with the actual IP address and port number. Process logic related to certificate authentication when HTTPS is used.
    return  "https://ip:port"
  }
}

func (orderDemo *OrderClient) VerifyToken(purchaseToken, productId string, accountFlag int) {
  bodyMap := map[string]string{"purchaseToken": purchaseToken, "productId": productId}
  url := getOrderUrl(accountFlag)+ "/applications/purchases/tokens/verify"
  bodyBytes, err := SendRequest(url, bodyMap)
  if err != nil {
    log.Printf("err is %s", err)
  }
  // TODO: Show the response as a character string in the console. You can replace the processing method based on the service logic.
  log.Printf("%s", bodyBytes)
}
搜索
请输入您想要搜索的关键词