Create Samsung Wallet Card Templates Using the Server API

M. A. Hasan Molla

Engineer, Samsung Developer Program

Samsung Wallet Partners can create and update card templates to meet their business needs through the Wallet Partners Portal. However, if the partner has a large number of cards, it can become difficult to manage them using the Wallet Partners Portal website. To provide partners with more flexibility, Samsung provides server APIs so that partners can easily create and modify Samsung Wallet card templates without using the Wallet Partners Portal. With these APIs, partners can also create their own user interface (UI) or dashboard to manage their cards.

In this article, we implement the Add Wallet Card Templates API to create a card template for a Coupon in the Wallet Partners Portal. We focus on the API implementation only and do not create a UI for card management.

Prerequisites

  1. If you are new to Samsung Wallet, complete the onboarding process and get the necessary certificates.
  2. As a Samsung Wallet Partner, you need permission to use this API. Only authorized partners are allowed to create wallet card templates using this API. You can reach out to Samsung Developer Support for further assistance.

API overview

The REST API discussed in this article provides an interface to add wallet card templates directly from the partner's server. This API utilizes a base URL, specific headers, and a well-structured body to ensure seamless integration.

URL: This is the endpoint where the request is sent to create a new wallet card template.

https://tsapi-card.walletsvc.samsung.com/partner/v1/card/template

Headers: The information provided in the headers ensures secure communication between the partner's server and Samsung's server.

  • Authorization: The Bearer token. See the JSON Web Token documentation for details.
  • X-smcs-partner-id: This is your partner ID. The partner ID gives you permission to use the API.
  • X-request-id: Use a randomly generated UUID string in this field.

Body: The body must be in the JWT token format. Convert the payload data (card template in JSON format) into a JWT token.

For more details about the API, refer to the documentation.

Implementation of the API to create a card template

The Add Wallet Card Templates API allows you to add a new card template to the Wallet Partners Portal. You can also create the card in the portal directly, but this API generates a new card template from your server, without requiring you to launch the Wallet Partners Portal. Follow these steps to add a new card template.

Step 1: Extracting the keys

Extract the following keys from the certificates. These keys are used while generating the JWT token.

RSAPublicKey partnerPublicKey = (RSAPublicKey) readPublicKey("partner.crt");
RSAPublicKey samsungPublicKey = (RSAPublicKey) readPublicKey("samsung.crt");
PrivateKey partnerPrivateKey = readPrivateKey("private_key.pem");

Extracting the public keys

Use the following code to extract the partner public key and the Samsung public key from the partner.crt and samsung.crt certificate files, respectively. You received these certificate files during the onboarding process.

private static PublicKey readPublicKey(String fileName) throws Exception {
    // Load the certificate file from resources
    ClassPathResource resource = new ClassPathResource(fileName);
    try (InputStream in = resource.getInputStream()) {
        CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
        X509Certificate certificate = (X509Certificate) certFactory.generateCertificate(in);
        return certificate.getPublicKey();
    }
}

Extracting the private key

The following code extracts the private key from the .pem file you generated during the onboarding process. This key is needed to build the auth token.

private static PrivateKey readPrivateKey(String fileName) throws Exception {
    String key = new String(Files.readAllBytes(new ClassPathResource(fileName).getFile().toPath()));
    key = key.replace("-----BEGIN PRIVATE KEY-----", "").replace("-----END PRIVATE KEY-----", "").replaceAll("\\s", "");
    byte[] keyBytes = Base64.getDecoder().decode(key);
    KeyFactory keyFactory = KeyFactory.getInstance("RSA");
    return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(keyBytes));
}

Step 2: Generating the authorization token

Samsung's server checks the authorization token of the API request to ensure the request is from an authorized partner. The authorization token is in the JWT format. Follow these steps to create an authorization token:

Building the auth header

Create an authHeader. Set “AUTH” as its payload content type to mark it as an authorization token. As you can create multiple certificates, use the corresponding certificate ID of the certificate that you use in the project. You can get the certificate ID from “My account > Encryption Management” of the Wallet Partners Portal.

    // create auth header
    JSONObject authHeader = new JSONObject();
    authHeader.put("cty", "AUTH");
    authHeader.put("ver", 3);
    authHeader.put("certificateId", certificateId);
    authHeader.put("partnerId", partnerId);
    authHeader.put("utc", utcTimestamp);
    authHeader.put("alg", "RS256");

Creating the payload

Create the payload using the authHeader. Follow this code snippet to create the payload.

    // create auth payload
    JSONObject authPayload = new JSONObject();
    authPayload.put("API", new JSONObject().put("method", "POST").put("path", "/partner/v1/card/template"));
    authPayload.put("refId", UUID.randomUUID().toString());

Building the auth token

Finally, generate the authorization token. For more details, refer to the “Authorization Token” section of the Security page

