Библиотека классов для обработки кредитных карт


Я занимаюсь разработкой библиотеки классов для обработки кредитных карт. Есть мысль в управлении в краткосрочной перспективе искать новый процессор кредитной карты. Поэтому я хочу написать один раз и использовать везде (мне должно быть все равно, верно?).

В настоящее время мы используем первые данные глобальной веб-шлюз API сервиса. Мне нужна отдельная настройка веб-ссылки для видео и тест.

Я пытаюсь сделать следующее:

//using ProcessCreditCard.WebReference;
using ProcessCreditCard.WebReferenceTest;

public class ProcessCreditCard
{
    private FDGGWSApiOrderService oFDGGWSApiOrderService = null;

    #region Intialize the object
    /// <summary>
    /// Initializes a new instance of the <see cref="ProcessCreditCard"/> class.
    /// </summary>
    public ProcessCreditCard()
    {
        ServicePointManager.Expect100Continue = false;
        // Initialize Service Object 
        oFDGGWSApiOrderService = new FDGGWSApiOrderService();
        // Set the WSDL URL
        oFDGGWSApiOrderService.Url = @Properties.Settings.Default.CcApiUrl;
        // Configure Client Certificate  
        oFDGGWSApiOrderService.ClientCertificates.Add(X509Certificate.CreateFromCertFile(Properties.Settings.Default.CertFile));
        // Set the Authentication Credentials
        NetworkCredential nc = new NetworkCredential(Properties.Settings.Default.CertUser, Properties.Settings.Default.CertPass);
        oFDGGWSApiOrderService.Credentials = nc;
    }

    /// <summary>
    /// Initializes a new instance of the test version of the <see cref="ProcessCreditCard"/> class.
    /// </summary>
    /// <param name="test">if set to <c>true</c> [test].</param>
    public ProcessCreditCard(bool test)
    {
        ServicePointManager.Expect100Continue = false;
        // Initialize Service Object 
        oFDGGWSApiOrderService = new FDGGWSApiOrderService();
        // Set the WSDL URL
        oFDGGWSApiOrderService.Url = @Properties.Settings.Default.CcApiUrl_Test;
        // Configure Client Certificate  
        oFDGGWSApiOrderService.ClientCertificates.Add(X509Certificate.CreateFromCertFile(Properties.Settings.Default.CertFile_Test));
        // Set the Authentication Credentials
        NetworkCredential nc = new NetworkCredential(Properties.Settings.Default.CertUser_Test, Properties.Settings.Default.CertPass_Test);
        oFDGGWSApiOrderService.Credentials = nc;
    }
    #endregion

