Windows Phone 8: Integrating with the Wallet

November 8, 2012

no comments

Earlier this week, Microsoft held the Discovery event in Tel Aviv, Israel, with a distinguished guest, Steve Ballmer. In the event, Microsoft has officially launched Windows 8 and Windows Phone 8 (and XBOX 360 and Kinect…) in Israel. During the presentations, a wallet application on Windows Phone was shown, which was developed by us, CodeValue (and specifically by me Smile). This article and this one describe something about the app (in Hebrew). Here are some screenshots (some text is in Hebrew):

 

wallet1wallet2wallet3wallet4

In this post, I’d like to show the basic steps to integrate an application with the built-in Windows Phone 8 wallet.

There are two ways to get a card into the wallet. The first is using the Wallet UI itself, which I won’t describe here. The second one is by writing some simple code that any application can use to insert cards (which may mean something to the app, not necessarily credit cards).

To do that, we need to use the AddWalletItemTask launcher, which requires a WalletItem-derived type to be prepared beforehand. Here’s a simple example:

var bmp = new BitmapImage();
bmp.SetSource(Application.GetResourceStream(new Uri(“Assets/ApplicationIcon.png”, UriKind.Relative)).Stream);


var item = new WalletTransactionItem("MyCard") {
    CustomerName = "John Doe",
    AccountNumber = "7890******",
    DisplayName = "The Master Card",
    Logo159x159 = bmp,
    Logo336x336 = bmp,
    Logo99x99 = bmp,
                    
    DisplayAvailableCredit = 5000m.ToString("c"),
    Message = "Hello, digital world!",
    IssuerName = "The Windows Phone Bank",
};
item.CustomProperties.Add("cardnumber", new CustomWalletProperty { Value = "1234567890" });

var task = new AddWalletItemTask { Item = item };
task.Show();

As can be seen from the code snippet, there are various properties we can use and even add custom ones (including a NavigationUri, that opens the app itself). The wallet doesn’t know what most properties mean – it just displays some of them in its UI.

After the launcher executes successfully, the card can be found in the wallet. The interesting part is doing something useful when the user selects the card inside the wallet. Since the application itself may not be running (suspended), or not even launched (the cards are saved until explicitly deleted by the user or the application), a background task is needed, so that the phone can launch it when appropriate. To do that, we can add a Scheduled Task Agent project to the solution in Visual Studio 2012:

SNAGHTML47698c

The agent’s base class needs to change to WalletAgent like so:

 public class MyWalletAgent : WalletAgent {

 

All that’s left to do is override the OnRefreshData method, go over the cards that are from our app and do something with them, such as get the last transactions from some web service:

protected override void OnRefreshData(RefreshDataEventArgs args) {
try {
        int cards = args.Items.Count;
        var svc = new MyCardServices.CardServiceClient("MyCardService");
        foreach (WalletTransactionItem item in args.Items) {
            svc.GetTransactionsCompleted += async (s, e) => {
                if (e.Error == null) {
                    var result = e.Result;
                    foreach (var tx in result) {
                        item.TransactionHistory.Add(tx.Id, new WalletTransaction {
                            Description = tx.Name,
                            Location = tx.Location,
                            NavigationUri = new Uri("/TransactionDetails.xaml?id=" + tx.Id, UriKind.Relative),
                            DisplayAmount = tx.Amount.ToString(),
                            TransactionDate = tx.Date
                        });
                        await item.SaveAsync();
                    }
                    if (Interlocked.Decrement(ref cards) == 0)
                        NotifyComplete();
                }
            };
            CustomWalletProperty cardid;
            if (item.CustomProperties.TryGetValue("cardnumber", out cardid)) {
                svc.GetTransactionsAsync(cardid.Value);
            }
        }
    }
    catch (Exception ex) {
        NotifyComplete();
    }
}

The interesting code goes over all cards added by the app. In my tests, there was always one card only in the collection, even if there were several in the wallet; the agent was invoked multiple times. The demo code uses some fictitious service to get some transaction information (asynchronously, using a completed style event). Then the TransactionHistory collection is updated, followed by a call to SaveAsync on the item to update the information in the wallet and refresh the wallet UI (all this happens when a card is actually selected within the wallet). Calling NotifyComplete indicates that the agent is done, and care must be taken not to do that too early, thus the await call. Also, note the deep link (NavigationUri property) that opens the actual app to show (in this case) more details on the transaction.

The last piece of the puzzle is connecting the main app to the agent, done via the manifest. It must be opened in text mode and add an extended task like so:

      <ExtendedTask Name="BackgroundTask">
        <BackgroundServiceAgent Specifier="WalletAgent" Name="WalletApp.Tasks" Source="WalletApp.Tasks"
             Type="WalletApp.Tasks.MyWalletAgent" />
      </ExtendedTask>

The Type attribute is the class name of the agent (Source is the assembly name).

That’s about it. Not too difficult indeed.

 

Add comment
facebook linkedin twitter email

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*