目录

Public APIs

Obtaining an Access Token

This API is used to obtain an access token. Each HTTPS request sent to the HUAWEI Wallet server needs to contain an access token, which will be verified by the HUAWEI Wallet server.

[h2]API Prototype

[h2]Request Parameters

Request Header

Parameter Mandatory Type Description
Content-Type Yes String Content type. The value is application/x-www-form-urlencoded.

Request Body

Parameter Mandatory Type Description
grant_type Yes String Permission grant mode. Set this parameter to client_credentials, which indicates the client credential mode.
client_id Yes String OAuth 2.0 client ID obtained during app development preparations. For an app created in AppGallery Connect, set this parameter to the value of Client ID.
client_secret Yes String Client secret allocated to the client ID created in app development preparations. For an app created in AppGallery Connect, set this parameter to the value of Client Secret.

[h2]Request Example

grant_type=client_credentials&client_id=<Client ID>&client_secret=<Client secret>

[h2]Response Parameters

Response Header

Parameter Mandatory Type Description
Content-Type Yes String Content type. The value is application/json;charset=UTF-8.

Response Body

Parameter Mandatory Type Description
token_type Yes String Token type. The value is always Bearer.
access_token Yes String Access token.
expires_in No Long Access token validity period, in seconds. The default value is 3600 seconds (that is, 60 minutes).

[h2]Response Example

{
  "access_token": "<Returned access token>",
  "expires_in": 3600,
  "token_type": "Bearer"
}

[h2]Call Example

    public static String getToken(String clientId, String clientSecret) {
        HttpHeaders header = new HttpHeaders();
        header.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

        MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
        map.add("grant_type", "client_credentials");
        map.add("client_id", clientId);
        map.add("client_secret", clientSecret);

        String tokenUrl = ConfigUtil.instants().getValue("gw.tokenUrl");

        HttpEntity<MultiValueMap<String, String>> entity = new HttpEntity<>(map, header);
        ResponseEntity<JSONObject> exchange =
            REST_TEMPLATE.exchange(tokenUrl, HttpMethod.POST, entity, JSONObject.class);

        JSONObject response = exchange.getBody();
        if (response == null) {
            throw new NullPointerException("Get null token response.");
        }
        String accessToken = response.getString("access_token");
        if (Strings.isEmpty(accessToken)) {
            throw new NullPointerException("Get null access token.");
        }
        return accessToken;
    }

Device Authentication

This API is used to request the third-party management service to authenticate the authorization certificate after pre-personalization. The authentication request is forwarded by the HUAWEI Wallet server and the request body contains the applet's public key and its corresponding digital signature issued by the HUAWEI Wallet server.

[h2]API Prototype

webServiceURL indicates the domain name of the DK management service.

[h2]Request Parameters

Request Header

Parameter Mandatory Type Description
Content-Type Yes String Content type. The value is application/json;charset=UTF-8.
Authorization Yes String Token value in the linkDevicePass parameter, used to apply for a key card. The token is used to check whether the request is valid.

Request Body

Parent Node Parameter Subnode Parameter Type Mandatory/Optional Description
requestBody passTypeIdentifier String Mandatory Service ID registered when applying for Wallet Kit in AppGallery Connect.
requestBody serialNumber String Mandatory Number of the car key card on the HUAWEI Wallet server, which is used by the issuer to identify the card.
requestBody passVersion String Optional Version number, which is always 10.0.
requestBody userDeviceId String Mandatory Unique ID of a user device.
requestBody transId String Mandatory Random number.
signature - String Mandatory Signature of the hash value in requestBody, created by using the applet's identity private key.
certificate signature String Mandatory Signature value generated for the public key by the HUAWEI Wallet server using the private key. When receiving the request, the DK management service needs to use the public key provided by the HUAWEI Wallet server to authenticate the signature.
certificate publicKey String Mandatory Identity public key of the applet.

[h2]Request Example

