0

I'm implementing a site where users pay for submissions and reviewers get paid. Drupal Commerce with Commerce Credits allows me to buy credits using Paypal and to pay on site with credits for submitting content.

Reviewers receive credits for performing the review, when they reach a certain amount I want them to offer the possibility to withdraw credits through Paypal.

I had a look at modules like Commerce Funds (broken) and Commerce-Marketplace (withdrawal not implemented yet) and Paypal Adaptive Payments (not public anymore), did I miss anything?

Is there anything I can do to automatize this process with rules? I could transfer credits to a withdrawal user account and manually make the transaction with Paypal. Any hints how to automatize this process and trigger a Paypal payment to users credit card?

1 Answer 1

2
+50

I suppose this can be done, but it won't be easy. There will be quite some components and you will have to write some code. Disclaimer is that I have not tested anything of this code, but I hope this to be useful to you.

This example is based on the commerce_funds_withdraw_action() on line 932 of the Commerce Funds Withdraw Module, part of Commerce Funds.

Most important is this part, which performs the actual transfer using PayPal Mass Pay (Read the integration guide for details about PayPal business accounts and contacting customer support to enable the feature.):

$response = commerce_paypal_api_request($payment_method, $nvp);
if($response['ACK'] == 'Success') {
  $withdraw->status = 'Transfered';
  $amount_paypal = $withdraw->amount;
  $withdraw->amount = commerce_currency_decimal_to_amount($withdraw->amount, $withdraw->currency_code);
  commerce_funds_withdraw_save($withdraw);
  $amount = array(
    'amount' => $amount_paypal,
    'currency_code' => $withdraw->currency_code,
    'reference' => $withdraw->uid,
  );
  commerce_funds_debit(user_load($withdraw->uid), $amount);
  drupal_set_message(t('Money were successfully transferred to @user_email.', array('@user_email' => $user->mail)), 'status');
}

If we remove all commerce funds transaction tracking, we are left with:

$response = commerce_paypal_api_request($payment_method, $nvp);
if($response['ACK'] == 'Success') {

  // Deduct credits from the account here, or do it in Rules later.

  drupal_set_message(t('Money was successfully transferred'), 'status');
}

The actual communication with the API is handled by commerce_paypal_api_request(), a function of the Commerce PayPal module, which requires 2 parameters;

  • $payment_method: The payment method instance array associated with this API request.
  • $nvp: The set of name-value pairs describing the transaction to submit. (See MassPay API Using NVP of the API documentation.)

Since there is no offical payment method to use, we create a custom payment method option:

$payment_method = array(
  'settings' => array(
    // Fill these to match the data configured with PayPal
    'server' => '',
    'api_username' => '',
    'api_password' => '',
    'api_signature' => '',
    'log' => array(
      'request' => FALSE, // Log outgoing request TRUE/FALSE.
      'response' => FALSE, // Log response from PayPal TRUE/FALSE.
    ),
  ),
);

And the NVP:

$nvp = array(
  'METHOD' => 'MassPay',
  'EMAILSUBJECT' => 'Withdraw',
  'CURRENCYCODE' => $currency_code,
  'RECEIVERTYPE' => 'EmailAddress',
  'L_EMAIL0' => $receiver_email,
  'L_AMT0' =>  $amount,
);

Now for getting this all together in a custom module and a Rules actions:

Create a rules_paypal_deposit folder for your module, with the following files:

rules_paypal_deposit.info:

name = Rules PayPal Deposit
description = Deposit funds to a paypal account using rules.
core = 7.x
dependencies[] = rules
dependencies[] = commerce_paypal

rules_paypal_deposit.module:

<?php
/* 
 * This function performs the actual transfer
 */
function rules_paypal_deposit_do_deposit($receiver_email, $amount, $currency_code) {
  $payment_method = array(
    'settings' => array(
      // Fill these to match the data configured with PayPal
      'server' => '',
      'api_username' => '',
      'api_password' => '',
      'api_signature' => '',
      'log' => array(
        'request' => FALSE, // Log outgoing request TRUE/FALSE.
        'response' => FALSE, // Log response from PayPal TRUE/FALSE.
      ),
    ),
  );

  $nvp = array(
    'METHOD' => 'MassPay',
    'EMAILSUBJECT' => 'Withdraw',
    'CURRENCYCODE' => $currency_code,
    'RECEIVERTYPE' => 'EmailAddress',
    'L_EMAIL0' => $receiver_email,
    'L_AMT0' =>  $amount,
  );

  $response = commerce_paypal_api_request($payment_method, $nvp);
  if($response['ACK'] == 'Success') {

    // Deduct credits from the account here, or do it in Rules later.

    drupal_set_message(t('Money was successfully transferred'), 'status');
  }
}

rules_paypal_deposit.rules.inc:

<?php
/**
 * Implement hook_rules_action_info()
 */
function rules_paypal_deposit_rules_action_info() {
  $actions = array(
    'rules_paypal_deposit_actions_deposit' => array(
      'label' => t('Transfer funds to a PayPal account'),
      'group' => t('Rules PayPal Deposit'),
      'parameter' => array(
        'receiver_email' => array(
          'type' => 'text',
          'label' => t('E-mail to transfer to.'),
        ),
        'amount' => array(
          'type' => 'decimal',
          'label' => t('Amount to transfer (format: 12.34)'),
        ),
        'currency_code' => array(
          'type' => 'text',
          'label' => t('3 Letter currency of the transfer, see <a href="@url">the PayPal documentation</a>', array('@url' => url('https://developer.paypal.com/docs/classic/mass-pay/integration-guide/currency_codes/'))),
        ),
      ),
    ),
  );
  return $actions;
}

/** 
 * The action for rules_paypal_deposit_actions_deposit
 */
function rules_paypal_deposit_actions_deposit($receiver_email, $amount, $currency_code) {
  rules_paypal_deposit_do_deposit($receiver_email, $amount, $currency_code)
}

You can choose to add the PayPal API settings server, api_username, api_password and api_signature as Rules parameters as well and add the parameters to rules_paypal_deposit_actions_deposit() and rules_paypal_deposit_do_deposit(). Or just define them in the code.


I really hope this is of use to you. It was written in a bit of spare time because I thought it was a nice puzzle. Do not get mad if it doesn't work ;)

Obviously this needs proper testing on the PayPal API sandbox first.

4
  • 1
    Thanks for your extensive guide. I'll follow your steps and come back to you in the next days.
    – geraldo
    Commented Mar 6, 2017 at 13:49
  • @geraldo, you managed to get this to work? Commented Mar 9, 2017 at 14:02
  • I'm on it, but don't have time to go on with it till next week. Till now your code looks promising and I wanted you to get the bounty ;)
    – geraldo
    Commented Mar 9, 2017 at 14:28
  • Much appreciated :). Please let me know the outcome in the end. Commented Mar 9, 2017 at 14:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.