Formidable PayPal

Knowledge BaseExtend Formidable FormsAdd Ons → Formidable PayPal

This plugin allows you to collect PayPal payments using Formidable Forms. You can send users and a total directly to PayPal after submitting a Formidable form. Your users do NOT need to have a Paypal account in order to pay with Paypal.

Download and install

  1. Download latest version:
    Please log in to download

    Note: Versions 2.0+ require Formidable v1.6+. View the change log to see a complete list of changes made in each version.

  2. In your WordPress admin, go to 'Plugins' → 'Add New' and click the 'Upload Plugin' button at the top of the page.
  3. Upload the zip file you just downloaded in step one. Once the plugin is installed, click ‘Activate Plugin’ or go to the ‘Plugins’ page, find ‘Formidable Payment’ and click ‘Activate’.

Set up the Paypal add-on

Now that the PayPal plugin is activated you’ll need to set up Formidable Forms to integrate with your PayPal account. To do this follow these steps below.

Global settings

  1. Now that the plugin is activated, go to 'Formidable' → 'Global Settings' and click the 'Paypal' tab.
  2. Insert your PayPal email address and update any other settings. For live sites, make sure the 'PayPal' environment is set to 'Live'; otherwise, users will be prompted to set up new PayPal accounts.
    PayPal Global Settings

Instant payment notifications

In order for your payments to get correctly marked as paid, you must configure your PayPal account to send payment notifications. Follow the directions below to set this up.

  1. Log into your PayPal account.
  2. Go to your 'Profile and settings' page and then 'My Selling Tools'.
  3. Click the 'Update' link next to 'Instant Payment Notifications'.
    PayPal IPN
  4. Edit and enter a notification URL. It doesn’t matter what URL you insert since Formidable PayPal will override it.
  5. Enable IPN Messages.
  6. Click Save.
    PayPal IPN Email

Form settings

  1. Go into edit the form you would like to use with PayPal. Click on 'Settings' → 'Form Actions' → 'PayPal'.
    PayPal Icon
  2. Give your Paypal action a Label for easy reference. This label will only be seen on the back-end.
    PayPal Label
  3. Choose an Item Name that will appear on the PayPal page and on the PayPal receipt. You can either type in the product name if it is not changing or select a field from your form if it will change depending on your user's selection.
    PayPal Item Name
  4. Set an Amount for the payment. You can either select a field from your form (this field should contain the payment amount) or select 'Set Amount' and insert a value in the box.
    PayPal Amount
  5. If this form will be used to collect Donations, select 'Payments made in this form are donations'.
    Paypal Donations
  6. If you do not want the user to receive Notifications until after the payment is received, check 'Hold email notifications until payment is received'.
    PayPal Notifications
  7. If you would like to conditionally send users to Paypal after form submission, you will need to add Conditional Logic.
    PayPal Conditional Logic
  8. Don’t forget to hit 'Update' so these settings will be saved.

Additional customizations

These code examples can be added to your theme functions.php file or the Code Snippets plugin.

Automatically publish a post after payment.

If your entry is set up to create WordPress posts, you can prevent the post from being created until payment is successful:

add_action('frm_payment_paypal_ipn', 'publish_paid_post');
function publish_paid_post($args){ if(!$args['pay_vars']['completed']) return; //don't publish if the payment was not completed
if(!$args['entry']->post_id) return; //don't publish if not linked to a post
wp_update_post(array('ID' => $args['entry']->post_id, 'post_status' => 'publish'));

Set payment status field to complete after payment

If you would like a field in your form to indicate the payment status, add a drop-down or radio field with two options: Yes, and No. Set the Visibility to 'Administrator', and select 'No' as the default value. Then, add this code to your theme functions.php or a new plugin to change the value to "Yes" when the payment is completed:

add_action('frm_payment_paypal_ipn', 'mark_as_complete');
function mark_as_complete($vars){
  if ( ! $vars['pay_vars']['completed'] ) {
    return; //don't change value if the payment was not completed

  $formIDToFieldID = array(
    6 => 92, // change 6 to the id of your form and 92 to your field id
    7 => 115 // change 7 to the id of your form and 115 to your field id

  global $frmdb, $wpdb;

  $entry_id = $vars['payment']->item_id;
  $form_id = $vars['entry']->form_id;

  if ( ! isset($formIDToFieldID[$form_id]) ) {
    return; // don't continue if this form is not one listed above

  $wpdb->update( $frmdb->entry_metas, array('meta_value' => 'Yes'), array(
    'item_id' => $entry_id, 'field_id' => $formIDToFieldID[$form_id]
  ) );

Change the user role after payment

The only change needed in the example is the user role the user should have: $new_role = 'contributor';

add_action('frm_payment_paypal_ipn', 'change_paid_user_role');

function change_paid_user_role($args){
    $new_role = 'contributor'; //change this to the role paid users should have
       return; //don't continue if the payment was not completed

    if(!$args['entry']->user_id or !is_numeric($args['entry']->user_id))
       return; //don't continue if not linked to a user

    $user = get_userdata($args['entry']->user_id);
        return; //don't continue if user doesn't exist

    $updated_user = (array)$user;

    // Get the highest/primary role for this user  
    $user_roles = $user->roles;
    $user_role = array_shift($user_roles);
    if ( $user_role == 'administrator' ) 
        return; //make sure we don't downgrade any admins

    $updated_user['role'] = $new_role;

Change return URL

add_filter('formidable_paypal_url', 'formidable_paypal_url', 10, 3);
function formidable_paypal_url($paypal_url, $entry_id, $form_id){
  if($form_id == 5) //change 5 to the ID of your form
    $paypal_url .= '&return='. urlencode('');
  return $paypal_url;

Use a different PayPal email

add_filter( 'formidable_paypal_url', 'formidable_paypal_url', 10, 3 );
function formidable_paypal_url( $paypal_url, $entry_id, $form_id ) {
  if( $form_id == 5 ) { //change 5 to the ID of your form
    $paypal_url .= '&business='. urlencode( '' ); //insert the email address here
  return $paypal_url;

Prevent PayPal return data

If you are not using SSL on your site, or you don't want any data returned from PayPal along with the user, you can add this.

add_filter('formidable_paypal_url', 'formidable_paypal_url', 10, 3);
function formidable_paypal_url($paypal_url, $entry_id, $form_id){
  $paypal_url .= '&rm=1';
  return $paypal_url;

Use different currencies

add_action('frm_after_create_entry', 'change_my_return_url', 40, 2);
function change_my_return_url($entry_id, $form_id){
    //check if sending to PayPal
    if ( !$_POST || (is_admin() && !defined('DOING_AJAX')) ) {

    if($form_id == 18){ //change 18 to the ID of the form to override the currency
        add_filter('frm_paypal_settings', 'change_my_GBP_currency');
    }else if($form == 19){
        add_filter('frm_paypal_settings', 'change_my_USD_currency');

function change_my_GBP_currency($settings){
  $settings->currency = 'GBP';
  return $settings;

function change_my_USD_currency($settings){
  $settings->currency = 'USD';
  return $settings;

If the payment fails the first time, you can generate a link to allow users to pay again without filling out the form a second time. This shortcode can be used in a number of different ways, but the most likely would be in a view where you can add filters like 'User ID is equal to current user', and the shortcode would be [pay_again id=[id]]. You can also set a specific entry id here if you would like [pay_again id=60].

add_shortcode('pay_again', 'pay_frm_again');
function pay_frm_again($atts) {
    if ( ! class_exists('FrmPaymentsController') ) {
    $atts = shortcode_atts(array('id' => '', 'form_id' => ''), $atts);
    $entry_id = $atts['id'];
    $entry = FrmEntry::getOne($entry_id, true);
    if ( empty($atts['form_id']) ) {
      $atts['form_id'] = $entry->form_id;

    $form = FrmForm::getOne($atts['form_id']);
    global $frm_pay_form_settings;
    if ( empty($frm_pay_form_settings) ) {
        $frm_pay_form_settings = $form->options;
        if ( ( ! isset($form->options['paypal']) || empty($form->options['paypal']) ) && class_exists('FrmFormActionsHelper') ) {
            // get the 2.0 form action settings
            $action_control = FrmFormActionsHelper::get_action_for_form($form->id, 'paypal', 1);
            if ( ! $action_control ) {
            $frm_pay_form_settings = $action_control->post_content;
            $frm_pay_form_settings['paypal'] = 1;

    $amount_field = isset($frm_pay_form_settings['paypal_amount_field']) ? $frm_pay_form_settings['paypal_amount_field'] : '';
    $_POST['item_meta'][$amount_field] = $entry->metas[$amount_field]; // set the POST for the amount
    $amount = FrmPaymentsController::get_amount($form, $frm_pay_form_settings);
    if ( empty($amount) ) {

    global $wpdb;
    $invoice = $wpdb->get_var($wpdb->prepare('SELECT id FROM '. $wpdb->prefix .'frm_payments WHERE item_id=%d AND amount=%s AND paysys=%s', $entry_id, (float) $amount, 'paypal'));
    if ( ! $invoice ) {

    $frm_payment_settings = new FrmPaymentSettings();

    $paypal_url = '';
    $paypal_url .= '?cmd='. (( isset($frm_pay_form_settings['paypal_type']) && ! empty($frm_pay_form_settings['paypal_type']) ) ? $frm_pay_form_settings['paypal_type'] : '_xclick');
    $paypal_url .= '&notify_url='. FrmPaymentsHelper::format_for_url(admin_url('admin-ajax.php') . "?action=frm_payments_paypal_ipn");
    $paypal_url .= '&business='. FrmPaymentsHelper::format_for_url($frm_payment_settings->settings->business_email);
    $paypal_url .= '&currency_code='. FrmPaymentsHelper::format_for_url($frm_payment_settings->settings->currency);
    $paypal_url .= '&return='. FrmPaymentsHelper::format_for_url($frm_payment_settings->settings->return_url); 
    $paypal_url .= '&cancel_return='. FrmPaymentsHelper::format_for_url($frm_payment_settings->settings->cancel_url); 
    $paypal_url .= '&invoice='. FrmPaymentsHelper::format_for_url($invoice .'-'. FrmPaymentsHelper::get_rand(3));
    $paypal_url .= '&custom='. $entry_id.'|'. wp_hash($entry_id);
    $paypal_url .= '&amount='. urlencode($amount);
    if ( defined('ICL_LANGUAGE_CODE') ) {
      $paypal_url .= '&lc='. FrmPaymentsHelper::format_for_url(ICL_LANGUAGE_CODE);
    $item_name = apply_filters('frm_content', $frm_pay_form_settings['paypal_item_name'], $form, $entry_id);
    $paypal_url .= "&item_name=". urlencode($item_name);

    return '<a href="'. $paypal_url .'">Pay Now</a>';