We use essential cookies for the website to function, as well as analytics cookies for analyzing and creating statistics of the website performance. To agree to the use of analytics cookies, click "Accept All". You can manage your preferences at any time by clicking "Cookie Settings" on the footer. More Information.

Only Essential Cookies
Accept All

Documents from this version have been archived, and will not continue to be maintained. Please use the latest version.

HMS Core GuidesWallet KitApp DevelopmentDevelopment ScenarioGenerating and Pushing a JWE to the Huawei ServerAdding a Button for Claiming Passes in Your App

Adding a Button for Claiming Passes in Your App

You can add a button to your app. When a user taps the button, a WebView page is displayed, and your server sends a JWE to the Huawei server through an intent to obtain and display the pass claiming result.

The procedure is as follows:

  • 1. Define a template and push it to the Huawei server through the REST API.

  • 2. Add a button to your app.

  • 3. Generate an instance and send it as a JWE to the Huawei server when a user taps the button.

1 Define a Template

Define a template of common merchant information about all passes. The following uses loyalty cards of a merchant as an example.

Collapse
Word wrap
Dark theme
Copy code
  1. HwWalletObject hwWalletObject = new HwWalletObject();
  2. hwWalletObject.setPassVersion("10.0");
  3. hwWalletObject.setOrganizationName("xxx");
  4. hwWalletObject.setPassStyleIdentifier("Loyalty001"); // Template ID, which is unique.
  5. hwWalletObject.setPassTypeIdentifier("hwpass.loyalty.merchant"); // Service ID specified during service registration.
  6. hwWalletObject.setWebServiceURL("https://www.xxx.com"); // Callback URL used when a user claims a loyalty card.
  7. Fields fields = new Fields();
  8. fields.setCountryCode("CN");
  9. // Geofence information.
  10. List<Location> locationList = new ArrayList<>();
  11. Location location = new Location();
  12. location.setLongitude("11x.0679603815");
  13. location.setLatitude("2x.6592051284");
  14. locationList.add(location);
  15. fields.setLocationList(locationList);
  16. List<CommonFields> commonFields = new ArrayList<>();
  17. CommonFields cardImage = new CommonFields();
  18. cardImage.setKey("backgroundImage");
  19. cardImage.setValue("https://www.xxx.com/.../cardImage.png"); // URI of the background image of a loyalty card issued by the merchant.
  20. commonFields.add(cardImage);
  21. CommonFields logo = new CommonFields();
  22. logo.setKey("logo");
  23. logo.setValue("https://www.xxx.com/.../logo.png"); // URI of the merchant's logo.
  24. commonFields.add(logo);
  25. // Merchant name. The following provides sample code for defining merchant names in multiple languages. You can specify a random string here, for example, merchantNameI18N, for obtaining the merchant name in the corresponding language from the value of Localized.
  26. CommonFields merchantName = new CommonFields();
  27. merchantName.setKey("merchantName");
  28. merchantName.setValue("Some merchant name");
  29. merchantName.setLocalizedValue("merchantNameI18N");
  30. commonFields.add(merchantName);
  31. // Loyalty card name.
  32. CommonFields name = new CommonFields();
  33. name.setKey("name");
  34. name.setValue("Loyalty Card");
  35. commonFields.add(name);
  36. fields.setCommonFields(commonFields);
  37. List<AppendFields> appendFields = new ArrayList<>();
  38. AppendFields nearbyLocations = new AppendFields();
  39. nearbyLocations.setKey("nearbyLocations");
  40. nearbyLocations.setValue("https://www.xxx.com/.../nearbyLocation.html"); // URI of the page listing nearby stores of the merchant.
  41. nearbyLocations.setLabel("Nearby Locations");
  42. appendFields.add(nearbyLocations);
  43. AppendFields website = new AppendFields();
  44. website.setKey("website");
  45. website.setValue("https://www.xxx.com/.../merchantMainPage.html"); // URI of the merchant's main page.
  46. website.setLabel("Website");
  47. appendFields.add(website);
  48. AppendFields hotline = new AppendFields();
  49. hotline.setKey("hotline");
  50. hotline.setValue("400820XXXX"); // Merchant's hotline.
  51. hotline.setLabel("Hotline");
  52. appendFields.add(hotline);
  53. fields.setAppendFields(appendFields);
  54. List<ValueObject> imageList = new ArrayList<>();
  55. ValueObject imagePic = new ValueObject();
  56. imagePic.setValue("https://www.xxx.com/.../banner.png"); // Promotion image.
  57. imageList.add(imagePic);
  58. fields.setImageList(imageList);
  59. List<Localized> localizedList = new ArrayList<>();
  60. // Merchant name in Chinese, which can be obtained based on the previously specified string merchantNameI18N.
  61. Localized merchantNameChinese = new Localized();
  62. merchantNameChinese.setKey("merchantNameI18N");
  63. merchantNameChinese.setLanguage("zh-CN");
  64. merchantNameChinese.setValue("Merchant name in Chinese");
  65. localizedList.add(merchantNameChinese);
  66. // Merchant name in English, which can be obtained based on the previously specified string merchantNameI18N.
  67. Localized merchantNameEnglish = new Localized();
  68. merchantNameEnglish.setKey("merchantNameI18N");
  69. merchantNameEnglish.setLanguage("en-GB");
  70. merchantNameEnglish.setValue("Merchant name in English");
  71. localizedList.add(merchantNameEnglish);
  72. fields.setLocalized(localizedList);
  73. hwWalletObject.setFields(fields);