    /// <summary>
    /// Charges the credit card.
    /// </summary>
    /// <returns></returns>
    public MktoResponse ChargeCreditCard()
    {
        /// Code here for setting up the transaction
        return BuildResponse(oFDGGWSApiOrderService.FDGGWSApiOrder(oOrderRequest));
    }

Так что на мой телефонный код, я могу создать правильные условия, основанные на булевых:

ProcessCreditCard.ProcessCreditCard pcc = new ProcessCreditCard.ProcessCreditCard(true);

Как я могу сделать это так, что когда я ссылаться на oFDGGWSApiOrderService объект, который я использую правильную среду?



1155
3
задан 6 сентября 2011 в 08:09 Источник Поделиться
Комментарии
2 ответа

Во-первых, я надеюсь, что этот вопрос по-прежнему актуален в вашей компании. Один момент, который вызывает большой интерес ко мне вопрос, это видение руководства использовать другие 3 поставщиков обработке платежей участника. Это напрямую означает, что код должен разместить этот абстрагируя работу по обработке заказов и устранении зависимостей от внешних систем.

Я приведу некоторые простые предложения, имеющие целью отделить код от конкретной реализации (следовательно, повышение повторного использования кода и тестирования)

Шаг я, разрешить зависимость от 3-й участник кредитных услуг

Это достигается путем абстрагирования функциональные возможности, предоставляемые службой (конечно, каждая услуга будет иметь разную API, но логика обработки будет следовать более или менее одной и той же схеме):

public interface IPaymentGateWayService
{
List<X509Certificate> ClientCertificates { get; }
string Url { set; }
NetworkCredential Credential { set; }
}

Так что теперь ваш платеж процессор агностик, к которому он использует как таковое:

class PaymentProessor
{
private readonly IPaymentGateWayService _paymentGateWayService;

public PaymentProessor(IPaymentGateWayService paymentGateWayService)
{
_paymentGateWayService = paymentGateWayService;
_propertyProvider = propertyProvider;
}

public void ProcessCreditCardPayment()
{
_paymentGateWayService.Url = /*service url*/;
_paymentGateWayService.ClientCertificates.Add(/*X509 certificate*/)
_paymentGateWayService.Credential = new NetworkCredential(/*username and password*/);

}
}

Вы затем создать оболочку для вашего FDGGWApiOrderService , который реализует IPaymentGateEayService интерфейс:

class FDGGWS : IPaymentGateWayService
{
private FDGGWSApiOrderService _fdggwsApiOrderService;

public FDGGWS()
{
_fdggwsApiOrderService = new FDGGWSApiOrderService();
}

public List<X509Certificate> ClientCertificates
{
/*delegate to _fdggwsApiOrderService*/
}

public string Url
{
/*delegate to _fdggwsApiOrderService*/
}

public NetworkCredential Credential
{
/*delegate to _fdggwsApiOrderService*/
}
}

Так что теперь, когда вы создаете свою платежную систему, вы передаете экземпляр сервиса, который вы хотите использовать.

new PaymentProessor(new FDGGWS());

Это позволяет повторно использовать код для размещения различных поставщиков услуг, также, вы можете поддержка нескольких провайдеров одновременно, создавая фабрики сервис, который возвращает требуемый конкретный экземпляр тех. обслуживание в зависимости от настроек конфигурации.

Шаг II, ручка настройки среды

Есть куча методов, которые позволяют считывать значения из конфигурации магазинах, как приложение.конфигурации или веб.конфиг. Но цель моего ответа я буду использовать технику инъекции зависимостей и устранить зависимость от свойств среды с помощью инъекций конструктор, подобный тому, что используется в абстрактный интерфейс сервиса.

Поэтому мы создаем интерфейса для настройки конфигурации:

internal interface IPropertyProvider
{
string Cert_File { get; }
string Cer_User { get; }
string Cer_Password { get; }
string ServiceUrl { get; }
}

И вы можете создать столько вкусов, которые есть среды, в вашем случае для теста и один для производства, вот сокращенный пример из:

class ProductionPropertyProvider : IPropertyProvider
{
public string Cert_File
{
get { return "Path to Production file"; }
}

/* other properties */
}

class TestPropertyProvider : IPropertyProvider
{
public string Cert_File
{
get { return "Path to test file"; }
}

/* other properties */
}

А вот как вы выполняете инъекцию зависимостей:

class PaymentProessor
{
private readonly IPaymentGateWayService _paymentGateWayService;
private readonly IPropertyProvider _propertyProvider;

public PaymentProessor()
:this(new FDGGWS(), new ProductionPropertyProvider())
{}
public PaymentProessor(IPaymentGateWayService paymentGateWayService, IPropertyProvider propertyProvider)
{
_paymentGateWayService = paymentGateWayService;
_propertyProvider = propertyProvider;
}

public void ProcessCreditCardPayment()
{
_paymentGateWayService.Url = _propertyProvider.ServiceUrl;
_paymentGateWayService.ClientCertificates.Add(X509Certificate.CreateFromCertFile(_propertyProvider.Cert_File));
_paymentGateWayService.Credential = new NetworkCredential(_propertyProvider.Cer_User, _propertyProvider.Cer_Password);

}
}

Обратите внимание на конструктор по умолчанию, который создается по умолчанию службы и экземпляры поставщика имущества. Это просто, чтобы продемонстрировать, что вы можете указать зависимостей по умолчанию в конструкторе по умолчанию

Наконец, все, что вам нужно, это один конфигурационный ключ в вашем приложении.config, который определяет какой среде она.. мы использовать этот ключ, чтобы определить тип IPropertyProvider.

Пример

//Read env setting from the application configuration file
var environment = ConfigurationManager.AppSettings["env"];

//create appropriate PropertyProvider
IPropertyProvider propertyProvider;
if (environment == "test")
propertyProvider = new TestPropertyProvider();
else
propertyProvider = new ProductionPropertyProvider();

//process the payment
new PaymentProessor(new FDGGWS(), propertyProvider).ProcessCreditCardPayment();

4
ответ дан 20 октября 2011 в 10:10 Источник Поделиться

Вот один способ. В файле настроек, определения "режим". Тумблер, что за текущий/тест. Затем создайте открытое свойство, которое использует тот (я положил его в Мои настройки.файл CS).

    /// <summary>
/// Gets the DB connection string
/// </summary>
/// <value>The DB connect.</value>
public string DBConnect {
get {
// Determine which database should be connected to
switch (this.DBConnect_Mode) {
// Connect to the live database
case "Live": return this.DBConnect_Live;
// Connect to the dev database
case "Dev": return this.DBConnect_Dev;
// All other cases, connect to the live database
default: return this.DBConnect_Live;
}
}
}

Затем в мой код вызова я просто использовать это:

var connection = Properties.Settings.Default.DBConnect;

Таким образом, вы можете легко переключаться и даже это будет необязательный параметр на экране конфигурации. Вы также можете использовать символы вместо 3-й параметр.

0
ответ дан 6 сентября 2011 в 08:09 Источник Поделиться