Home > Development, Mobile > Linking Your App to the Wallet

Linking Your App to the Wallet

So Windows Phone has an integrated wallet experience, but why would you want to link it to your app? Well if you’re a financial institution of course you might want to enable payments with your cards. But even if you’re not a bank and your app offers deals, coupons, a membership or even stored value, integrating with the wallet give the user increased visibility to your offers. Oh, and did I mention free promotion in the wallet app – even if your app isn’t installed?

 

Adding Wallet support is actually quite easy, especially if the app doesn’t need to update the wallet when it’s not running.

The first step is to add the wallet capability to the app. This can be done by double-clicking on WMAppManifest.xml (under Properties), switching to the Capabilities tab and checking the ID_CAP_WALLET checkbox.

 

clip_image001

 

Don’t check the other two wallet-related boxes unless you want to add real payment options (e.g. Visa credit cards) that can be used to buy music, apps, etc. These boxes don’t need to be checked for membership cards (like a Starbucks card).

 

Note: If a financial app does want to add payment cards it will need to pass a few extra certification requirements with the Windows Phone store.

 

Next we need to register our app as an extension to the wallet. Unfortunately there isn’t a way to do this in the UI so we’ll need to save our work, right click on WMAppManifest.xml and choose ‘View Code’. After the closing </Tokens> tag, add an Extensions block like this:

 

<Extensions>
  <Extension ExtensionName="Wallet_app_membership" ConsumerID="{5B04B775-356B-4AA0-AAF8-6491FFEA5683}" TaskID="_default"/>
</Extensions>

ConsumerID and TaskID will never change – they’re always those values. But ExtensionName might change depending on how you want to interact with the wallet. The choices are:

  • Wallet_app_other – for non-specific Wallet items
  • Wallet_app_loyalty – for loyalty cards
  • Wallet_app_membership – for membership cards
  • Wallet_app_transit – for transit cards
  • Wallet_app_payment – for payment cards

Wallet_app_membership is a good choice for most applications, and if you want to register support multiple extensions you could do it like this:

 

<Extensions>
  <Extension ExtensionName="Wallet_app_membership" ConsumerID="{5B04B775-356B-4AA0-AAF8-6491FFEA5683}" TaskID="_default"/>
  <Extension ExtensionName="Wallet_app_loyalty" ConsumerID="{5B04B775-356B-4AA0-AAF8-6491FFEA5683}" TaskID="_default"/>
</Extensions>

 

Now save WMAppManifest.xml and when you submit your app to the store it will start getting promoted in the wallet app. That’s a tremendous advertising advantage!

 

clip_image002

 

The last thing we need to do is have our application add a card to the wallet. Up to this point we’ve given the app the ability to interact with the wallet and gotten our application advertised there, but there’s still no link from the wallet back into our app once it’s installed. Don’t worry, the card you create can simply be a membership card. It doesn’t have to report a live credit balance (though it can if you want it to). You might just want to display a logo and give the user the ability to launch the app. Of course this is a great place to add customer support information like e-mail addresses and phone numbers, and you might want to display a QR code for example to identify the user at a retail store. It’s up to you how much information you want to add, but the WalletTransactionItem documentation gives you a listing of what’s possible.

When your app adds the card is up to you, but a good place to ask is on application launch. Of course if the user declines the card we don’t want to ask again (though we probably want to give them the option to add it later via a button or menu item). Also keep in mind that the membership card might have already been added so we want to make sure it doesn’t exist before we try to add it again.

Finally, there are some slightly unusual requirements we need to knowing about the card logo image. First of all, the card actually needs three image sizes (336×336, 159×159 and 99×99). Luckily we can supply one large image for all three sizes and the system will resize it for us. The more important requirement is that the image has to be fully loaded before the request is made to add the card. Most people don’t know that passing a URI into the constructor of BitmapImage doesn’t load it right away. It kicks off a background task to load the image and you’ll get an exception if you try to add your card before this task completes.

There are a couple of workarounds but the easiest one is to store the image as a resource and load it as a stream. Don’t forget to set the Build Action in the property window to ‘Embedded Resource’ instead of ‘Content’, which is the default.

Here is one possible method for adding a membership card:

 

private void EnsureMembership()
{
    // If the membership already exists, just ignore
    var existing = Wallet.FindItem("MainMembership");
    if (existing != null)
    {
        Debug.WriteLine("Membership card already exists; not adding again.");
        return;
    }

    // We have to load our image before we can create the membership
    // Otherwise adding the membership will fail
    var logoImage = new BitmapImage();
    using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("PhoneWalletTest.Images.Logo336.png"))
    {
        logoImage.SetSource(stream);
    }

    // Create membership card
    var membershipItem = new WalletTransactionItem("MainMembership");
    membershipItem.DisplayName = "Sample Membership";
    membershipItem.IssuerName = "Sample Business";
    membershipItem.IssuerPhone.Business = "(###) ###-####";
    membershipItem.IssuerWebsite = new Uri("http://www.samplebusiness.com&quot;);
    membershipItem.BillingPhone = "(###) ###-####";
            
    // All three logo sizes must be set, but they can automatically be
    // resized from a larger one.
    membershipItem.Logo336x336 = logoImage;
    membershipItem.Logo159x159 = logoImage;
    membershipItem.Logo99x99 = logoImage;

    // Create a task to add the card and subscribe to the completed
    // event so we know if anything went wrong.
    var addItemTask = new AddWalletItemTask();
    addItemTask.Completed += addItemTask_Completed;

    // Set the membership as the item and show the task to add the card
    addItemTask.Item = membershipItem;
    addItemTask.Show();
}

 

We also need the event handler for when the task completes. This is so we can inform the user if something went wrong and it’s also a good place to store a flag if the user chooses to decline the card:

 

private void addItemTask_Completed(object sender, AddWalletItemResult e)
{
    if (e.TaskResult == TaskResult.OK)
    {
        Debug.WriteLine("Membership card added.");
    }
    else if (e.TaskResult == TaskResult.Cancel)
    {
        Debug.WriteLine("User declined membership card.");

        // Remember that the user cancelled so we don't ask them again
        IsolatedStorageSettings.ApplicationSettings["MembershipCardCanceled"] = true;
        IsolatedStorageSettings.ApplicationSettings.Save();
    }
    else if (e.Error != null)
    {
        MessageBox.Show(string.Format("Problem adding membership card {0}", e.Error));
    }
}

 

Now we can call EnsureMembership from the page Loaded event or from a button click. In the loaded event we only want to call it automatically if the user hasn’t declined the card before.

 

private void MainPage_Loaded(object sender, RoutedEventArgs e)
{
    // Make sure the user hasn't previously declined the card
    // before we try to add it again.
    if (IsolatedStorageSettings.ApplicationSettings.Contains("MembershipCardCanceled"))
    {
        Debug.WriteLine("User declined to add card previously. Not attempting to add again.");
    }
    else
    {
        EnsureMembership();
    }
}

 

And finally, we can call the same method from a button click without checking for a previous decline (since the user is actually making the request).

 

private void AddMembershipButton_Click(object sender, RoutedEventArgs e)
{
    EnsureMembership();
}

 

These are the basic steps needed for wallet integration and the sample code can be downloaded here. If you’d like to know more about the wallet like payment cards and updating the wallet in the background, I highly recommend this video on Channel 9.

Advertisements
Categories: Development, Mobile Tags:
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: