Create an application that features in-app purchases

The following task demonstrates how to create an application that displays an in-app purchase option on the BlackBerry App World storefront 3.1. When the user clicks Buy, the application initiates a purchase request using the provided SKU and name. When the user clicks Display Purchases, the application displays a record of past purchases.
  1. Import the required classes and interfaces.
    import net.rimlib.blackberry.api.paymentsdk.*;
    import net.rim.device.api.ui.*;
    import net.rim.device.api.ui.component.*;
    import net.rim.device.api.ui.container.*;
  2. Create the application framework by extending the UiApplication class. In main(), create an instance of the new class and invoke enterEventDispatcher() to enable the application to receive events. In the application constructor, invoke pushScreen() to display the custom screen for the application. In the following code sample, the PurchaseDemoScreen class, described in step 3, represents the custom screen.
    public class PurchaseDemo extends UiApplication
        public static void main(String[] args) 
            PurchaseDemo theApp = new PurchaseDemo();
        public PurchaseDemo() 
            pushScreen(new PurchaseDemoScreen());
  3. Create the framework for the custom screen by extending the MainScreen class and implementing FieldChangeListener.
    private static class PurchaseDemoScreen extends MainScreen implements FieldChangeListener
        public PurchaseDemoScreen()
  4. In PurchaseDemoScreen, declare the application's instance variables and create an instance of the PaymentEngine class by invoking getInstance().
    private ButtonField buyButton;
    private ButtonField displayButton;
    private BasicEditField digitalGoodName;
    private BasicEditField digitalGoodSku;
    private PaymentEngine engine = PaymentEngine.getInstance();
  5. In the screen constructor, create an if statement to check whether the PaymentEngine object is created successfully (meaning that in-app purchases are available). Within the else statement, create an error message to indicate that in-app purchases are unavailable.
    if (engine != null)
        errorMessage = new RichTextField("Sorry, in-app purchases are unavailable");
  6. Within the if statement, create the UI for the application. The UI features two BasicEditField objects that allow the user to type a SKU and a name for digital goods, and two ButtonField objects that either initiate a purchase or display a record of past purchases. Set change listeners on the buttons.
    digitalGoodName = new BasicEditField("Digital Good Name:  ", "Sample Good");
    digitalGoodSku = new BasicEditField("Digital Good SKU:   ", "abc123");
    HorizontalFieldManager hfm = new HorizontalFieldManager();
    buyButton = new ButtonField("Buy");
    displayButton = new ButtonField("Display Purchases");
  7. In PurchaseDemoScreen, override fieldChanged() to customize the behavior that is invoked when a user clicks a button.
    public void fieldChanged(Field field, int context)
  8. Within fieldChanged() create an if statement that checks which button is clicked.
    if (field == buyButton)
    else if (field == displayButton)
  9. Within the if statement, which is executed if the user clicks Buy, invoke getText() on the BasicEditField objects to obtain the current SKU and name. Create a PurchaseArguments object by using the PurchaseArgumentsBuilder class and invoke the appropriate methods to pass the SKU and the name as arguments.
    String name = digitalGoodName.getText();
    String sku = digitalGoodSku.getText();
    PurchaseArgumentsBuilder arguments = new PurchaseArgumentsBuilder()
        .withDigitalGoodSku( sku )
        .withDigitalGoodName( name )
        .withMetadata( name )
        .withPurchasingAppName( "Payment Service SDK Demo" );
  10. In a try/catch block, invoke purchase() and pass the PurchaseArguments object as a parameter. Catch the appropriate exceptions.
        PurchaseResult purchase = engine.purchase(;
        Dialog.inform("Purchase of " + purchase.getMetadata() 
            + " is successful.");
    catch (IllegalArgumentException e) 
    catch (PaymentException e) 
  11. Within the else if statement, which is executed if the user clicks Display Purchases, invoke PurchaseHistoryListingListener with an anonymous class to execute the method's callback. Verify that the Purchase objects are not empty by invoking getExistingPurchases(). Create an if statement that deletes any records of past purchases that are already displayed on the screen. Create a for loop that prints the SKU and the name of the digital goods from the updated record of past purchases. Invoking PurchaseHistory.get() returns an array of purchase history objects through the success method of the PurchaseHistoryListeningListner. Pass the listener to PurchaseHistory.get().

    purchaseHistoryListener = new PurchaseHistoryListingListener() {
      public void error( String message, int errorCode ) {
        Dialog.inform( message );
      public void success( Purchase[] purchases ) {
        if( purchases.length != 0 ) {
          if( getFieldCount() > 3 ) {
            deleteRange( 3, ( getFieldCount() - 3 ) );
          for( int i = 0; i < purchases.length; i++ ) {
            RichTextField purchaseRecord = new RichTextField( "Name: " + 
              purchases[ i ].getMetadata() +
              " SKU: " + purchases[ i ].getDigitalGoodSku() );
            add( purchaseRecord );
        } else {
          Dialog.inform( "No existing purchases" );
Previous topic: Handling exceptions

Was this information helpful? Send us your comments.