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.
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 of this sample application consists of a TabbedPane with three pages:
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.
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.
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.
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.