Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hard error if objects contain classid #72

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

Defman
Copy link

@Defman Defman commented May 2, 2023

The sample on creating generic pass and then generating a JWT token for an existing object is inaccurate. The objects should not contain classId

I have updated all the samples, however I have only tested the python generic sample.

@google-cla
Copy link

google-cla bot commented May 2, 2023

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@singhdilip1007
Copy link

@Defman Can you please help to generate google generic pass using C# please? I've searched lots and didn't find any fruitful result

@Defman
Copy link
Author

Defman commented Aug 7, 2023

@singhdilip1007 what's the issue? I don't know much about C#.

Google passes are basically JWT tokens. You can either deliver the pass as a url with the pass fully encoded as JWT or as a JWT containing a reference to a pre-created/-uploaded object or the JWT token can contain the object(large token).

https://developers.google.com/wallet/tickets/boarding-passes/web

@singhdilip1007
Copy link

@Defman Thank you so much for your reply here.

I've gone through this link https://developers.google.com/wallet/generic/resources/pass-builder

Saw the sample Class definition & Object definition and able to generate JWT token. but not able to get how to use this JWT tokens to generate passes. If you can help me on it so, I can generate JWT token using C# and can use that token with URL to generate passes. Please help me on it.

Thanks in advance

@anita-kamat
Copy link

anita-kamat commented Aug 7, 2023 via email

@singhdilip1007
Copy link

Dilip, Here is the link I used. https://github.com/google-pay/wallet-samples/tree/main/dotnet From: Singh Dilip @.> Sent: Monday, August 7, 2023 9:58 AM To: google-pay/wallet-samples @.> Cc: Subscribed @.> Subject: Re: [google-pay/wallet-samples] Hard error if objects contain classid (PR #72) https://github.com/Defman Caution: This email originated outside of the organization. Do not open any attachments or click on links unless you recognize the sender and know the content is safe.https://github.com/Defman https://github.com/Defman https://github.com/Defman

________________________________ @Defmanhttps://github.com/Defman Thank you so much for your reply here. I've gone through this link https://developers.google.com/wallet/generic/resources/pass-builderhttps://developers.google.com/wallet/generic/resources/pass-builder Saw the sample Class definition & Object definition and able to generate JWT token. but not able to get how to use this JWT tokens to generate passes. If you can help me on it so, I can generate JWT token using C# and can use that token with URL to generate passes. Please help me on it. Thanks in advance — Reply to this email directly, view it on GitHub<#72 (comment)>, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AY6KNXSHIDP3ELULZ762R4TXUDX77ANCNFSM6AAAAAAXTJPVGI. You are receiving this because you are subscribed to this thread.Message ID: @.
@.***>> Important Notice: This e-mail and any files transmitted with it are intended solely for the use of the individual or entity to which they are addressed and may contain confidential and/or privileged material. Any review, retransmission, dissemination or other use of, or taking of any action in reliance upon, this information by persons or entities other than the intended recipient is prohibited. If you have received this e-mail in error, please contact the sender and delete the material from your computer. Please note that any view or opinions presented in this e-mail are solely those of the author and do not necessarily represent those of Confie Administrative Services, Inc. and/or its affiliates ("Confie"). Finally, the recipient should check this e-mail and any attachments for the presence of viruses. Confie accepts no liability for any damage caused by any virus transmitted by this e-mail.

Thanks for this. I've cloned the application and opened with VS2022 and seems lots of compile time error

image

its looking very hard to me to see much kind of issue, Also, I need to generate pas ASAP because this is very important for me @Defman

@anita-kamat
Copy link

anita-kamat commented Aug 7, 2023 via email

@anita-kamat
Copy link

anita-kamat commented Aug 7, 2023 via email

@singhdilip1007
Copy link

@Defman I'm sorry to not mention with above. I've installed below dependencies but not able to fix above errors:
image

@anita-kamat
Copy link

@singhdilip1007
I have these

  • Google.Apis
  • Google.Apis.Auth
  • Google.Apis.Core

