The buyCRED Payment Gateway API

Home / Tutorials / The buyCRED Payment Gateway API

Description

In this tutorial I will introduce you to the gateway API used by the buyCRED add-on.

By default myCRED offers 4 different payment gateways for you to use but you can expand this and add any number of other gateways.

Requirements

  • Basic PHP knowledge.
  • Experience with building WordPress plugins.

Before we get started

This tutorial is meant for users who have some experience with building WordPress plugins and have a basic understanding of PHP!

While I am happy to troubleshoot any gateway related issues or answer questions, I will not be offering any support on troubleshooting the payment service you are attempting to implement! Please remember that myCRED is a one man operation and I just can’t support every single payment gateway out there.

Gateway Types

myCRED was built for two main types of payment processors:

  • Local
    Local gateways collects the necessary payment information from the user on your website and sends this information after validation to a payment processor. The user never leaves your website. I.e. Zombaio and NETbilling.
  • Remote
    Remove gateways will redirect a user to a remote website where the user enters their payment details, gets processed and returned to your website once completed or cancelled. I.e. PayPal and Skrill (Moneybookers).

The Process

When a user requests to buy points though the mycred_buy or mycred_buy_form shortcodes, they are re-directed to the processing page with their request. Example requests:

// Request though the mycred_buy shortcode
$_GET = array(
	'mycred_buy' => 'gateway-id',
	'amount'     => 10,
	'token'      => 'securitytoken'
)
// Request though the mycred_buy_form shortcode
$_POST = array(
	'mycred_buy' => 'gateway-id',
	'amount'     => 10,
	'token'      => 'securitytoken',
	'post_id'    => 1,
	'gift_to'    => 1
)

As you can see the mycred_buy shortcode sends the request though $_GET while the mycred_buy_form sends it though $_POST.

Notes on the above request examples:

  1. The post_id variable is only sent if you have setup the mycred_buy_form shortcode to allow users to purchase points for the content author. If this is not setup or used, the post_id variable will not be included.
  2. The gift_to variable is only used if the purchase is made for another member (a.k.a. Gifting). If you do not use this feature this variable will not be included.
  3. The user id of the buyer is not included in the request! You would need to use get_current_user_id to get the buyers ID.

Registering your Gateway

Before constructing the gateway, the first thing you would need to do is to register your custom gateway with myCRED. This is done though the mycred_setup_gateways filter.

add_filter( 'mycred_setup_gateways', 'register_custom_gateway' );
function register_custom_gateway( $gateways )
{
	// Using a gateway class
	$gateways['unique-gateway-id'] = array(
		'title'    => __( 'Gateway Title' ),
		'callback' => array( 'gateway_class_name' )
	);
	// or Using a gateway function
	$gateways['unique-gateway-id'] = array(
		'title'    => __( 'Gateway Title' ),
		'callback' => 'gateway_function_name'
	);
	return $gateways;
}

Note that you can either use a class for your gateway in which case the ‘callback’ value must be inside an array or you can use a function in which case you should just set it to the function name.

The myCRED_Payment_Gateway Class

The myCRED_Payment_Gateway class is an abstract class used by all built-in gateways. It contains commonly used functions along with help functions for drop-down menus. You don’t need to use it, if you prefer to write everything yourself, that’s perfectly fine. In this tutorial however I will be going through how to use the class method.

There are three class methods that your custom gateway must include:

  1. process() This method is called either when a local request is made (i.e. your local form is submitted) or if this is a remote gateway, when the IPN call is returned. Note! For this to work, the IPN call from the payment processor must contain the mycred_call variable!
  2. buy() This method is called when the user submits a purchase request though the two shortcodes and either re-directs the user to a remote gateway or presents the purchase form.
  3. returning() This method is used when the user is returning from a remote payment processor. You can use this method to either process the result as the user returns (if thats how the payment system works) or use it to redirect users to the appropriate landing page (i.e. Cancelled or Thank You page).

The Payment Processing Page

Either when you need to collect your buyers payment details (for local gateways) or when you redirect the buyer to a payment processor (for remote gateways), the buyCRED add-on generates a “Processing” page.