Push the template to the Huawei server through the following REST API using POST:

Collapse
Word wrap
Dark theme
Copy code
  1. POST
  2. https://{walletkit_server_url}/hmspass/v1/loyalty/model

Note: You need to replace {walletkit_server_url} in the preceding URL based on the region to which the server belongs. For privacy considerations, data of a region is kept within the region. It is recommended that you push the JWE to all of the following regions.For details, please refer to Wallet Server Address.

China

passentrust-drcn.wallet.hicloud.com

Russia

passentrust-drru.wallet.hicloud.com

Asia, Africa, and Latin America

passentrust-dra.wallet.hicloud.com

Europe

passentrust-dre.wallet.hicloud.com

The code for pushing hwWalletObject to the Huawei server is as follows:

Collapse
Word wrap
Dark theme
Copy code
  1. boolean validateClass = HwWalletObjectUtil.validateHwWalletObjectClass(hwWalletObject);
  2. if (validateClass) {
  3.  // post hwWalletObject to Huawei server
  4.  WalletBuildService walletBuildService = new WalletBuildServiceImpl();
  5.  HwWalletObject loyaltyClass = walletBuildService.postHwWalletClassToWalletServer("loyalty/model", hwWalletObject);
  6. }

2 Adding the Add to HUAWEI Wallet Button

Add a button to your app. A tap on the button will start an activity via the ACTION_VIEW intent. You can add either of the following URIs to the button:

Collapse
Word wrap
Dark theme
Copy code
  1. hms://www.huawei.com/payapp/{jwt_content}

Or

Collapse
Word wrap
Dark theme
Copy code
  1. https://{walletkit_website_url}/walletkit/consumer/pass/save?jwt={jwe_content}

Note: The former URI only applies to mobile phones with HMS Core (APK) installed. When the button is tapped, a page specified by HMS Core (APK) will be displayed, guiding the user to claim the card. The latter URI does not have such a restriction. It allows the user to claim the card by using a browser or the HUAWEI Wallet app that is installed on the user device.

3 Generating a JWT and Sending It to the Huawei Server

Generate an instance of a user's personalized information when a user taps the Add to HUAWEI Wallet button.