@anita-kamat
Copy link

Google.Apis.Walletobjects.v1.txt
change the attached file to .cs from .txt and add this class to your project

@Defman
Copy link
Author

Defman commented Aug 7, 2023

Here's some old python code of mine.

import json
import os
import uuid
import logging

from google.auth.transport.requests import AuthorizedSession
from google.oauth2.service_account import Credentials
from google.auth import jwt, crypt

PATH_TO_KEY = 'key.json'
ISSUER_ID = ''

class Membership:
    def __init__(self):
        self.key_file_path = os.environ.get('GOOGLE_APPLICATION_CREDENTIALS',
                                            PATH_TO_KEY)
        self.base_url = 'https://walletobjects.googleapis.com/walletobjects/v1'
        self.batch_url = 'https://walletobjects.googleapis.com/batch'
        self.class_url = f'{self.base_url}/genericClass'
        self.object_url = f'{self.base_url}/genericObject'

        self.issuer_id = ISSUER_ID
        self.class_suffix = "membership"

        self.auth()

    def auth(self):
        """Create authenticated HTTP client using a service account file."""
        self.credentials = Credentials.from_service_account_file(
            self.key_file_path,
            scopes=['https://www.googleapis.com/auth/wallet_object.issuer'])

        self.http_client = AuthorizedSession(self.credentials)

    def listObjcets(self) -> str:
        response = self.http_client.get(
            url=f'https://walletobjects.googleapis.com/walletobjects/v1/genericObject?classId={ISSUER_ID}.membership')
        
        return response.json()

    def update_class(self) -> str:
        # Check if the class exists
        response = self.http_client.get(
            url=f'{self.class_url}/{self.issuer_id}.{self.class_suffix}')

        if response.status_code == 404:
            print(f'Class {self.issuer_id}.{self.class_suffix} not found!')
            return f'{self.issuer_id}.{self.class_suffix}'
        elif response.status_code != 200:
            # Something else went wrong...
            print(response.text)
            return f'{self.issuer_id}.{self.class_suffix}'
        
        updated_class = {
            "id": f"{self.issuer_id}.{self.class_suffix}",
            "multipleDevicesAndHoldersAllowedStatus": "ONE_USER_ALL_DEVICES",
            "classTemplateInfo": {
                "cardTemplateOverride": {
                "cardRowTemplateInfos": [
                    {
                    "twoItems": {
                        "startItem": {
                        "firstValue": {
                            "fields": [
                            {
                                "fieldPath": "object.textModulesData['fieldA']",
                            },
                            ],
                        },
                        },
                        "endItem": {
                        "firstValue": {
                            "fields": [
                            {
                                "fieldPath": "object.textModulesData['fieldB']",
                            },
                            ],
                        },
                        },
                    },
                    },
                ],
                },
            },
        }
        response = self.http_client.put(
            url=f'{self.class_url}/{self.issuer_id}.{self.class_suffix}',
            json=updated_class)

        print('Class update response')
        print(response.text)

        return response.json().get('id')
    
    def create_class(self) -> str:
        """Create a class.

        Args:
            issuer_id (str): The issuer ID being used for this request.
            class_suffix (str): Developer-defined unique ID for this pass class.

        Returns:
            The pass class ID: f"{issuer_id}.{self.class_suffix}"
        """

        # Check if the class exists
        response = self.http_client.get(
            url=f'{self.class_url}/{self.issuer_id}.{self.class_suffix}')

        if response.status_code == 200:
            print(f'Class {self.issuer_id}.{self.class_suffix} already exists!')
            return f'{self.issuer_id}.{self.class_suffix}'
        elif response.status_code != 404:
            # Something else went wrong...
            print(response.text)
            return f'{self.issuer_id}.{self.class_suffix}'

        # See link below for more information on required properties
        # https://developers.google.com/wallet/generic/rest/v1/genericclass
        new_class = {
            "id": f"{self.issuer_id}.{self.class_suffix}",
            "multipleDevicesAndHoldersAllowedStatus": "ONE_USER_ALL_DEVICES",
            "classTemplateInfo": {
                "cardTemplateOverride": {
                "cardRowTemplateInfos": [
                    {
                    "twoItems": {
                        "startItem": {
                        "firstValue": {
                            "fields": [
                            {
                                "fieldPath": "object.textModulesData['fieldA']",
                            },
                            ],
                        },
                        },
                        "endItem": {
                        "firstValue": {
                            "fields": [
                            {
                                "fieldPath": "object.textModulesData['fieldB']",
                            },
                            ],
                        },
                        },
                    },
                    },
                ],
                },
            },
        }

        response = self.http_client.post(url=self.class_url, json=new_class)

        print('Class insert response')
        print(response.text)

        return response.json().get('id')


    def create_object(self, object_suffix: str, active: bool, full_name: str, fieldA: str, fieldB: str) -> str:
        """Create an object.

        Args:
            issuer_id (str): The issuer ID being used for this request.
            class_suffix (str): Developer-defined unique ID for the pass class.
            object_suffix (str): Developer-defined unique ID for the pass object.

        Returns:
            The pass object ID: f"{issuer_id}.{object_suffix}"
        """

        # Check if the object exists
        response = self.http_client.get(
            url=f'{self.object_url}/{self.issuer_id}.{object_suffix}')

        if response.status_code == 200:
            logging.info(f'Object {self.issuer_id}.{object_suffix} already exists!')
            return f'{self.issuer_id}.{object_suffix}'
        elif response.status_code != 404:
            # Something else went wrong...
            logging.error(response.text)
            return f'{self.issuer_id}.{object_suffix}'

        # See link below for more information on required properties
        # https://developers.google.com/wallet/generic/rest/v1/genericobject
        new_object = {
            'id': f'{self.issuer_id}.{object_suffix}',
            'classId': f'{self.issuer_id}.{self.class_suffix}',
            'state': 'ACTIVE' if active else 'EXPIRED',
            "logo": {
                "sourceUri": {
                "uri": "https://site.tld/path.png",
                },
                "contentDescription": {
                "defaultValue": {
                    "language": "da",
                    "value": "Title",
                },
                },
            },
            "cardTitle": {
                "defaultValue": {
                "language": "da",
                "value": "Medlemskort",
                },
            },
            "subheader": {
                "defaultValue": {
                "language": "da",
                "value": "Navn",
                },
            },
            "header": {
                "defaultValue": {
                "language": "da",
                "value": full_name,
                },
            },
            "textModulesData": [
                {
                "id": "fieldA",
                "header": "fieldA Title",
                "body": fieldA,
                },
                {
                "id": "filedB",
                "header": "fieldB Title",
                "body": fieldB,
                },
            ],
            "hexBackgroundColor": "#134395",
        }

        # Create the object
        response = self.http_client.post(url=self.object_url, json=new_object)
        print("foo")
        print(response.text)
        
        return response.json().get('id')

    # [END createObject]

    # [START expireObject]
    def expire_object(self, object_suffix: str) -> str:
        """Expire an object.

        Sets the object's state to Expired. If the valid time interval is
        already set, the pass will expire automatically up to 24 hours after.

        Args:
            issuer_id (str): The issuer ID being used for this request.
            object_suffix (str): Developer-defined unique ID for the pass object.

        Returns:
            The pass object ID: f"{issuer_id}.{object_suffix}"
        """

        # Check if the object exists
        response = self.http_client.get(
            url=f'{self.object_url}/{self.issuer_id}.{object_suffix}')

        if response.status_code == 404:
            logging.error(f'Object {self.issuer_id}.{object_suffix} not found!')
            return f'{self.issuer_id}.{object_suffix}'
        elif response.status_code != 200:
            # Something else went wrong...
            logging.error(response.text)
            return f'{self.issuer_id}.{object_suffix}'

        # Patch the object, setting the pass as expired
        patch_body = {'state': 'EXPIRED'}

        response = self.http_client.patch(
            url=f'{self.object_url}/{self.issuer_id}.{object_suffix}',
            json=patch_body)

        return response.json().get('id')

    # [END expireObject]

    # [START jwtExisting]
    def create_jwt_existing_objects(self, object_suffix: str) -> str:
        """Generate a signed JWT that references an existing pass object.

        When the user opens the "Add to Google Wallet" URL and saves the pass to
        their wallet, the pass objects defined in the JWT are added to the
        user's Google Wallet app. This allows the user to save multiple pass
        objects in one API call.

        The objects to add must follow the below format:

        {
            'id': 'ISSUER_ID.OBJECT_SUFFIX',
            'classId': 'ISSUER_ID.CLASS_SUFFIX'
        }

        Args:
            issuer_id (str): The issuer ID being used for this request.

        Returns:
            An "Add to Google Wallet" link
        """

        # Multiple pass types can be added at the same time
        # At least one type must be specified in the JWT claims
        # Note: Make sure to replace the placeholder class and object suffixes
        objects_to_add = {
            # Generic passes
            'genericObjects': [{
                'id': f'{self.issuer_id}.{object_suffix}',
            }]
        }

        # Create the JWT claims
        claims = {
            'iss': self.credentials.service_account_email,
            'aud': 'google',
            'origins': ['card.unf.dk'],
            'typ': 'savetowallet',
            'payload': objects_to_add
        }

        # The service account credentials are used to sign the JWT
        signer = crypt.RSASigner.from_service_account_file(self.key_file_path)
        token = jwt.encode(signer, claims).decode('utf-8')

        return f'https://pay.google.com/gp/v/save/{token}'
    
    def create_jwt_new_objects(self, object_suffix: str, full_name: str) -> str:
        """Generate a signed JWT that creates a new pass class and object.

        When the user opens the "Add to Google Wallet" URL and saves the pass to
        their wallet, the pass class and object defined in the JWT are
        created. This allows you to create multiple pass classes and objects in
        one API call when the user saves the pass to their wallet.

        Args:
            issuer_id (str): The issuer ID being used for this request.
            class_suffix (str): Developer-defined unique ID for the pass class.
            object_suffix (str): Developer-defined unique ID for the pass object.

        Returns:
            An "Add to Google Wallet" link.
        """


        # See link below for more information on required properties
        # https://developers.google.com/wallet/generic/rest/v1/genericobject
        new_object = {
            'id': f'{self.issuer_id}.{object_suffix}',
            'classId': f'{self.issuer_id}.{self.class_suffix}',
            'state': 'EXPIRED',
            "logo": {
                "sourceUri": {
                "uri": "https://example.tld/path.png",
                },
                "contentDescription": {
                "defaultValue": {
                    "language": "da",
                    "value": "Title",
                },
                },
            },
            "cardTitle": {
                "defaultValue": {
                "language": "da",
                "value": "Medlemskort",
                },
            },
            "subheader": {
                "defaultValue": {
                "language": "da",
                "value": "Navn",
                },
            },
            "header": {
                "defaultValue": {
                "language": "da",
                "value": "example",
                },
            },
            "textModulesData": [
                {
                "id": "fieldA",
                "header": "fieldA Title",
                "body": "example",
                },
                {
                "id": "fieldA",
                "header": "fieldA Title",
                "body": "2024-04-31",
                },
            ],
            "hexBackgroundColor": "#134395",
        }

        # Create the JWT claims
        claims = {
            'iss': self.credentials.service_account_email,
            'aud': 'google',
            'origins': ['card.unf.dk'],
            'typ': 'savetowallet',
            'payload': {
                # The listed classes and objects will be created
                'genericObjects': [new_object]
            }
        }

        # The service account credentials are used to sign the JWT
        signer = crypt.RSASigner.from_service_account_file(self.key_file_path)
        token = jwt.encode(signer, claims).decode('utf-8')

        print('Add to Google Wallet link')
        print(f'https://pay.google.com/gp/v/save/{token}')

        return f'https://pay.google.com/gp/v/save/{token}'

