Posted by reni10 on September 23, 2009 at 10:33am
Jump to:
| Project: | Sage Pay Go Direct Payment Gateway for Ubercart |
| Version: | 6.x-2.x-dev |
| Component: | Code |
| Category: | feature request |
| Priority: | normal |
| Assigned: | longwave |
| Status: | closed (fixed) |
Issue Summary
It would be great to integrate this SagePay Payment Gateway module with the new UC_Recurring fees module that is being developed.
Anyone out there able to make this happen?
Comments
#1
Yes a great idea i would like to see this happen also.
#2
I am available to develop this if someone is willing to sponsor development. Contact me through my profile page to discuss this further.
#3
subscribing
#4
Hi Everyone,
I'm trying to implement recurring payments with uc_sagepay_token module. It seems that this is the right way to go as we do not need to store any cc details, just the token.
What I have done so far is :
added hook_recurring_info() implementation to uc_sagepay_token module:
function uc_sagepay_token_recurring_info() {$items = array();
$items['uc_sagepay_token'] = array(
'name' => t('Protx VSP Direct Stored'),
'payment method' => 'uc_sagepay_token',
'module' => 'uc_sagepay_token',
'fee handler' => 'uc_sagepay_token',
'renew callback' => 'uc_sagepay_token_recurring_process',
'process callback' => 'uc_sagepay_token_recurring_process',
'own handler' => TRUE,
'saved profile' => TRUE,
);
return $items;
}
for now both renew callback and process callback point to same functions.
The callback function body:
/**
* Set up the recurring fee
*
* @param $order
* The order object.
* @param $fee
* The fee object.
* @return
* TRUE if recurring fee setup
*/
function uc_sagepay_token_recurring_process($order, &$fee){
// unset($_SESSION['cc_pay']);
// Attempt to process using the standard credit card payment method, with a custom transaction type.
$fee->fee_handler = 'uc_sagepay_token';
$data = array('txn_type' => 'sagepay_token');
$pass = uc_payment_process('credit', $order->order_id, $order->order_total, $data, TRUE, NULL, FALSE);
drupal_set_message(print_r($pass));
if (!$pass) {
$message = variable_get('uc_credit_fail_message', t('We were unable to process your credit card payment. Please verify your card details and try again. If the problem persists, contact us to complete your order.'));
return array(array('pass' => FALSE, 'message' => $message));
}
return TRUE;
}
Which I have basically copied from uc_sagepay_token_order()
The problem I'm currently struggling with is that there is no payment methods available on the order checkout page at /cart/checkout and the message it outputs is : "Checkout cannot be completed without any payment methods enabled. Please contact an administrator to resolve the issue."
I have enabled new recurring payment method (new method is available - partial success) at /admin/store/settings/payment/edit/recurring but still no luck.
Any help would be much appreciated.
Cheers,
Rafal Jachimczyk
#5
#6
I think you are supposed to use the Sage Pay REPEAT instead of TOKEN feature for recurring payments, as REPEAT sets up a "continuous authority" transaction which is what you should be using for taking regular payments from a customer; otherwise, I'm not sure why they introduced TOKEN when REPEAT is already available.
If you do get this working, please post a patch (preferably a separate submodule, as uc_sagepay_token doesn't need to depend on uc_recurring otherwise) and I'd be happy to commit it to the 6.x-2.x-dev branch, it would be good if the module supported all the features that Sage Pay can provide.
#7
Oh wait, I think you will need to use REPEAT for this - with TOKEN, Sage Pay will only let you store CVV for one transaction (which in this implementation, is used up immediately), after that you must submit it as part of the transaction (which is why uc_sagepay_token asks for that field at checkout), and you aren't allowed to store it in your own database.
#8
Hi Longwave
To setup REPEAT transactions you need to apply for “Continuous Authority” merchant number from your
bank as it is stated in SagePay Direct Integration Documentation : http://www.sagepay.com/help/userguides/590
Also, REPEAT transactions will always carry on the same Order Amount, which for some might not be acceptable.
With TOKEN type transactions we can do much more and CV2/CVV and 3D Secure check can be omitted by overriding some transaction values like:
$transaction['Apply3DSecure'] = 2;$transaction['ApplyAVSCV2'] = 2;
Here's what I have extracted from API documentation:
ApplyAVSCV2 ( Using this flag you can fine tune the AVS/CV2 checks and rule set you’ve defined at a transaction level. This is useful in circumstances where direct and trusted customer contact has been established and you wish to override the default security checks.
Flag 0 = If AVS/CV2 enabled then check them. If rules apply, use rules (default).
1 = Force AVS/CV2 checks even if not enabled for the account. If rules apply, use rules.
2 = Force NO AVS/CV2 checks even if enabled on account.
3 = Force AVS/CV2 checks even if not enabled for the account but DON’T apply any rules.
Apply3DSecure
Flag 0 = If 3D-Secure checks are possible and rules allow, perform the checks and apply the authorisation rules (default).
1 = Force 3D-Secure checks for this transaction only (if your account is 3D-enabled) and apply rules.
2 = Do not perform 3D-Secure checks for this transaction only and authorise.
3 = Force 3D-Secure checks for this transaction (if your account is 3D-enabled) but ALWAYS obtain an auth
code, irrespective of rule base.
Using this flag you can fine tune the 3D Secure checks and rule set you’ve defined, at a transaction level. This is useful in circumstances where direct and trusted customer contact has been established and you wish to override the default security checks.
Using this flag you can fine tune the 3D Secure checks and rule set you’ve defined, at a transaction level. This is useful in circumstances where direct and trusted customer contact has been established and you wish to override the default security checks.
NB: If 3D Secure is ON for your account this field becomes compulsory.
It seems the whole point of the token system is to take payment without having access to card details, for subscriptions, spreading payments etc. See the details at: https://www.sagepay.com/products_services/bolt_ons/token_system
on that page : "Multiple uses - Using the token multiple times provides the ability to hold the shopper’s card details allowing you to process a transaction several times without requesting the card information from the shopper each time. This is great should you offer a monthly payments or subscription service."
The solution lies in taking and verifying the CV2 on the first payment (which stores and returns the token) and then from thereon not require the CV2.
Let me know what you think, we can meet up on IRC (my nick jahmal at irc.freenode.net) and talk this further.
Rafal
#9
Still having the problem with no available payment methods at /cart/checkout when purchasing product with recurring fee.
Checkout cannot be completed without any payment methods enabled. Please contact an administrator to resolve the issue.
function uc_recurring_sagepay_token_recurring_info() {$items = array();
$items['uc_recurring_sagepay_token'] = array(
'name' => t('SagePay Direct Stored'),
'payment method' => 'uc_recurring_sagepay_token',
'module' => 'uc_recurring_sagepay_token',
'fee handler' => 'uc_recurring_sagepay_token',
'renew callback' => 'uc_recurring_sagepay_token_process',
'process callback' => 'uc_recurring_sagepay_token_process',
'saved profile' => TRUE,
'menu' => array(
'charge' => UC_RECURRING_MENU_DEFAULT,
'edit' => UC_RECURRING_MENU_DEFAULT,
'cancel' => UC_RECURRING_MENU_DEFAULT,
), // Use the default user operation defined in uc_recurring.
);
return $items;
}
#10
Ah ok, I thought you had to send CVV, but if you don't mind AVS/CV2 or 3D Secure checks not being performed (and you can do these as part of the first transaction, which should be enough) then yes I guess TOKEN is good for this.
Regarding the "no available payment methods" this must be something specific with uc_recurring and your hook implementation, I don't see why the Sage Pay module itself would cause this. If I get time later I will try installing uc_recurring and see if I can help.
#11
This key in the recurring handler definition needs to match the payment gateway or payment method id:
<?php$items['uc_recurring_sagepay_token'] = array(
?>
I'm guessing that the gateway id is not uc_recurring_sagepay_token and probably just something like sagepay, secondly prefixing 'uc_recurring_' in a uc_recurring handler is a bit redundant. All uc_recurring handlers are uc_recurring handlers.
Where a payment gateway offers multiple recurring payment options, you probably will want to do something like this:
<?php$items['sagepay_token'] = array(
...
// this line tells us want to save with the record for renewals, updating credit card
// and any other operations
'fee handler' => 'sagepay_token',
...
);
$items['sagepay_recurring'] = array(
...
'fee handler' => 'sagepay_recurring', // we could even point this to 'sagepay_token'
...
);
// then add some logic for the default sagepay handler, you need to still define
// both above so we can access them by the 'fee handler' key which is what we
// use on renewals
if (/*logic to decide which recurring handle to use by default*/) {
$items['sagepay'] = $item['sagepay_token'];
}
else {
$items['sagepay'] = $item['sagepay_recurring'];
}
?>
The 'fee handler' tells us what to use for the renewals as that is saved with each recurring payment record.
#12
Still no luck with it. Could the problem be that payment gateway and additional payment method are in separate modules ?
payment gateway id is : uc_protx_vsp_direct
payment method id : uc_sagepay_token
#13
Ok so I took a quick look at the module code here:
module name is: uc_sagepay_token
in that module there is one payment method with the id: sagepay_token
So its quite simple, you need to add a hook for handle recurring stuff:
<?php
/**
* Implementation of hook_recurring_info()
*/
function uc_sagepay_token_recurring_info() {
$items['sagepay_token'] = array(
'name' => t('SagePay Direct Stored'),
'payment method' => 'sagepay_token',
'module' => 'uc_sagepay_token',
'fee handler' => 'sagepay_token',
'renew callback' => 'uc_sagepay_token_recurring_renew', // prefix your own module name on your own functions.
'process callback' => 'uc_sagepay_token_recurring_reprocess',
'menu' => array(
'charge' => UC_RECURRING_MENU_DEFAULT,
'edit' => UC_RECURRING_MENU_DEFAULT,
'cancel' => UC_RECURRING_MENU_DEFAULT,
),
);
}
function uc_sagepay_token_recurring_process($order, &$fee){
// code to setup the recurring schedule with the gateway
}
function uc_sagepay_token_recurring_renew($order, &$fee){
// precess a renewal
}
?>
The above goes in the uc_sagepay_token module.
#14
I think that approach should work if the user already has a token from Sage Pay, ie. they have made a previous purchase on the site and selected to store their credit card.
However there is another case that I imagine will be fairly common: the user can make their initial checkout through uc_credit and the uc_protx_vsp_direct gateway, and their card details are exchanged for a token as part of this transaction, then subsequent recurring payments should be made through the separate uc_sagepay_token method. Can uc_recurring handle this scenario?
#15
Thats what the "fee handlers" meant to define.
This is how the "credit" payment gateway work, you checkout with 'credit', but by defining a different fee_handler you can tell uc_recurring that on renewals, don't use credit, use authorizenet_cim (or what every the specific gateway is)
So if the original payment is handled with one gateway uc_proxx_vsp_direct and then everything else is handled with another handler, you can do something like:
<?php
/**
* Implementation of hook_recurring_info()
*/
function <module_name>_recurring_info() {
$items['uc_protx_vsp_direct'] = array(
'name' => t('SagePay Direct Stored'),
'payment method' => 'credit',
'module' => '<module_name>',
'fee handler' => 'sagepay_token',
'renew callback' => '', // you can probably ignore this if it doesn't handle any renewals.
'process callback' => 'uc_sagepay_token_recurring_reprocess',
'menu' => array(
'charge' => UC_RECURRING_MENU_DEFAULT,
'edit' => UC_RECURRING_MENU_DEFAULT,
'cancel' => UC_RECURRING_MENU_DEFAULT,
),
);
}
function <module_name>_recurring_process($order, &$fee){
// code to setup the recurring schedule with the gateway
$fee->fee_handler = 'sagepay_token';
}
?>
#16
I'm working on this at the moment and have most aspects fully working, just one or two minor issues to iron out and some more testing before I commit it to -dev.
@univate: your code samples above were very helpful!
One issue I don't think I can avoid occurs with Maestro cards used for recurring payments. 3D Secure is mandatory for Maestro transactions, but as there is no user interaction for renewals, we can't get them to enter their password. Not sure how this will work out in practice, I guess Maestro just cannot be used for recurring transactions using the token system.
#17
Committed to CVS. With uc_recurring enabled, recurring payments can be taken whether the user pays with a new credit card or an existing stored card. At /admin/store/settings/payment/edit/recurring, enable both "Credit card" and "Sage Pay stored credit card", then set up recurring payments under the Features tab when editing a product.
#18
Automatically closed -- issue fixed for 2 weeks with no activity.