This processing page is constructed by using the purchase_header() and purchase_footer() class methods. If you are building a remote gateway, you can also use form_with_redirect() while if you are building a local gateway, you would need to output your form or any details needed yourself between the purchase_header and purchase footer functions.

Example 1: Constructing a payment page for a local gateway:

class My_Custom_Gateway extends myCRED_Payment_Gateway {
	function __construct( $gateway_prefs ) {
		parent::__construct( $args, $gateway_prefs );
	}
	function buy() {
		$this->purchase_header( 'Header / Title' );
		echo 'these things needs to be included on this page';
		$this->purchase_footer();
	}
}

Example 2: Constructing a payment page for a remote gateway:

class My_Custom_Gateway extends myCRED_Payment_Gateway {
	function __construct( $gateway_prefs ) {
		parent::__construct( $args, $gateway_prefs );
	}
	function buy() {
		$this->purchase_header( 'Header / Title' );
		$arguments = array();
		$this->form_with_redirect( $arguments );
		$this->purchase_footer();
	}
}

You can find more information on these functions in the documentation for the myCRED_Payment_Gateway class. I also recommend you look at how existing gateways do this!

IPN handling for remote gateways

When working with remote gateways, we are required to intercept calls from the gateway confirming the users payment. Most payment processors offer a “Instant Payment Notifications” service where they will call your website on a specific URL informing you how things went.

When a IPN call is made and contains the mycred_call variable, the gateway API will load the corresponding gateway to handle this callback. buyCRED in-itself does not do anything about these calls besides intercepting them, it is up to your gateway class to handle this.

To achieve this, buyCRED will load the process() method in your class. This method should do whatever you need to do in order to verify the call and award points according to the purchase. I recommend you have a look how the PayPal gateway handles IPN calls in it’s process() function.

On the other hand if your building a local gateway, make sure you include the mycred_call variable in your form in order for the process() function to fire!

Other useful methods

The myCRED_Payment_Gateway class comes with several help functions for you to play with:

  • currencies_dropdown This function generates a dropdown menu with all supported currencies for your user to select from. You can use the mycred_dropdown_currencies filter to add more currencies that your gateway might support.
  • item_types_dropdown This function generates a dropdown of item types. Mainly used by PayPal but can be customized via the mycred_dropdown_item_types filter.
  • list_option_countries This function will generate the options to use in a select element with a list of countries and their two character codes as values.
  • list_option_us_states This function will generate the options to use in a select element with a list of US states and their two character codes as values.
  • list_option_months This function will generate the options to use in a select element which a list of months and their numeric values with a leading zero.
  • list_option_card_years This function will generate the options to use in a select element for selection of year (expiration year for credit cards). The first year returned is the current year and you can select how many years to return (defaults to 16).

Done

