Qt-based BB10 API Examples Documentation

Contents

Payment Service Example

Files:

The Payment service example demonstrates how to use the cascades payment service to include features such as "Buy" button as well as displaying history of purchases and the display of subscription terms, allowing you monetize your application content.

Overview

In this example we'll learn how to use the PaymentService class to provide an end-to-end payment solution for monetizing application content. Through the use of of a custom element named PaymentServiceControl you can purchase digital goods, retrieve their prizes and even query your purchase history for starters.

The PaymentServiceControl outlines the behaviours for all the success events in response to the appropriate requests, from price queries to subscription queries, or subscription cancellations. This API can be used from purchasing additional levels in a gaming application to music from a radio application or any other digital good registered on the Vendor Portal for BalckBerry App world.

The UI

The UI of this sample application consists of a TabbedPane with three pages:

Buy

    Button {
        text: qsTr ("BUY")
        // Perform the purchase transaction on click
        onClicked: {
            // Reset some old values
            receipt.text = ""
            message.visible = false
            paymentControl.purchase (paymentControl.id, paymentControl.sku, paymentControl.name, paymentControl.metadata)
        }
    }

    // A standard Button
    Button {
        text: qsTr ("SUB TERMS")

        // Display the subscription terms on click
        onClicked: {
            paymentControl.getSubscriptionTerms (paymentControl.id, paymentControl.sku)
        }
    }

These are "Buy" and "SUB Terms" control buttons. The "Buy" button allows you to purchase the selected digital good by invoking the purchase function from the payment service upon button press. The "SUB Terms" button queries the subscription terms for the selected good.

    // A standard ListView
    ListView {
        // The data model to use for propagating the list
        dataModel: XmlDataModel {
            source: "models/goods.xml"
        }
        // The component to use for data items
        listItemComponents: [
            ListItemComponent {
                type: "digitalgood"
                DigitalGood {
                }
            }
        ]

        onTriggered: {
            clearSelection()
            select(indexPath)
        }

        // Retrieve and save the selected items data
        onSelectionChanged: {
            // Reset some old values
            resetSubscriptionText()
            if(selected) {
                receipt.text = ""
                message.visible = false
                var chosenItem = dataModel.data (indexPath)
                paymentControl.id = chosenItem.id
                paymentControl.sku = chosenItem.sku
                paymentControl.name = chosenItem.name
                paymentControl.metadata = chosenItem.metadata
                paymentControl.getPrice (paymentControl.id, paymentControl.sku)
            }
        }
    }

In the main view, one of the more important visual elements is the ListView, which contains the list of digital goods available for purchasing. This list is loaded using the XmlDataModel that loads the items from an XML file, where each element(except the mandatory root element) can be shown shown as an item. Upon list item selection events it invokes the payment services' price query, which animates and displays the price Label.

    Label {
        id: subscription

        horizontalAlignment: HorizontalAlignment.Right
        verticalAlignment: VerticalAlignment.Center

        text: qsTr ("CHECK subscription")
        textStyle {
            base: SystemDefaults.TextStyles.BodyText
            color: Color.White
        }

        // Check the item subscription and display on touch
        onTouch: {
            if ( event.isDown() )
                paymentControl.checkSubscriptionStatus (paymentControl.id, paymentControl.sku)
        }
    }

This label provides application functionality to query the digital goods subscription. Upon a touch event, it invokes the payment services subscription status query, and displays the queries result.

    // The custom payment element for holding item data
    // and used for method invocation and receiving events as a
    // result of those invocations
    PaymentServiceControl {
        id: paymentControl
        property string id
        property string sku
        property string name
        property string metadata
        onPriceResponseSuccess: {
            // Play price request animation on response
            priceLabel.text = price;
            priceAnim.play ()
        }

        // Play receipt animation on purchase response
        onPurchaseResponseSuccess: {
            i = 0
            receiptArea = receiptString
            timer1.start (50);
        }
        onExistingPurchasesResponseSuccess: {
            purchases.text = receiptsString
        }
        onSubscriptionTermsResponseSuccess: {
            message.text = qsTr ("Price: %1\nInitialPeriod: %2\nRenewalPrice: %3\nRenewalPeriod: %4").arg(price).arg(initialPeriod).arg(renewalPrice).arg(renewalPeriod)
            message.visible = true
        }
        onCancelSubscriptionResponseSuccess: {
            cancellations.text = (cancelled ? qsTr ("Canceled? yes") : qsTr ("Canceled? no"))
        }
        onCheckStatusResponseSuccess: {
            subscription.textStyle.color = Color.Green
            subscription.text = (status ? qsTr ("Active? yes") : qsTr("Active? no"))
        }
        onInfoResponseError: {
        }
    }