{
  "requestBody": {
    "passTypeIdentifier": "Replace with the Service ID you applied on AGC",
    "passVersion": "10.0",
    "serialNumber": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "transId": "16198381994485116358",
    "userDeviceId": "xxx"
  },
  "certificate": {
    "publicKey": "xxx",
    "signature": "xxx"
  },
  "signature": "xxx"
}

[h2]Response Parameters

Response Header

Parameter Mandatory Type Description
Content-Type Yes String Content type. The value is application/json;charset=UTF-8.

Response Body

Parent Node Parameter Subnode Parameter Type Mandatory/Optional Description
Httpstatus - String Mandatory HTTP status code.
response certificate Certificate Optional Certificate returned, which is signed by the DK management service using the private key generated in step 5 of applying for Wallet Kit.

Certificate Parameters

Certificate Subnode Parameter Type Mandatory/Optional Description
signature String Mandatory Signature value generated for the public key by the HUAWEI Wallet server using the private key. When receiving the request, the DK management service needs to use the public key provided by the HUAWEI Wallet server to authenticate the signature.
publicKey String Mandatory Identity public key of the applet.

[h2]Response Example

{
  "httpStatus": "0",
  "response": {
    "certificate": {
      "signature": "xxx",
      "publicKey": "xxx"
    }
  }
}

[h2]Call Example of the Third-Party Management Service

For details about the complete call example, please refer to the sample code in Wallet Kit - Card Activation on the Server.

    public RegistrationsResponse dealWithRegisterRequest(String token, RegistrationsRequest request) {
        RegistrationsResponse response = new RegistrationsResponse();
        if (token == null) {
            response.setHttpStatus(String.valueOf(Constants.RESULT_CODE_PARAM_ERROR));
            return response;
        }
        if (!ParamChecker.isValidRegistrationsRequest(request)) {
            response.setHttpStatus(String.valueOf(Constants.RESULT_CODE_PARAM_ERROR));
            return response;
        }
        Certificate walletCertificate = request.getCertificate();
        if (!verifyWalletCert(walletCertificate)) {
            response.setHttpStatus(String.valueOf(Constants.RESULT_CODE_SIGN_ERROR));
            return response;
        }

        if (!ParamChecker.hashSignatureCheck(request.toJsonString(), request.getSignature(),
                appletAuthPublicKey, DataConvertUtil.SIGN_MODE_SHA256_RSA_MGF1)) {
            response.setHttpStatus(String.valueOf(Constants.RESULT_CODE_SIGN_ERROR));
            return response;
        }

        String userDeviceId = request.getRequestBody().getUserDeviceId();
        response.setHttpStatus(String.valueOf(Constants.RESULT_CODE_OK));
        Response responseBody = new Response();
        Certificate serverCert = PassData.getServerCert(appletAuthPublicKey);
        responseBody.setCertificate(serverCert);
        response.setResponse(responseBody);
        deviceIdCertMap.put(userDeviceId, serverCert);
        return response;
    }

Obtaining a Personal Data Token

This API is used to obtain a personal data token from the third-party management service. The request is forwarded by the HUAWEI Wallet server. The token will be used to calculate the hash value in the personal data request.

[h2]API Prototype

[h2]Request Parameters

Request Header

Parameter Mandatory Type Description
Content-Type Yes String Content type. The value is application/json;charset=UTF-8.
Authorization Yes String Token value in the linkDevicePass parameter, used to apply for a key card. The token is used to check whether the request is valid.

Request Body

Parent Node Parameter Subnode Parameter Type Mandatory/Optional Description
requestBody passTypeIdentifier String Mandatory Service ID registered when applying for Wallet Kit in AppGallery Connect.
requestBody serialNumber String Mandatory Number of the car key card on the HUAWEI Wallet server, which is used by the issuer to identify the card.
requestBody passVersion String Optional Version number, which is always 10.0.
requestBody userDeviceId String Mandatory Unique ID of a user device.
requestBody transId String Mandatory Random number.
signature - String Mandatory Signature of the hash value in requestBody, created by using the applet's identity private key.
certificate signature String Mandatory