If you have any questions regarding how to use this API or if you think something could be improved / added, please comment below.

  1. I am working on adding support for the Stripe credit card gateway and the good news is that I have it charging transactions successfully using the mycred_buy short code. The issue that I’m having is stripe is a local gateway and so I have defined my html form fields in the buy method, but wp renders the form above my templates header. I have looked at the other local gateways and can’t seem to figure out what I’m doing wrong. I’m I missing something simple?

    Once I get the gateway working is there a place that you’d like to link to it?

    Thanks for your great plugin!

  2. Good afternoon Gabriel,

    Hope you are well.

    May I have your suggestion about how to add buyCred button(buy token button) on on Insufficient funds template, please?

    You do not have enough %plural% to buy access to this %post_type%. Price: %price% (plan to add buy token button here)

    Thanks very much,

    -Almod

  3. Hi Gabriel – we are just about done completing a gateway for i-payout, that allows users to pay with ipayout and then transfer their “funds” from mycred wallet into a i-payout wallet allowing them to load a debit card with their funds,… will keep u posted on this… we have one query…

    How do we allow in admin of gateways the admin to choose the “point type” as in we have multiple point types, and in this gateway we only allow one point type (not mycred_default) to be used in this gateway?

    What is ‘exchange’ => $default_exchange

    1. Hey Greg.

      If you have a look at the i.e. PayPal gateway that is built-into myCRED, you will see that when you construct the gateway class, I loop though all point types and by that setup the default exchange rates.

      This is done because in your buyCRED settings on the myCRED > Settings page, you get to select which point types that users can buy using buyCRED. This array of point types is then parsed against the default ones (to make sure there is always a default value for all point types).

      Once you have saved which point types you are allowed to sell, each gateway then offers you the option to set an exchange rate for all of these point types you have selected. if you only selected one, then you will only have one exchange rate but if you selected to sell 2 point types then you will have two exchange rates (one per type).

      This option to sell more then one point type is what your gateway must take into account as some would sell one, while others might want to sell more then one type.

      You should use the get_point_type() and get_cost() class methods in your gateway to get the correct cost and point type for your purchase. These functions take care of the job of parsing which point type a user has requested to buy (if any) and to get the appropriate exchange rate. If an exchange rate does not exist for the point type a user is requesting to buy, the gateway will default to 1=1. Note that these functions also take into account if the buyer has a special exchange rate set via their profile.

  4. I love buyCred so much. but one thing need advice, after an user bought myCred, I have to click “pay out” in the pending payment page. How to make it auto pay out??

    1. Hey Kim.

      Which gateway are you having issues with? Pending payments are only shown if they are still awaiting confirmation to be paid. So if a user buys point but never pays, their “purchase” comes up on this page. If a user does pay then the “purchase” will be moved to the trash.

      If you can confirm that a user has paid for an order but the order is still coming up on the Purchase page AND you can confirm that the user has not received their points (check his history) then the gateway you are using is not receiving confirmation from the payment processor.

    2. buyCRED supports live and sandbox payments. So when you buy points, it shows up on the Pending Payments page? Do you get any updates? Are PayPal IPNs reaching your website? Some maintenance mode plugins for example can redirect any callback which means buyCRED never receives a confirmation of payment.

    3. Hi Gabriel, sorry for a late reply.
      1. So when you buy points, it shows up on the Pending Payments page? “Selling Tools” enable “Instant Payment Notifications”. Make sure the “Notification URL” is set to the above address and that you have selected “Receive IPN messages (Enabled)” <— I have set it in my paypal live account (I don't find it in developer sandbox site)
      3. For the sandbox testing, the page says the purchase is completed still I can only find it on the Pending payment page.
      4. For your questions: Do you get any updates? Are PayPal IPNs reaching your website? How to get the updates and how to testing if the IPNs is reaching my website?

    4. The PayPal gateway will send the IPN address to PayPal with the purchase so it is actually no longer needed to setup in your account.

      In sandbox mode, you can use the sandbox tools PayPal offers to send test IPN calls. The way I test to see if a IPN call gets catched is by add in a temporary catching of the request inside the process() method. For example adding something like this as the first thing to run in the method:

      update_option( 'catch_paypal_ipn', $_REQUEST );
      

      I then add in on a page:

      echo get_option( 'catch_paypal_ipn', 'no catch' );
      

      Until we catch something, this will show “no catch” but once an IPN call has been received and the process() method runs this will be populated with everything sent. If a catch is made you know the IPN address is valid and the IPN call is correctly caught by buyCRED.

    5. Hi Gabriel, I have just got the Credits go straight to the users account after the payment is completed. However the amount of credit seems to be not correct, it charges the users for 500 but only 100 credits are bank in to the users account.

    6. I would make a new purchase request but as I am redirected to the payment gateway I would go back and check the Pending payment and see what amount is saved. If the amount is the correct amount that a user will receive the issue would then be in the process() method or if the amount is not correct already here, we know the issue is in the buy() method.

  5. Hello,

    I implemented a new gateway for MercadoPago but i don’t get how to we check if the payment was successfully made.
    This is what i get from the payment platform sandbox http://localhost:8080/…/?page_id=6&collection_id=1417572352&collection_status=approved&preference_id=87749040-2c669ccd-331a-47b6-b4a6-82e3193167d6&external_reference=SY040I&payment_type=credit_card

    Thank you.

    1. Hi. It looks like you are sending the buyCRED transaction ID under the external_reference variable. You can use the get_pending_payment() class method to convert that into a post ID representing the pending payment in buyCRED:

      $transaction_id = sanitize_text_field( $_GET['external_reference'] );
      $post_id = $this->get_pending_payment( $transaction_id );
      

      The get_pending_payment() method will either return the post ID or false if nothing was found. If you get a post ID then the post contains all the pending information which you should use to verify that the postback call you are processing is correct (e.g. make sure the user actually paid the amount owned and not some minimum amount).

      If you are using the callback URL then you do this in the process() method while if you are not using it you can use the returning() method to catch the callback and then run the process() method from that. The PayPal gateway is an example where the callback url is used and the netbilling gateway is an example where we use the returning() method to trigger process().

    2. Verification can be done in many ways and most gateways have their own way of doing things. buyCRED PayPal Payments Standard uses the IPN system in PayPal which tells PayPal where to send the notification. In the case of PayPal, this message is sent back to PayPal to which PayPal replies either “valid” or “invalid”. This verified the call being authentic.

      Next you need to make sure that the payment matches what we are expecting. Usually you match: currency, transaction id and cost amount.

  6. Hello MR.Merovingi .

    i wrote my custom payment gateway and its work very good . but i have a small problem :

    when the users purchased , in bellow link shows empty :
    wp-admin/admin.php?page=myCRED_page_gateways_log_mycred_default
    but in “wp-admin/admin.php?page=myCRED” all thins is okey …

    also … when i do “pay out” pending payment , the logs in “wp-admin/admin.php?page=myCRED_page_gateways_log_mycred_default” show empty too …

    please help me …

    1. Have you enabled WP_DEBUG to see if you get any errors? The information that is supposed to be shown there are information you save when the gateway awards points. If you have a look at the for example PayPal payment gateway process() you will see that the sales information is saved along with the log entry.

    2. If you could show in a pastebin or similar your process() class method and what you are doing when awarding points I could look over it and see if there are any issues. Hard to give concrete solution when not knowing what you are doing 🙂

    3. Just a small tip. When adding a gateway, you can always use the mycred_buycred_load_gateways action hook which will only fire if buyCRED is enabled. When it fires you can be assured that the myCRED_Payment_Gateway class is available. Because if you disable the buyCRED gateway with your code, you will have a fatal error as the abstract class will no longer be available but myCRED will still be active.

      add_action( 'mycred_buycred_load_gateways', 'load_my_custom_gateway' );
      function load_my_custom_gateway() {
      
      	// your gateway class
      
      }
      
    4. thanks … i understood what you say … but i used below code rather than this hook to fire my gateway :

      if ( is_plugin_active(‘mycred/mycred.php’) && defined( ‘myCRED_VERSION’ ) && class_exists( ‘myCRED_Payment_Gateway’ ) ) {

      //my gateway codes

      }

  7. Hello !

    First of all, I’m really sorry for my english but I’m french and I don’t speak English very well.

    I would apply that in my model but it does not work :

    In the div is a picture that appears but I can not click.
    So I can’t open the Papal payment page.

    Thanks

  8. Hi,

    Compliments on the plugin! A little thing i do miss, is an easy way to change the way the [mycred_buy_form] is displayed. What I am trying to do is show something like this:

    “I have %plural” (this is easy with [mycred_my_balance] but I want the amount to show inline!)

    “Buy 10 %plural% / 25 %plural% / 50 %plural%” (I already have this dropdown using amount in the shortcode , just not the suffix)

    “You will be billed ” (Not a clue how to add this inside the shortcode)

    “buy now” button (this I have 🙂 )

    ————-

    That should be it, any thoughts?
    Thanks in advance!

  9. Hi Gabriel, your plugin is excellent. I have a problem with payment gateway, I use “skrill” and I filled all the fields in its configuration. But when I test it, there is an error message saying “Transaction not allowed
    Wrong merchant email address! ”
    The other problem is that I used “PayFast” in “Sandbox” mode and when paying it says “The supplied variables are not according to specification:

    Cancel_url: cancel_url must be a valid URL ”
    Can you help me please?
    Thank you

Leave a Reply

Last edited October 31, 2018

11