Selling digital goods

How to

Process purchases of digital goods that you offer in your application.

Solution

bps_initialize();

paymentservice_request_events(0);           // 0 indicates that all
                                            // events requested

paymentservice_set_connection_mode(true);   // Allows local testing

const char* digital_good_id = "Digital-Good-1-ID";
const char* digital_good_name = "Sample Digital Good 1";
const char* digital_good_sku = "SAMPLE_DIGITAL_GOOD_SKU_1";
const char* metadata = "Sample purchase metadata";
const char* purchase_app_icon =
    "http://www.rim.com/products/appworld_3col.jpg";
const char* purchase_app_name = "Payment Service Sample App";

unsigned request_id = 0;

if (paymentservice_purchase_request(digital_good_id, digital_good_sku,
    digital_good_name, metadata, purchase_app_name, purchase_app_icon,
    get_window_group_id(), &request_id) != BPS_SUCCESS) {
        fprintf(stderr, "Error: purchase request failed.\n");
    }

bps_event_t *event = NULL;
bps_get_event(&event, -1);        // -1 means that the function blocks
                                  // until an event is received

if (event) {
    if (bps_event_get_domain(event) == paymentservice_get_domain()) {
        if (SUCCESS_RESPONSE == 
            paymentservice_event_get_response_code(event)) {
                if (PURCHASE_RESPONSE == bps_event_get_code(event)) {
                    // Handle a successful purchase here
                    char* digital_good =
                       paymentservice_event_get_digital_good_id(
                           event, 0);
                    char* digital_sku =
                       paymentservice_event_get_digital_good_sku(
                           event, 0);
                    // ...

                } else {
                    // Handle a successful query for past purchases here
                    int numPurchases =
                        paymentservice_event_get_number_purchases(event);
                    // ...
                }
        } else {
            int error_id = paymentservice_event_get_error_id(event);
            const char* error_text =
                paymentservice_event_get_error_text(event);
            
            fprintf(stderr, "Payment System error: ID: %d  Text: %s\n",
                error_id, error_text ? error_text : "N/A"); 
        }
    }
}

Build requirements

You must include the following header files from the BlackBerry Platform Services (BPS) library:

#include <bps/bps.h>
#include <bps/paymentservice.h>

This solution also requires that you register any digital goods that you want to make available in your application in the vendor portal for the BlackBerry World storefront. For more information about registering digital goods, read the BlackBerry World Vendor Portal Administration Guide.

Discussion

You can create applications that offer digital goods for your users to download. You might offer additional levels for a game, or premium content for other types of applications. You can use the Payment Service to make digital goods available for purchase in your applications.

First, you must initialize the BlackBerry Platform Services library by calling bps_initialize(). This initialization lets you call other functions in the library, including Payment Service functions. You can then call paymentservice_request_events() to start receiving Payment Service events.

As an optional step, you can call paymentservice_set_connection_mode(). This method sets the type of connection mode to the Payment Service that your application uses, either local mode or network mode. Passing an argument of true sets the connection mode to local, meaning that when your application sends a purchase request, the request isn't delivered to the Payment Service servers and your application won't receive an actual purchase response. Instead, your application receives a simulated purchase response and purchase result.

Local connection mode is useful when you're testing your application, because you won't be charged for digital goods in this mode. The default connection mode is network, meaning that purchase requests are sent to the Payment Service servers and your application will receive actual purchase responses and results. You should remove any calls to paymentservice_set_connection_mode() when your application is ready for public distribution, so that purchase requests are processed properly.

Next, you can specify the parameters for the digital goods that a user is purchasing. These parameters should match those that you registered with the vendor portal for BlackBerry World. After you've specified these parameters, you can call paymentservice_purchase_request() to initiate the purchase of the digital goods. Your application can now wait for a Payment Service event by calling bps_get_event(). After an event is received, you should determine whether it's a Payment Service event by calling bps_event_get_domain() and paymentservice_get_domain().

There are two types of events that the Payment Service generates. An event code of PURCHASE_RESPONSE indicates that the event was generated in response to a purchase request. An event code of GET_EXISTING_PURCHASES_RESPONSE indicates that the event was generated in response to a request for the past purchases that the user made in the application (a call to paymentservice_get_existing_purchases_request()). You can determine the event code by calling bps_get_event_code(). Each Payment Service event also includes a response code. A response code of SUCCESS_RESPONSE indicates that the request that generated the event was successful, and a response code of FAILURE_RESPONSE indicates that the request was unsuccessful. You can determine the response code by calling paymentservice_event_get_response_code().

When you know the type of Payment Service event that was received and the response code of the event, you can respond to the event any way you want. For example, if the event indicates that a purchase request was successful, you might want to retrieve purchase information, such as the ID or SKU of the digital goods (by calling paymentservice_event_get_digital_good_id() and paymentservice_event_get_digital_good_sku() respectively), and act on that information accordingly. If the event indicates that a request for past purchases was successful, you might want to retrieve the number of past purchases that the user made (by calling paymentservice_event_get_number_purchases()). You can also respond to events that indicate that a request was unsuccessful and use paymentservice_event_get_error_id() and paymentservice_event_get_error_text() to get information about the error.

Nice to know

When you call paymentservice_purchase_request() to initiate the purchase of digital goods, you don't need to specify both the ID and the SKU of the digital goods to be purchased; you can specify only one or the other. If you provide both the ID and the SKU, then the ID takes precedence, and the SKU is used only if the digital goods could not be located on the Payment Service server using the ID.