Collapse
Word wrap
Dark theme
Copy code
  1. HwWalletObject hwWalletObject = new HwWalletObject();
  2. hwWalletObject.setSerialNumber("854687156"); // Instance ID unique to the associated template.
  3. hwWalletObject.setPassStyleIdentifier("Loyalty001"); // Template ID, which is unique.
  4. hwWalletObject.setPassTypeIdentifier("hwpass.loyalty.merchant"); // Service ID specified during service registration.
  5. hwWalletObject.setOrganizationPassId("1231")
  6. Fields fields = new Fields();
  7. // Loyalty card status, which cannot be specified for an expired loyalty card.
  8. Status status = new Status();
  9. status.setState("active");
  10. status.setEffectTime("2019-11-11T00:00:00.000Z");
  11. status.setExpireTime("2029-11-10T23:59:59.999Z");
  12. fields.setStatus(status);
  13. // Template IDs and instance IDs of coupons associated with the loyalty card.
  14. List<LinkedPassId> relatedPassIds = new ArrayList<>();
  15. LinkedPassId linkedCoupon = new LinkedPassId();
  16. linkedCoupon.setTypeId("Coupon template id");
  17. linkedCoupon.setId("Coupon instance id");
  18. relatedPassIds.add(linkedCoupon);
  19. fields.setRelatedPassIds(relatedPassIdss);
  20. // Barcode or QR code.
  21. BarCode barCode = new BarCode();
  22. barCode.setText("Refresh every ten minutes");
  23. barCode.setType("codabar"); // codabar or qrCode
  24. barCode.setValue("829383819844342342");
  25. fields.setBarCode(barCode);
  26. List<CommonFields> commonFields = new ArrayList<>();
  27. // Member name. The following provides sample code for defining member names in multiple languages.
  28. CommonFields accountName = new CommonFields();
  29. accountName.setKey("accountName");
  30. accountName.setValue("Member name");
  31. accountName.setLocalizedValue("accountName18N");
  32. commonFields.add(accountName);
  33. // Loyalty card number.
  34. CommonFields cardNumber = new CommonFields();
  35. cardNumber.setKey("cardNumber");
  36. cardNumber.setValue("4527809736");
  37. commonFields.add(cardNumber);
  38. fields.setCommonFields(commonFields);
  39. List<AppendFields> appendFields = new ArrayList<>();
  40. // Loyalty points.
  41. AppendFields points = new AppendFields();
  42. points.setKey("points");
  43. points.setLabel("Points");
  44. points.setValue("1299");
  45. appendFields.add(points);
  46. AppendFields balance = new AppendFields();
  47. balance.setKey("balance");
  48. balance.setValue("$19");
  49. balance.setLabel("Balance");
  50. appendFields.add(balance);
  51. // Loyalty level.
  52. AppendFields level = new AppendFields();
  53. level.setKey("level");
  54. level.setValue("Gloden");
  55. level.setLabel("Level");
  56. appendFields.add(level);
  57. fields.setAppendFields(appendFields);
  58. List<Localized> localizedList = new ArrayList<>();
  59. // Member name in Chinese.
  60. Localized accountNameChinese = new Localized();
  61. accountNameChinese.setKey("accountName18N");
  62. accountNameChinese.setLanguage("zh-CN");
  63. accountNameChinese.setValue("Member name in Chinese");
  64. localizedList.add(accountNameChinese);
  65. // Member name in English.
  66. Localized accountNameEnglish = new Localized();
  67. accountNameEnglish.setKey("accountName18N");
  68. accountNameEnglish.setLanguage("en-GB");
  69. accountNameEnglish.setValue("Member name in English");
  70. localizedList.add(accountNameEnglish);
  71. fields.setImageList(localizedList);
  72. hwWalletObject.setFields(fields);

Convert the generated instance to a JWE, which consists of five parts:

  • Part 1: header

  • Part 2: RSA-encrypted session key, which is generated using the RSA public key provided by Huawei server

  • Part 3: initialization vector (IV), a string of 12 bytes

  • Part 4: HwWalletObject, which is encrypted and compressed using the AES-GCM method based on the session key (serving as the symmetric key) and the IV (serving as the encryption vector)

  • Part 5: signature, which is generated by signing the previous four parts using your JWE private key, which is obtained from HUAWEI Developers through an application process