private static String generateAuthToken(String partnerId, String certificateId, long utcTimestamp, PrivateKey privateKey) throws Exception {
        
    // create auth header

    // create auth payload

    // return auth token
    return Jwts.builder()
            .setHeader(authHeader.toMap())
            .setPayload(authPayload.toString())
            .signWith(privateKey, SignatureAlgorithm.RS256)
            .compact();
}

Step 3: Generating a payload object token

The request body contains a parameter named “ctemplate” which is a JWT token. Follow these steps to create the “ctemplate.”

Creating the card template object

Select the proper card template you want to create from the Card Specs documentation. Get the payload object as JSON format. Now create the JSONObject from the JSON file using the following code snippet.

// creating card template object
JSONObject cDataPayload = new JSONObject();
cDataPayload.put("cardTemplate", new JSONObject()
            .put("prtnrId", partnerId)
            .put("title", "Sample Card")
            .put("countryCode", "KR")
            .put("cardType", "coupon")
            .put("subType", "others")
            .put("saveInServerYn", "Y"));

Generating the JWE token

Create the JWE token using the following code snippet. For more details about the JWE format, refer to the “Card Data Token” section of the Security page.

// JWE payload generation
EncryptionMethod jweEnc = EncryptionMethod.A128GCM;
JWEAlgorithm jweAlg = JWEAlgorithm.RSA1_5;
JWEHeader jweHeader = new JWEHeader.Builder(jweAlg, jweEnc).build();
RSAEncrypter encryptor = new RSAEncrypter((RSAPublicKey) samsungPublicKey);
JWEObject jwe = new JWEObject(jweHeader, new Payload(String.valueOf(cDataPayload)));
try {
    jwe.encrypt(encryptor);
} catch (JOSEException e) {
    e.printStackTrace();
}
String payload = jwe.serialize();

Building the JWS header

Next, follow this code snippet to build the JWS header. Set “CARD” as the payload content type in this header.

// JWS Header
JWSHeader jwsHeader = new JWSHeader.Builder(JWSAlgorithm.RS256)
        .contentType("CARD")
        .customParam("partnerId", partnerId)
        .customParam("ver", 3)
        .customParam("certificateId", certificateId)
        .customParam("utc", utcTimestamp)
        .build();

Building the JWS token

Generate the JWS token from the previously generated JWE token and, finally, get the “ctemplate” JWT. Follow the “JWS Format” section of the Security page.

private static String generateCDataToken(String partnerId, PublicKey partnerPublicKey, PublicKey samsungPublicKey, PrivateKey partnerPrivateKey, String certificateId, long utcTimestamp) throws Exception {
    
    // creating card template object
    
    // JWE payload generation

    // JWS Header

    // JWS Token generation
    JWSObject jwsObj = new JWSObject(jwsHeader, new Payload(payload));

    RSAKey rsaJWK = new RSAKey.Builder((RSAPublicKey) partnerPublicKey)
            .privateKey(partnerPrivateKey)
            .build();
    JWSSigner signer = new RSASSASigner( );
    jwsObj.sign(signer);

    return jwsObj.serialize();
}

Step 4: Building the request

As all of the required fields to create the request have been generated, you can now create the request to add a new template. Follow the code snippet to generate the request.

private static Request buildRequest(String endpoint, String partnerId, String requestId, String authToken, String cDataToken) {
    // Prepare JSON body
    JSONObject cDataJsonBody = new JSONObject();
    cDataJsonBody.put("ctemplate", cDataToken);

    RequestBody requestBody = RequestBody.create(
            MediaType.parse("application/json; charset=utf-8"),
            cDataJsonBody.toString()
    );

    // Build HTTP Request
    Request request = new Request.Builder()
            .url(endpoint)
            .post(requestBody)
            .addHeader("Authorization", "Bearer " + authToken)
            .addHeader("x-smcs-partner-id", partnerId)
            .addHeader("x-request-id", requestId)
            .addHeader("x-smcs-cc2", "KR")
            .addHeader("Content-Type", "application/json")
            .build();

    return request;
}

Step 5: Executing the request

If the request is successful, a new card is added to the Wallet Partners Portal and its “cardId” value is returned as a response.

private static void executeRequest(Request request) {
    // Execute HTTP Request
    try (Response response = client.newCall(request).execute()) {
        if (response.isSuccessful()) {
            System.out.println("Wallet Card Template added successfully: " + response.body().string());
        } else {
            System.out.println("Failed to add Wallet Card Template: " + response.body().string());
        }
    }
}

Implement as a server

At this point, you can add a webpage UI for creating card templates and deploy it as a web service. In this sample project, there is no UI added. But, you can deploy this sample as a web service and test it.

Conclusion

This tutorial shows you how you can create a new Samsung Wallet card template directly from your server by using a REST API. Now that you can implement the API, you can add a UI and make it more user-friendly. Also implement the Updating Wallet Cards Templates API for better card management.

References

For additional information on this topic, refer to the resources below:

  1. Sample project code.
  2. Business Support for Special Purposes documentation.

Preferences Submitted

You have successfully updated your cookie preferences.