Signature of the certificate returned by the device authentication API.

The DK management service signs the identity public key of the applet using the private key generated in step 5 of applying for Wallet Kit.

certificate publicKey String Mandatory Identity public key of the applet in the certificate returned by the device authentication API.

[h2]Request Example

{
  "requestBody": {
    "passTypeIdentifier": "Replace with the Service ID you applied on AGC",
    "passVersion": "10.0",
    "serialNumber": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "transId": "16198381994485116358",
    "userDeviceId": "xxx"
  },
  "certificate": {
    "publicKey": "xxx",
    "signature": "xxx"
  },
  "signature": "xxx"
}

[h2]Response Parameters

Response Header

Parameter Mandatory Type Description
Content-Type Yes String Content type. The value is application/json;charset=UTF-8.

Response Body

Parent Node Parameter Subnode Parameter Type Mandatory/Optional Description
Httpstatus - String Mandatory HTTP status code.
response token String Mandatory Personal data token.

[h2]Response Example

{
  "httpStatus": "0",
  "response": {
    "token": "sp.token.1619838979341"
  }
}

[h2]Call Example of the Third-Party Management Service

For details about the complete call example, please refer to the sample code in Wallet Kit - Card Activation on the Server.

    public RequestTokenResponse dealWithTokenRequest(RequestTokenRequest request) {
        RequestTokenResponse response = new RequestTokenResponse();
        String userDeviceId = request.getRequestBody().getUserDeviceId();
        Certificate spCertFromRequest = request.getCertificate();
        if (CommonUtils.isStringEmpty(userDeviceId) || !ParamChecker.checkSpServerCertificate(spCertFromRequest)) {
            response.setHttpStatus(String.valueOf(Constants.RESULT_CODE_PARAM_ERROR));
            return response;
        }
        Certificate cachedCert = deviceIdCertMap.get(userDeviceId);
        if (cachedCert == null) {
            response.setHttpStatus(String.valueOf(Constants.RESULT_CODE_SIGN_ERROR));
            return response;
        }
        if (!ParamChecker.hashSignatureCheck(request.toJsonString(), request.getSignature(),
                appletAuthPublicKey, DataConvertUtil.SIGN_MODE_SHA256_RSA_MGF1)) {
            response.setHttpStatus(String.valueOf(Constants.RESULT_CODE_SIGN_ERROR));
            return response;
        }
        response.setHttpStatus(String.valueOf(Constants.RESULT_CODE_OK));
        Response responseBody = new Response();
        String personalizeToken = PassData.getPersonalizeToken();
        responseBody.setToken(personalizeToken);
        deviceIdTokenMap.put(userDeviceId, personalizeToken);
        response.setResponse(responseBody);
        return response;
    }

Obtaining Personal Data

This API is used to obtain personal data from the third-party management service. The request is forwarded by the HUAWEI Wallet server.

[h2]API Prototype

[h2]Request Parameters

Request Header

Parameter Mandatory Type Description
Content-Type Yes String Content type. The value is application/json;charset=UTF-8.
Authorization Yes String Token value returned by the API for obtaining a personal data token. The token is used to check whether the request is valid.

Request Body

Parent Node Parameter Subnode Parameter Type Mandatory/Optional Description
requestBody cardSEId String Mandatory Unique ID of an applet, which can be used to distribute the car key.
requestBody passTypeIdentifier String Mandatory Service ID registered when applying for Wallet Kit in AppGallery Connect.
requestBody serialNumber String Mandatory Number of the car key card on the HUAWEI Wallet server, which is used by the issuer to identify the card.
requestBody passVersion String Optional Version number, which is always 10.0.
requestBody userDeviceId String Mandatory Unique ID of a user device.
requestBody personalizePublicKey String Mandatory Personal public key of the applet, which is used to encrypt personal data field values.
requestBody personalizeCert String Mandatory Signature of personalizePublicKey, created by using the applet's identity private key.
requestBody personalizeCertType String Mandatory Fixed value. The private-key signature is used by default.
requestBody transPublicKey String Mandatory Transaction public key, which is used to encrypt the returned symmetric key and make a digital envelope for the returned data.
requestBody transId String Mandatory Transaction ID, which is used to combine the returned symmetric key.
signature - String Mandatory Signature of the hash value in requestBody, created by using the applet's identity private key. The token obtained by calling the API for obtaining a personal data token is used as a key value in requestBody for hash value calculation.
certificate signature String Mandatory

