ePDQ payment Module

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.
13 years ago
I've just added an ePDQ payment module to a nop based project and due to popular demand (ok, only 3 people have asked me about it :)) I've stuck it on SourceForge and added a HOW-TO post on my web site (http://www.n-webdesign.co.uk/epdq-intergration-for-nopcommerce-part/).

It has been done on a 1.5 site. I'll test it in 1.6/8 shortly.  
It integrates with the nop payment model.
It sends invoice/delivery details to ePDQ.
It writes back (if required).
It has a 'test mode' (set to true/false) that writes an entry in the nop log after writeback.

It doesn't update payment status for declined/failed.
It doesn't do any recurring billing.
It doesn't do refunds from nop.

This has literally been written yesterday, BETA tested today, UAT tomorrow, so bear that in mind if you use it. :$

Any/all feedback welcome.
13 years ago
Did you manage to test this on v1.8??  Any chance of some screenshots??  I am very interested in integrating this.
13 years ago
...for you Dr House...

I haven't as yet I'm afraid. I'll try and do a 1.8 install on localhost today and see what happens?

Watch this space!
13 years ago
Ok no probs :)  I thinking about writing a little WinForms desktop app and a couple of web services that spoke to it?  Its would be useful for us, and I thought other people in the community might find it useful :S
13 years ago
I've downloaded nop 1.8, installed it, added ePDQ, set it up and run it in debug to the point of submitting to the gateway. (Took less than an hour, so it's not too bad).

This is my first try of running 1.8, and it's pretty cool. The module works ok with a few small changes.

To use this ePDQ module in 1.8 (and probably 1.7) there are a few things to change/update.

When you copy the ePDQ module into the payment libraries, it will prompt (in VS2010 or Web Developer) to upgrade the project. Just say ok. Once it's added, you may need to remove and re-add the references to Nop.Common and Nop.BusinessLogic.

I completely missed the Templates/Payment/ePDQ folder from the install files and HOW-TO (ooops). I've updated these now.

Once you add things to the project (just copy into the relevant place, refresh, show all files and 'add to project') you will get 2 errors related to property name changes in 1.8 from 1.6. These are:

order.OrderId in Necesse.Payment.ePDQ.ePDQPaymentProcessor.cs
paymentInfo.CreditCardCvv2 in Templates/payment/ePDQ/paymentModule.cs

Just update these (Intellisense will show the renamed properties/methods).

From there, just run it, add the config details (that you need from Barclays) and test it out.

Any more questions, just shout up :)

HTH.
13 years ago
Hi EdNice

Followed all the steps and on the rebuild i get one error

'Necesse.Payment.ePDQ.ePDQPaymentProcessor' does not implement interface member 'NopSolutions.NopCommerce.BusinessLogic.Payment.IPaymentMethod.CanPartiallyRefund'
ePDQPAymentProcessor.cs Line 25 Column 11

ePDQPAymentProcessor.cs
Line 25:  class ePDQPaymentProcessor : IPaymentMethod

also the namespace is :
namespace Necesse.Payment.ePDQ

Using NOP v1.8, VS2010 and .Net4 and redownloaded the source 28/10/2010
Changed the Payment Properties to .Net 4 also...system / core /  etc...

Some help would be great or a post of your ePDQPaymentProcessor.cs so i can check etc.... cheers Simon
13 years ago
Hi Ed,
When i hover over ePDQPaymentProcessor.cs  .... blue wavy line and the popup (thingie - sorry no idea whats its called but like a tool tip...) says  'Necesse.Payment.ePDQ.ePDQPaymentProcessor' does not implement interface member 'NopSolutions.NopCommerce.BusinessLogic.Payment.IPaymentMethod.CanPartiallyRefund'


In the Fields - do i have to assign the id's or any other strings under the class ePDQPaymentProcessor...?

#region Fields
private string StoreID;

Is what is shown... Sorry for long post but below is my ePDQPaymentProcessor.cs.... Has anyone else had any luck with this module..?

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Globalization;
using System.IO;
using System.Net;
using System.Text;
using System.Web;
using System.Xml;
using NopSolutions.NopCommerce.BusinessLogic;
using NopSolutions.NopCommerce.BusinessLogic.Configuration.Settings;
using NopSolutions.NopCommerce.BusinessLogic.CustomerManagement;
using NopSolutions.NopCommerce.BusinessLogic.Directory;
using NopSolutions.NopCommerce.BusinessLogic.Orders;
using NopSolutions.NopCommerce.BusinessLogic.Payment;
using NopSolutions.NopCommerce.BusinessLogic.Utils;
using NopSolutions.NopCommerce.Common.Utils;
using NopSolutions.NopCommerce.Common;

