I'm debugging an extension that allows recurring Paypal payments in Magento 1.9, and I've found a major issue with it--if a customer has placed a subscription order in the past, the Magento's API does not request a new billing agreement id from Paypal when placing the order. Instead, it looks in the 'sales_billing_agreement' table, and if it finds an active billing agreement, it omits the 'BILLINGTYPE' of 'MerchantInitiatedBilling' from the SetExpressCheckout call.

It does this here, in Mage_Paypal_Model_Express_Checkout, where needToCreateForCustomer($this->_customerId) returns false if the number of rows with active status found in the 'sales_billing_agreement' table for the customers ID is greater than zero:

protected function _setBillingAgreementRequest()
    if (!$this->_customerId || $this->_quote->hasNominalItems()) {
        return $this;

    $isRequested = $this->_isBARequested || $this->_quote->getPayment()

    if (!($this->_config->allow_ba_signup == Mage_Paypal_Model_Config::EC_BA_SIGNUP_AUTO
        || $isRequested && $this->_config->shouldAskToCreateBillingAgreement())) {
        return $this;

    if (!Mage::getModel('sales/billing_agreement')->needToCreateForCustomer($this->_customerId)) {
        return $this;

    return $this;

The problem with this is that, if a customer cancels a billing agreement through their Paypal account, that billing ID is no longer valid and Paypal will reject future payments that attempt to use this billing ID. However, Magento is not notified that the billing ID has been invalidated and continues to assign it to new orders.

That means customers who cancel a subscription through their Paypal accounts cannot be charged for any current subscriptions or future sign ups.

Why would Magento set things up this way? Is this just a bug, and will I cause any problems if I create a model rewrite that eliminates this check?


Your Answer

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

Browse other questions tagged or ask your own question.