Signature of the certificate returned by the device authentication API.

The DK management service signs the identity public key of the applet using the private key generated in step 5 of applying for Wallet Kit.

certificate publicKey String Mandatory Identity public key of the applet in the certificate returned by the device authentication API.

[h2]Request Example

{
  "requestBody": {
    "cardSEId": "xxxxxxxxxxxxxxxx",
    "personalizeCert": "xxx",
    "personalizeCertType": "",
    "personalizePublicKey": "xxx",
    "transPublicKey": "xxx",
    "passTypeIdentifier": "Replace with the Service ID you applied on AGC",
    "passVersion": "10.0",
    "serialNumber": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "transId": "858947076d58a5e66ee22b9ed1c43c4d",
    "userDeviceId": "xxx"
  },
  "certificate": {
    "publicKey": "xxx",
    "signature": "xxx"
  },
  "signature": "xxx"
}

[h2]Response Parameters

Response Header

Parameter Mandatory Type Description
Content-Type Yes String Content type. The value is application/json;charset=UTF-8.

Response Body

Parent Node Parameter Subnode Parameter Type Mandatory/Optional Description
Httpstatus - String Mandatory HTTP status code.
response encryptSessionKey String Mandatory Session key encrypted by the DK management service using transPublicKey in the request. The fields involved in encryption using Base64 encoding are described as follows: The AES128 values of aesKey and aesIv are generated by the third-party management service and are used to generate encryptAppletPersonalizeFields and encryptDevicePass after encryption. The values of transId, aesKey, and aesIv are encrypted using transPublicKey in the request and then encoded by Base64 to obtain encryptSessionKey. Encryption algorithm: RSA/ECB/OAEPWithSHA-256AndMGF1Padding.
response encryptDevicePass String Optional Empty string.
response encryptAppletPersonalizeFields String Mandatory Personal data parameter of the applet, used for authentication and data encryption and decryption during Bluetooth/NFC card swiping. The parameter is encrypted by the DK management service using the generated session key. The value is then encoded by Base64.
signature - String Mandatory The DK management service signs the hash value of the response using the private key generated in step 5 of applying for Wallet Kit.
encryptAppletPersonalizeFields Subnode Parameter Type Mandatory/Optional Storage Format Description
temp_key String Mandatory - Plaintext of AES128 key, left padded with a fixed hexadecimal string 34810233 and then encrypted using appletPublicKey. The AES128 key contains 16 bytes and is used to encrypt CardId and cardPrivateInfo. The encryption algorithm is RSA/NONE/OAEPWithSHA1AndMGF1Padding.
temp_iv String Mandatory - AES-128 IV encrypted using appletPublicKey (applet's personal public key), which contains 16 bytes and is used by the applet to decrypt the card data. The encryption algorithm is RSA/NONE/OAEPWithSHA1AndMGF1Padding.
card_id String Mandatory 9F3B + Lc + CardId Unique ID of a card issued by the issuer, which is the same as the value of serialNumber defined when the key card is generated. The ID contains 16 bytes. The card ID is encoded in TLV format, where T=9F3B indicates the data type, Lc=10 specifies the length as 10 bytes, and V represents the card ID. The entire TLV is encrypted using aesKey and aesIv and then converted into a hexadecimal string. The CBC encryption mode is used and the encryption algorithm is AES/CBC/NoPadding.
card_key String Mandatory - Key of a card, which contains 16 bytes and is used to calculate SessionKey. Each card supports one key. The key is left padded with 34010133, and then the entire string is converted into a hexadecimal string and encrypted using appletPublicKey. The encryption algorithm is RSA/NONE/OAEPWithSHA1AndMGF1Padding.
card_info String Mandatory 9F05 + Lc + CardInfo1 + 9F31 + Lc + CardAuthParameter Private information about a card, which can be read before authentication (GetProcessData step) and stored in TLV format (with multiple TLV records combined). The plaintext TLV data is padded with 800...00 to a multiple of 16 bytes. The result is encrypted using aesKey and aesIv, and then converted into a hexadecimal string. The CBC encryption mode is used and the encryption algorithm is AES/CBC/NoPadding.
card_privateInfo String Mandatory - Private information about a card, such as the validity period and permissions. The information is read after authentication (ReadBinary step) and parsed by the third-party management service. The plaintext data is padded with 800...00 to a multiple of 16 bytes. The result is encrypted using aesKey and aesIv, and then converted into a hexadecimal string. The CBC encryption mode is used and the encryption algorithm is AES/CBC/NoPadding.
card_key_iv String Mandatory Lc + CardKeyIV Session key negotiated in the transaction process (which needs to be delivered to the car synchronously). The value contains 16 bytes. If you do not need to use this value, pass zeros for all bytes.

[h2]Response Example

{
  "httpStatus": "0",
  "response": {
    "encryptDevicePass": "xxx",
    "encryptAppletPersonalizeFields": "xxx",
    "encryptSessionKey": "xxx"
  },
  "signature": "xxx"
}

[h2]Call Example of the Third-Party Management Service

For details about the complete call example, please refer to the sample code in Wallet Kit - Card Activation on the Server.

    public PersonalizeResponse dealWithPersonalizeDataRequest(String token, PersonalizeRequest request) {
        PersonalizeResponse response = new PersonalizeResponse();
        RequestBody requestBody = request.getRequestBody();
        String userDeviceId = requestBody.getUserDeviceId();
        Certificate spCertFromRequest = request.getCertificate();
        String cachedToken = deviceIdTokenMap.remove(userDeviceId);
        if (cachedToken == null || !cachedToken.equals(token)) {
            response.setHttpStatus(String.valueOf(Constants.RESULT_CODE_PARAM_ERROR));
            return response;
        }
        if (CommonUtils.isStringEmpty(userDeviceId) || !ParamChecker.checkSpServerCertificate(spCertFromRequest)) {
            response.setHttpStatus(String.valueOf(Constants.RESULT_CODE_PARAM_ERROR));
            return response;
        }

        Certificate cachedCert = deviceIdCertMap.get(userDeviceId);
        if (cachedCert == null) {
            response.setHttpStatus(String.valueOf(Constants.RESULT_CODE_PARAM_ERROR));
            return response;
        }
        if (!ParamChecker.hashSignatureCheck(request.toJsonString(token), request.getSignature(),
                appletAuthPublicKey, DataConvertUtil.SIGN_MODE_SHA256_RSA_MGF1)) {
            response.setHttpStatus(String.valueOf(Constants.RESULT_CODE_SIGN_ERROR));
            return response;
        }
        String personalizePKSign = requestBody.getPersonalizeCert();
        byte[] srcBytes = DataConvertUtil.base64Decode(requestBody.getPersonalizePublicKey());
        if (!DataConvertUtil.checkSign(srcBytes, personalizePKSign,
                appletAuthPublicKey, DataConvertUtil.SIGN_MODE_SHA256_RSA_MGF1)) {
            response.setHttpStatus(String.valueOf(Constants.RESULT_CODE_SIGN_ERROR));
            return response;
        }
        response.setHttpStatus(String.valueOf(Constants.RESULT_CODE_OK));
        PassDataResponse passData = getDevicePassData(requestBody);
        response.setResponse(passData);
        String passDataStr = passData.toJsonString();
        String passHashValue = DataConvertUtil.encodeSHA256(passDataStr);
        String signature = DataConvertUtil.signData(passHashValue, Constants.SERVER_SECRET_KEY);
        response.setSignature(signature);
        return response;
    }