namespace Necesse.Payment.ePDQ
{
    /// <summary>
    /// ePDQ (UK) payment processor
    /// </summary>
    public class ePDQPaymentProcessor : IPaymentMethod
    {
        #region Fields

        private string StoreID;
        private string Password;
        private string ePDQEncUrl;
        private string ePDQUrl;
        private string CurrencyCode;
        private string MerchantName;
        private string MandateCSC;

        #endregion

        #region Ctor
        /// <summary>
        /// Creates a new instance of the ePDQPaymentProcessor class
        /// </summary>
        public ePDQPaymentProcessor()
        {
            StoreID = SettingManager.GetSettingValue("PaymentMethod.ePDQ.StoreID");
            Password = SettingManager.GetSettingValue("PaymentMethod.ePDQ.ePDQPassword");
            ePDQEncUrl = SettingManager.GetSettingValue("PaymentMethod.ePDQ.RemoteEncURL");
            ePDQUrl = SettingManager.GetSettingValue("PaymentMethod.ePDQ.RemoteURL");
            CurrencyCode = SettingManager.GetSettingValue("PaymentMethod.ePDQ.CurrencyCode");
            MerchantName = SettingManager.GetSettingValue("PaymentMethod.ePDQ.MerchantName");
            MandateCSC = SettingManager.GetSettingValue("PaymentMethod.ePDQ.MandateCSC");
        }
        #endregion

        #region Classes

        #endregion

        #region Utilities

        private string GenerateEncOrder(Order order)
        {
            StringBuilder encBuilder = new StringBuilder();

            // Basic authentication an requirements...
            encBuilder.AppendFormat("clientid={0}", StoreID);
            encBuilder.AppendFormat("&password={0}", Password);
            encBuilder.AppendFormat("&oid={0}", order.OrderId.ToString());
            encBuilder.AppendFormat("&chargetype={0}", "Auth");
            encBuilder.AppendFormat("&currencycode={0}", CurrencyCode);
            encBuilder.AppendFormat("&total={0}", order.OrderTotal.ToString());
            encBuilder.AppendFormat("&mandatecsc={0}", MandateCSC);

            return encBuilder.ToString();
        }

        private string ProcessEncOrder(Order order)
        {
            WebClient c = new WebClient();
            c.Headers.Add("Content-Type", "application/x-www-form-urlencoded");

            byte[] resp = c.UploadData(ePDQEncUrl, "POST", Encoding.ASCII.GetBytes(GenerateEncOrder(order)));

            return Encoding.ASCII.GetString(resp);
        }

        #endregion

        #region Methods

        /// <summary>
        /// Process payment
        /// </summary>
        /// <param name="paymentInfo">Payment info required for an order processing</param>
        /// <param name="customer">Customer</param>
        /// <param name="OrderGuid">Unique order identifier</param>
        /// <param name="processPaymentResult">Process payment result</param>
        public void ProcessPayment(PaymentInfo paymentInfo, Customer customer, Guid OrderGuid, ref ProcessPaymentResult processPaymentResult)
        {
            processPaymentResult.PaymentStatus = PaymentStatusEnum.Pending;
        }

        /// <summary>
        /// Post process payment (payment gateways that require redirecting)
        /// </summary>
        /// <param name="order">Order</param>
        /// <returns>The error status, or String.Empty if no errors</returns>
        public string PostProcessPayment(Order order)
        {
            // This is slightly different in ePDQ that SagePay, as it has a 2 way encryption going on that needs some consideration?
            RemotePost remotePostHelper = new RemotePost();
            remotePostHelper.FormName = "ePDQForm";
            remotePostHelper.Url = ePDQUrl;

            remotePostHelper.Add("returnurl", CommonHelper.GetStoreLocation(false));
            remotePostHelper.Add("merchantdisplayname", MerchantName);
            remotePostHelper.Add("epdqdata", StripHTML(ProcessEncOrder(order)));

            // Additional field values from the order object...
            remotePostHelper.Add("baddr1", order.BillingAddress1);
            remotePostHelper.Add("baddr2", order.BillingAddress2);
            remotePostHelper.Add("bcity", order.BillingCity);
            remotePostHelper.Add("bcountyprovince", order.BillingStateProvince);
            // remotePostHelper.Add("bcountry", order.BillingCountry);
            remotePostHelper.Add("bpostalcode", order.BillingZipPostalCode);
            remotePostHelper.Add("btelephonenumber", order.BillingPhoneNumber);
            remotePostHelper.Add("email", order.BillingEmail);
            remotePostHelper.Add("saddr1", order.ShippingAddress1);
            remotePostHelper.Add("saddr2", order.ShippingAddress2);
            remotePostHelper.Add("scity", order.ShippingCity);
            remotePostHelper.Add("scountyprovince", order.ShippingStateProvince);
            // remotePostHelper.Add("scountry", order.ShippingCountry);
            remotePostHelper.Add("spostalcode", order.ShippingZipPostalCode);
            remotePostHelper.Add("stelephonenumber", order.ShippingPhoneNumber);

            remotePostHelper.Post();

            return string.Empty;
        }