Each part is Base64-encoded.

Note: It is recommended that you change the session key and IV each time.

Note: Classes CommonUtil, RandomUtils, and JweUtil are referenced but not implemented in the following code. For their definitions, please refer to Server Sample Code.

Collapse
Word wrap
Dark theme
Copy code
  1. // The app ID registered in AppGallery Connect.
  2. String appId = "Replace with your app ID";
  3. // Create a loyalty card instance and link it to a user.
  4. String newInstanceJson = CommonUtil.readWalletObject("LoyaltyInstance.json");
  5. JSONObject newInstanceJsonObject = JSONObject.parseObject(newInstanceJson);
  6. newInstanceJsonObject.put("iss", appId);
  7. // Generate a session key to encrypt payload data. A session key is a string of random hex numbers.
  8. String sessionKey = RandomUtils.generateSecureRandomFactor(16);
  9. System.out.println("sessionKey: " + sessionKey);
  10. // The public key provided by Huawei, which is used to encrypt the session key.
  11. String sessionKeyPublicKey =
  12.          "MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAgBJB4usbO33Xg5vhJqfHJsMZj44f7rxpjRuPhGy37bUBjSLXN+dS6HpxnZwSVJCtmiydjl3Inq3Mzu4SCGxfb9RIjqRRfHA7ab5p3JnJVQfTEHMHy8XcABl6EPYIJMh26kztPOKU2Mkn6yhRaCurhVUD3n9bD8omiNrR4rg442AJlNamA7vgKs65AoqBuU4NBkGHg0VWWpEHCUx/xyX6hIwqc1aD7P2f62ZHsKpNZBOek/riWhaVx3dTAa9ZS+Av3IGLOZiplhYIow9f8dlWyqs8nff9FZoJO03QhXLvOORT+lPAkW6gFzaoeMaGb40HakkZn3uvlAEKrKrtR0rZEok+N1hnboaAu8oaKK0rF1W6iNrXcFrO0rcrCsFTVF8qCa/1dFmIXwUd2M6cUzT9W0YkNyb6ZBbwEhjwBL4DNW4JfeF2Dzj0eZYlSuYV7e7e1e+XEO8lwPLAiy4bEFAWCaeuDVIhbIoBaU6xHNVQoyzct98gaOYxE4mVDqAUVmhfAgMBAAE=";
  13. // The private key you obtained during service application in AppGallery Connect.  
  14. String jweSignPrivateKey = "Replace with your private key.";
  15. // Generate a JWE.
  16. String jweStrByInstanceIds = JweUtil.generateJwe(sessionKey, jweSignPrivateKey,newInstanceJsonObject.toJSONString(), sessionKeyPublicKey);

Send the encoded JWE to the Huawei server through an intent.

Note: The JWE must be encoded using URLEncoder.encode(jweStrByInstanceIds, StandardCharsets.UTF_8.toString()).

Collapse
Word wrap
Dark theme
Copy code
  1. Intent intent = new Intent(Intent.ACTION_VIEW);
  2. intent.setData(Uri.parse("hms://www.huawei.com/payapp/{" + jwe_content + "}"));
  3. try {
  4.    startActivityForResult(intent, requestCode)
  5. } catch (ActivityNotFoundException e) {
  6. ...
  7. }
  8. Or
  9. Intent intent = new Intent(Intent.ACTION_VIEW);
  10. intent.setData(Uri.parse("https://{walletkit_website_url}/walletkit/consumer/pass/save?jwt={" + jwe_content + "}"));
  11. try {
  12.    startActivityForResult(intent, requestCode)
  13. } catch (ActivityNotFoundException e) {
  14. ...
  15. }


This page may contain third-party content. For details, click here.
Search in Guides
Enter a keyword.