Sorry can't help you on the C# issue. But you will need a .json key file to authenticate with google.

Passes are quite simple, try reading some C# JWT reference material?
https://github.com/jwt-dotnet/jwt

Note.

I don't work for or with google, neither do I have any relation to them.

@singhdilip1007
Copy link

@Defman
Now, I've also same packages but still ist showing like this while I'm using VS2022 professional. Please ley me know

image

@anita-kamat
Copy link

@Defman Now, I've also same packages but still ist showing like this while I'm using VS2022 professional. Please ley me know

image

create a folder called "lib" and added the class I had send above

@singhdilip1007
Copy link

@Defman Your kind support will make me much more valuable on it. PLease help me to fix the same

@Defman
Copy link
Author

Defman commented Aug 7, 2023

@singhdilip1007
Copy link

@Defman thanks, while I've followed the same but will try to do the same again and will update you. It will be great if you can provide me a demo application from your end, I'll edit my own issuerid for test

@singhdilip1007
Copy link

singhdilip1007 commented Aug 8, 2023

@Defman @anita-kamat @stephenmcd

below steps I've followed so far:

  1. downloaded application from https://github.com/google-pay/wallet-samples
  2. downloaded class library from https://developers.google.com/wallet/generic/resources/libraries#c

and then followed below steps:
1. Open the wallet-rest-samples.csproj file in your .NET editor of choice.