        private string StripHTML(string p)
        {
            p = p.Replace("<INPUT name=epdqdata type=hidden value=\"", "");
            p = p.Replace("\">", "");
            return p;
        }

        /// <summary>
        /// Gets additional handling fee
        /// </summary>
        /// <returns>Additional handling fee</returns>
        public decimal GetAdditionalHandlingFee()
        {
            return SettingManager.GetSettingValueDecimalNative("PaymentMethod.eWayUK.AdditionalFee");
        }

        /// <summary>
        /// Captures payment
        /// </summary>
        /// <param name="order">Order</param>
        /// <param name="processPaymentResult">Process payment result</param>
        public void Capture(Order order, ref ProcessPaymentResult processPaymentResult)
        {
            throw new NopException("Capture method not supported");
        }

        /// <summary>
        /// Refunds payment
        /// </summary>
        /// <param name="order">Order</param>
        /// <param name="cancelPaymentResult">Cancel payment result</param>        
        public void Refund(Order order, ref CancelPaymentResult cancelPaymentResult)
        {
            throw new NopException("Refund method not supported");
        }

        /// <summary>
        /// Voids payment
        /// </summary>
        /// <param name="order">Order</param>
        /// <param name="cancelPaymentResult">Cancel payment result</param>        
        public void Void(Order order, ref CancelPaymentResult cancelPaymentResult)
        {
            throw new NopException("Void method not supported");
        }

        /// <summary>
        /// Process recurring payment
        /// </summary>
        /// <param name="paymentInfo">Payment info required for an order processing</param>
        /// <param name="customer">Customer</param>
        /// <param name="OrderGuid">Unique order identifier</param>
        /// <param name="processPaymentResult">Process payment result</param>
        public void ProcessRecurringPayment(PaymentInfo paymentInfo, Customer customer, Guid OrderGuid, ref ProcessPaymentResult processPaymentResult)
        {
            throw new NopException("Recurring payments not supported");
        }

        /// <summary>
        /// Cancels recurring payment
        /// </summary>
        /// <param name="order">Order</param>
        /// <param name="cancelPaymentResult">Cancel payment result</param>        
        public void CancelRecurringPayment(Order order, ref CancelPaymentResult cancelPaymentResult)
        {
        }

        #endregion

        #region Properties
        /// <summary>
        /// Gets a value indicating whether capture is supported
        /// </summary>
        public bool CanCapture
        {
            get
            {
                return false;
            }
        }
        /// <summary>
        /// Gets a value indicating whether refund is supported
        /// </summary>
        public bool CanRefund
        {
            get
            {
                return false;
            }
        }

        /// <summary>
        /// Gets a value indicating whether void is supported
        /// </summary>
        public bool CanVoid
        {
            get
            {
                return false;
            }
        }

        /// <summary>
        /// Gets a recurring payment type of payment method
        /// </summary>
        /// <returns>A recurring payment type of payment method</returns>
        public RecurringPaymentTypeEnum SupportRecurringPayments
        {
            get
            {
                return RecurringPaymentTypeEnum.NotSupported;
            }
        }

        /// <summary>
        /// Gets a payment method type
        /// </summary>
        /// <returns>A payment method type</returns>
        public PaymentMethodTypeEnum PaymentMethodType
        {
            get
            {
                return PaymentMethodTypeEnum.Standard;
            }
        }
        #endregion
    }
}
13 years ago
Will have got it build - opens up in the Demo mode....

ePDQPaymentProcessor.cs

I added line 266 new code...
/// <summary>
/// Gets a value indicating whether void is supported
/// </summary>
public bool CanPartiallyRefund
{
get
{
return false;
}
{

---------- Then rebuild and opens up the local Demo Store -----
Now to test the Barclay Card... Will give feedback hopefully soon....
13 years ago
Hi cityvouchers,

Sorry for not getting back to you.

I've replied behindthe scenes, so once resolved, we'll update this thread to tell you what was wrong.

Ed.
12 years ago
Would i be able to get a couple of this module, as i am interested in intergrating this into our store.
This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.