In this tutorial, you will learn how to support third-party plugins for In-App Purchases (IAP). This allows you to sell access to content coming from third-party plugins, through IAP from the Apple App Store and Google Play Store.
The BuddyBoss App already supports purchasing LearnDash courses and memberships from many popular membership plugins, but if there’s a specific plugin that you need to support with in-app purchases, you can add support for it by using custom code.
In your own plugin:
1. Create one class file and extend ‘BuddyBossApp\InAppPurchases\IntegrationAbstract’.
use BuddyBossApp\InAppPurchases\IntegrationAbstract;
class <ClassName> extends IntegrationAbstract {
// Class code
}
2. Register your third party plugin for In-App Purchases.
Integration_slug : Integration slug.
integration_type : Integration type to identify integration items.
integration_label : Integration label
Item_label : Integration item label
Enabled : Integration should be enabled or disabled.
Class : In-app purchase integration class name
/** * Setup IAP integration */ public function register() { $this->integration_slug = '<iap_slug>'; $this->integration_type = '<iap_type>'; $this->integration_label = '<iap_label>'; $this->item_label = '<iap_item_label>'; // Register 3rd party plugin for iap bbapp_iap()->integrations[ $this->integration_slug ] = array( 'type' => $this->integration_type, 'label' => $this->integration_label, 'enabled' => true, 'class' => self::class, ); parent::set_up( $this->integration_type, $this->integration_label ); // Register Instance bbapp_iap()->integration[ $this->integration_type ] = $this::instance(); }
3. Implement an abstract method in the newly created class. The next steps will provide you with detailed information for each abstract method.
Abstract Methods
4. Iap_linking_options
Iap_linking_options : Use the method helps to show integration items in the BuddyBoss App Plugin Product via Ajax.
Results : Items list for this Integration.
Public function iap_linking_options( $results ) {
// TODO: Implement iap_linking_options() method.
/* Data should be return in following format
return array(
array(
'id' => '<item_id>',
'text' => '<item_label>',
),
...
);*/
}
5. Iap_integration_ids
Iap_integration_ids : This method converts items IDs into labels.
Results : Items listed for this Integration.
integration_ids : Item IDs.
Public function iap_integration_ids( $results, $integration_ids ) { // TODO: Implement iap_integration_ids() method. /* Data should be return in following format return array( array( 'id' => '<item_id>', 'text' => '<item_label>', ), ... );*/ }
6. item_id_permalink
item_id_permalink : This method updates the link url of items page.
Public function item_id_permalink( $link, $item_id ) {
// TODO: Implement item_id_permalink() method.
}
7. is_purchase_available
is_purchase_available : This method allows you to check whether an item is available to purchase or not for a particular post.
Is_available : Flag for if an item is available or not for purchase
forItemId : Post ID or item ID. (This value mostly passes by endpoint to find out available items for a particular post)
Integration_item_id : Integration item ID.
Public function is_purchase_available( $is_available, $forItemId, $integration_item_id ) {
// TODO: Implement is_purchase_available() method.
}
8. has_access
has_access : This method checks if a current user has access to a given item.
item_ids : item IDs
Order : Order object
Public function has_access( $item_ids, $order ) {
// TODO: Implement has_access() method.
}
9. on_order_completed
on_order_completed : This method executes when an order is completed so you can give item access to the user.
item_ids : items IDs
Order : Order object
Public function on_order_completed( $item_ids, $order ) {
// TODO: Implement on_order_completed() method.
}
10. on_order_activate
on_order_activate : This method executes when an order is activated so you can give item access to the user.
item_ids : items IDs
Order : Order object
Public function on_order_activate( $item_ids, $order ) {
// TODO: Implement on_order_activate() method.
}
11. on_order_cancelled
on_order_cancelled : This method executes when an order is cancelled so you can remove item access from the user.
item_ids : items IDs
Order : Order object
Public function on_order_cancelled( $item_ids, $order ) {
// TODO: Implement on_order_cancelled() method.
}
12. on_order_expired
on_order_expired : This method executes when an order is expired so you can remove item access from the user.
item_ids : items ids
Order : Order object
Public function on_order_expired( $item_ids, $order ) {
// TODO: Implement on_order_expired() method.
}
Example Plugin
You can assemble the two PHP template files below into a folder, to create a plugin that will allow users to purchase access for LearnDash Groups, which can be seen when editing a product’s “Integration Type” at BuddyBoss App > In-App Purchases > Products.
Our built-in IAP system already allows you to select LearnDash LMS (groups) from within the Membership option in the dropdown, so you would not actually need this new integration. It is just an example of testing. You would want to modify this example to enroll users into some other membership system or enrollment type.
Note: For this example to actually display in your app or website, we are assuming you are using LearnDash and have created some LearnDash Groups already.
buddyboss-app-custom.php
This is the loader file. Create a plugin folder and add this file into it.
<?php /* Plugin Name: BuddyBoss App Custom In-App Purchases Plugin URI: {add your own} Description: {add your own} Version: 1.0.0 Author: {add your own} Author URI: {add your own} */ if ( ! defined( 'ABSPATH' ) ) { exit(); } /** * Load Custom work */ function bbapp_custom_work_init() { if ( class_exists( 'bbapp' ) ) { include 'buddyboss-app-custom-iap.php'; BuddyBossApp\Custom\IAP::instance(); } } add_action( 'plugins_loaded', 'bbapp_custom_work_init' );
buddyboss-app-custom-iap.php
This file also goes into your plugin folder. This file contains the functional code to register the new In-App Purchase integration type.
<?php namespace BuddyBossApp\Custom; if ( ! defined( 'ABSPATH' ) ) { exit(); } use BuddyBossApp\InAppPurchases\IntegrationAbstract; use BuddyBossApp\InAppPurchases\Orders; // Learndash Group Integration for BuddyBossApp InAppPurchases. final class IAP extends IntegrationAbstract { private static $instance = null; /** * LearnDashGroupIntegration constructor. */ private function __construct() { // ... leave empty, see Singleton below } /** * Get the instance of this class. * @return IAP|null */ public static function instance() { if ( null === self::$instance ) { $className = __CLASS__; self::$instance = new $className; self::$instance->register(); } return self::$instance; } /** * Setup IAP integration */ public function register() { $this->integration_slug = 'ld-groups'; $this->integration_type = 'ld-groups'; $this->integration_label = __( 'LearnDash Group', 'buddyboss-app' ); $this->item_label = __( 'LearnDash Group', 'buddyboss-app' );; // Register 3rd party plugin for iap bbapp_iap()->integrations[ $this->integration_slug ] = array( 'type' => $this->integration_type, 'label' => $this->integration_label, 'enabled' => true, 'class' => self::class, ); parent::set_up( $this->integration_type, $this->integration_label ); // Register Instance bbapp_iap()->integration[ $this->integration_type ] = $this::instance(); } /** * Below function get triggers when(hook) order is completed. * * @param $item_ids * @param $order * * @return mixed */ public function on_order_completed( $item_ids, $order ) { foreach ( $item_ids as $item_identifier ) { $split = explode( ':', $item_identifier ); $group_id = $split[0]; $readable_item_ids[] = "<a href=\"post.php?post=$group_id&action=edit\" target='_blank'>$group_id</a>"; // grant the group access ld_update_group_access( $order->user_id, $group_id, false ); // update user group count. $this->user_update_count( $group_id, $order->user_id, "plus" ); } $readable_item_ids = implode( ', ', $readable_item_ids ); Orders::instance()->add_history( $order->id, 'info', sprintf( __( "User enrolled in Group(s), ID(s) are : %s", 'buddyboss-app' ), $readable_item_ids ) ); Orders::instance()->update_meta( $order->id, "_learndash_group_ids", serialize( $item_ids ) ); } /** * Below function get triggers when(hook) order is activated. * * @param $item_ids * @param $order * * @return mixed */ public function on_order_activate( $item_ids, $order ) { // NOTE : Similar to onOrderCompleted($order) until something needs to be changed? return $this->on_order_completed( $item_ids, $order ); } /** * Below function get triggers when(hook) order is expired. * * @param $item_ids * @param $order * * @return mixed */ public function on_order_expired( $item_ids, $order ) { // NOTE : Similar to onOrderCancelled($order) until something needs to be changed? $this->on_order_cancelled( $item_ids, $order ); } /** * Below function get triggers when(hook) order is cancelled. * * @param $item_ids * @param $order * * @return mixed */ public function on_order_cancelled( $item_ids, $order ) { //$item_ids = unserialize( Orders::instance()->get_meta( $order->id, "_learndash_course_ids" ) ); foreach ( $item_ids as $item_identifier ) { $split = explode( ':', $item_identifier ); $group_id = $split[0]; $readable_item_ids[] = "<a href=\"post.php?post=$group_id&action=edit\" target='_blank'>$group_id</a>"; // revoke the group access ld_update_group_access( $order->user_id, $group_id, true ); // update user group count. $this->user_update_count( $group_id, $order->user_id, "minus" ); } $readable_item_ids = implode( ', ', $readable_item_ids ); Orders::instance()->add_history( $order->id, 'info', sprintf( __( "User un-enrolled in group(s), ID(s) are : %s ", 'buddyboss-app' ), $readable_item_ids ) ); } /** * Helper function to update users group counts. * * @param $group_id * @param $user_id * @param string $action */ public function user_update_count( $group_id, $user_id, $action = "plus" ) { $groups = get_user_meta( $user_id, '_learndash_inapp_purchase_enrolled_group_access_counter', true ); if ( ! empty( $groups ) ) { $groups = maybe_unserialize( $groups ); } else { $groups = array(); } if ( isset( $groups[ $group_id ] ) ) { if ( $action == "plus" ) { $groups[ $group_id ] += 1; } else { $groups[ $group_id ] -= 1; } } else { $groups[ $group_id ] = ( $action == "plus" ) ? 1 : 0; } update_user_meta( $user_id, '_learndash_inapp_purchase_enrolled_group_access_counter', $groups ); } function iap_linking_options( $results ) { return \BuddyBossApp\Admin\InAppPurchases\Helpers::getIntegrationItems( 'groups' ); } function iap_integration_ids( $results, $integration_ids ) { foreach ( $integration_ids as $key => $integration_id ) { $results[ $key ]['id'] = $integration_id; $results[ $key ]['text'] = get_the_title( $integration_id ); } return $results; } function item_id_permalink( $link, $item_id ) { return "post.php?post=$item_id&action=edit"; } function is_purchase_available( $is_available, $item_id, $integration_item_id ) { return learndash_group_has_course( $integration_item_id, $item_id ); } /** * Check given integration item has access. * * @param $item_ids * @param $order * * @return false */ function has_access( $item_ids, $order ) { $has_access = false; foreach ( $item_ids as $item_identifier ) { $split = explode( ':', $item_identifier ); $group_id = $split[0]; if ( learndash_is_user_in_group( $order->user_id, $group_id ) ) { $has_access = true; break; } } return $has_access; } }