This "PaymentServiceControl" is the custom element that exposes the payment service control functionality to the QML context, allowing you to call purchase or simple price query functions. This component outlines the behaviour upon receiving a successful event for the payment service requests, such as price, subscription term queries, or purchasing of items.

Purchases

    Button {
        horizontalAlignment: HorizontalAlignment.Center

        text: qsTr ("Purchases")

        // Retrieve purchases made data on click
        onClicked: paymentControl.getExisting (false);
    }

This page demonstrates how to query the payment service for purchases made and display them in a TextArea.

Cancellation

    Button {
        horizontalAlignment: HorizontalAlignment.Center
        topMargin: 50

        text: qsTr ("Cancel")

        // Cancel entered purchase on click
        onClicked: {
            paymentControl.cancelSubscription (purchaseId.text)
        }
    }

This page demonstrates how to cancel subscriptions.

PaymentServiceControl

The PaymentServiceControl has id, sku, name and metadata properties of type string, which are used to store the specific information about the selected digital good. The onPriceResponseSuccess, onPurchaseResponseSuccess, onExistingPurchasesResponseSuccess, onSubscriptionTermsResponseSuccess, onCancelSubscriptionResponseSuccess, onCheckStatusResponseSuccess, and onInfoResponseError signals are used to outline the actions taken upon receiving a successful response for each of these payment service requests.

    class PaymentServiceControl : public QObject
    {
        Q_OBJECT
    public:
        PaymentServiceControl(QObject *parent = 0);
        virtual ~PaymentServiceControl();

        //invokable purchase method from the qml control
        Q_INVOKABLE void purchase(const QString &id, const QString &sku, const QString &name, const QString &metadata);

        //invokable purchases query from the qml control
        Q_INVOKABLE void getExisting(bool refresh);

        //invokable price query from the qml control
        Q_INVOKABLE void getPrice(const QString &id, const QString &sku);

        //invokable subscription terms query from the qml control
        Q_INVOKABLE void getSubscriptionTerms(const QString &id, const QString &sku);

        //invokable subscription status query from the qml control
        Q_INVOKABLE void checkSubscriptionStatus(const QString &id, const QString &sku);

        //invokable subscription cancellation from the qml control
        Q_INVOKABLE void cancelSubscription(const QString &purchaseId);

    public Q_SLOTS:
        //This method is called whenever a purchase is invoked
        void purchaseResponse();

        //This method is called whenever a purchases query is invoked
        void existingPurchasesResponse();

        //This method is called whenever a price request is made
        void priceResponse();

        //This method is called whenever subscription terms are queried
        void subscriptionTermsResponse();

        //This method is called whenever subscription status checks are performed
        void subscriptionStatusResponse();

        //This method is called whenever subscription cancellations are made
        void cancelSubscriptionResponse();

    Q_SIGNALS:
        //This signal is emited upon successful purchase
        void purchaseResponseSuccess(const QString &receiptString);

        //This signal is emitted upon purchases query success
        void existingPurchasesResponseSuccess(const QString &receiptsString);

        //This signal is emitted upon successful price query
        void priceResponseSuccess(const QString &price);

        //This signal is emitted upon making successful subscription terms query
        void subscriptionTermsResponseSuccess(const QString &price, const QString &initialPeriod, const QString &renewalPrice, const QString &renewalPeriod);

        //This signal is emitted upon successful subscription status checks.
        void checkStatusResponseSuccess(bool status);

        //This signal is emitted upon successful subscription cancellations.
        void cancelSubscriptionResponseSuccess(bool cancelled);

        //This signal is emitted whenever any of the payment service requests generated an error
        void infoResponseError(int errorCode, const QString &errorText);

    private:
        bb::platform::PaymentManager *m_paymentManager;
    };

The PaymentServiceControl inherits from bb::cascades::CustomControl, so it can be placed inside a Container.