2. Copy the path to the Google Wallet API Client library ( Google.Apis.Walletobjects.v1.csproj file) you downloaded. If needed, update the path in wallet-rest-samples.csproj (line 19).

<CodeFiles Include="lib/Google.Apis.Walletobjects.v1.cs" /> (Its added)

3. Build the project to install the dependencies.

below is my project structure

image

during build below error is showing:

image

Please guide me for next. I've to create google generic pass ba an URL or an API call

@anita-kamat
Copy link

anita-kamat commented Aug 8, 2023 via email

@singhdilip1007
Copy link

@anita-kamat yes, can see in lib folder. I've added there then make reference to with same file and then build. Now just one error message

@singhdilip1007
Copy link

@anita-kamat @Defman

Here's some progress done by me while trying to generate google generic pass.

This is what I got the link and how its looking:

Link generated : (https://pay.google.com/gp/v/save/eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ3YWxsZXRAaG9uZXN0LXJ4LTIxNjMyMC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImF1ZCI6Imdvb2dsZSIsIm9yaWdpbnMiOlsid3d3LmV4YW1wbGUuY29tIl0sInR5cCI6InNhdmV0b3dhbGxldCIsInBheWxvYWQiOnsiZ2VuZXJpY0NsYXNzZXMiOlt7ImlkIjoiMzM4ODAwMDAwMDAyMjExNjIwNC45Y2Q1NjliYy1hOGFiLTRjOGQtOGI1Yy1lZmFhMzE4MTg4N2EifV0sImdlbmVyaWNPYmplY3RzIjpbeyJiYXJjb2RlIjp7InR5cGUiOiJRUl9DT0RFIiwidmFsdWUiOiJRUiBjb2RlIn0sImNhcmRUaXRsZSI6eyJkZWZhdWx0VmFsdWUiOnsibGFuZ3VhZ2UiOiJlbi1VUyIsInZhbHVlIjoiR2xpYyBIZWFsdGggR29vZ2xlIFBhc3MifX0sImNsYXNzSWQiOiIzMzg4MDAwMDAwMDIyMTE2MjA0LjljZDU2OWJjLWE4YWItNGM4ZC04YjVjLWVmYWEzMTgxODg3YSIsImhlYWRlciI6eyJkZWZhdWx0VmFsdWUiOnsibGFuZ3VhZ2UiOiJlbi1VUyIsInZhbHVlIjoiR2VuZXJpYyBoZWFkZXIifX0sImhlcm9JbWFnZSI6eyJjb250ZW50RGVzY3JpcHRpb24iOnsiZGVmYXVsdFZhbHVlIjp7Imxhbmd1YWdlIjoiZW4tVVMiLCJ2YWx1ZSI6Ikhlcm8gaW1hZ2UgZGVzY3JpcHRpb24ifX0sInNvdXJjZVVyaSI6eyJ1cmkiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vd2FsbGV0LWxhYi10b29scy1jb2RlbGFiLWFydGlmYWN0cy1wdWJsaWMvcGFzc19nb29nbGVfbG9nby5qcGcifX0sImhleEJhY2tncm91bmRDb2xvciI6IiM0Mjg1ZjQiLCJpZCI6IjMzODgwMDAwMDAwMjIxMTYyMDQuZjg1OWVjMDktMTFhZi00MThkLWEzYjAtYTIzOTliMGQwZjI3IiwiaW1hZ2VNb2R1bGVzRGF0YSI6W3siaWQiOiJJTUFHRV9NT0RVTEVfSUQiLCJtYWluSW1hZ2UiOnsiY29udGVudERlc2NyaXB0aW9uIjp7ImRlZmF1bHRWYWx1ZSI6eyJsYW5ndWFnZSI6ImVuLVVTIiwidmFsdWUiOiJJbWFnZSBtb2R1bGUgZGVzY3JpcHRpb24ifX0sInNvdXJjZVVyaSI6eyJ1cmkiOiJodHRwOi8vZmFybTQuc3RhdGljZmxpY2tyLmNvbS8zNzM4LzEyNDQwNzk5NzgzXzNkYzNjMjA2MDZfYi5qcGcifX19XSwibGlua3NNb2R1bGVEYXRhIjp7InVyaXMiOlt7ImRlc2NyaXB0aW9uIjoiTGluayBtb2R1bGUgVVJJIGRlc2NyaXB0aW9uIiwiaWQiOiJMSU5LX01PRFVMRV9VUklfSUQiLCJ1cmkiOiJodHRwOi8vbWFwcy5nb29nbGUuY29tLyJ9LHsiZGVzY3JpcHRpb24iOiJMaW5rIG1vZHVsZSB0ZWwgZGVzY3JpcHRpb24iLCJpZCI6IkxJTktfTU9EVUxFX1RFTF9JRCIsInVyaSI6InRlbDo2NTA1NTU1NTU1In1dfSwibG9nbyI6eyJjb250ZW50RGVzY3JpcHRpb24iOnsiZGVmYXVsdFZhbHVlIjp7Imxhbmd1YWdlIjoiZW4tVVMiLCJ2YWx1ZSI6IkdlbmVyaWMgY2FyZCBsb2dvIn19LCJzb3VyY2VVcmkiOnsidXJpIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL3dhbGxldC1sYWItdG9vbHMtY29kZWxhYi1hcnRpZmFjdHMtcHVibGljL3Bhc3NfZ29vZ2xlX2xvZ28uanBnIn19LCJzdGF0ZSI6IkFDVElWRSIsInRleHRNb2R1bGVzRGF0YSI6W3siYm9keSI6IjExMTIiLCJoZWFkZXIiOiJMX2xibDEiLCJpZCI6ImxfbGJsMSJ9LHsiYm9keSI6Im1pZGRsZSIsImhlYWRlciI6Ik1fbGJsMSIsImlkIjoiTV9sYmwxIn0seyJib2R5IjoiUmlnaHQiLCJoZWFkZXIiOiJSX2xibDEiLCJpZCI6IlJfbGJsMSJ9XX1dfX0.F9AynHlZg6EzCt9xD0dPUV19FbQePDZJvqMLgIsGvofpEoY3SdEWoJ74nGiVxdR4BFn8BxwSR9WLm6x0nb9q97C9idiE8tshNZ9f_3BP4ieQupgEJB7MPQLR__QrU6nWcFxT2n_-tjpaVKrqiP-j_AjezJZBwK3Mw3pEjso9lWaPhE5Y1uBv-t81EKs2lbE3B_VaiaVgrm1wLfrhMalDxGRIVOwwHJQZ4D2thEfJWrKen3eMDXOMErYZcpH7F7xoVi1Fr50aiSBWUa_dYZTQ5pGjn3qL19UZI9bRXJynXIL6tPEXNTbV48QIZPV-KyhS2Jx0BhP147BIyrjwKRvyfQ)

image

But I want to add more fields like below
https://developers.google.com/wallet/generic/resources/pass-builder

and I've used below code :

GenericObject newObject = new GenericObject
        {
            Id = $"{issuerId}.{objectSuffix}",
            ClassId = $"{issuerId}.{classSuffix}",
            State = "ACTIVE",
            HeroImage = new Image
            {
                SourceUri = new ImageUri
                {
                    Uri = "https://storage.googleapis.com/wallet-lab-tools-codelab-artifacts-public/pass_google_logo.jpg"// "https://farm4.staticflickr.com/3723/11177041115_6e6a3b6f49_o.jpg"
                },
                ContentDescription = new LocalizedString
                {
                    DefaultValue = new TranslatedString
                    {
                        Language = "en-US",
                        Value = "Hero image description"
                    }
                }
            },
            LinksModuleData = new LinksModuleData
            {
                Uris = new List<Google.Apis.Walletobjects.v1.Data.Uri>
          {
            new Google.Apis.Walletobjects.v1.Data.Uri
            {
              UriValue = "http://maps.google.com/",
              Description = "Link module URI description",
              Id = "LINK_MODULE_URI_ID"
            },
            new Google.Apis.Walletobjects.v1.Data.Uri
            {
              UriValue = "tel:6505555555",
              Description = "Link module tel description",
              Id = "LINK_MODULE_TEL_ID"
            }
          }
            },
            ImageModulesData = new List<ImageModuleData>
        {
          new ImageModuleData
          {
            MainImage = new Image
            {
              SourceUri = new ImageUri
              {
                Uri = "http://farm4.staticflickr.com/3738/12440799783_3dc3c20606_b.jpg"
              },
              ContentDescription = new LocalizedString
              {
                DefaultValue = new TranslatedString
                {
                  Language = "en-US",
                  Value = "Image module description"
                }
              }
            },
            Id = "IMAGE_MODULE_ID"
          }
        },
            Barcode = new Barcode
            {
                Type = "QR_CODE",
                Value = "QR code"
            },
            CardTitle = new LocalizedString
            {
                DefaultValue = new TranslatedString
                {
                    Language = "en-US",
                    Value = "Glic Health Google Pass"
                }
            },
            Header = new LocalizedString
            {
                DefaultValue = new TranslatedString
                {
                    Language = "en-US",
                    Value = "Generic header"
                }
            },
            TextModulesData = new List<TextModuleData>
        {
          new TextModuleData
          {
            Header = "L_lbl1",
            Body = "1112",
            Id = "l_lbl1"
          },
          new TextModuleData
          {
              Header = "M_lbl1",
            Body = "middle",
            Id = "M_lbl1"
          },
          new TextModuleData
          {
              Header = "R_lbl1",
            Body = "Right",
            Id = "R_lbl1"
          }
        },
            HexBackgroundColor = "#4285f4",
            Logo = new Image
            {
                SourceUri = new ImageUri
                {
                    Uri = "https://storage.googleapis.com/wallet-lab-tools-codelab-artifacts-public/pass_google_logo.jpg"
                },
                ContentDescription = new LocalizedString
                {
                    DefaultValue = new TranslatedString
                    {
                        Language = "en-US",
                        Value = "Generic card logo"
                    }
                },
            }
        };

@singhdilip1007
Copy link

@anita-kamat @Defman
This is how I'm looking actually (my expectation)

image

@singhdilip1007
Copy link

@Defman @anita-kamat
Thanks for your kind support, I've done all the things I was looking for with Google Pass. Great help from your end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants