Hide

Loyalty Tutorial

The Wallet Objects API allows you to manipulate Wallet Objects, enabling you to engage with users through Google Wallet. This tutorial provides conceptual background, setup information, and a walkthrough of the process of interacting with Loyalty Objects.

Contents

Concepts

There are three essential pieces to a loyalty solution: Your server containing a web service, Google Wallet where loyalty information is stored, and the Google Wallet app used by users to access their loyalty information.

The Google Wallet app sends information to the card issuer using the Loyalty Web Services API. For example, if a user wants to add their loyalty card in the Google Wallet app, Google will send your server a JSON RPC request informing your server of the link request.

You interact with Google Wallet using either the Wallet Objects REST API or the Save to Wallet API. For example, you can add a Save To Wallet button on your site to enable a user to save their loyalty information to Google Wallet.

Before you can share any information with Google Wallet, you must create a Loyalty Class to represent your loyalty program, and post it to a specific REST URI (https://www.googleapis.com/walletobjects/v1/loyaltyClass). A Loyalty Class contains data common for every user of your loyalty program, such as the ID and template used to display loyalty information in the Google Wallet app. For example, you may create a Loyalty Class for each tier of your loyalty program. Any updates to a Loyalty Class will be propagated to all Loyalty Objects that reference the class. Loyalty Classes are represented by the Loyaltyclass resource in the Wallet Objects REST API.

A Loyalty Object contains data specific to a user such as the number of loyalty points they have accumulated. The majority of communication between you and Google Wallet involves retrieving and updating Loyalty Objects (such as when a loyalty point total is increased). Loyalty Objects are represented by the Loyaltyobject resource in the Wallet Objects REST API. Any updates to Loyalty Class or Loyalty Object will be pushed to the affected users' Google Wallet app.

Templates identify how elements found in a Loyalty Class and Loyalty Object are displayed in the Google Wallet app. The tutorial provides detailed information about Loyalty templates.

Refer to the Glossary for a complete list of Wallet Objects terms.

Detailed API flow diagram

The communication flow for the four primary loyalty API flows are illustrated in the following image:

Detailed API flows.

This diagram identifies the API (REST API, Web Service API, Save to Google API) used for different use case or API flow. The text in bold represents each API flow. All actions between "Your Server" and "Google Wallet" are your responsibility to implement.

  1. User discovers and joins new program from within Google Wallet app:
    1. Google Wallet app posts JSON signup information to your web service URL specified in your Discoverable (a special feature of the Loyalty Wallet Object type). There is a shared secret password in this request's header.
    2. If approved, you respond with JSON response containing the Loyalty Object representing user's specific representation of Loyalty Class. If rejected, you respond with JSON response containing rejection message.
  2. User links to existing loyalty program from within Google Wallet app:
    1. Wallet app posts JSON signup information to your specified web service URL specified in your Discoverable (a special feature of the Loyalty Wallet Object type). There is a shared secret password in this request's header.
    2. If approved, you respond with JSON response containing the Loyalty Object representing user's specific representation of Loyalty Class. If rejected, you respond with JSON response containing rejection message.
  3. User clicks Save to Google button on merchant's website:
    1. Consumer navigates to merchant web site.
    2. Browser issues GET request for your page HTML. Your server generates the Save to Google JWT and g:savetowallet button and adds them to response HTML.
    3. Browser receives and parses HTML and starts loading Save to Google JavaScript.
    4. JavaScript loads, automatically parses the DOM, and displays Save to Google button.
    5. User clicks Save to Google button on merchant's website to save the Loyalty Object to Google Wallet.
    6. Loyalty Object is pushed to the Google Wallet app.
  4. This tutorial and the Save to Google Tutorial combine to show you how to implement this flow.

  5. Card issuer engages user with realtime updates and messaging:
    1. Card issuer gets the Loyalty Object from Google Wallet using the object ID.
    2. Card issuer updates Loyalty Object.
    3. Card issuer pushes the Loyalty Object back to Google Wallet.
    4. Loyalty Object is pushed to the Google Wallet app.

Configure Wallet Objects authentication

The Loyalty Web Service API uses a shared secret passed in the request header. The Wallet Objects REST API uses OAuth 2.0 service accounts, which do not require user authorization for access.

Configure Wallet Objects REST API authentication

The Wallet Objects Save to Wallet and REST APIs use OAuth 2.0 service accounts for authentication to Google Wallet. The requesting application has to prove its own identity to gain access to an API. However, an end-user doesn't have to be prompted during authentication because the requests don't involve user data.

1. Register your application

All applications that access a Google API must be registered through the Developers Console. The result of this registration process is a set of values that are known only to Google and your application (client ID, email address, private key). To register your application:

  1. Access the Developers Console.
  2. Click Create Project. The New project page appears.
  3. Enter a project name and unique ID.
  4. Click Create. The project's Overview page is displayed.
  5. Click APIs & auth in the left-hand menu.
  6. Click APIs in the left-hand menu. A list of all APIs is displayed.
  7. Scroll down and click on the OFF button next to the Wallet Objects API. The API is toggled to "ON."

  8. Note: You must sign up for Wallet Objects API access for the Wallet Object API to appear in the list of APIs.

  9. Click Credentials in the left-hand menu. The credentials for your application appear.
  10. Click Create new Client ID. The Create Client ID dialog box appears.
  11. Select Service account.
  12. Click Create Client ID. The New Public/Private Key Generated dialog box appears.
  13. Click Okay, got it. A new Service Account has been added to your list of accounts and a private key is downloaded to your local file system. This is the only copy of this key and are responsible for keeping this key file in a secure location. You will use this key later.
  14. Copy the Service Account email address. You will use this address later.

Warning: The private key must be stored and managed securely for both developer and production environments. Google does not keep a copy of the private key, only the public key.

2. Tie your service account to Google Wallet Objects Account

Your Wallet Objects Account should have been created for you by your Google point of contact. The Wallet Objects Merchant Console is a web site you can use to manage your Wallet Objects Account and all your associated Wallet Objects (view classes and objects, create and test Discoverables, and so on). You will want to tie your service account created in the Register your application section to the Wallet Objects Merchant Console so you can use its features to manage your Wallet Objects. To tie your service account to the Wallet Objects Merchant Console:

  1. Access the Wallet Objects Merchant Console.
  2. Click Account Management on the left-hand navigation. The Account Info page is displayed.

  3. Note: Make a note of your Issuer Id (also called a Merchant ID). You will use this later when making calls to Wallet Objects.

  4. Click Share. The Share settings appear.
  5. Select the email address from the Register Your Application section and paste it in the Invite people field.
  6. Click Share & save. Your service account is tied to your Wallet Objects Account and your Wallet Objects Account is ready to be used to issue REST calls to Google Wallet.

3. Use OAuth 2.0 for your Server to Server application

The Google OAuth 2.0 Authorization Server supports server-to-server interactions such as those between a web application and Google Cloud Storage. The requesting application has to prove its own identity to gain access to an API, and an end-user doesn't have to be involved.

You need to obtain an access token to authorize your API requests (creating a JSON Web Token (JWT), signing the JWT, forming the access token request, and handling the response). We strongly recommend that you use a client library to simplify this process. Refer to Samples, Tools, and Libraries for a list of client libraries available for different programming languages.

Read Use a library to use the credentials form, encode and sign the JWT claim set if you are using a library for your OAuth 2.0 authentication.

Read Obtain an access token manually if you are manually building all of your OAuth 2.0 authentication code.

Use a library to create a service account credential

The following tabs show code examples in different languages to create a service account credential:

Java

GoogleCredential credential = new GoogleCredential.Builder().setTransport(httpTransport)
  .setJsonFactory(jsonFactory)
  .setServiceAccountId("ServiceAccountEmail@developer.gserviceaccount.com")
  .setServiceAccountScopes("https://www.googleapis.com/auth/wallet_object.issuer")
  .setServiceAccountPrivateKeyFromP12File(new File("/example/path/to/yourp12file.p12"))
  .build();

Ruby

client = Google::APIClient.new(
  :application_name => 'Wallet Objects App'
)
key = Google::APIClient::KeyUtils.load_from_pkcs12('/example/path/to/yourp12file.p12', 'notasecret')
client.authorization = Signet::OAuth2::Client.new(
  :token_credential_uri => 'https://accounts.google.com/o/oauth2/token',
  :audience => 'https://accounts.google.com/o/oauth2/token',
  :scope => 'https://www.googleapis.com/auth/wallet_object.issuer',
  :issuer => 'ServiceAccountEmail@developer.gserviceaccount.com',
  :signing_key => key)
## Request a token for our service account
client.authorization.fetch_access_token!

PHP

$client = new Google_Client();
$client->setApplicationName('Wallet Objects App');
$client->setScopes(array('https://www.googleapis.com/auth/wallet_object.issuer'));
$key = file_get_contents('/example/path/to/yourp12file.p12');
$cred = new Google_Auth_AssertionCredentials(
    'ServiceAccountEmail@developer.gserviceaccount.com',
    array('https://www.googleapis.com/auth/wallet_object.issuer'),
    $key
);
$client->setAssertionCredentials($cred);

Python

f = file('/example/path/to/yourp12file.p12', 'rb')
key = f.read()
f.close()
credentials = SignedJwtAssertionCredentials(
    'ServiceAccountEmail@developer.gserviceaccount.com',
    key,
    scope='https://www.googleapis.com/auth/wallet_object.issuer')
http = httplib2.Http()
http = credentials.authorize(http)

C#

WobCredentials credentials = new WobCredentials(
  WebConfigurationManager.AppSettings["ServiceAccountEmailAddress"],
  WebConfigurationManager.AppSettings["ServiceAccountPrivateKey"],
  WebConfigurationManager.AppSettings["ApplicationName"],
  WebConfigurationManager.AppSettings["IssuerId"]);

// OAuth - setup certificate based on private key file
X509Certificate2 certificate = new X509Certificate2(
  AppDomain.CurrentDomain.BaseDirectory + credentials.serviceAccountPrivateKey,
  "notasecret",
  X509KeyStorageFlags.Exportable);

// create service account credential
ServiceAccountCredential credential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(credentials.serviceAccountEmailAddress) {
  Scopes = new[] { "https://www.googleapis.com/auth/wallet_object.issuer" }
}.FromCertificate(certificate));

The resulting credential will be used when you are executing REST API commands, such as inserting a class.

Obtain an access token manually

Refer to The Using OAuth 2.0 for Server to Server Applications to manually obtain an access token. In summary, you will need to create a JWT and sign it with the private key, and then construct an access token request in the appropriate format. Your application then sends the token request to the Google OAuth 2.0 Authorization Server and an access token will be returned. Your application can access the API only after receiving the access token. When the access token expires, the application repeats the process.

Note: The iss field in the JWT claim set is the service account email address generated from the Google Developers Console in the Register your application section. The scope field in the JWT claim set is a space-delimited list of the permissions the application requests. The valid scope for production applications is https://www.googleapis.com/auth/wallet_object.issuer

Configure Loyalty Web Service API authentication

Your Web Service endpoint must be secured with SSL or TLS. You have your choice of two methods for authentication between Google and your Web Service endpoint: single SSL authentication and a mutual SSL authentication.

Note: The Google Wallet client supports TLS. Ideally your web server also runs TLS 1.2. However, Google Wallet client can communicate with older SSL and TLS versions. Also, Google does not limit ciphers; any cipher required by TLS 1.2 should work fine.

Single SSL authentication

Single SSL authentication provides a one-way handshake between Google and your Web Service endpoint. Single SSL authentication works like this:

  1. Google requests access to your Web Service (the server).
  2. Your server sends its certificate back.
  3. Google verifies that the server’s certificate is signed by a trusted certificate authority. Refer to the FAQ for a list of root certificates that Google accepts.
  4. If the server’s certificate is verified, an encrypted channel is opened.
  5. Google sends the request, such as a request to sign up for your loyalty program, to your web server. This encrypted request has a token string in the Google-Token header field.
  6. Google-Token: csu9uBq4uAbEI8iy1HHnOxeDOKxyIv9IS01ulMypfg
  7. Your server verifies the token.
  8. If the token is verified, your server process the request and sends either a success or failure response. Refer to Generate Loyalty Objects for examples of this response.

To enable Single SSL authentication:

  1. Follow the instructions in the Create a Discoverable section.
  2. Select Merchant Call Back Linking or Merchant Callback Signup. You can select both if your Wallet Object supports both signup and linking. The Merchant Callback Configuration section of the form appears. The Auth token field under the Merchant Callback Configuration section will contain a generated token string. This is the token string you will verify when accepting or rejecting requests from Google.
  3. Finish creating your discoverable.
  4. Ensure your server has a valid certificate signed by one of the trusted certificate authorities listed in the FAQ.

Mutual SSL authentication

Mutual SSL authentication provides a more robust handshake than single SSL authentication because both the client and the server (Google and your server) verify each others' credentials before a request is accepted. Mutual SSL authentication works like this:

  1. Google requests access to your Web Service (the server).
  2. Your Web Service sends your certificate to Google (the client).
  3. Google checks that your server’s certificate is valid and signed by one of the trusted certificate authorities.
  4. If successful, Google sends its certificate to your Web Service (the server).
  5. Your server validates Google's certificate against an intermediary certificate that you get from Google.
  6. If the certificate is verified, an encrypted channel is opened.
  7. Google sends the request, such as a request to sign up for your loyalty program, to your web server.
  8. The Web Service processes the request and sends a Web Service response. Refer to Generate Loyalty Objects for examples of this response.

To enable mutual SSL authentication:

  1. Follow the instructions in the Create a Discoverable section.
  2. Select Merchant Call Back Linking or Merchant Callback Signup. You can select both if your Wallet Object supports both signup and linking. The SSL Authentication section of the form appears.
  3. Select a client certificate from the Client Certificate drop-down list. This is the certificate Google will send to your Web Service.
  4. Paste the certificate that you want to be your primary certificate in the Primary Server Certificate field. This is the certificate that you will send to Google.
  5. Note: You must convert your certificate to an ASCII format with a .PEM extension if your certificate is in a binary form (.DER, .CRT, or .CER). Refer to Convert a binary certificate to ASCII for further information.

  6. (Optional) Paste a second certificate that you want to use in the Secondary Server Certificate field. This is the certificate that you will send to Google if your primary certificate has changed, expired, or been revoked.
  7. Finish creating and saving your discoverable.
  8. Download the intermediate certificate from the Repository of Documentation and Issuing CA Certificates and install on your server as a trusted client certificate.

Convert a binary certificate to ASCII

You must convert your certificate to an ASCII format with a .PEM extension if your certificate is in a binary form (.DER, .CRT, or .CER). Use the following command to convert a binary certificate to an ASCII .PEM format:

openssl x509 -in certificate.der -inform DER

This command results in output similar to the following:

-----BEGIN CERTIFICATE-----
MIIErTCCA5WgAwIBAgIIB6Dw22KMy2kwDQYJKoZIhvcNAQEFBQAwSTELMAkGA1UE
BhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxJTAjBgNVBAMTHEdvb2dsZSBJbnRl
cm5ldCBBdXRob3JpdHkgRzIwHhcNMTMxMDA3MDkzNDU0WhcNMTQxMDA3MDkzNDU0
WjCBgzELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcM
DU1vdW50YWluIFZpZXcxEzARBgNVBAoMCkdvb2dsZSBJbmMxMjAwBgNVBAMMKXdh
bGxldC1vYmplY3RzLXByb2Qtc3NsLndhbGxldC5nb29nbGUuY29tMIIBIjANBgkq
hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApdc1qkPsSj4oB9ZyIikXTAfvc/rX7zwY
UkSQyy6I26P15CFW8QuwkWoqnBz2jlYaXwZIebuXD3f02hR+nNGKKJXZlqt4l29X
6O2IklOzXRftpSGmNoOmM/DaWuInVTstwrhqplPGvAfERls5VxxQ0O2h9NesNTsY
VqQoUDrUoYUYK+eCA7mOsDkNAeGt8i4KAFw/i7iZjvpQ6Iq+gcQQ7Byre0PV6c9v
hTmJ/60VE+3Lsuxl3q/OCXLV5l/eryE+wMaGOfZR/IoV7D1vuwXDl/WnGrdA4YxA
WkzrEMs0nhlbtDpkLT8es2aBienlt5HDdVpvYrFpnZij9GlnpTqR8QIDAQABo4IB
XDCCAVgwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMDQGA1UdEQQtMCuC
KXdhbGxldC1vYmplY3RzLXByb2Qtc3NsLndhbGxldC5nb29nbGUuY29tMGgGCCsG
AQUFBwEBBFwwWjArBggrBgEFBQcwAoYfaHR0cDovL3BraS5nb29nbGUuY29tL0dJ
QUcyLmNydDArBggrBgEFBQcwAYYfaHR0cDovL2NsaWVudHMxLmdvb2dsZS5jb20v
b2NzcDAdBgNVHQ4EFgQUsfZTR7pQdQui96beisZ8Ug8K5hswDAYDVR0TAQH/BAIw
ADAfBgNVHSMEGDAWgBRK3QYWG7z2aLV29YG2u2IaulqBLzAXBgNVHSAEEDAOMAwG
CisGAQQB1nkCBQEwMAYDVR0fBCkwJzAloCOgIYYfaHR0cDovL3BraS5nb29nbGUu
Y29tL0dJQUcyLmNybDANBgkqhkiG9w0BAQUFAAOCAQEARRx/kpVmTl6BotbVusMK
YTSS9ToY6ONpEIAcR5Y8icDdbwJKs3NT7bVZs7I7aCypqpY7C/ixQrflnef2WL8p
pjfWCthrHt2ybZMoIdkIKxRQoNoIIx4fIed0Cu9mjAkBbvnBxMZ/ul+OF0uLoesB
zIluM//sZ/iIy6k/Z1mqk2k1dsK70VN44ZhBBcGqZXYMYh+RhX8NLY9WxB3YV8EW
4ree3gsmb6cr0SCQlTefN2KAJ0CXrsAZv8rf56DKjkPnxJ+qk9janZoVvJ21b1l6
dVg151t+RtlJOeHMyUWAEqnsItPCBF88yoliDVF4Wi64ZcQgkIwGXOQWBiVTmFv7
5w==
-----END CERTIFICATE-----

Paste everything starting with -----BEGIN CERTIFICATE----- up to ( and including) -----END CERTIFICATE----- into the Wallet Objects Merchant Console.

Examine the loyalty template

Following is an image showing the mapping of Loyalty Class and Loyalty Object fields to the loyalty template that you use in the Google Wallet app. Note:

  • The class preface indicates that the field is defined in the Wallet Class
  • The object preface indicates that the field is defined in the Wallet Object
  • A * preface indicates that the field can be specified in either Wallet Object or Wallet Class
Loyalty object template mapping
class.programLogo
class.issuerName
class.programName
object.loyaltyPoints.label
object.loyaltyPoints.balance
class.rewardsTierLabel
class.rewardsTier
object.barcode.label
object.barcode.type
object.barcode.value
object.barcode.alternateText
class.accountIdLabel
object.accountId
class.accountNameLabel
object.accountName
*.infoModuleData.labelValueRows[0].columns[0].label
*.infoModuleData.labelValueRows[0].columns[0].value
*.infoModuleData.labelValueRows[0].hexBackgroundColor
*.infoModuleData.labelValueRows[0].hexFontColor

*.infoModuleData.labelValueRows[0].columns[1].label
*.infoModuleData.labelValueRows[0].columns[1].value
*.showLastUpdateTime
*.imageModulesData.mainImage
*.messages[1].header
*.messages[1].body
*.messages[1].actionUri
*.messages[1].image
*.messages[0].header
*.messages[0].body
*.messages[0].actionUri
*.messages[0].image
*.textModulesData[0].header
*.textModulesData[0].body
*.textModulesData[1].header
*.textModulesData[1].body
*.linksModuleData.uris[0].description
*.linksModuleData.uris[0].uri
*.linksModuleData.uris[1].description
*.linksModuleData.uris[1].uri
*.linksModuleData.uris[2].description
*.linksModuleData.uris[2].uri
*.linksModuleData.uris[3].description
*.linksModuleData.uris[3].uri

Notes

  • This image includes all fields necessary to fill the 1.loyalty_expanded template. However, not all of these fields are required to create a valid Wallet Object. Refer to Loyaltyclass: insert and Loyaltyobject: insert for a list of required fields.
  • The character limit for a 1 column layout is 30 characters for a label and 30 characters for the value (refers to #11 in the image).
  • If a field in a module is not specified, the field is suppressed and other content expands to fill the area. For example, if you don't include an image in the message section of this template, the message text expands to fill the entire area where the image would have been located. If only one column of a two column infoModule is included, that one column is stretched to fill the entire area (goes from two 15 character columns to one 30 character column in number 11 in the image).
  • The most recent 3 messages are displayed in the expanded view of a wallet object.
  • Set the object.infoModuleData.hexFontColor and object.infoModuleData.hexBackgroundColor fields to change the font color and background colors of all elements (represented by #9-11 on the previous image). You can also set the font and background color on individual rows in the infoModuleData.
  • You can use .homepageUri or .linksModuleData to identify a URI to your home page. A URI placed in the .homepageUri field is placed before .linksModuleData.uris[0].

Save a loyalty card

Merchants create Loyalty Classes to represent loyalty cards. A consumer can then save a loyalty card to their Google Wallet either through the Google Wallet app or by clicking on a Save to Google button on the merchant's website. Saving a loyalty card creates a consumer-specific Loyalty Object in their Google Wallet.

1. Create a Discoverable

You will likely want to allow consumers to discover your loyalty programs from within the Google Wallet app and then either join them (if the consumer is not already a member) or link to them (if the consumer is a member, but doesn't have the program in Google Wallet). Loyalty programs that can be "discovered" using the Google Wallet app are called discoverables and present certain information to a consumer when the user decides to join or link to the program. Refer to the Discoverable Tutorial for information on how to make your loyalty programs and loyalty cards discoverable.

Note: You do not need to enable the Loyalty Web Service API if you want to create a loyalty program that is not discoverable (is only saved using the Save to Google button from the merchant's website).

2. Generate Loyalty Classes

The second step in integrating the Wallet Objects API is to create a Loyalty Class to represent your loyalty card. Your classes must go through the Class Approval Process before they can be used publicly.

Warning: You must set the reviewStatus field from draft to underReview when you believe the class is ready for review. The class will not be reviewed if you do not set the class to underReview. Unreviewed classes (classes set to draft) will not be visible to the public (only to trusted testers).

Loyalty Classes are posted to the following REST URI:

https://www.googleapis.com/walletobjects/v1/loyaltyClass

Note: Add the strict=true parameter to the REST URI to enable strict error parsing and catch additional errors, such as duplicate ID fields: https://www.googleapis.com/walletobjects/v1/loyaltyClass?strict=true

Following is an example Loyalty Class resource and code example demonstrating how to generate a Loyalty Class. Note that all required fields are represented in these examples, but not all optional fields. Refer to the REST API reference for a complete list of all optional fields in this resource.

Resource

{
  "accountIdLabel": "Member Id",
  "accountNameLabel": "Member Name",
  "allowMultipleUsersPerObject": true,
  "id": "2945482443380251551.ExampleClass1",
  "issuerName": "Baconrista",
  "kind": "walletobjects#loyaltyClass",
  "textModulesData": [
    {
      "header": "Rewards details",
      "body": "Welcome to Baconrista rewards.  Enjoy your rewards for being a loyal customer. " +
               "10 points for every dollar spent.  Redeem your points for free coffee, bacon and more!"
    }
  ],
  "linksModuleData": {
    "uris": [
      {
        "kind": "walletobjects#uri",
        "uri": "http://maps.google.com/map?q=google",
        "description": "Nearby Locations"
      },
      {
        "kind": "walletobjects#uri",
        "uri": "tel:6505555555",
        "description": "Call Customer Service"
      }
    ]
  },
  "infoModuleData": {
    "hexFontColor": "#F8EDC1",
    "hexBackgroundColor": "#442905"
  },
  "imageModulesData": [
    {
      "mainImage": {
        "kind": "walletobjects#image",
        "sourceUri": {
          "kind": "walletobjects#uri",
          "uri": "http://farm4.staticflickr.com/3738/12440799783_3dc3c20606_b.jpg",
          "description": "Coffee beans"
        }
      }
    }
  ],
  "messages": [{
    "actionUri": {
      "kind": "walletobjects#uri",
      "uri": "http://baconrista.com"
    },
    "header": "Welcome to Banconrista Rewards!",
    "body": "Featuring our new bacon donuts.",
    "image": {
      "kind": "walletobjects#image",
      "sourceUri": {
        "kind": "walletobjects#uri",
        "uri": "http://farm8.staticflickr.com/7302/11177240353_115daa5729_o.jpg"
      }
    },
    "kind": "walletobjects#walletObjectMessage"
  }],
  "locations"=>[{
    "kind": "walletobjects#latLongPoint",
    "latitude": 37.424015499999996,
    "longitude": -122.09259560000001
    },{
    "kind": "walletobjects#latLongPoint",
    "latitude": 37.424354,
    "longitude": -122.09508869999999
    },{
    "kind": "walletobjects#latLongPoint",
    "latitude": 37.7901435,
    "longitude": -122.39026709999997
    },{
    "kind": "walletobjects#latLongPoint",
    "latitude": 40.7406578,
    "longitude": -74.00208940000002
  }],
  "programLogo": {
    "kind": "walletobjects#image",
    "sourceUri": {
      "kind": "walletobjects#uri",
      "uri": "http://farm8.staticflickr.com/7340/11177041185_a61a7f2139_o.jpg"
    }
  },
  "programName": "Baconrista Rewards",
  "renderSpecs": [{
    "templateFamily": "1.loyalty_list",
    "viewName": "g_list"
  }, {
    "templateFamily": "1.loyalty_expanded",
    "viewName": "g_expanded"
  }],
  "rewardsTier": "Gold",
  "rewardsTierLabel": "Tier",
  "reviewStatus": "underReview",
}

Java

// Define rendering templates per view
List<RenderSpec> renderSpec = new ArrayList<RenderSpec>();

RenderSpec listRenderSpec = new RenderSpec().setViewName("g_list")
    .setTemplateFamily("1.loyalty_list");
RenderSpec expandedRenderSpec = new RenderSpec().setViewName("g_expanded")
    .setTemplateFamily("1.loyalty_expanded");

renderSpec.add(listRenderSpec);
renderSpec.add(expandedRenderSpec);

// Define the Image Module Data
List<ImageModuleData> imageModuleData = new ArrayList<ImageModuleData>();

ImageModuleData image = new ImageModuleData().setMainImage(
    new Image().setSourceUri(
        new Uri().setUri("http://farm4.staticflickr.com/3738/12440799783_3dc3c20606_b.jpg")));

imageModuleData.add(image);

// Define Text Module Data
List<TextModuleData> textModulesData = new ArrayList<TextModuleData>();

TextModuleData textModuleData = new TextModuleData().setHeader("Rewards details")
    .setBody(
        "Welcome to Baconrista rewards.  Enjoy your rewards for being a loyal customer.  10 points for ever dollar spent.  Redeem your points for free coffee, bacon and more!");
textModulesData.add(textModuleData);

// Define Links Module Data
List<Uri> uris = new ArrayList<Uri>();
Uri uri1 = new Uri().setDescription("Nearby Locations").setUri("http://maps.google.com/?q=google");
Uri uri2 = new Uri().setDescription("Call Customer Service").setUri("tel:6505555555");

uris.add(uri1);
uris.add(uri2);

LinksModuleData linksModuleData = new LinksModuleData().setUris(uris);

// Define Info Module
InfoModuleData infoModuleData = new InfoModuleData().setHexFontColor("#F8EDC1")
    .setHexBackgroundColor("#442905")
    .setShowLastUpdateTime(true);

// Define general messages
List<WalletObjectMessage> messages = new ArrayList<WalletObjectMessage>();
WalletObjectMessage message = new WalletObjectMessage()
    .setHeader("Welcome to Baconrista")
    .setBody("Featuring our new bacon donuts.")
    .setImage(
        new Image().setSourceUri(new Uri()
            .setUri("http://farm8.staticflickr.com/7302/11177240353_115daa5729_o.jpg")))
    .setActionUri(new Uri().setUri("http://baconrista.com"));
messages.add(message);

// Define Geofence locations
List<LatLongPoint> locations = new ArrayList<LatLongPoint>();
locations.add(new LatLongPoint().setLatitude(37.422601).setLongitude(
    -122.085286));
locations.add(new LatLongPoint().setLatitude(37.424354).setLongitude(
    -122.09508869999999));
locations.add(new LatLongPoint().setLatitude(40.7406578).setLongitude(
    -74.00208940000002));

// Create class
LoyaltyClass wobClass = new LoyaltyClass()
    .setId('2945482443380251551.ExampleClass1')
    .setIssuerName("Baconrista")
    .setProgramName("Baconrista Rewards")
    .setProgramLogo(
        new Image().setSourceUri(new Uri()
            .setUri("http://farm8.staticflickr.com/7340/11177041185_a61a7f2139_o.jpg")))
    .setRewardsTierLabel("Tier").setRewardsTier("Gold")
    .setImageModulesData(imageModuleData)
    .setTextModulesData(textModulesData)
    .setLinksModuleData(linksModuleData)
    .setInfoModuleData(infoModuleData)
    .setAccountNameLabel("Member Name").setAccountIdLabel("Member Id")
    .setRenderSpecs(renderSpec).setMessages(messages)
    .setReviewStatus("underReview").setAllowMultipleUsersPerObject(true)
    .setLocations(locations);

LoyaltyClass response = client.loyaltyclass().insert(wobClass).execute();

Ruby

loyalty_class = {
  "accountIdLabel" => "Member Id",
  "accountNameLabel" => "Member Name",
  "allowMultipleUsersPerObject" => true,
  "id" => "2945482443380251551.ExampleClass1",
  "issuerName" => "Baconrista",
  "kind" => "walletobjects#loyaltyClass",
  "textModulesData" => [
    {
      "header" => "Rewards details",
      "body" => "Welcome to Baconrista rewards.  Enjoy your rewards for being a loyal customer. " +
               "10 points for every dollar spent.  Redeem your points for free coffee, bacon and more!"
    }
  ],
  "linksModuleData" => {
    "uris" => [
      {
        "kind" => "walletobjects#uri",
        "uri" => "http://maps.google.com/map?q=google",
        "description" => "Nearby Locations"
      },
      {
        "kind" => "walletobjects#uri",
        "uri" => "tel:6505555555",
        "description" => "Call Customer Service"
      }
    ]
  },
  "infoModuleData" => {
    "hexFontColor" => "#F8EDC1",
    "hexBackgroundColor" => "#442905"
  },
  "imageModulesData" => [
    {
      "mainImage" => {
        "kind" => "walletobjects#image",
        "sourceUri" => {
          "kind" => "walletobjects#uri",
          "uri" => "http://farm4.staticflickr.com/3738/12440799783_3dc3c20606_b.jpg",
          "description" => "Coffee beans"
        }
      }
    }
  ],
  "messages" => [{
    "actionUri" => {
      "kind" => "walletobjects#uri",
      "uri" => "http://baconrista.com"
    },
    "header" => "Welcome to Banconrista Rewards!",
    "body" => "Featuring our new bacon donuts.",
    "image" => {
      "kind" => "walletobjects#image",
      "sourceUri" => {
        "kind" => "walletobjects#uri",
        "uri" => "http://farm8.staticflickr.com/7302/11177240353_115daa5729_o.jpg"
      }
    },
    "kind" => "walletobjects#walletObjectMessage"
  }],
  "locations"=>[{
    "kind" => "walletobjects#latLongPoint",
    "latitude" => 37.424015499999996,
    "longitude" => -122.09259560000001
    },{
    "kind" => "walletobjects#latLongPoint",
    "latitude" => 37.424354,
    "longitude" => -122.09508869999999
    },{
    "kind" => "walletobjects#latLongPoint",
    "latitude" => 37.7901435,
    "longitude" => -122.39026709999997
    },{
    "kind" => "walletobjects#latLongPoint",
    "latitude" => 40.7406578,
    "longitude" => -74.00208940000002
  }],
  "programLogo" => {
    "kind" => "walletobjects#image",
    "sourceUri" => {
      "kind" => "walletobjects#uri",
      "uri" => "http://farm8.staticflickr.com/7340/11177041185_a61a7f2139_o.jpg"
    }
  },
  "programName" => "Baconrista Rewards",
  "renderSpecs" => [{
    "templateFamily" => "1.loyalty_list",
    "viewName" => "g_list"
  }, {
    "templateFamily" => "1.loyalty_expanded",
    "viewName" => "g_expanded"
  }],
  "rewardsTier" => "Gold",
  "rewardsTierLabel" => "Tier",
  "reviewStatus" => "underReview",
}

result = api_client.execute(
  :api_method => walletobjects.loyaltyclass.insert,
  :body_object => loyalty_class
)

PHP

$renderSpecs = array(
    array('templateFamily' => '1.loyalty_list',
        'viewName' => 'g_list'),
    array('templateFamily' => '1.loyalty_expanded',
        'viewName' => 'g_expanded'));
// Define text module data.
$textModulesData = array(
    array(
        'header' => 'Rewards details',
        'body' => 'Welcome to Baconrista rewards.  Enjoy your rewards for being a loyal customer. ' .
            '10 points for every dollar spent.  Redeem your points for free coffee, bacon and more!'
    )
);
// Define links module data.
$linksModuleData = new Google_Service_Walletobjects_LinksModuleData();
$uris = array (
    array(
        'uri' => 'http://maps.google.com/map?q=google',
        'kind' => 'walletobjecs#uri',
        'description' => 'Nearby Locations'
    ),
    array(
        'uri' => 'tel:6505555555',
        'kind' => 'walletobjecs#uri',
        'description' => 'Call Customer Service'
    )
);
$linksModuleData->setUris($uris);
// Define info module data.
$infoModuleData = new Google_Service_Walletobjects_InfoModuleData();
$infoModuleData->setHexBackgroundColor('#442905');
$infoModuleData->setHexFontColor('#F8EDC1');

$uriModuleImageInstance = new Google_Service_Walletobjects_Uri();
$uriModuleImageInstance->setUri(
    'http://farm4.staticflickr.com/3738/12440799783_3dc3c20606_b.jpg'
);
$uriModuleImageInstance->setDescription('Coffee beans');
$imageModuleImageInstance = new Google_Service_Walletobjects_Image();
$imageModuleImageInstance->setSourceUri($uriModuleImageInstance);
$imagesModuleData = new Google_Service_Walletobjects_ImageModuleData();
$imagesModuleData->setMainImage($imageModuleImageInstance);
$imagesModuleDataArr = array ($imagesModuleData);

// Messages to be displayed to all users of Wallet Objects.
$messages = array(array(
    'actionUri' => array(
        'kind' => 'walletobjects#uri',
        'uri' => 'http://baconrista.com'
    ),
    'header' => 'Welcome to Banconrista Rewards!',
    'body' => 'Featuring our new bacon donuts.',
    'image' => array(
        'kind' => 'walletobjects#image',
        'sourceUri' => array(
            'kind' => 'walletobjects#uri',
            'uri' => 'http://farm8.staticflickr.com/7302/'.
            '11177240353_115daa5729_o.jpg'
        )
    ),
    'kind' => 'walletobjects#walletObjectMessage'
));
$locations = array(
    array(
        'kind' => 'walletobjects#latLongPoint',
        'latitude' => 37.424015499999996,
        'longitude' => -122.09259560000001
    ),
    array(
        'kind' => 'walletobjects#latLongPoint',
        'latitude' => 37.424354,
        'longitude' => -122.09508869999999
    ),
    array(
        'kind' => 'walletobjects#latLongPoint',
        'latitude' => 37.7901435,
        'longitude' => -122.39026709999997
    ),
    array(
        'kind' => 'walletobjects#latLongPoint',
        'latitude' => 40.7406578,
        'longitude' => -74.00208940000002
    )
);
// Source uri of program logo.
$uriInstance = new Google_Service_Walletobjects_Uri();
$imageInstance = new Google_Service_Walletobjects_Image();
$uriInstance->setUri(
    'http://farm8.staticflickr.com/7340/11177041185_a61a7f2139_o.jpg'
);
$imageInstance->setSourceUri($uriInstance);
// Create wallet class.
$wobClass = new Google_Service_Walletobjects_LoyaltyClass();
$wobClass->setId('2945482443380251551.ExampleClass1');
$wobClass->setIssuerName('Baconrista');
$wobClass->setProgramName('Baconrista Rewards');
$wobClass->setProgramLogo($imageInstance);
$wobClass->setRewardsTierLabel('Tier');
$wobClass->setRewardsTier('Gold');
$wobClass->setAccountNameLabel('Member Name');
$wobClass->setAccountIdLabel('Member Id');
$wobClass->setRenderSpecs($renderSpecs);
$wobClass->setInfoModuleData($infoModuleData);
$wobClass->setLinksModuleData($linksModuleData);
$wobClass->setTextModulesData($textModulesData);
$wobClass->setImageModulesData($imagesModuleDataArr);
$wobClass->setMessages($messages);
$wobClass->setReviewStatus('underReview');
$wobClass->setAllowMultipleUsersPerObject(true);
$wobClass->setLocations($locations);

$service->loyaltyclass->insert($wobClass);

Python

loyalty_class = {
  'accountIdLabel': 'Member Id',
  'accountNameLabel': 'Member Name',
  'allowMultipleUsersPerObject': True,
  'id': '2945482443380251551.ExampleClass1',
  'issuerName': 'Baconrista',
  'kind': 'walletobjects#loyaltyClass',
  'locations': [{
      'kind': 'walletobjects#latLongPoint',
      'latitude': 37.424015499999996,
      'longitude': -122.09259560000001
      },{
      'kind': 'walletobjects#latLongPoint',
      'latitude': 37.424354,
      'longitude': -122.09508869999999
      },{
      'kind': 'walletobjects#latLongPoint',
      'latitude': 37.7901435,
      'longitude': -122.39026709999997
      },{
      'kind': 'walletobjects#latLongPoint',
      'latitude': 40.7406578,
      'longitude': -74.00208940000002
  }],
  'textModulesData': [{
    'header': 'Rewards details',
    'body': 'Welcome to Baconrista rewards.  Enjoy your rewards for being a loyal customer. ' +
            '10 points for ever dollar spent.  Redeem your points for free coffee, bacon and more! '
  }],
  'linksModuleData': {
    'uris': [
      {
        'kind': 'walletobjects#uri',
        'uri': 'http://maps.google.com/map?q=google',
        'description': 'Nearby Locations'
      },{
        'kind': 'walletobjects#uri',
        'uri': 'tel:6505555555',
        'description': 'Call Customer Service'
      }]
  },
  'infoModuleData': {
    'hexFontColor': '#F8EDC1',
    'hexBackgroundColor': '#442905'
  },
  'imageModulesData': [
    {
      'mainImage': {
        'kind': 'walletobjects#image',
        'sourceUri': {
          'kind': 'walletobjects#uri',
          'uri':  'http://farm4.staticflickr.com/3738/12440799783_3dc3c20606_b.jpg',
          'description': 'Coffee beans'
        }
      }
    }
  ],
  'messages': [{
      'actionUri': {
          'kind': 'walletobjects#uri',
          'uri': 'http://baconrista.com'
      },
      'header': 'Welcome to Banconrista Rewards!',
      'body': 'Featuring our new bacon donuts.',
      'image': {
          'kind': 'walletobjects#image',
          'sourceUri': {
              'kind': 'walletobjects#uri',
              'uri': 'http://farm8.staticflickr.com/7302/11177240353_115daa5729_o.jpg'
          }
      },
      'kind': 'walletobjects#walletObjectMessage'
  }],
  'programLogo': {
      'kind': 'walletobjects#image',
      'sourceUri': {
          'kind': 'walletobjects#uri',
          'uri': 'http://farm8.staticflickr.com/7340/11177041185_a61a7f2139_o.jpg'
      }
  },
  'programName': 'Baconrista Rewards',
  'renderSpecs': [{
      'templateFamily': '1.loyalty_list',
      'viewName': 'g_list'
      }, {
      'templateFamily': '1.loyalty_expanded',
      'viewName': 'g_expanded'
  }],
  'rewardsTier': 'Gold',
  'rewardsTierLabel': 'Tier',
  'reviewStatus': 'underReview',
}

api_request = service.loyaltyclass().insert(body=loyalty_class)
api_response = api_request.execute()

C Sharp

// Define rendering templates per view
IList<RenderSpec> renderSpec = new List<RenderSpec>();

RenderSpec listRenderSpec = new RenderSpec() {
  ViewName = "g_list",
  TemplateFamily = "1.loyalty_list"
};

RenderSpec expandedRenderSpec = new RenderSpec() {
  ViewName = "g_expanded",
  TemplateFamily = "1.loyalty_expanded"
};

renderSpec.Add(listRenderSpec);
renderSpec.Add(expandedRenderSpec);

// Define the Image Module Data
IList<ImageModuleData> imageModulesData = new List<ImageModuleData>();
ImageModuleData image = new ImageModuleData() {
  MainImage = new Image() {
    SourceUri = new Uri() {
      UriValue = "http://farm4.staticflickr.com/3738/12440799783_3dc3c20606_b.jpg",
      Description = "Coffee beans"
    }
  }
};
imageModulesData.Add(image);

// Define Text Module Data
IList<TextModuleData> textModulesData = new List<TextModuleData>();
TextModuleData textModuleData = new TextModuleData() {
  Header = "Rewards details",
  Body = "Welcome to Baconrista rewards.  Enjoy your rewards for being a loyal customer.  " +
  "10 points for ever dollar spent.  Redeem your points for free coffee, bacon and more!"
};
textModulesData.Add(textModuleData);

// Define Links Module Data
IList<Uri> uris = new List<Uri>();
Uri uri1 = new Uri() {
  Description = "Nearby Locations",
  UriValue = "http://maps.google.com/?q=google"
};
Uri uri2 = new Uri() {
  Description = "Call Customer Service",
  UriValue = "tel:6505555555"
};
uris.Add(uri1);
uris.Add(uri2);

LinksModuleData linksModuleData = new LinksModuleData() {
  Uris = uris
};

// Define Info Module
InfoModuleData infoModuleData = new InfoModuleData() {
  HexFontColor = "#F8EDC1",
  HexBackgroundColor = "#442905",
  ShowLastUpdateTime = true
};

// Define general messages
IList<WalletObjectMessage> messages = new List<WalletObjectMessage>();
WalletObjectMessage message = new WalletObjectMessage() {
  Header = "Welcome to Banconrista Rewards!",
  Body = "Featuring our new bacon donuts.",
  Image = new Image() {
    SourceUri = new Uri() {
      UriValue = "http://farm8.staticflickr.com/7302/11177240353_115daa5729_o.jpg"
    }
  },
  ActionUri = new Uri() { UriValue = "http://baconrista.com" }
};
messages.Add(message);

// Define Geofence locations
IList<LatLongPoint> locations = new List<LatLongPoint>();
locations.Add(new LatLongPoint() { Latitude = 37.422601, Longitude = -122.085286 });
locations.Add(new LatLongPoint() { Latitude = 37.424354, Longitude = -122.09508869999999 });
locations.Add(new LatLongPoint() { Latitude = 40.7406578, Longitude = -74.00208940000002 });

// Create Loyalty class
LoyaltyClass wobClass = new LoyaltyClass() {
  Id = issuerId + "." + classId,
  IssuerName = "Baconrista",
  ProgramName = "Baconrista Rewards",
  ProgramLogo = new Image() {
    SourceUri = new Uri() {
      UriValue = "http://farm8.staticflickr.com/7340/11177041185_a61a7f2139_o.jpg"
    }
  },
  RewardsTierLabel = "Tier",
  RewardsTier = "Gold",
  AccountNameLabel = "Member Name",
  AccountIdLabel = "Member Id",
  RenderSpecs = renderSpec,
  Messages = messages,
  ReviewStatus = "underReview",
  AllowMultipleUsersPerObject = true,
  Locations = locations,
  ImageModulesData = imageModulesData,
  InfoModuleData = infoModuleData,
  TextModulesData = textModulesData,
  LinksModuleData = linksModuleData
};

3. Generate Loyalty Objects

The third step in saving a loyalty card is to generate the loyalty object for the consumer. There are three user flows that cause a new Loyalty Object to be created:

  • Consumer signs up for a new loyalty account using the Google Wallet app.
  • Consumer links an existing loyalty account through the Google Wallet app.
  • Consumer saves a loyalty card using the Save to Google button on the merchant's website

The signup and linking actions from the Google Wallet app result in requests to your web service. Google will attempt to contact your web service once with 3 second connection timeouts and 10 second read timeouts. An error message is sent to the user if Google does not receive a response within these timeframes.

Note: Google will provide the Program-Id as an HTTP header parameter enabling you to differentiate if you handle multiple loyalty programs (Program-Id: EXTERNAL_PROGRAM_ID).

a. Create objects as part of new account signup

The Google Wallet app allows users to discover and sign up for new loyalty programs. Google will POST the following JSON to your specified web service URL with the authentication described in the Loyalty Web Service API authentication section above.

{
  "apiVersion": "1.0",
  "method": "signup",
  "id": "ABCDEF",
  "params": {
    "walletUser": {
      "firstName": "Jane",
      "lastName": "Doe",
      "addressLine1": "1600 Amphitheatre Pkwy",
      "addressLine2": "Apt 123",
      "addressLine3": "Attn: Jane",
      "city": "Mountain View",
      "state": "CA",
      "zipcode": "94043",
      "country": "US",
      "email": "jane.doe@example.com",
      "phone": "555-555-5555",
      "gender": "FEMALE",
      "birthday": "0222",
      "userModifiedFields": [
      "BIRTHDAY"
      ]
    },
    "tosUserAcceptance": true,
    "promotionalEmailOptIn": true
  }
}

The following tabs provide code examples in different languages to deserialize the JSON to an object:

Java

Gson gson = new Gson();
WebserviceRequest req = gson.fromJson(json, WebserviceRequest.class);

Ruby

before do request.body.rewind
    @input = JSON.parse request.body.read  if (request.body && request.body.size > 0)
end

PHP

$utils = new WobUtils();
$input= json_decode( $inputJson, TRUE );
$requestObject = $utils->getWebserviceRequestObject($input);

Python

input = request.params

C Sharp

Stream inputStream = request.InputStream;
WebserviceRequest webRequest = NewtonsoftJsonSerializer.Instance.Deserialize<WebserviceRequest>(inputStream);

Your server must respond to Google Wallet with the result of the signup (success or failure). A successful response contains a JWT of the user's Loyalty Object to be stored in Google Wallet. The recommended response header content type is Content-Type: Application/JWT. Following is an success response body resource and code example showing how to create this response. The JSON needs to be encapsulated a JWT, signed with your OAuth private key using RSA256.

Resource

{
  "apiVersion": "1.0",
  "iss": "example_service_acct_email@developer.gserviceaccount.com",
  "typ": "loyaltywebservice",
  "aud": "google",
  "iat": 1365119677,
  "payload":
  {
    "webserviceResponse": {
      "status" : "SUCCESS"
    },
    "loyaltyObjects": [{
      "accountId": "1234567890",
      "accountName": "Jane Doe",
      "barcode": {
        "alternateText": "12345",
        "label": "User Id",
        "type": "qrCode",
        "value": "28343E3"
      },
      "classId": "2945482443380251551.ExampleClass1",
      "id": "2945482443380251551.ExampleObject1",
      "textModulesData": [{
        "header": "Jane's Baconrista Rewards",
        "body": "You are 5 coffees away from receiving a free bacon fat latte"
      }],
      "linksModuleData": {
        "uris": [
          {
            "kind": "walletobjects#uri",
            "uri": "http://www.baconrista.com/myaccount",
            "description": "My Baconrista Account"
          }]
      },
      "infoModuleData": {
        "hexFontColor": "#FFFFFF",
        "hexBackgroundColor": "#FC058C",
        "labelValueRows": [
          {
            "hexFontColor": "#000000",
            "hexBackgroundColor": "#BBCCFC",
            "columns": [
              {
                "label": "Member Name",
                "value": "Jane Doe"
              },
              {
                "label": "Membership #",
                "value": "1234567890"
              }
            ]
          },
          {
            "hexFontColor": "#EDEDDD",
            "hexBackgroundColor": "#FFFB00",
            "columns": [
              {
                "label": "Next Reward in",
                "value": "2 coffees"
              },
              {
                "label": "Member Since",
                "value": "01/15/2013"
              }
            ]
          }
        ],
        "showLastUpdateTime": true
      },
      "loyaltyPoints": {
        "balance": {
          "string": "500"
        },
        "label": "Points",
        "pointsType": "Rewards"
      },
      "messages": [{
        "actionUri": {
          "uri": "http://baconrista.com"
        },
        "header": "Jane, welcome to Banconrista Rewards!",
        "body": "Thanks for joining our program. Show this message to our barista for your first free coffee on us!",
        "image": {
          "sourceUri": {
            "uri": "http://farm8.staticflickr.com/7365/10949419886_974d6f7fc7_o.jpg"
          }
        }
      }],
      "state": "active",
      "version": 1
    }]
  }
}

Java

// Define Barcode
Barcode barcode = new Barcode().setType("qrCode")
    .setValue("28343E3")
    .setAlternateText("12345")
    .setLabel("User Id");

// Define Points
LoyaltyPoints points = new LoyaltyPoints()
    .setLabel("Points")
    .setPointsType("points")
    .setBalance(new LoyaltyPointsBalance().setString("500"));

// Define Text Module Data
List<TextModuleData> textModulesData = new ArrayList<TextModuleData>();
TextModuleData textModuleData = new TextModuleData()
    .setHeader("Jane's Baconrista Rewards")
    .setBody(
        "Save more at your local Mountain View store Jane.  You get 1 bacon fat latte for every 5 coffees purchased.  Also just for you, 10% off all pastries in the Mountain View store.");
textModulesData.add(textModuleData);

// Define Links Module Data
List<Uri> uris = new ArrayList<Uri>();
Uri uri1 = new Uri().setDescription("My Baconrista Account")
    .setUri("http://www.baconrista.com/myaccount?id=1234567890");
uris.add(uri1);
LinksModuleData linksModuleData = new LinksModuleData().setUris(uris);

// Define Info Module
List<LabelValue> row0cols = new ArrayList<LabelValue>();
LabelValue row0col0 = new LabelValue().setLabel("Next Reward in")
    .setValue("2 coffees");
LabelValue row0col1 = new LabelValue().setLabel("Member Since")
    .setValue("01/15/2013");
row0cols.add(row0col0);
row0cols.add(row0col1);

List<LabelValue> row1cols = new ArrayList<LabelValue>();
LabelValue row1col0 = new LabelValue().setLabel("Local Store")
    .setValue("Mountain View");
row1cols.add(row1col0);

List<LabelValueRow> rows = new ArrayList<LabelValueRow>();
LabelValueRow row0 = new LabelValueRow().setHexBackgroundColor("#922635")
    .setHexFontColor("#F8EDC1").setColumns(row0cols);
LabelValueRow row1 = new LabelValueRow().setHexBackgroundColor("#922635")
    .setHexFontColor("#F8EDC1").setColumns(row1cols);

rows.add(row0);
rows.add(row1);

InfoModuleData infoModuleData = new InfoModuleData().setHexFontColor("#F8EDC1")
    .setHexBackgroundColor("#442905")
    .setShowLastUpdateTime(true)
    .setLabelValueRows(rows);

// Define general messages
List<WalletObjectMessage> messages = new ArrayList<WalletObjectMessage>();
WalletObjectMessage message = new WalletObjectMessage()
    .setHeader("Hi Jane!")
    .setBody("Thanks for joining our program. Show this message to " +
        "our barista for your first free coffee on us!")
    .setImage(
        new Image().setSourceUri(new Uri()
            .setUri("http://farm4.staticflickr.com/3723/11177041115_6e6a3b6f49_o.jpg")))
    .setActionUri(new Uri().setUri("http://baconrista.com"));
messages.add(message);

// Define Wallet Instance
LoyaltyObject object = new LoyaltyObject()
    .setClassId('2945482443380251551.ExampleClass1').setId('2945482443380251551.ExampleObject1')
    .setVersion(1L).setState("active").setBarcode(barcode).setInfoModuleData(infoModuleData)
    .setAccountName("Jane Doe").setTextModulesData(textModulesData)
    .setMessages(messages).setLinksModuleData(linksModuleData)
    .setAccountId("1234567890").setLoyaltyPoints(points);

WebServiceResponse webResponse = new WebserviceResponse(WebserviceResponse.ResponseCode.SUCCESS);

String responseJwt = null;

try {
  WobCredentials credentials = new WobCredentials(
      ServiceAccountEmailAddress,
      ServiceAccountPrivateKey,
      ApplicationName,
      IssuerId);

  WobUtils utils = new WobUtils(credentials);

  responseJwt = utils.generateWebserviceResponseJwt(object, webResponse)
} catch (KeyStoreException e) {
  // Catch errors
  e.printStackTrace();
} catch (GeneralSecurityException e) {
  // Catch errors
  e.printStackTrace();
}

Ruby

jwt = {
  "iss" => SERVICE_ACCOUNT_EMAIL_ADDRESS,
  "aud" => "google",
  "typ" => "loyaltywebservice",
  "iat" => Time.now.utc.to_i,
  "payload" => {
    "webserviceResponse" => {
       "status"=> "SUCCESS"
    },
    "loyaltyObjects" => Array.new
  },
}
loyalty_object = {
  "accountId" => "1234567890",
  "accountName" => "Jane Doe",
  "barcode" => {
    "alternateText" => "12345",
    "label" => "User Id",
    "type" => "qrCode",
    "value" => "28343E3"
  },
  "classId" => "2945482443380251551.ExampleClass1",
  "id" => "2945482443380251551.ExampleObject1",
  "textModulesData" => [{
    "header" => "Jane's Baconrista Rewards",
    "body" => "You are 5 coffees away from receiving a free " +
              "bacon fat latte"
  }],
  "linksModuleData" => {
    "uris" => [
      {
        "kind" => "walletobjects#uri",
        "uri" => "http://www.baconrista.com/myaccount?id=1234567890",
        "description" => "My Baconrista Account"
      }]
  },
  "infoModuleData" => {
    "hexFontColor" => "#FFFFFF",
    "hexBackgroundColor" => "#FC058C",
    "labelValueRows" => [{
      "hexFontColor" => "#000000",
      "hexBackgroundColor" => "#BBCCFC",
      "columns" => [{
        "label" => "Member Name",
        "value" => "Jane Doe"
      }, {
        "label" => "Membership #",
        "value" => "1234567890"
      }]
    }, {
      "hexFontColor" => "#EDEDDD",
      "hexBackgroundColor" => "#FFFB00",
      "columns" => [{
        "label" => "Next Reward in",
        "value" => "2 coffees"
      }, {
        "label" => "Member Since",
        "value" => "01/15/2013"
      }]
    }],
    "showLastUpdateTime" => "true"
  },
  "loyaltyPoints" => {
    "balance" => {
      "string" => "500"
    },
    "label" => "Points",
      "pointsType" => "points"
  },
  "messages" => [{
    "actionUri" => {
      "uri" => "http://baconrista.com"
    },
    "header" => "Jane, welcome to Banconrista Rewards!",
    "body" => "Thanks for joining our program. Show this message to " +
              "our barista for your first free coffee on us!",
    "image" => {
      "sourceUri" => {
        "uri" => "http://farm4.staticflickr.com/3723/11177041115_6e6a3b6f49_o.jpg"
      }
    }
  }],
  "state" => "active",
  "version" => 1
}

jwt['payload']['loyaltyObjects'].push(loyalty_object)
private_key = Google::APIClient::PKCS12.load_key(KEYFILE, MERCHANT_SECRET)
jwt_encoded = JWT.encode(jwt, private_key, "RS256")

PHP

// Define barcode type and value.
$barcode = new Google_Service_Walletobjects_Barcode();
$barcode->setAlternateText('12345');
$barcode->setLabel('User Id');
$barcode->setType('qrCode');
$barcode->setValue('28343E3');
// Define text module data.
$textModulesData = array(
    array(
        'header' => 'Janes Baconrista Rewards',
        'body' => 'You are 5 coffees away from receiving a free '.
                  'bacon fat latte'
    )
);
// Define links module data.
$linksModuleData = new Google_Service_Walletobjects_LinksModuleData();
$uris = array (
    array(
        'uri' => 'http://www.baconrista.com/myaccount?id=1234567890',
        'kind' => 'walletobjecs#uri',
        'description' => 'My Baconrista Account'
    )
);
$linksModuleData->setUris($uris);
// Define label values.
$labelValueRows = array(
    array(
        'hexFontColor' => '#000000',
        'hexBackgroundColor' => '#BBCCFC',
        'columns' => array(
            array(
                'label' => 'Member Name',
                'value' => 'Jane Doe'
            ), array(
                'label' => 'Membership #',
                'value' => '1234567890'
            )
        )
    ),
    array(
        'hexFontColor' => '#EDEDDD',
        'hexBackgroundColor' => '#FFFB00',
        'columns' => array(
            array(
                'label' => 'Next Reward in',
                'value' => '2 coffees'
            ), array(
                'label' => 'Member Since',
                'value' => '01/15/2013'
            )
        )
    )
);
// Define info module data.
$infoModuleData = new Google_Service_Walletobjects_InfoModuleData();
$infoModuleData->setHexBackgroundColor('#FC058C');
$infoModuleData->setHexFontColor('#FFFFFF');
$infoModuleData->setShowLastUpdateTime(true);
$infoModuleData->setLabelValueRows($labelValueRows);
// Messages to be displayed.
$messages = array(array(
    'actionUri' => array(
        'kind' => 'walletobjects#uri',
        'uri' => 'http://baconrista.com'
    ),
    'header' => 'Jane, welcome to Banconrista Rewards!',
    'body' => 'Thanks for joining our program. Show this message to '.
              'our barista for your first free coffee on us!',
    'image' => array(
        'kind' => 'walletobjects#image',
        'sourceUri' => array(
            'kind' => 'walletobjects#uri',
            'uri' => 'http://farm4.staticflickr.com/3723/'.
            '11177041115_6e6a3b6f49_o.jpg'
        )
    ),
    'kind' => 'walletobjects#walletObjectMessage'
));
// Reward points a user has.
$points = new Google_Service_Walletobjects_LoyaltyPoints();
$balance = new Google_Service_Walletobjects_LoyaltyPointsBalance();
$balance->setString('500');
$points->setBalance($balance);
$points->setLabel('Points');
$points->setPointsType('points');
// Create wallet object.
$wobObject = new Google_Service_Walletobjects_LoyaltyObject();
$wobObject->setClassId('2945482443380251551.ExampleClass1');
$wobObject->setId('2945482443380251551.ExampleObject1');
$wobObject->setState('active');
$wobObject->setBarcode($barcode);
$wobObject->setInfoModuleData($infoModuleData);
$wobObject->setLinksModuleData($linksModuleData);
$wobObject->setTextModulesData($textModulesData);
$wobObject->setAccountName('Jane Doe');
$wobObject->setAccountId('1234567890');
$wobObject->setLoyaltyPoints($points);
$wobObject->setMessages($messages);

$webResponse = new WebserviceResponse('SUCCESS');
$responseBody = $utils->generateWebserviceResponse($loyaltyObject,
    $webResponse, $apiVersion);
$jwt = $utils->makeSignedJwt($responseBody, $cred);

Python

jwt = {
      'iss': config.SERVICE_ACCOUNT_EMAIL_ADDRESS,
      'aud': config.AUDIENCE,
      'typ': config.LOYALTY_WEB,
      'iat':  int(time.time()),
      'payload': {
        'webserviceResponse': {
          'status': 'SUCCESS'
        },
        'loyaltyObjects': []
      }
}
loyalty_object = {
    'accountId': '1234567890',
    'accountName': 'Jane Doe',
    'barcode': {
        'alternateText' : '12345',
        'label' : 'User Id',
        'type' : 'qrCode',
        'value' : '28343E3'
    },
    'classId' : '2945482443380251551.ExampleClass1',
    'id' : '2945482443380251551.ExampleObject1',
    'textModulesData': [{
      'header': 'Jane\'s Baconrista Rewards',
      'body': 'You are 5 coffees away from receiving a free ' +
              'bacon fat latte. '
    }],
    'linksModuleData': {
      'uris': [
        {
          'kind': 'walletobjects#uri',
          'uri': 'http://www.baconrista.com/myaccount?id=1234567890',
          'description': 'My Baconrista Account'
        }]
    },
    'infoModuleData': {
      'hexFontColor': '#FFFFFF',
      'hexBackgroundColor': '#FC058C',
      'labelValueRows': [{
          'hexFontColor': '#000000',
          'hexBackgroundColor': '#BBCCFC',
          'columns': [{
            'label': 'Member Name',
            'value': 'Jane Doe'
        }, {
          'label': 'Membership #',
          'value': '1234567890'
        }]
      }, {
          'hexFontColor': '#EDEDDD',
          'hexBackgroundColor': '#FFFB00',
          'columns': [{
            'label': 'Next Reward in',
            'value': '2 coffees'
          }, {
            'label': 'Member Since',
            'value': '01/15/2013'
          }]
      }],
      'showLastUpdateTime': 'true'
    },
    'loyaltyPoints': {
        'balance': {
            'string': '500'
        },
        'label': 'Points',
        'pointsType': 'points'
    },
    'state': 'active',
    'version': 1
}
jwt['payload']['loyaltyObjects'].append(loyalty_object)
signer = crypt.Signer.from_string(app_key)
signed_jwt = crypt.make_signed_jwt(signer, jwt)

C Sharp

// Define Barcode
Barcode barcode = new Barcode() { 
  Type = "qrCode",
  Value = "28343E3",
  AlternateText = "12345",
  Label = "User Id"
};

// Define Points
LoyaltyPoints points = new LoyaltyPoints() {
  Label = "Points",
  PointsType = "points",
  Balance = new LoyaltyPointsBalance() { String = "500" }
};

// Define Text Module Data
IList<TextModuleData> textModulesData = new List<TextModuleData>();
TextModuleData textModuleData = new TextModuleData() {
  Header = "Jane's Baconrista Rewards",
  Body = "Save more at your local Mountain View store Jane.  " + 
  "You get 1 bacon fat latte for every 5 coffees purchased.  " +
  "Also just for you, 10% off all pastries in the Mountain View store."
};
textModulesData.Add(textModuleData);          
    
// Define Links Module Data
IList<Uri> uris = new List<Uri>();
Uri uri1 = new Uri() {
  Description = "My Baconrista Account",
  UriValue = "http://www.baconrista.com/myaccount?id=1234567890"
};
uris.Add(uri1);

LinksModuleData linksModuleData = new LinksModuleData() {
  Uris = uris
};
    
// Define Info Module
IList<LabelValue> row0cols = new List<LabelValue>();
LabelValue row0col0 = new LabelValue() { Label = "Next Reward in", Value = "2 coffees" };
LabelValue row0col1 = new LabelValue() { Label = "Member Since", Value = "01/15/2013" };          
row0cols.Add(row0col0);
row0cols.Add(row0col1);

IList<LabelValue> row1cols = new List<LabelValue>();
LabelValue row1col0 = new LabelValue() { Label = "Local Store", Value = "Mountain View" };
row1cols.Add(row1col0);

IList<LabelValueRow> rows = new List<LabelValueRow>();
LabelValueRow row0 = new LabelValueRow() {
  HexBackgroundColor = "#922635",
  HexFontColor = "#F8EDC1",
  Columns = row0cols };
LabelValueRow row1 = new LabelValueRow() {
  HexBackgroundColor = "#922635",
  HexFontColor = "#F8EDC1",
  Columns = row1cols };

rows.Add(row0);
rows.Add(row1);

InfoModuleData infoModuleData = new InfoModuleData() {
  HexFontColor = "#F8EDC1",
  HexBackgroundColor = "#442905",
  ShowLastUpdateTime = true,
  LabelValueRows = rows 
};

// Define general messages
IList<WalletObjectMessage> messages = new List<WalletObjectMessage>();
WalletObjectMessage message = new WalletObjectMessage() {
  Header = "Hi Jane!",
  Body = "Thanks for joining our program. Show this message to " +
          "our barista for your first free coffee on us!",
  Image = new Image() {
    SourceUri = new Uri() {
      UriValue = "http://farm4.staticflickr.com/3723/11177041115_6e6a3b6f49_o.jpg"
    }
  },
  ActionUri = new Uri() { UriValue = "http://baconrista.com" }
};

messages.Add(message);

// Define Wallet Instance
LoyaltyObject loyaltyObj = new LoyaltyObject() {          
  ClassId = issuerId + "." + classId,
  Id = issuerId + "." + objectId,
  Version = 1,
  State = "active",
  Barcode = barcode,
  AccountName = "Jane Doe",
  AccountId = "1234567890",
  LoyaltyPoints = points,
  Messages = messages,
  InfoModuleData = infoModuleData,
  TextModulesData = textModulesData,
  LinksModuleData = linksModuleData
};

webRequest = NewtonsoftJsonSerializer.Instance.Deserialize<WebserviceRequest>(inputStream);

webResponse = new JsonWebToken.Payload.WebserviceResponse() {
  Status = SUCCESS
};

utils = new WobUtils(credentials.IssuerId, certificate);

string linkId = webRequest.Params.LinkingId;
LoyaltyObject loyaltyObject = Loyalty.generateLoyaltyObject(credentials.IssuerId, "LoyaltyClass", (linkId != null) ? linkId : "LoyaltyObject");
utils.addObject(loyaltyObject);

jwt = utils.GenerateWsJwt(webResponse);

HttpResponse response = context.Response;             
response.Write(jwt);

Following is a failure response body resource and code example showing how to create this response.

Resource

{
  "iss": "YourServiceAccount@developer.gserviceaccount.com",
  "aud": "google",
  "typ": "loyaltywebservice",
  "iat": 1375909526,
  "payload": {
    "webserviceResponse": {
      "status": "ERROR_INVALID_DATA_FORMAT",
      "invalidWalletUserFields": [ "zipcode", "phone" ]
    }
  }
}

Java

//Create invalid fields
List<String> invalidWalletUserFields = new ArrayList<String>();
invalidWalletUserFields.add("zipcode");
invalidWalletUserFields.add("phone");

//Create response
WebserviceResponse webResponse = new WebserviceResponse(
    WebserviceResponse.ResponseCode.ERROR_INVALID_DATA_FORMAT,
    invalidWalletUserFields);

WobUtils utils = null;
WobCredentials credentials = null;

String jwt

try {
  WobCredentials credentials = new WobCredentials(
        ServiceAccountEmailAddress,
        ServiceAccountPrivateKey,
        ApplicationName,
        IssuerId);
  utils = new WobUtils(credentials);
  jwt = utils.generateWebserviceFailureResponseJwt(webResponse);
} catch (FileNotFoundException e) {
  e.printStackTrace();
} catch (KeyStoreException e) {
  e.printStackTrace();
} catch (IOException e) {
  e.printStackTrace();
} catch (GeneralSecurityException e) {
  e.printStackTrace();
} catch (SignatureException e) {
e.printStackTrace();
}

Ruby

if(!success)
  jwt = {
    "iss" => SERVICE_ACCOUNT_EMAIL_ADDRESS,
    "aud" => "google",
    "typ" => "loyaltywebservice",
    "iat" => Time.now.utc.to_i,
    "payload" => {
      "webserviceResponse" => {
        "status" => "ERROR_INVALID_DATA_FORMAT",
        "invalidWalletUserFields" => [ "zipcode", "phone" ]
      },
    },
  }
private_key = Google::APIClient::PKCS12.load_key(KEYFILE, MERCHANT_SECRET)
jwt_encoded = JWT.encode(jwt, private_key, "RS256")

PHP

$errorAction = ($linkId != NULL) ? ResponseCode::ERROR_INVALID_LINKING_ID : ResponseCode::ERROR_ACCOUNT_ALREADY_LINKED;
// For rejected sign-up/linking.
$webResponse = new WebserviceResponse($errorAction);
$invalidFields = array('zipcode', 'phone');
$webResponse->setInvalidWalletUserFields($invalidFields);
// Generate Web Service Response Body.
$responseBody = $utils->generateWebserviceResponse('', $webResponse,
    $apiVersion);
$jwt = $utils->makeSignedJwt($responseBody, $cred);

Python

error_action = 'link' if request.params.get('linkingId') else 'signup'
jwt = {
  'iss': config.SERVICE_ACCOUNT_EMAIL_ADDRESS,
  'aud': config.AUDIENCE,
  'typ': config.LOYALTY_WEB,
  'iat':  int(time.time()),
  'payload': {
    'webserviceResponse': {
      'status': 'ERROR_INVALID_DATA_FORMAT',
      'invalidWalletUserFields': ['zipcode','phone']
    }
  }
}
signer = crypt.Signer.from_string(app_key)
signed_jwt = crypt.make_signed_jwt(signer, jwt)

Note: The status field is not configurable (valid values are defined in the API reference).

The Google Wallet app allows consumers to link to their existing loyalty programs. Google will send the following link request JSON to your web service:

{
  "apiVersion": "1.0",
  "method": "link",
  "id": "ABCDEF",
  "params": {
    "linkingId": "123456890",
    "walletUser": {
      "firstName": "Jane",
      "lastName": "Doe",
      "addressLine1": "1600 Amphitheatre Pkwy",
      "addressLine2": "Apt 123",
      "addressLine3": "Attn: Jane",
      "city": "Mountain View",
      "state": "CA",
      "zipcode": "94043",
      "country": "US",
      "email": "jane.doe@example.com",
      "zipcode": "94043",
      "phone": "555-555-5555",
      "gender": "FEMALE",
      "birthday": "0222",
      "userModifiedFields": [
      "BIRTHDAY"
      ]
    }
  }
}

The following tabs provide code examples in different languages to deserialize the JSON to an object:

Java

Gson gson = new Gson();
WebserviceRequest req = gson.fromJson(json, WebserviceRequest.class);

Ruby

before do request.body.rewind
    @input = JSON.parse request.body.read  if (request.body && request.body.size > 0)
end

PHP

$utils = new WobUtils();
$input= json_decode( $inputJson, TRUE );
$requestObject = $utils->getWebserviceRequestObject($input);

Python

input = request.params

C Sharp

Stream inputStream = request.InputStream;
WebserviceRequest webRequest = NewtonsoftJsonSerializer.Instance.Deserialize<WebserviceRequest>(inputStream);

Your server must respond to Google Wallet with the result of the link (success or failure). The response object is the same as response object for a sign up request. The recommended response header content type is also Content-Type: Application/JWT. You should change the messaging to represent a successful link. The JSON below also needs to be encapsulated into a JWT signed with your OAuth private key using RSA256.

Resource

{
  "apiVersion": "1.0",
  "iss": "example_service_acct_email@developer.gserviceaccount.com",
  "typ": "loyaltywebservice",
  "aud": "google",
  "iat": 1365119677,
  "payload":
  {
    "webserviceResponse": {
      "status" : "SUCCESS"
    },
    "loyaltyObjects": [{
      "accountId": "1234567890",
      "accountName": "Jane Doe",
      "barcode": {
        "alternateText": "12345",
        "label": "User Id",
        "type": "qrCode",
        "value": "28343E3"
      },
      "classId": "2945482443380251551.ExampleClass1",
      "id": "2945482443380251551.ExampleObject1",
      "textModulesData": [{
        "header": "Jane's Baconrista Rewards",
        "body": "You are 5 coffees away from receiving a free bacon fat latte"
      }],
      "linksModuleData": {
        "uris": [
          {
            "kind": "walletobjects#uri",
            "uri": "http://www.baconrista.com/myaccount",
            "description": "My Baconrista Account"
          }]
      },
      "infoModuleData": {
        "hexFontColor": "#FFFFFF",
        "hexBackgroundColor": "#FC058C",
        "labelValueRows": [
          {
            "hexFontColor": "#000000",
            "hexBackgroundColor": "#BBCCFC",
            "columns": [
              {
                "label": "Member Name",
                "value": "Jane Doe"
              },
              {
                "label": "Membership #",
                "value": "1234567890"
              }
            ]
          },
          {
            "hexFontColor": "#EDEDDD",
            "hexBackgroundColor": "#FFFB00",
            "columns": [
              {
                "label": "Next Reward in",
                "value": "2 coffees"
              },
              {
                "label": "Member Since",
                "value": "01/15/2013"
              }
            ]
          }
        ],
        "showLastUpdateTime": true
      },
      "loyaltyPoints": {
        "balance": {
          "string": "500"
        },
        "label": "Points",
        "pointsType": "Rewards"
      },
      "messages": [{
        "actionUri": {
          "uri": "http://baconrista.com"
        },
        "header": "Jane, welcome to Banconrista Rewards!",
        "body": "Thanks for joining our program. Show this message to our barista for your first free coffee on us!",
        "image": {
          "sourceUri": {
            "uri": "http://farm8.staticflickr.com/7365/10949419886_974d6f7fc7_o.jpg"
          }
        }
      }],
      "state": "active",
      "version": 1
    }]
  }
}

Java

// Define Barcode
Barcode barcode = new Barcode().setType("qrCode")
    .setValue("28343E3")
    .setAlternateText("12345")
    .setLabel("User Id");

// Define Points
LoyaltyPoints points = new LoyaltyPoints()
    .setLabel("Points")
    .setPointsType("points")
    .setBalance(new LoyaltyPointsBalance().setString("500"));

// Define Text Module Data
List<TextModuleData> textModulesData = new ArrayList<TextModuleData>();
TextModuleData textModuleData = new TextModuleData()
    .setHeader("Jane's Baconrista Rewards")
    .setBody(
        "Save more at your local Mountain View store Jane.  You get 1 bacon fat latte for every 5 coffees purchased.  Also just for you, 10% off all pastries in the Mountain View store.");
textModulesData.add(textModuleData);

// Define Links Module Data
List<Uri> uris = new ArrayList<Uri>();
Uri uri1 = new Uri().setDescription("My Baconrista Account")
    .setUri("http://www.baconrista.com/myaccount?id=1234567890");
uris.add(uri1);
LinksModuleData linksModuleData = new LinksModuleData().setUris(uris);

// Define Info Module
List<LabelValue> row0cols = new ArrayList<LabelValue>();
LabelValue row0col0 = new LabelValue().setLabel("Next Reward in")
    .setValue("2 coffees");
LabelValue row0col1 = new LabelValue().setLabel("Member Since")
    .setValue("01/15/2013");
row0cols.add(row0col0);
row0cols.add(row0col1);

List<LabelValue> row1cols = new ArrayList<LabelValue>();
LabelValue row1col0 = new LabelValue().setLabel("Local Store")
    .setValue("Mountain View");
row1cols.add(row1col0);

List<LabelValueRow> rows = new ArrayList<LabelValueRow>();
LabelValueRow row0 = new LabelValueRow().setHexBackgroundColor("#922635")
    .setHexFontColor("#F8EDC1").setColumns(row0cols);
LabelValueRow row1 = new LabelValueRow().setHexBackgroundColor("#922635")
    .setHexFontColor("#F8EDC1").setColumns(row1cols);

rows.add(row0);
rows.add(row1);

InfoModuleData infoModuleData = new InfoModuleData().setHexFontColor("#F8EDC1")
    .setHexBackgroundColor("#442905")
    .setShowLastUpdateTime(true)
    .setLabelValueRows(rows);

// Define general messages
List<WalletObjectMessage> messages = new ArrayList<WalletObjectMessage>();
WalletObjectMessage message = new WalletObjectMessage()
    .setHeader("Hi Jane!")
    .setBody("Thanks for joining our program. Show this message to " +
        "our barista for your first free coffee on us!")
    .setImage(
        new Image().setSourceUri(new Uri()
            .setUri("http://farm4.staticflickr.com/3723/11177041115_6e6a3b6f49_o.jpg")))
    .setActionUri(new Uri().setUri("http://baconrista.com"));
messages.add(message);

// Define Wallet Instance
LoyaltyObject object = new LoyaltyObject()
    .setClassId('2945482443380251551.ExampleClass1').setId('2945482443380251551.ExampleObject1')
    .setVersion(1L).setState("active").setBarcode(barcode).setInfoModuleData(infoModuleData)
    .setAccountName("Jane Doe").setTextModulesData(textModulesData)
    .setMessages(messages).setLinksModuleData(linksModuleData)
    .setAccountId("1234567890").setLoyaltyPoints(points);

WebServiceResponse webResponse = new WebserviceResponse(WebserviceResponse.ResponseCode.SUCCESS);

String responseJwt = null;

try {
  WobCredentials credentials = new WobCredentials(
      ServiceAccountEmailAddress,
      ServiceAccountPrivateKey,
      ApplicationName,
      IssuerId);

  WobUtils utils = new WobUtils(credentials);

  responseJwt = utils.generateWebserviceResponseJwt(object, webResponse)
} catch (KeyStoreException e) {
  // Catch errors
  e.printStackTrace();
} catch (GeneralSecurityException e) {
  // Catch errors
  e.printStackTrace();
}

Ruby

jwt = {
  "iss" => SERVICE_ACCOUNT_EMAIL_ADDRESS,
  "aud" => "google",
  "typ" => "loyaltywebservice",
  "iat" => Time.now.utc.to_i,
  "payload" => {
    "webserviceResponse" => {
       "status"=> "SUCCESS"
    },
    "loyaltyObjects" => Array.new
  },
}
loyalty_object = {
  "accountId" => "1234567890",
  "accountName" => "Jane Doe",
  "barcode" => {
    "alternateText" => "12345",
    "label" => "User Id",
    "type" => "qrCode",
    "value" => "28343E3"
  },
  "classId" => "2945482443380251551.ExampleClass1",
  "id" => "2945482443380251551.ExampleObject1",
  "textModulesData" => [{
    "header" => "Jane's Baconrista Rewards",
    "body" => "You are 5 coffees away from receiving a free " +
              "bacon fat latte"
  }],
  "linksModuleData" => {
    "uris" => [
      {
        "kind" => "walletobjects#uri",
        "uri" => "http://www.baconrista.com/myaccount?id=1234567890",
        "description" => "My Baconrista Account"
      }]
  },
  "infoModuleData" => {
    "hexFontColor" => "#FFFFFF",
    "hexBackgroundColor" => "#FC058C",
    "labelValueRows" => [{
      "hexFontColor" => "#000000",
      "hexBackgroundColor" => "#BBCCFC",
      "columns" => [{
        "label" => "Member Name",
        "value" => "Jane Doe"
      }, {
        "label" => "Membership #",
        "value" => "1234567890"
      }]
    }, {
      "hexFontColor" => "#EDEDDD",
      "hexBackgroundColor" => "#FFFB00",
      "columns" => [{
        "label" => "Next Reward in",
        "value" => "2 coffees"
      }, {
        "label" => "Member Since",
        "value" => "01/15/2013"
      }]
    }],
    "showLastUpdateTime" => "true"
  },
  "loyaltyPoints" => {
    "balance" => {
      "string" => "500"
    },
    "label" => "Points",
      "pointsType" => "points"
  },
  "messages" => [{
    "actionUri" => {
      "uri" => "http://baconrista.com"
    },
    "header" => "Jane, welcome to Banconrista Rewards!",
    "body" => "Thanks for joining our program. Show this message to " +
              "our barista for your first free coffee on us!",
    "image" => {
      "sourceUri" => {
        "uri" => "http://farm4.staticflickr.com/3723/11177041115_6e6a3b6f49_o.jpg"
      }
    }
  }],
  "state" => "active",
  "version" => 1
}

jwt['payload']['loyaltyObjects'].push(loyalty_object)
private_key = Google::APIClient::PKCS12.load_key(KEYFILE, MERCHANT_SECRET)
jwt_encoded = JWT.encode(jwt, private_key, "RS256")

PHP

// Define barcode type and value.
$barcode = new Google_Service_Walletobjects_Barcode();
$barcode->setAlternateText('12345');
$barcode->setLabel('User Id');
$barcode->setType('qrCode');
$barcode->setValue('28343E3');
// Define text module data.
$textModulesData = array(
    array(
        'header' => 'Janes Baconrista Rewards',
        'body' => 'You are 5 coffees away from receiving a free '.
                  'bacon fat latte'
    )
);
// Define links module data.
$linksModuleData = new Google_Service_Walletobjects_LinksModuleData();
$uris = array (
    array(
        'uri' => 'http://www.baconrista.com/myaccount?id=1234567890',
        'kind' => 'walletobjecs#uri',
        'description' => 'My Baconrista Account'
    )
);
$linksModuleData->setUris($uris);
// Define label values.
$labelValueRows = array(
    array(
        'hexFontColor' => '#000000',
        'hexBackgroundColor' => '#BBCCFC',
        'columns' => array(
            array(
                'label' => 'Member Name',
                'value' => 'Jane Doe'
            ), array(
                'label' => 'Membership #',
                'value' => '1234567890'
            )
        )
    ),
    array(
        'hexFontColor' => '#EDEDDD',
        'hexBackgroundColor' => '#FFFB00',
        'columns' => array(
            array(
                'label' => 'Next Reward in',
                'value' => '2 coffees'
            ), array(
                'label' => 'Member Since',
                'value' => '01/15/2013'
            )
        )
    )
);
// Define info module data.
$infoModuleData = new Google_Service_Walletobjects_InfoModuleData();
$infoModuleData->setHexBackgroundColor('#FC058C');
$infoModuleData->setHexFontColor('#FFFFFF');
$infoModuleData->setShowLastUpdateTime(true);
$infoModuleData->setLabelValueRows($labelValueRows);
// Messages to be displayed.
$messages = array(array(
    'actionUri' => array(
        'kind' => 'walletobjects#uri',
        'uri' => 'http://baconrista.com'
    ),
    'header' => 'Jane, welcome to Banconrista Rewards!',
    'body' => 'Thanks for joining our program. Show this message to '.
              'our barista for your first free coffee on us!',
    'image' => array(
        'kind' => 'walletobjects#image',
        'sourceUri' => array(
            'kind' => 'walletobjects#uri',
            'uri' => 'http://farm4.staticflickr.com/3723/'.
            '11177041115_6e6a3b6f49_o.jpg'
        )
    ),
    'kind' => 'walletobjects#walletObjectMessage'
));
// Reward points a user has.
$points = new Google_Service_Walletobjects_LoyaltyPoints();
$balance = new Google_Service_Walletobjects_LoyaltyPointsBalance();
$balance->setString('500');
$points->setBalance($balance);
$points->setLabel('Points');
$points->setPointsType('points');
// Create wallet object.
$wobObject = new Google_Service_Walletobjects_LoyaltyObject();
$wobObject->setClassId('2945482443380251551.ExampleClass1');
$wobObject->setId('2945482443380251551.ExampleObject1');
$wobObject->setState('active');
$wobObject->setBarcode($barcode);
$wobObject->setInfoModuleData($infoModuleData);
$wobObject->setLinksModuleData($linksModuleData);
$wobObject->setTextModulesData($textModulesData);
$wobObject->setAccountName('Jane Doe');
$wobObject->setAccountId('1234567890');
$wobObject->setLoyaltyPoints($points);
$wobObject->setMessages($messages);

$webResponse = new WebserviceResponse('SUCCESS');
$responseBody = $utils->generateWebserviceResponse($loyaltyObject,
    $webResponse, $apiVersion);
$jwt = $utils->makeSignedJwt($responseBody, $cred);

Python

jwt = {
      'iss': config.SERVICE_ACCOUNT_EMAIL_ADDRESS,
      'aud': config.AUDIENCE,
      'typ': config.LOYALTY_WEB,
      'iat':  int(time.time()),
      'payload': {
        'webserviceResponse': {
          'status': 'SUCCESS'
        },
        'loyaltyObjects': []
      }
}
loyalty_object = {
    'accountId': '1234567890',
    'accountName': 'Jane Doe',
    'barcode': {
        'alternateText' : '12345',
        'label' : 'User Id',
        'type' : 'qrCode',
        'value' : '28343E3'
    },
    'classId' : '2945482443380251551.ExampleClass1',
    'id' : '2945482443380251551.ExampleObject1',
    'textModulesData': [{
      'header': 'Jane\'s Baconrista Rewards',
      'body': 'You are 5 coffees away from receiving a free ' +
              'bacon fat latte. '
    }],
    'linksModuleData': {
      'uris': [
        {
          'kind': 'walletobjects#uri',
          'uri': 'http://www.baconrista.com/myaccount?id=1234567890',
          'description': 'My Baconrista Account'
        }]
    },
    'infoModuleData': {
      'hexFontColor': '#FFFFFF',
      'hexBackgroundColor': '#FC058C',
      'labelValueRows': [{
          'hexFontColor': '#000000',
          'hexBackgroundColor': '#BBCCFC',
          'columns': [{
            'label': 'Member Name',
            'value': 'Jane Doe'
        }, {
          'label': 'Membership #',
          'value': '1234567890'
        }]
      }, {
          'hexFontColor': '#EDEDDD',
          'hexBackgroundColor': '#FFFB00',
          'columns': [{
            'label': 'Next Reward in',
            'value': '2 coffees'
          }, {
            'label': 'Member Since',
            'value': '01/15/2013'
          }]
      }],
      'showLastUpdateTime': 'true'
    },
    'loyaltyPoints': {
        'balance': {
            'string': '500'
        },
        'label': 'Points',
        'pointsType': 'points'
    },
    'state': 'active',
    'version': 1
}
jwt['payload']['loyaltyObjects'].append(loyalty_object)
signer = crypt.Signer.from_string(app_key)
signed_jwt = crypt.make_signed_jwt(signer, jwt)

C Sharp

    // Define Barcode
Barcode barcode = new Barcode() { 
  Type = "qrCode",
  Value = "28343E3",
  AlternateText = "12345",
  Label = "User Id"
};

// Define Points
LoyaltyPoints points = new LoyaltyPoints() {
  Label = "Points",
  PointsType = "points",
  Balance = new LoyaltyPointsBalance() { String = "500" }
};

// Define Text Module Data
IList<TextModuleData> textModulesData = new List<TextModuleData>();
TextModuleData textModuleData = new TextModuleData() {
  Header = "Jane's Baconrista Rewards",
  Body = "Save more at your local Mountain View store Jane.  " + 
  "You get 1 bacon fat latte for every 5 coffees purchased.  " +
  "Also just for you, 10% off all pastries in the Mountain View store."
};
textModulesData.Add(textModuleData);          
    
// Define Links Module Data
IList<Uri> uris = new List<Uri>();
Uri uri1 = new Uri() {
  Description = "My Baconrista Account",
  UriValue = "http://www.baconrista.com/myaccount?id=1234567890"
};
uris.Add(uri1);

LinksModuleData linksModuleData = new LinksModuleData() {
  Uris = uris
};
    
// Define Info Module
IList<LabelValue> row0cols = new List<LabelValue>();
LabelValue row0col0 = new LabelValue() { Label = "Next Reward in", Value = "2 coffees" };
LabelValue row0col1 = new LabelValue() { Label = "Member Since", Value = "01/15/2013" };          
row0cols.Add(row0col0);
row0cols.Add(row0col1);

IList<LabelValue> row1cols = new List<LabelValue>();
LabelValue row1col0 = new LabelValue() { Label = "Local Store", Value = "Mountain View" };
row1cols.Add(row1col0);

IList<LabelValueRow> rows = new List<LabelValueRow>();
LabelValueRow row0 = new LabelValueRow() {
  HexBackgroundColor = "#922635",
  HexFontColor = "#F8EDC1",
  Columns = row0cols };
LabelValueRow row1 = new LabelValueRow() {
  HexBackgroundColor = "#922635",
  HexFontColor = "#F8EDC1",
  Columns = row1cols };

rows.Add(row0);
rows.Add(row1);

InfoModuleData infoModuleData = new InfoModuleData() {
  HexFontColor = "#F8EDC1",
  HexBackgroundColor = "#442905",
  ShowLastUpdateTime = true,
  LabelValueRows = rows 
};

// Define general messages
IList<WalletObjectMessage> messages = new List<WalletObjectMessage>();
WalletObjectMessage message = new WalletObjectMessage() {
  Header = "Hi Jane!",
  Body = "Thanks for joining our program. Show this message to " +
          "our barista for your first free coffee on us!",
  Image = new Image() {
    SourceUri = new Uri() {
      UriValue = "http://farm4.staticflickr.com/3723/11177041115_6e6a3b6f49_o.jpg"
    }
  },
  ActionUri = new Uri() { UriValue = "http://baconrista.com" }
};

messages.Add(message);

// Define Wallet Instance
LoyaltyObject loyaltyObj = new LoyaltyObject() {          
  ClassId = issuerId + "." + classId,
  Id = issuerId + "." + objectId,
  Version = 1,
  State = "active",
  Barcode = barcode,
  AccountName = "Jane Doe",
  AccountId = "1234567890",
  LoyaltyPoints = points,
  Messages = messages,
  InfoModuleData = infoModuleData,
  TextModulesData = textModulesData,
  LinksModuleData = linksModuleData
};

webRequest = NewtonsoftJsonSerializer.Instance.Deserialize<WebserviceRequest>(inputStream);

webResponse = new JsonWebToken.Payload.WebserviceResponse() {
  Status = SUCCESS
};

utils = new WobUtils(credentials.IssuerId, certificate);

string linkId = webRequest.Params.LinkingId;
LoyaltyObject loyaltyObject = Loyalty.generateLoyaltyObject(credentials.IssuerId, "LoyaltyClass", (linkId != null) ? linkId : "LoyaltyObject");
utils.addObject(loyaltyObject);

jwt = utils.GenerateWsJwt(webResponse);

HttpResponse response = context.Response;             
response.Write(jwt);

The following is a sample failure response body.

Resource

{
  "iss": "YourServiceAccount@developer.gserviceaccount.com",
  "aud": "google",
  "typ": "loyaltywebservice",
  "iat": 1375909526,
  "payload": {
    "webserviceResponse": {
      "status": "ERROR_INVALID_DATA_FORMAT",
      "invalidWalletUserFields": [ "zipcode", "phone" ]
    }
  }
}

Java

//Create invalid fields
List<String> invalidWalletUserFields = new ArrayList<String>();
invalidWalletUserFields.add("zipcode");
invalidWalletUserFields.add("phone");

//Create response
WebserviceResponse webResponse = new WebserviceResponse(
    WebserviceResponse.ResponseCode.ERROR_INVALID_DATA_FORMAT,
    invalidWalletUserFields);

WobUtils utils = null;
WobCredentials credentials = null;

String jwt

try {
  WobCredentials credentials = new WobCredentials(
        ServiceAccountEmailAddress,
        ServiceAccountPrivateKey,
        ApplicationName,
        IssuerId);
  utils = new WobUtils(credentials);
  jwt = utils.generateWebserviceFailureResponseJwt(webResponse);
} catch (FileNotFoundException e) {
  e.printStackTrace();
} catch (KeyStoreException e) {
  e.printStackTrace();
} catch (IOException e) {
  e.printStackTrace();
} catch (GeneralSecurityException e) {
  e.printStackTrace();
} catch (SignatureException e) {
e.printStackTrace();
}

Ruby

if(!success)
  jwt = {
    "iss" => SERVICE_ACCOUNT_EMAIL_ADDRESS,
    "aud" => "google",
    "typ" => "loyaltywebservice",
    "iat" => Time.now.utc.to_i,
    "payload" => {
      "webserviceResponse" => {
        "status" => "ERROR_INVALID_DATA_FORMAT",
        "invalidWalletUserFields" => [ "zipcode", "phone" ]
      },
    },
  }
private_key = Google::APIClient::PKCS12.load_key(KEYFILE, MERCHANT_SECRET)
jwt_encoded = JWT.encode(jwt, private_key, "RS256")

PHP

$errorAction = ($linkId != NULL) ? ResponseCode::ERROR_INVALID_LINKING_ID : ResponseCode::ERROR_ACCOUNT_ALREADY_LINKED;
// For rejected sign-up/linking.
$webResponse = new WebserviceResponse($errorAction);
$invalidFields = array('zipcode', 'phone');
$webResponse->setInvalidWalletUserFields($invalidFields);
// Generate Web Service Response Body.
$responseBody = $utils->generateWebserviceResponse('', $webResponse,
    $apiVersion);
$jwt = $utils->makeSignedJwt($responseBody, $cred);

Python

error_action = 'link' if request.params.get('linkingId') else 'signup'
jwt = {
  'iss': config.SERVICE_ACCOUNT_EMAIL_ADDRESS,
  'aud': config.AUDIENCE,
  'typ': config.LOYALTY_WEB,
  'iat':  int(time.time()),
  'payload': {
    'webserviceResponse': {
      'status': 'ERROR_INVALID_DATA_FORMAT',
      'invalidWalletUserFields': ['zipcode','phone']
    }
  }
}
signer = crypt.Signer.from_string(app_key)
signed_jwt = crypt.make_signed_jwt(signer, jwt)

Note: The status field is not configurable (valid values are defined in the API reference).

c. Create objects as part of Save to Google

Consumer can save loyalty cards to their Google Wallet by finding those cards on the web and clicking on a Save to Google button. You will use the Save to Google API to provide this functionality. The first step is generate the Loyalty Object to save.

Reference

{
  "classId": "2945482443380251551.ExampleClass1",
  "id": "2945482443380251551.ExampleObject1",
  "accountId": "1234567890",
  "accountName": "Jane Doe",
  "barcode": {
    "alternateText": "12345",
    "label": "User Id",
    "type": "qrCode",
    "value": "28343E3"
  },
  "classId": "#{issuerId}.#{classId}",
  "id": "#{issuerId}.#{objectId}",
  "textModulesData": [{
    "header": "Jane's Baconrista Rewards",
    "body": "Save more at your local Mountain View store Jane. " +
              "You get 1 bacon fat latte for every 5 coffees purchased.  " +
              "Also just for you, 10% off all pastries in the Mountain View store."
  }],
  "linksModuleData": {
    "uris": [
      {
        "kind": "walletobjects#uri",
        "uri": "http://www.baconrista.com/myaccount?id=1234567890",
        "description": "My Baconrista Account"
      }]
  },
  "infoModuleData": {
    "hexFontColor": "#F8EDC1",
    "hexBackgroundColor": "#442905",
    "labelValueRows": [{
      "hexFontColor": "#F8EDC1",
      "hexBackgroundColor": "#922635",
      "columns": [{
        "label": "Next Reward in",
        "value": "2 coffees"
      }, {
        "label": "Member Since",
        "value": "01/15/2013"
      }]
    }, {
      "hexFontColor": "#F8EDC1",
      "hexBackgroundColor": "#922635",
      "columns": [{
        "label": "Local Store",
        "value": "Mountain View"
      }]
    }],
    "showLastUpdateTime": "true"
  },
  "loyaltyPoints": {
    "balance": {
      "string": "5000"
    },
    "label": "Points",
      "pointsType": "points"
  },
  "messages": [{
    "actionUri": {
      "uri": "http://baconrista.com"
    },
    "header": "Jane, welcome to Banconrista Rewards!",
    "body": "Thanks for joining our program. Show this message to " +
              "our barista for your first free coffee on us!",
    "image": {
      "sourceUri": {
        "uri": "http://farm4.staticflickr.com/3723/11177041115_6e6a3b6f49_o.jpg"
      }
    }
  }],
  "state": "active",
  "version": 1
}

Java

// Define Barcode
Barcode barcode = new Barcode().setType("qrCode")
    .setValue("28343E3")
    .setAlternateText("12345")
    .setLabel("User Id");

// Define Points
LoyaltyPoints points = new LoyaltyPoints()
    .setLabel("Points")
    .setPointsType("points")
    .setBalance(new LoyaltyPointsBalance().setString("500"));

// Define Text Module Data
List<TextModuleData> textModulesData = new ArrayList<TextModuleData>();
TextModuleData textModuleData = new TextModuleData()
    .setHeader("Jane's Baconrista Rewards")
    .setBody(
        "Save more at your local Mountain View store Jane.  You get 1 bacon fat latte for every 5 coffees purchased.  Also just for you, 10% off all pastries in the Mountain View store.");
textModulesData.add(textModuleData);

// Define Links Module Data
List<Uri> uris = new ArrayList<Uri>();
Uri uri1 = new Uri().setDescription("My Baconrista Account")
    .setUri("http://www.baconrista.com/myaccount?id=1234567890");
uris.add(uri1);
LinksModuleData linksModuleData = new LinksModuleData().setUris(uris);

// Define Info Module
List<LabelValue> row0cols = new ArrayList<LabelValue>();
LabelValue row0col0 = new LabelValue().setLabel("Next Reward in")
    .setValue("2 coffees");
LabelValue row0col1 = new LabelValue().setLabel("Member Since")
    .setValue("01/15/2013");
row0cols.add(row0col0);
row0cols.add(row0col1);

List<LabelValue> row1cols = new ArrayList<LabelValue>();
LabelValue row1col0 = new LabelValue().setLabel("Local Store")
    .setValue("Mountain View");
row1cols.add(row1col0);

List<LabelValueRow> rows = new ArrayList<LabelValueRow>();
LabelValueRow row0 = new LabelValueRow().setHexBackgroundColor("#922635")
    .setHexFontColor("#F8EDC1").setColumns(row0cols);
LabelValueRow row1 = new LabelValueRow().setHexBackgroundColor("#922635")
    .setHexFontColor("#F8EDC1").setColumns(row1cols);

rows.add(row0);
rows.add(row1);

InfoModuleData infoModuleData = new InfoModuleData().setHexFontColor("#F8EDC1")
    .setHexBackgroundColor("#442905")
    .setShowLastUpdateTime(true)
    .setLabelValueRows(rows);

// Define general messages
List<WalletObjectMessage> messages = new ArrayList<WalletObjectMessage>();
WalletObjectMessage message = new WalletObjectMessage()
    .setHeader("Hi Jane!")
    .setBody("Thanks for joining our program. Show this message to " +
        "our barista for your first free coffee on us!")
    .setImage(
        new Image().setSourceUri(new Uri()
            .setUri("http://farm4.staticflickr.com/3723/11177041115_6e6a3b6f49_o.jpg")))
    .setActionUri(new Uri().setUri("http://baconrista.com"));
messages.add(message);

// Define Wallet Instance
LoyaltyObject object = new LoyaltyObject()
    .setClassId('2945482443380251551.ExampleClass1').setId('2945482443380251551.ExampleObject1')
    .setVersion(1L).setState("active").setBarcode(barcode).setInfoModuleData(infoModuleData)
    .setAccountName("Jane Doe").setTextModulesData(textModulesData)
    .setMessages(messages).setLinksModuleData(linksModuleData)
    .setAccountId("1234567890").setLoyaltyPoints(points);

Ruby

loyalty_object = {
  "classId" => "2945482443380251551.ExampleClass1",
  "id" => "2945482443380251551.ExampleObject1",
  "accountId" => "1234567890",
  "accountName" => "Jane Doe",
  "barcode" => {
    "alternateText" => "12345",
    "label" => "User Id",
    "type" => "qrCode",
    "value" => "28343E3"
  },
  "classId" => "#{issuerId}.#{classId}",
  "id" => "#{issuerId}.#{objectId}",
  "textModulesData" => [{
    "header" => "Jane's Baconrista Rewards",
    "body" => "Save more at your local Mountain View store Jane. " +
              "You get 1 bacon fat latte for every 5 coffees purchased.  " +
              "Also just for you, 10% off all pastries in the Mountain View store."
  }],
  "linksModuleData" => {
    "uris" => [
      {
        "kind" => "walletobjects#uri",
        "uri" => "http://www.baconrista.com/myaccount?id=1234567890",
        "description" => "My Baconrista Account"
      }]
  },
  "infoModuleData" => {
    "hexFontColor" => "#F8EDC1",
    "hexBackgroundColor" => "#442905",
    "labelValueRows" => [{
      "hexFontColor" => "#F8EDC1",
      "hexBackgroundColor" => "#922635",
      "columns" => [{
        "label" => "Next Reward in",
        "value" => "2 coffees"
      }, {
        "label" => "Member Since",
        "value" => "01/15/2013"
      }]
    }, {
      "hexFontColor" => "#F8EDC1",
      "hexBackgroundColor" => "#922635",
      "columns" => [{
        "label" => "Local Store",
        "value" => "Mountain View"
      }]
    }],
    "showLastUpdateTime" => "true"
  },
  "loyaltyPoints" => {
    "balance" => {
      "string" => "5000"
    },
    "label" => "Points",
      "pointsType" => "points"
  },
  "messages" => [{
    "actionUri" => {
      "uri" => "http://baconrista.com"
    },
    "header" => "Jane, welcome to Banconrista Rewards!",
    "body" => "Thanks for joining our program. Show this message to " +
              "our barista for your first free coffee on us!",
    "image" => {
      "sourceUri" => {
        "uri" => "http://farm4.staticflickr.com/3723/11177041115_6e6a3b6f49_o.jpg"
      }
    }
  }],
  "state" => "active",
  "version" => 1
}

PHP

$barcode = new Google_Service_Walletobjects_Barcode();
$barcode->setAlternateText('12345');
$barcode->setLabel('User Id');
$barcode->setType('qrCode');
$barcode->setValue('28343E3');
// Define text module data.
$textModulesData = array(
    array(
        'header' => 'Janes Baconrista Rewards',
        'body' => 'Save more at your local Mountain View store Jane. ' .
                  'You get 1 bacon fat latte for every 5 coffees purchased. ' .
                  'Also just for you, 10% off all pastries in the Mountain View store.'
    )
);
// Define links module data.
$linksModuleData = new Google_Service_Walletobjects_LinksModuleData();
$uris = array (
    array(
        'uri' => 'http://www.baconrista.com/myaccount?id=1234567890',
        'kind' => 'walletobjecs#uri',
        'description' => 'My Baconrista Account'
    )
);
$linksModuleData->setUris($uris);
// Define label values.
$labelValueRows = array(
    array(
        'hexFontColor' => '#F8EDC1',
        'hexBackgroundColor' => '#922635',
        'columns' => array(
            array(
                'label' => 'Next Reward in',
                'value' => '2 coffees'
            ), array(
                'label' => 'Member Since',
                'value' => '01/15/2013'
            )
        )
    ),
    array(
        'hexFontColor' => '#F8EDC1',
        'hexBackgroundColor' => '#922635',
        'columns' => array(
            array(
                'label' => 'Local Store',
                'value' => 'Mountain View'
            )
        )
    )
);
// Define info module data.
$infoModuleData = new Google_Service_Walletobjects_InfoModuleData();
$infoModuleData->setHexBackgroundColor('#442905');
$infoModuleData->setHexFontColor('#F8EDC1');
$infoModuleData->setShowLastUpdateTime(true);
$infoModuleData->setLabelValueRows($labelValueRows);
// Messages to be displayed.
$messages = array(array(
    'actionUri' => array(
        'kind' => 'walletobjects#uri',
        'uri' => 'http://baconrista.com'
    ),
    'header' => 'Jane, welcome to Banconrista Rewards!',
    'body' => 'Thanks for joining our program. Show this message to '.
              'our barista for your first free coffee on us!',
    'image' => array(
        'kind' => 'walletobjects#image',
        'sourceUri' => array(
            'kind' => 'walletobjects#uri',
            'uri' => 'http://farm4.staticflickr.com/3723/'.
            '11177041115_6e6a3b6f49_o.jpg'
        )
    ),
    'kind' => 'walletobjects#walletObjectMessage'
));
// Reward points a user has.
$points = new Google_Service_Walletobjects_LoyaltyPoints();
$balance = new Google_Service_Walletobjects_LoyaltyPointsBalance();
$balance->setString('500');
$points->setBalance($balance);
$points->setLabel('Points');
$points->setPointsType('points');
// Create wallet object.
$wobObject = new Google_Service_Walletobjects_LoyaltyObject();
$wobObject->setClassId('2945482443380251551.ExampleClass1');
$wobObject->setId('2945482443380251551.ExampleObject1');
$wobObject->setVersion(1);
$wobObject->setState('active');
$wobObject->setBarcode($barcode);
$wobObject->setInfoModuleData($infoModuleData);
$wobObject->setLinksModuleData($linksModuleData);
$wobObject->setTextModulesData($textModulesData);
$wobObject->setAccountName('Jane Doe');
$wobObject->setAccountId('1234567890');
$wobObject->setLoyaltyPoints($points);
$wobObject->setMessages($messages);

Python

loyalty_object = {
  'classId' : '2945482443380251551.ExampleClass1',
  'id' : '2945482443380251551.ExampleObject1',
  'accountId': '1234567890',
  'accountName': 'Jane Doe',
  'barcode': {
      'alternateText' : '12345',
      'label' : 'User Id',
      'type' : 'qrCode',
      'value' : '28343E3'
  },
  'textModulesData': [{
    'header': 'Jane\'s Baconrista Rewards',
    'body': 'Save more at your local Mountain View store Jane. ' +
            ' You get 1 bacon fat latte for every 5 coffees purchased.  ' +
            'Also just for you, 10% off all pastries in the Mountain View store.'
  }],
  'linksModuleData': {
    'uris': [
      {
        'kind': 'walletobjects#uri',
        'uri': 'http://www.baconrista.com/myaccount?id=1234567890',
        'description': 'My Baconrista Account'
      }]
  },
  'infoModuleData': {
    'hexFontColor': '#F8EDC1',
    'hexBackgroundColor': '#442905',
    'labelValueRows': [{
        'hexFontColor': '#F8EDC1',
        'hexBackgroundColor': '#922635',
        'columns': [{
          'label': 'Next Reward in',
          'value': '2 coffees'
        }, {
          'label': 'Member Since',
          'value': '01/15/2013'
        }]
      },{
        'hexFontColor': '#F8EDC1',
        'hexBackgroundColor': '#922635',
        'columns': [{
          'label': 'Local Store',
          'value': 'Mountain View'
        }]
    }],
    'showLastUpdateTime': 'true'
  },
  'messages': [{
      'actionUri': {
          'kind': 'walletobjects#uri',
          'uri': 'http://baconrista.com'
      },
      'header': 'Jane, welcome to Banconrista Rewards',
      'body': 'Thanks for joining our program. Show this message to ' +
              'our barista for your first free coffee on us!',
      'image': {
          'kind': 'walletobjects#image',
          'sourceUri': {
              'kind': 'walletobjects#uri',
              'uri': 'http://farm4.staticflickr.com/3723/11177041115_6e6a3b6f49_o.jpg'
          }
      },
      'kind': 'walletobjects#walletObjectMessage'
  }],
  'loyaltyPoints': {
      'balance': {
          'string': '500'
      },
      'label': 'Points',
      'pointsType': 'points'
  },
  'state': 'active',
  'version': 1
}

C Sharp

// Define Barcode
Barcode barcode = new Barcode() {
  Type = "qrCode",
  Value = "28343E3",
  AlternateText = "12345",
  Label = "User Id"
};

// Define Points
LoyaltyPoints points = new LoyaltyPoints() {
  Label = "Points",
  PointsType = "points",
  Balance = new LoyaltyPointsBalance() { String = "500" }
};

// Define Text Module Data
IList<TextModuleData> textModulesData = new List<TextModuleData>();
TextModuleData textModuleData = new TextModuleData() {
  Header = "Jane's Baconrista Rewards",
  Body = "Save more at your local Mountain View store Jane.  " +
  "You get 1 bacon fat latte for every 5 coffees purchased.  " +
  "Also just for you, 10% off all pastries in the Mountain View store."
};
textModulesData.Add(textModuleData);

// Define Links Module Data
IList<Uri> uris = new List<Uri>();
Uri uri1 = new Uri() {
  Description = "My Baconrista Account",
  UriValue = "http://www.baconrista.com/myaccount?id=1234567890"
};
uris.Add(uri1);

LinksModuleData linksModuleData = new LinksModuleData() {
  Uris = uris
};

// Define Info Module
IList<LabelValue> row0cols = new List<LabelValue>();
LabelValue row0col0 = new LabelValue() { Label = "Next Reward in", Value = "2 coffees" };
LabelValue row0col1 = new LabelValue() { Label = "Member Since", Value = "01/15/2013" };
row0cols.Add(row0col0);
row0cols.Add(row0col1);

IList<LabelValue> row1cols = new List<LabelValue>();
LabelValue row1col0 = new LabelValue() { Label = "Local Store", Value = "Mountain View" };
row1cols.Add(row1col0);

IList<LabelValueRow> rows = new List<LabelValueRow>();
LabelValueRow row0 = new LabelValueRow() {
  HexBackgroundColor = "#922635",
  HexFontColor = "#F8EDC1",
  Columns = row0cols };
LabelValueRow row1 = new LabelValueRow() {
  HexBackgroundColor = "#922635",
  HexFontColor = "#F8EDC1",
  Columns = row1cols };

rows.Add(row0);
rows.Add(row1);

InfoModuleData infoModuleData = new InfoModuleData() {
  HexFontColor = "#F8EDC1",
  HexBackgroundColor = "#442905",
  ShowLastUpdateTime = true,
  LabelValueRows = rows
};

// Define general messages
IList<WalletObjectMessage> messages = new List<WalletObjectMessage>();
WalletObjectMessage message = new WalletObjectMessage() {
  Header = "Hi Jane!",
  Body = "Thanks for joining our program. Show this message to " +
          "our barista for your first free coffee on us!",
  Image = new Image() {
    SourceUri = new Uri() {
      UriValue = "http://farm4.staticflickr.com/3723/11177041115_6e6a3b6f49_o.jpg"
    }
  },
  ActionUri = new Uri() { UriValue = "http://baconrista.com" }
};

messages.Add(message);

// Define Wallet Instance
LoyaltyObject loyaltyObj = new LoyaltyObject() {
  ClassId = issuerId + "." + classId,
  Id = issuerId + "." + objectId,
  Version = "1",
  State = "active",
  Barcode = barcode,
  AccountName = "Jane Doe",
  AccountId = "1234567890",
  LoyaltyPoints = points,
  Messages = messages,
  InfoModuleData = infoModuleData,
  TextModulesData = textModulesData,
  LinksModuleData = linksModuleData
};

The next step for saving a loyalty card is to create a server-side JSON Web Token (JWT) encapsulating the classes and objects and then to create the HTML functionality for the Save to Google button. Refer to the Save to Google Tutorial to continue with this part of your integration.

Note: You will need the private key and email address obtained in the Authentication section for the Save to Google API.

Update a loyalty card

You can update Loyalty Class fields if there is a change affecting all consumers holding the loyalty card. You can also update a specific Loyalty Object if there are changes to a specific consumer's card. Updating a loyalty card is a 3-step process: Use a GET request to retrieve the Loyalty Class or Loyalty Object, make the change to the class or object resource, use an UPDATE request to update the class or object.

Update a specific Loyalty Class

The following REST URIs are used to get a class and to put (update) a class:

GET https://www.googleapis.com/walletobjects/v1/loyaltyClass/resourceId
PUT https://www.googleapis.com/walletobjects/v1/loyaltyClass/resourceId
The following tabs provide code examples in different langauges to update a specific class:

Java

// Get the specific Loyalty Class
LoyaltyClass cls = client.loyaltyclass().get("2945482443380251551.ExampleClass1").execute();
// Update the program name
cls.setProgramName("Baconrista Rewards V2");
cls.setReviewStatus("underReview");
// Update the Loyalty Class
LoyaltyClass returnCls = client.loyaltyclass().update(cls.getClassId(), cls).execute();

Ruby

# Get the specific Loyalty Class
result = api_client.execute(
   :api_method => walletobjects.loyaltyclass.get,
   :parameters => {'resourceId' => '2945482443380251551.ExampleClass1' }
)
# Update the program name
class_toupdate["programName"] = "Program Name Updated"
# need to update reviewStatus for the class to be reviewed again
class_toupdate["reviewStatus"] = "underReview"
# Update the Loyalty Class
update_result = api_client.execute(
  :api_method => walletobjects.loyaltyclass.update,
  :parameters = {'resourceId' => '2945482443380251551.ExampleClass1' },
  :body_object => class_toupdate
)

PHP

// Get the specific Offer Class
Google_LoyaltyClass loyaltyClass = $service->loyaltyclass->get('2945482443380251551.ExampleClass1');
// Update the program name
loyaltyClass.setReviewStatus('underReview');
loyaltyClass.setProgramName('Baconrista Rewards V2');
// Update the Loyalty Class
Google_LoyaltyClass loyaltyClass = $service->loyaltyclass->update('2945482443380251551.ExampleClass1',loyaltyClass);

Python

# Get the specific Loyalty Class
loyalty_class = service.loyaltyclass().get(resourceId='2945482443380251551.ExampleClass1')
# Update the program name
loyalty_class['reviewStatus'] = 'underReview'
loyalty_class['programName'] = 'Baconrista Rewards V2'
# Update the Loyalty Class
api_request = service.loyaltyclass().update(resourceId='2945482443380251551.ExampleClass1',body=loyalty_class)
api_response = api_request.execute()

A get request is made to retrieve a specific class based on classID. Google Wallet responds to the request with the Loyalty Class. The program name is changed to "Baconrista Rewards V2." Finally, an update is made to update the class in Google Wallet.

Note: Changes to any of the fields listed in the Trigging an automatic review portion of the Class Approval Process will result in the class being re-reviewed.

Update a specific Loyalty Object

The following REST URIs are used to get an object and to put (update) an object:

GET https://www.googleapis.com/walletobjects/v1/loyaltyObject/resourceId
PUT https://www.googleapis.com/walletobjects/v1/loyaltyObject/resourceId

The following tabs provide code examples in different languages to update an object:

Java

// Get the specific Loyalty Object
LoyaltyObject obj = client.loyaltyobject().get("2945482443380251551.ExampleObject1").execute();
// Update the version and points
obj.setVersion(obj.getVersion() + 1L);
obj.setPoints(points);
// Update the Loyalty Object
LoyaltyObject returnObj = client.loyaltyobject().update(obj.getId(), obj).execute();

Ruby

# Get the specific Loyalty Object
result = api_client.execute(
  :api_method => walletobjects.loyaltyobject.get,
  :parameters => {'resourceId' => '2945482443380251551.ExampleObject1' }
)
# Update the version and points
obj_toupdate["version"] = obj_toupdate["version"].to_i + 1
obj_toupdate["loyaltyPoints"]["balance"]["string"] = "1000"
# Update the Loyalty Object
update_result = api_client.execute(
  :api_method => walletobjects.loyaltyobject.update,
  :parameters => {'resourceId' =>  '2945482443380251551.ExampleObject1'},
  :body_object => obj_toupdate
)

PHP

// Get the specific Loyalty Object
Google_LoyaltyObject loyaltyObj = $service->loyaltyobject->get('2945482443380251551.ExampleObject1');
// Update the version and points
loyaltyObj.setVersion(loyaltyObj.getVersion() + 1);
loyaltyObj.setLoyaltyPoints(points);
// Update the Loyalty Object
Google_LoyaltyObject loyaltyObj = $service->loyaltyobject->update('2945482443380251551.ExampleObject1',loyaltyObj);

Python

# Get the specific Loyalty Object
loyalty_object = service.loyaltyobject().get(resourceId='2945482443380251551.ExampleObject1')
# Update the version and points
loyalty_object['version'] = str(int(loyalty_object['version']) + 1)
loyalty_object['points'] = points
# Update the Loyalty Object
api_request = service.loyaltyobject().update(resourceId='2945482443380251551.ExampleObject1',body=loyalty_object)
api_response = api_request.execute()

A get request is made to retrieve a specific object based on objectID. Google Wallet responds to the request with the Loyalty Object. The version of the object is incremented and the points value is changed. Finally, an update is made to update the object in Google Wallet.

Other REST API use cases

The following section demonstrates how to use the REST API for other use cases.

Get a specific Loyalty Class

The following REST URI is used to get a Loyalty Class with a specific Class ID (resourceId):

GET https://www.googleapis.com/walletobjects/v1/loyaltyClass/resourceId

The following tabs provide code examples in different languages to get a Loyalty Class with a specific Class ID (resourceId).

Java

// Get the specific Loyalty Class
LoyaltyClass cls = client.loyaltyclass().get("2945482443380251551.ExampleClass1").execute();

Ruby

# Get the specific Loyalty Class
result = api_client.execute(
   :api_method => walletobjects.loyaltyclass.get,
   :parameters => {'resourceId' => '2945482443380251551.ExampleClass1' }

PHP

// Get the specific Offer Class
Google_LoyaltyClass loyaltyClass = $service->loyaltyclass->get('2945482443380251551.ExampleClass1');

Python

# Get the specific Loyalty Class
loyalty_class = service.loyaltyclass().get(resourceId='2945482443380251551.ExampleClass1')

Google Wallet responds to the request with the Loyalty Class.

{
  "accountIdLabel": "Member Id",
  "accountNameLabel": "Member Name",
  "allowMultipleUsersPerObject": true,
  "id": "2945482443380251551.ExampleClass1",
  "issuerName": "Baconrista",
  "kind": "walletobjects#loyaltyClass",
  "textModulesData": [
    {
      "header": "Rewards details",
      "body": "Welcome to Baconrista rewards.  Enjoy your rewards for being a loyal customer. " +
               "10 points for every dollar spent.  Redeem your points for free coffee, bacon and more!"
    }
  ],
  "linksModuleData": {
    "uris": [
      {
        "kind": "walletobjects#uri",
        "uri": "http://maps.google.com/map?q=google",
        "description": "Nearby Locations"
      },
      {
        "kind": "walletobjects#uri",
        "uri": "tel:6505555555",
        "description": "Call Customer Service"
      }
    ]
  },
  "infoModuleData": {
    "hexFontColor": "#F8EDC1",
    "hexBackgroundColor": "#442905"
  },
  "imageModulesData": [
    {
      "mainImage": {
        "kind": "walletobjects#image",
        "sourceUri": {
          "kind": "walletobjects#uri",
          "uri": "http://farm4.staticflickr.com/3738/12440799783_3dc3c20606_b.jpg",
          "description": "Coffee beans"
        }
      }
    }
  ],
  "messages": [{
    "actionUri": {
      "kind": "walletobjects#uri",
      "uri": "http://baconrista.com"
    },
    "header": "Welcome to Banconrista Rewards!",
    "body": "Featuring our new bacon donuts.",
    "image": {
      "kind": "walletobjects#image",
      "sourceUri": {
        "kind": "walletobjects#uri",
        "uri": "http://farm8.staticflickr.com/7302/11177240353_115daa5729_o.jpg"
      }
    },
    "kind": "walletobjects#walletObjectMessage"
  }],
  "locations"=>[{
    "kind": "walletobjects#latLongPoint",
    "latitude": 37.424015499999996,
    "longitude": -122.09259560000001
    },{
    "kind": "walletobjects#latLongPoint",
    "latitude": 37.424354,
    "longitude": -122.09508869999999
    },{
    "kind": "walletobjects#latLongPoint",
    "latitude": 37.7901435,
    "longitude": -122.39026709999997
    },{
    "kind": "walletobjects#latLongPoint",
    "latitude": 40.7406578,
    "longitude": -74.00208940000002
  }],
  "programLogo": {
    "kind": "walletobjects#image",
    "sourceUri": {
      "kind": "walletobjects#uri",
      "uri": "http://farm8.staticflickr.com/7340/11177041185_a61a7f2139_o.jpg"
    }
  },
  "programName": "Baconrista Rewards",
  "renderSpecs": [{
    "templateFamily": "1.loyalty_list",
    "viewName": "g_list"
  }, {
    "templateFamily": "1.loyalty_expanded",
    "viewName": "g_expanded"
  }],
  "rewardsTier": "Gold",
  "rewardsTierLabel": "Tier",
  "reviewStatus": "underReview",
}

Get a specific Loyalty Object

The following REST URI is used to get a Loyalty Object with a specific Object ID (resourceId):

GET https://www.googleapis.com/walletobjects/v1/loyaltyClass/resourceId

The following tabs provide code examples in different languages to get a Loyalty Object with a specific Object ID (resourceId).

Java

// Get the specific Loyalty Object
LoyaltyObject obj = client.loyaltyobject().get("2945482443380251551.ExampleObject1").execute();

Ruby

# Get the specific Loyalty Object
result = api_client.execute(
  :api_method => walletobjects.loyaltyobject.get,
  :parameters => {'resourceId' => '2945482443380251551.ExampleObject1' }
)

PHP

// Get the specific Loyalty Object
Google_LoyaltyObject loyaltyObj = $service->loyaltyobject->get('2945482443380251551.ExampleObject1');

Python

# Get the specific Loyalty Object
loyalty_obj = service.loyaltyobject().get(resourceId='2945482443380251551.ExampleObject1')

Google Wallet responds to the request with the Loyalty Object.

{
  "classId": "2945482443380251551.ExampleClass1",
  "id": "2945482443380251551.ExampleObject1",
  "accountId": "1234567890",
  "accountName": "Jane Doe",
  "barcode": {
    "alternateText": "12345",
    "label": "User Id",
    "type": "qrCode",
    "value": "28343E3"
  },
  "classId": "#{issuerId}.#{classId}",
  "id": "#{issuerId}.#{objectId}",
  "textModulesData": [{
    "header": "Jane's Baconrista Rewards",
    "body": "Save more at your local Mountain View store Jane. " +
              "You get 1 bacon fat latte for every 5 coffees purchased.  " +
              "Also just for you, 10% off all pastries in the Mountain View store."
  }],
  "linksModuleData": {
    "uris": [
      {
        "kind": "walletobjects#uri",
        "uri": "http://www.baconrista.com/myaccount?id=1234567890",
        "description": "My Baconrista Account"
      }]
  },
  "infoModuleData": {
    "hexFontColor": "#F8EDC1",
    "hexBackgroundColor": "#442905",
    "labelValueRows": [{
      "hexFontColor": "#F8EDC1",
      "hexBackgroundColor": "#922635",
      "columns": [{
        "label": "Next Reward in",
        "value": "2 coffees"
      }, {
        "label": "Member Since",
        "value": "01/15/2013"
      }]
    }, {
      "hexFontColor": "#F8EDC1",
      "hexBackgroundColor": "#922635",
      "columns": [{
        "label": "Local Store",
        "value": "Mountain View"
      }]
    }],
    "showLastUpdateTime": "true"
  },
  "loyaltyPoints": {
    "balance": {
      "string": "5000"
    },
    "label": "Points",
      "pointsType": "points"
  },
  "messages": [{
    "actionUri": {
      "uri": "http://baconrista.com"
    },
    "header": "Jane, welcome to Banconrista Rewards!",
    "body": "Thanks for joining our program. Show this message to " +
              "our barista for your first free coffee on us!",
    "image": {
      "sourceUri": {
        "uri": "http://farm4.staticflickr.com/3723/11177041115_6e6a3b6f49_o.jpg"
      }
    }
  }],
  "state": "active",
  "version": 1
}

List Loyalty Classes

The following REST URI is used to list (GET) Loyalty Classes:

GET https://www.googleapis.com/walletobjects/v1/loyaltyClass?issuerId=issuerId

The following tabs provide code examples in different languages to list Loyalty Classes created by an issuer with a specific issuer ID (issuerId). Note that LoyaltyClass1 and LoyaltyClass2 represent Loyalty Classes. All results are returned if maxResults isn't defined.

Java

LoyaltyClassListResponse classes = client.loyaltyclass()
  .list(1234567L)
  .setMaxResults(25)
  .execute();

Ruby

result = api_client.execute(
  :api_method => walletobjects.loyaltyclass.list,
  :parameters => {'issuerId' => '1234567',
    'maxResults' => '25' }
)

PHP

$optParams = array('maxResults' => '25');
$loyaltyClasses = $service->loyaltyclass->listLoyaltyclass('1234567', $optParams);

Python

api_request = service.loyaltyclass().list(issuerId='1234567', maxResults='25')
loyalty_classes = api_request.execute()

Google Wallet responds to the request with a list of Loyalty Classes:

{
  "pagination": {
    "kind": "walletobjects#pagination",
    "resultsPerPage": integer,
    "nextPageToken": string
  },
  "resources": [
    {LoyaltyClass1},
    {LoyaltyClass2}
  ]
}

List Loyalty Objects

The following REST URI is used to list (GET) Loyalty Objects:

GET https://www.googleapis.com/walletobjects/v1/loyaltyObject?classId=classId

The following tabs provide code examples in different languages to list Loyalty Objects of a specific Loyalty Class ID (classId). Note that LoyaltyObject1 and LoyaltyObject2 represent Loyalty Objects. All results are returned if maxResults isn't defined.

Java

LoyaltyObjectListResponse objs = client.loyaltyobject()
  .list("1234567.ExampleClass")
  .setMaxResults(25)
  .execute();

Ruby

class_id = "1234567.ExampleClass"
result = api_client.execute(
  :api_method => walletobjects.loyaltyobject.list,
  :parameters => {'classId' => '1234567.ExampleClass',
    'maxResults' => '25' }
)

PHP

$optParams = array('maxResults' => '25');
$loyaltyObjects = $service->loyaltyobject->listLoyaltyobject('1234567.ExampleClass', $optParams);

Python

api_request = service.loyaltyobject().list(classId='1234567.ExampleClass',
  maxResults='25')
obj_list = api_request.execute()

Google Wallet responds to the request with a list of Loyalty Objects:

{
  "pagination": {
    "kind": "walletobjects#pagination",
    "resultsPerPage": integer,
    "nextPageToken": string
  },
  "resources": [
    {LoyaltyObject1},
    {LoyaltyObject2}
  ]
}

Send a message

You can send messages to all users of a Loyalty Class or to specific Loyalty Objects. There are two ways to add a message to a Loyalty Class or Loyalty Object:

  • You can use the process in the Update a loyalty card section which allows you to get an update the message fields
  • You can simply POST the message to the addMessage URL. The Google Wallet app will will display the last five messages defined in the message array, with the most recent appearing at the top.

If you have time sensitive messages, you can set the window to display a message with start time and end time. When a message expires, Google Wallet automatically removes it from the array.

Add a message to a Loyalty Class

The following REST URI is used to post a message to a Loyalty Class with a specific Class ID:

POST https://www.googleapis.com/walletobjects/v1/loyaltyClass/classId/addMessage

The following tabs provide code examples in different languages to add a message to a Loyalty Class with a specific Class ID (classId).

Resource

{
  "header": "Congrats",
  "body": "Welcome to the program",
  "actionUri": {
    "uri": "http://action/uri",
  },
  "image": {
    "sourceUri":{
      "uri": "http://path/to/image",
    }
  },
  "displayInterval": {
    "startTime": "2014-04-12T23:20:50.52Z"
  },
}

Java

// Create the message
WalletObjectMessage message = new WalletObjectMessage()
  .setHeader("Welcome")
  .setBody("Welcome to Banconrista Rewards!")
  .setImage(new Image().setSourceUri(new Uri().setUri("http://baconrisa.com/example/path")))
  .setActionUri(new Uri().setUri("Resource://path/to/action"));
// Add the message to the class
WalletObjectMessage response = client.loyaltyclass().addMessage("2945482443380251551.ExampleClass1", message).execute();

Ruby

# Create the message
add_message = {
  "message" => {
    "actionUri" => {
      "uri" => "http://www.barista.com"
    },
    "body" => "Welcome to Banconrista Rewards!",
    "header" => "Welcome",
    "image" => {
      "sourceUri" => {
        "uri" => "http://baconrisa.com/example/path"
      }
    }
  }
}
# Add the message to the class
update_result = api_client.execute(
  :api_method => walletobjects.loyaltyclass.addmessage,
  :parameters => {'resourceId' => '2945482443380251551.ExampleClass1' },
  :body_object => add_message
)

PHP

// Create the message
Google_WalletObjectMessage message = new Google_WalletObjectMessage().
  .setHeader("Welcome")
  .setBody("Welcome to Banconrista Rewards!")
  .setImage(new Google_Image().setSourceUri(new Google_Uri().setUri("http://baconrisa.com/example/path")))
  .setActionUri(new Google_Uri().setUri("Resource://path/to/action"));
Google_LoyaltyClassAddMessageRequest messageRequest = new Google_LoyaltyClassAddMessageRequest().setMessage(message);
// Add the message to the class
Google_LoyaltyClassAddMessageResponse addMessageResponse = $service->loyaltyclass->addMessage('2945482443380251551.ExampleClass1',messageRequest);

Python

# Create the message
add_message = {
  "message": {
    "actionUri": {
      "uri": "http://www.barista.com"
    },
    "body": "Welcome to Banconrista Rewards!",
    "header": "Welcome",
    "image": {
      "sourceUri": {
        "uri": "http://baconrisa.com/example/path"
      }
    }
  }
}
# Add the message to the class
api_object = json.dumps(add_message)
api_request = service.loyaltyclass().addmessage(resourceId='2945482443380251551.ExampleClass1',body=api_object)
api_response = api_request.execute()

Note: The most recent 3 messages are displayed in the expanded view of a wallet object.

Add a message to a Loyalty Object

The following REST URI is used to post a message to a Loyalty Class with a specific Class ID:

POST https://www.googleapis.com/walletobjects/v1/loyaltyObject/id/addMessage

The following tabs provide code examples in different languages to add a message to a Loyalty Object with a specific Object ID (id).

Resource

{
  "header": "Congrats",
  "body": "Welcome to the program",
  "actionUri": {
    "uri": "http://action/uri",
  },
  "image": {
    "sourceUri":{
      "uri": "http://path/to/image",
    }
  },
  "displayInterval": {
    "startTime": "2014-04-12T23:20:50.52Z"
  },
}

Java

// Create the message
WalletObjectMessage message = new WalletObjectMessage()
  .setHeader("Welcome")
  .setBody("Welcome to Banconrista Rewards!")
  .setImage(new Image().setSourceUri(new Uri().setUri("http://baconrisa.com/example/path")))
  .setActionUri(new Uri().setUri("Resource://path/to/action"));
// Add the message to the object
WalletObjectMessage response = client.walletobject().addMessage("2945482443380251551.ExampleObject1", message).execute();

Ruby

# Create the message
add_message = {
  "message" => {
    "actionUri" => {
      "uri" => "http://www.barista.com"
    },
    "body" => "Welcome to Banconrista Rewards!",
    "header" => "Welcome",
    "image" => {
      "sourceUri" => {
        "uri" => "http://baconrisa.com/example/path"
      }
    }
  }
}
# Add the message to the object
update_result = api_client.execute(
  :api_method => walletobjects.loyaltyobject.addmessage,
  :parameters => {'resourceId' => '2945482443380251551.ExampleObject1' },
  :body_object => add_message
)

PHP

// Create the message
Google_WalletObjectMessage message = new Google_WalletObjectMessage().
  .setHeader("Welcome")
  .setBody("Welcome to Banconrista Rewards!")
  .setImage(new Google_Image().setSourceUri(new Google_Uri().setUri("http://baconrisa.com/example/path")))
  .setActionUri(new Google_Uri().setUri("Resource://path/to/action"));
Google_LoyaltyObjectAddMessageRequest messageRequest = new Google_LoyaltyObjectAddMessageRequest().setMessage(message);
// Add the message to the object
Google_LoyaltyObjectAddMessageResponse addMessageResponse = $service->loyaltyobject->addMessage('2945482443380251551.ExampleObject1',messageRequest);

Python

# Create the message
add_message = {
  "message": {
    "actionUri": {
      "uri": "http://www.barista.com"
    },
    "body": "Welcome to Banconrista Rewards!",
    "header": "Welcome",
    "image": {
      "sourceUri": {
        "uri": "http://baconrisa.com/example/path"
      }
    }
  }
}
# Add the message to the object
api_object = json.dumps(add_message)
api_request = service.loyaltyobject().addmessage(resourceId='2945482443380251551.ExampleObject1',body=api_object)
api_response = api_request.execute()

Note: The most recent 3 messages are displayed in the expanded view of a wallet object.

Next steps

Once you have a working integration in your development environment, make sure it meets Google's acceptance criteria before going live to consumers. See Loyalty Merchant Acceptance Testing for more information.