Keeping Payment Instruments Up-To-Date with a Background Agent

,

Background agents allow your app to perform a task both while your app is running or not running. For more information on background agents, see Chapter 32, “Conducting Background Activities with Scheduled Actions.”

Perform the following steps to create a Background Agent for your Wallet-enabled app:

1. Create a new Windows Phone Class Library project. Right-click the solution node in the Visual Studio Solution Explorer and select Add/New Project. Select the project type from the Windows Phone node in the Add New Project dialog.

2. Create a new class and add the following using statement to the top of the file:

using Microsoft.Phone.Wallet;

3. Make your class a subclass of WalletAgent.

4. Override the WalletAgent class’s OnRefreshData method.

5. Add a reference to the class library from your main app project.

6. Modify the WMAppManifest.xml file of your main app project to include a BackgroundServiceAgent element that specifies your Wallet agent.

To modify the WMAppManifest.xml file in step 6, open the file in a text editor by right-clicking the WMAppManifest.xml file in the Visual Studio Solution Explorer and selecting View Code.

Listing 25.8 demonstrates how to nominate a WalletAgent in the WMAppManifest.xml file. The Specifier attribute indicates the type of background agent and must be equal to WalletAgent. The Source attribute is the name of the assembly where the agent resides. The Type attribute is the fully qualified type name of the agent.

LISTING 25.8. WPUnleashed.PaymentInstrumentApp WMAppManifest.xml (excerpt)


<Tasks>
  ...
  <ExtendedTask Name="BackgroundTask">
    <BackgroundServiceAgent Specifier="WalletAgent"
                            Name="WPUnleashed.WalletAgent"
                            Source="DanielVaughan.WPUnleashed.WalletAgent"
                            Type="DanielVaughan.WPUnleashed.UnleashedWalletAgent" />
  </ExtendedTask>
</Tasks>


The WalletAgent class’s OnRefreshData method provides you with the opportunity to update Wallet items, including payment instruments, in the Wallet (see Listing 25.9). The RefreshDataEventArgs specifies the WalletItem objects that may require updating.

The WalletAgent for the Payment Instrument sample app iterates over the payment instruments and retrieves the transaction history for each instrument using the WCF service.

The method then retrieves the corresponding card from the server and updates either the Balance or DisplayAvailableCredit property, depending on the type of card. The agent uses the card’s CultureName property to format the currency value.

LISTING 25.9. UnleashedWalletAgent.OnRefreshData Method


protected override async void OnRefreshData(RefreshDataEventArgs args)
{
    /* Iterate through each wallet item that may require updating. */
    foreach (PaymentInstrument paymentInstrument
                in args.Items.OfType<PaymentInstrument>())
    {
        try
        {
            var bankService = (IBankService)new BankServiceClient();
            Guid cardId;

            if (!Guid.TryParse(paymentInstrument.Id, out cardId))
            {
                continue;
            }

            IEnumerable<AccountTransaction> transactions
                = await Task<IEnumerable<AccountTransaction>>.Factory.FromAsync(
                    bankService.BeginGetCardTransactions,
                    bankService.EndGetCardTransactions, cardId, null);

            if (transactions == null)
            {
                continue;
            }

            paymentInstrument.TransactionHistory.Clear();
            int count = 0;

            foreach (AccountTransaction accountTransaction in transactions)
            {
                WalletTransaction walletTransaction = new WalletTransaction
                    {
                        Description = accountTransaction.Description,
                        DisplayAmount = accountTransaction.DisplayAmount,
                        TransactionDate = accountTransaction.TransactionDate
                    };

                string transactionKey = cardId.ToString() + DateTime.Now + count++;
      paymentInstrument.TransactionHistory.Add(transactionKey, walletTransaction);
            }

            IEnumerable<Card> retrievedCards
                                 = await Task<IEnumerable<Card>>.Factory.FromAsync(
                bankService.BeginGetCards, bankService.EndGetCards, null);

            Card cardFromServer = retrievedCards.SingleOrDefault(
                retrievedCard => retrievedCard.Id == cardId);

            if (cardFromServer != null)
            {
                CultureInfo cultureInfo = new CultureInfo(cardFromServer.CultureName);

                if (paymentInstrument.PaymentInstrumentKinds
                                             == PaymentInstrumentKinds.Credit)
                {
                    var creditCard = (CreditCard)cardFromServer;
                    paymentInstrument.DisplayAvailableCredit
                        = creditCard.AvailableCredit.ToString("C", cultureInfo);
                }
                else if (paymentInstrument.PaymentInstrumentKinds
                                              == PaymentInstrumentKinds.Debit)
                {
                    var debitCard = (DebitCard)cardFromServer;
                    paymentInstrument.DisplayBalance
                                = debitCard.Balance.ToString("C", cultureInfo);
                }
            }

            await paymentInstrument.SaveAsync();
        }
        catch (Exception ex)
        {
            Debug.WriteLine("Unable to retrieve transaction history for card. + " ex);
        }
    }

    NotifyComplete();
}


For apps that provide banking-related capabilities, use payment instruments. For less payment-oriented scenarios, where you are handling things such as club memberships and loyalty cards, use the more general WalletTransactionItem. This is the topic of the next section.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.147.36.213